Skip to content
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

Add support for dirty worktrees #2

Merged
merged 6 commits into from
Nov 10, 2020
Merged

Add support for dirty worktrees #2

merged 6 commits into from
Nov 10, 2020

Conversation

betwo
Copy link
Collaborator

@betwo betwo commented Oct 7, 2020

Hey @siedentop,

thank you for this nice git extension!

I noticed that local changes in the repository are reset if the --keep flag is not specified, as

repo.reset(&head_1.as_object(), ResetType::Hard, None)?;

performs a hard reset on the HEAD.

As this could lead to lost work, I propose a few tweaks / features:

  1. Check if the worktree is dirty, refuse to do anything in this case, except for ...
  2. ...when the proposed --autostash flag is given, in which case a temporary stash is created like with rebase.autoStash.
  3. Create the target branch before performing the cherry pick, to keep the main branch unmodified

(3. is actually independent of the other changes, but greatly helps with repeatedly running the command.)

I have also split the command into several functions, because the stash_... functions required a &mut Repository and this way explicit drop(...) invocations can be avoided.

I'm happy to continue working on this, If you'd like to keep any of these features.

Cheers

@betwo betwo changed the title Add support for diry worktrees Add support for dirty worktrees Oct 7, 2020
Copy link
Owner

@siedentop siedentop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for identifying this issue!

It showed me that I really need to add the tests that I've been thinking of.

@@ -50,7 +53,6 @@ cargo install git-quickfix

## Known Issues

- A dirty index or modified working directory will likely not work.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't your changes fix this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the line is removed because the issues should be fixed by this PR.

// Create the new branch
let new_branch = repo
.branch(&opts.branch, &main_commit, opts.force)
.suggestion("Consider using --force to overwrite the existing branch")?;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to create the branch after the cherry picking. In case the cherry pick fails.

I believe that this might be a misunderstanding -- the previous version should not have ever modified the master branch.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look into it again. What I had seen was that master had been modified after running the command, but now I'm not sure anymore.

let fix_commit = repo.head()?.peel_to_commit()?;
if fix_commit.parent_count() != 1 {
return Err(eyre!("Only works with non-merge commits"))
.suggestion("Quickfixing a merge commit is not supported. If you meant to do this please file a ticket with your usecase.");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remind me: I should point to this repo for filling tickets.

cherrypick_commit_onto_new_branch(&repo, &opts)?;

if !opts.keep {
remove_commit(&mut repo, &opts, is_dirty)?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I misunderstand this, but shouldn't it be if !opts.keep && is_dirty ? I see that it would potentially stash if is_dirty is true and --stash has been provided. That seems to be mixing responsibilities a bit.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic now says that if the user does not specify --keep, the command should always try to remove the commit.
Removing the commit will raise an error if the working directory is dirty and --stash is not given.

I think the latest commit can be removed if either

  1. the working directory is clean, aka !is_dirty, or
  2. is_dirty and opts.stash is activated.

Changing the line to

if !opts.keep && is_dirty {

would cause the 1. case to fail, right?

Would you prefer to inline the remove_commit function here to make the "stashing" more visible?

@dvogt23
Copy link

dvogt23 commented Nov 10, 2020

Please merge it, had lost my unstaged changes 😢 🙏

@betwo
Copy link
Collaborator Author

betwo commented Nov 10, 2020

Sorry, I got sidetracked. Will respond the the review comments now

siedentop added a commit that referenced this pull request Nov 10, 2020
Thanks to @betwo for the fruitful discussion and explanation of the
code.

#2
@siedentop siedentop merged commit 5346509 into siedentop:main Nov 10, 2020
@siedentop
Copy link
Owner

Dear @dvogt23 ,

I am extremely sorry that this bug caused you the loss of work. I will try very hard that this does not happen again, and hope that quickfix will be valuable in the future.

Please let me know if you have any ideas for improvement.

Kind regards,
Christoph

siedentop added a commit that referenced this pull request Nov 10, 2020
Thanks to @betwo for the fruitful discussion and explanation of the
code.

#2
siedentop added a commit that referenced this pull request Nov 11, 2020
Thanks to @betwo for the fruitful discussion and explanation of the
code.

#2
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.

3 participants