开发者

Can I interactively pick hunks from another git commit?

I'm looking for exactly the same behavior as

git add -i -p

But instead of composing a commit from my working directory, I'd like to compose my working directory from (parts of) a commit. How can I do that ?

My use case is that I have several distinct fe开发者_开发知识库atures that are grouped together in a single commit and I'd like to test them one by one

Using cherry-pick -n is not really satisfactory, since it leaves me with the dirty job of removing all the unrequired code. I'd really just like to pick the selected changes I want to test.


Using cherry-pick -n is not really satisfactory, since it leaves me with the dirty job of removing all the unrequired code. I'd really just like to pick the selected changes I want to test.

The job may have been a dirty one before, but with the advent of git checkout --patch, you can now selectively discard changes, similar to git add -p for adding.


You could use git reset --mixed HEAD^1 to revert the index, then pick the hunks you want with git add -i.

The reset will roll back the index to the previous commit (essentially un-committing whatever was the HEAD), but it won't touch the working tree. You can now stage the hunks you want, commit them and throw away the rest with a git reset --hard HEAD.


Building on the great answer from Cameron Skinner, I will expand this a bit to include the case when you have a branch with multiple commits, perhaps merge commits, perhaps a lot of "noise" and you want to cherry-pick only very specific hunks from it. (which was exactly what happened to me today)

Follow these steps:

git checkout source-branch
git checkout -b cherry-pick-branch # Gives you a new branch based on source-branch
git reset --mixed master

This will leave you with a branch where all changes are in the filesystem, but nothing has been commited/staged. Then use git add -p to selectively add which parts you want to stage, and then commit & push as normal.


dirty job of removing all the unrequired code

If this is not acceptable,

git cherry-pick -n ...         # Starting from clean status
git reset                      # unstage
git add -p / -i [<pathspec>…​]  # add hunks interactively
git restore .                  # wipe the rest (at root dir)

, for example if you want to merge into uncommited changes or don't want to spoil time stamps, then using git apply like this may be a cleaner option:

git show <commit> | tee _.patch
edit _.patch                    # strip unwanted hunks
git apply -3 _.patch

(As long as git cherry-pick and git apply do not support -p directly)

Note: Methods like git checkout / restore -p ... do not consistently revert hunks from a specific commit but pick parts from a certain file state - possibly loosing changes in other later commits.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜