Repository navigation
fix(worktrees): withhold a shallow clone's unprovable force verdict - #2195
Merged
Merged
Conversation
…verdicts In a --depth clone, `git fetch --depth` can make a branch's upstream a shallow root whose parent, the local tip, is hidden. A branch that only needed a fetch then counted as 1 ahead and 1 behind and was classified would-force (or default-branch-force-push), offering a FORCE confirmation for a push the lease was bound to refuse. shallow::divergence_is_provable now says whether "ahead and behind" proves divergence: always in a complete repository, and in a shallow one only when a merge base is visible inside the cut, read through the same handle the walk uses. The push classifier reports Skipped(HistoryUnreadable) when it is not, before the default-branch gate. A visible merge base is a heuristic, not a proof, which the docs say. Fixes #2175
The history-unreadable skip text read as corruption when the cause is a shallow cut hiding whether a branch diverged. It now says the history could not be compared and names `git fetch --unshallow`, in the CLI and the VS Code extension, and the extension changelog records the change.
CoverageTotal: 97.95% ⚪ 0 pp vs Comparing No per-file coverage changes vs 🔇 269 ignored region(s), 0 tolerated region(s)
Patch coveragePatch: 100% (137/137 new lines covered)
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
In a
--depthclone,git fetch --depthcan make a branch's upstream a shallow root whose parent, the local tip, is hidden. A branch that only needed a fetch then counted as 1 ahead and 1 behind, the same as a rewritten one, and the push classifier reportedwould-force(ordefault-branch-force-push). The user got a FORCE confirmation for a push the lease was bound to refuse."Ahead and behind" now proves divergence in a shallow repository only when a merge base is visible inside the cut. Otherwise the row is
skippedwithhistory-unreadable. This coversomni-dev worktrees pushand the daemon'spushop, which share the classifier.Type of Change
Related Issue
Closes #2175
Plan comment: #2175 (comment)
Changes Made
Core Changes:
crate::git::shallow::divergence_is_provable:truefor a complete repository; for a shallow one,trueonly whenmerge_basefinds an ancestor. It reads through the handlegraph_ahead_behinduses (the common dir for a linked worktree, the only handle that applies the cut). A failed walk or open is not provable. The handle choice is now one private helper,with_cut_applied, shared by both functions.worktree_push::classifyreturnsSkipped { HistoryUnreadable }for an unprovable ahead-and-behind row, before the default-branch gate.history-unreadableskip text (CLI and VS Code extension) now reads "could not compare its history with its upstream (in a shallow clone,git fetch --unshallowmay settle it)".Documentation:
docs/worktrees-service.md,CLAUDE.md, both changelogs. The docs say a visible merge base is a heuristic, not a proof.Testing:
shallow.rs: unit tests for complete, shallow with no merge base, shallow with a visible merge base (main checkout and linked worktree), and an unanswerable walk.worktree_push.rs: the issue's reproduction with a real--depth 1clone (only behind, so skipped); the default-branch variant; the existing real-clone counts test moved to--depth 2, where the merge base stays visible and the row is stillWouldForcewith git's own counts. The depth-1 test that ended inDefaultBranchForcePushnow expectsHistoryUnreadable.Testing
Automated Testing:
The VS Code extension tests were not run: the worktree has no
node_modules, and the extension change is one string literal and its expected value inpushReport.test.ts.Departure from plan / behaviour notes
history-unreadableand cannot be force-pushed until the clone is deepened. That is the direction the issue chose, and there is deliberately no force escape hatch (ADR-0061). The skip text now namesgit fetch --unshallow.origin/mainafterfetch --depth 1) now readshistory-unreadableinstead ofdefault-branch-force-push, as the issue anticipated.Review findings (one round)
Fixed: the skip text read as corruption and gave no remediation (now names
--unshallow; extension changelog entry added); an over-long module doc line.Skipped, with reasons:
--depth 2divergence, where the merge base is itself a shallow root.merge_baseerrors other thanNotFound. The safe direction, and hard to exercise in a test. The failed-open case is already logged.Follow-ups
ahead-behindop still shows the cut counts (↑1 ↓1) in a shallow clone, withshallow: true. Whether to mark them unreliable is a separate UI question the issue also left open.