I have a file named foo. I make some modification M1 to foo and stage it. Then I revert it in the working tree by checking it out from HEAD, and make another modification M2 to it. Now I want to merge these two modifications before commit. How can this be done? Thanks!
(I know branches are for this kind of work. But I’d like to know whether there is a way to merge a staged file with the modified version in the working tree.)
The most obvious solution is to create two commits, and merge them. This is fairly safe, as once you get your changes into two different commits, it’s fairly hard to lose them, and if the merge doesn’t go as you want, you can throw away the merge commit and try again.
For the first commit, you already have the changes staged, so just
git commitshould be sufficient.For the second, you have a state in your working copy that represents changes to the original
HEAD. But now that you’ve done that commit, there’s an intervening one;HEADis what was in the index, so it looks like your working copy reverts those changes. To get around this, we need to reset where ourHEADpoints, without changing what’s in the working copy.Before doing so, let’s save a pointer to our current
HEAD:git branch was-in-index. Now we can reset to the previousHEAD(the parent ofHEAD) withgit reset HEAD^, and add and commit our changesgit add some stuff; git commit(orgit commit -a, if you want all of your changes).Now we have two branches; our current one, which contains the changes from the working copy, and
was-in-index, which contains the changes which were in the index. Now you can merge these however you want;git merge was-in-index,git rebase was-in-index, or what have you. You can delete thewas-in-indexbranch when you’re done.