Here is the scenario:
-I made a lot of small and开发者_运维百科 big modifications to my files and didn't commit them
-I decided to use git commit --interactive
and use the patch command to stage parts of commits
-I tried to leave all commits relevant when I did it
-I discovered after multiple commits that I accidentally put in a change I was supposed to leave out in the first place 6 commits ago, so I reverted that commit.
-The revert deleted the text relevant in the file, which is expected behavior.
The last step is the one I want to modify. What I want to do is revert a commit, but leave the text in the file so I can re-stage the commit. The way I went about it was diffing the HEAD to the commit before the revert commit, and then I copied and pasted the text and modified it so it wasn't in diff format so I could use it in the file, and then committed it properly.
I do realize I need to learn the habit of committing early and often. I haven't gotten the hang of it, yet, since it likes to interrupt my mindset when I'm just coding away.
The way I did fixed it was tedious. Is there a way to just leave the text in a file that would be removed in a revert as if it is an unstaged change (kind of like reset does)? Any suggestions beyond that?
You can run the revert twice, and the last time apply --no-commit
which will leave the changes in the index ready for committing:
git revert <the commit you want back in the working tree>
git revert HEAD --no-commit
The changes are now staged and ready for a new commit. To unstage run:
git reset HEAD
After you've run the git revert BADCOMMIT
you can restore a particular file to its state before that commit with:
git checkout HEAD^ -- filename
... which should update your working copy of filename
to its state before the revert commit. (The old version will also be staged, so if you want to unstage it, do git reset HEAD -- filename
afterwards.) I don't think there's an easier way of doing that.
git reset -p <COMMITHASH>
This will prompt for reapplying the patch to your index.
Remember this will choose the changes from the commit you mentioned to the index, which means it will try to apply (reversely) all the previous 6 commits to your index. You have to choose only the changes you want to remove.
After you reverted the commit, you could apply the revert in reverse to “unrevert” it only in the working tree:
git revert C && # you already did this part
git show HEAD | git apply -R
By default, git apply
only patches the working tree. It also has options to patch only the index or both the index and working tree. So, instead of using git revert
, you could have used git apply
to apply the changes in reverse to only the index and then commit (all without ever touching the working tree):
# assumption: we start with no staged changes, and have not reverted anything yet
# revert C directly in the index (does not touch the working tree), then commit
git show C | git apply --cached -R &&
git commit --edit -m'Reverted C'
精彩评论