-
Notifications
You must be signed in to change notification settings - Fork 788
git: worktree, Don't delete local untracked files when resetting worktree #1540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refines the worktree reset functionality so that local untracked files are preserved when resetting the worktree, addressing issue #53.
- Updates the test in worktree_test.go to verify that untracked files (e.g. "foo") remain unaltered.
- Modifies the ResetSparsely, resetIndex, and resetWorktree functions in worktree.go to track removed files and adjust the file checkout logic based on untracked status.
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
File | Description |
---|---|
worktree_test.go | Replaces a simple IsClean assertion with a loop to validate specific file statuses. |
worktree.go | Returns removed file information from resetIndex and uses it in resetWorktree to decide which files to check out. |
worktree.go
Outdated
// only checkout an untracked file if it is in the list of files | ||
// a reset should leave untracked files alone | ||
file := nameFromAction(&ch) | ||
if status.File(file).Worktree != Untracked || inFiles(files, file) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use ch
instead of status? I think something like
action, err := ch.Action()
if err != nil {
return err
}
if action != merkletrie.Insert {
// checkout the file
}
Would work since "Untracked" would mean that the file appears in worktree but not in staging.
For reference, Status()
also works this way internally.
Lines 93 to 118 in 93ed29d
right, err := w.diffStagingWithWorktree(false, true) | |
if err != nil { | |
return nil, err | |
} | |
for _, ch := range right { | |
a, err := ch.Action() | |
if err != nil { | |
return nil, err | |
} | |
fs := s.File(nameFromAction(&ch)) | |
if fs.Staging == Untracked { | |
fs.Staging = Unmodified | |
} | |
switch a { | |
case merkletrie.Delete: | |
fs.Worktree = Deleted | |
case merkletrie.Insert: | |
fs.Worktree = Untracked | |
fs.Staging = Untracked | |
case merkletrie.Modify: | |
fs.Worktree = Modified | |
} | |
} |
This way we can avoid re-doing computations that we already have done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @onee-only
Thanks for the reviews. I just realised that I don't need the check at all and I can directly do checkout.
The files
being passed is always going to just include the files which need changes and no other files.
worktree.go
Outdated
// only checkout an untracked file if it is in the list of files | ||
// a reset should leave untracked files alone | ||
file := nameFromAction(&ch) | ||
if status.File(file).Worktree != Untracked || inFiles(files, file) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any specific reason that we check inFiles
here? I think it is already done in block above.
I wasn't paying attention to the comment. Sorry for the confusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey
You were right actually. I just removed the complete condition.
Fixes #53