Keep per-file index flags when rebuilding the workspace index - #15185
Open
ameyypawar wants to merge 2 commits into
Open
Keep per-file index flags when rebuilding the workspace index#15185ameyypawar wants to merge 2 commits into
ameyypawar wants to merge 2 commits into
Conversation
`skip-worktree` and `assume-unchanged` live only in the index, so rebuilding it from the workspace tree dropped them. libgit2 keeps an entry whose blob and mode are unchanged but clears its extended flags either way, which loses skip-worktree on every path and assume-unchanged wherever the entry is replaced. The flags are taken before the checkout, which writes the index itself, and put back on the paths that are still tracked once the rebuild is done.
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.
🧠 Changes
update_workspace_commit_with_vb_state()now carriesskip-worktreeandassume-unchangedacross the index rebuild. The flags are read before the checkout, which writes.git/indexitself, and put back onto the paths that are still tracked once the rebuild is done. Only those two bits are carried over, the rest of each entry belonging to the tree the index was just rebuilt from.☕️ Reasoning
Both flags live only in the index, since a tree has nowhere to record them, so
git_index_read_tree()drops them. Its per-entry callback copies the old entry when blob and mode are unchanged, keepingflags, and then clearsflags_extendedunconditionally.skip-worktreelives in the latter and goes every time;assume-unchangedlives in the former and survives until the rebuild actually replaces the entry.Rebuilding the index runs after most legacy-path operations, which is what makes the flags look like they are being undone continuously rather than at one identifiable moment.
Three tests cover this, one per mechanism:
skip-worktreeon a path the workspace commit does not touch,assume-unchangedon a path it does, which is what it takes to lose that one, and both flags across thecheckout_new_worktreepath, where the checkout writes the index before the rebuild gets there.Two places outside this function still clear the flags wholesale, and this change leaves them alone:
reset_index_to_tree()ingitbutler-oplogrebuilds the index from the snapshot tree, so undo clears themsave_and_return_to_workspace()ingitbutler-edit-modedoes the same on the way out of edit modeBoth would want the same treatment, and doing it properly probably means a shared helper rather than three copies, so I have kept this change to the path described in the issue. Happy to follow up separately or fold them in here, whichever you prefer. #5842 remains the separate sparse-checkout gap.
🎫 Affected issues
Addresses: #2674