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