Skip to content

Keep per-file index flags when rebuilding the workspace index - #15185

Open
ameyypawar wants to merge 2 commits into
gitbutlerapp:masterfrom
ameyypawar:fix/2674-skip-worktree
Open

Keep per-file index flags when rebuilding the workspace index#15185
ameyypawar wants to merge 2 commits into
gitbutlerapp:masterfrom
ameyypawar:fix/2674-skip-worktree

Conversation

@ameyypawar

Copy link
Copy Markdown
Contributor

🧠 Changes

update_workspace_commit_with_vb_state() now carries skip-worktree and assume-unchanged across the index rebuild. The flags are read before the checkout, which writes .git/index itself, 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, keeping flags, and then clears flags_extended unconditionally. skip-worktree lives in the latter and goes every time; assume-unchanged lives 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-worktree on a path the workspace commit does not touch, assume-unchanged on a path it does, which is what it takes to lose that one, and both flags across the checkout_new_worktree path, 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() in gitbutler-oplog rebuilds the index from the snapshot tree, so undo clears them
  • save_and_return_to_workspace() in gitbutler-edit-mode does the same on the way out of edit mode

Both 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

`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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant