问题
In Git when I have commits eg. A - B - C and I want to edit the B commit, I
- use
git rebase -i <A-commit-hash>, - in the list I write
editcommand in front ofBcommit, - git rebase stops right after
Bcommit so I can fix anything I want usinggit commit --amend, - and then I continue using
git rebase --continue.
As far as I know this is the best practice how to do this. With this method I can edit any commit in the past (as long as it hasn't been pushed to remote branch yet), and moreover with -p flag I can even preserve the merges. This is just great.
My current problem is: I did a mistake (typo) on one line in a merge commit (while resolving a conflict when merging two branches).
I'd like to fix it but I don't know how to make git rebase to stop at a merge commit. The git rebase -p -i <blah> list ignores merge commits, so I cannot write edit command in front of it and make the git rebase stop there to let me edit it.
Any help please? I just want to fix this line in the merge commit while preserving all the commits (and merges) after it.
Thanks.
回答1:
Git does not make it easy to do interactive rebases when merges are involved. The -p option uses the -i mechanism internally, so mixing the two doesn't really work.
However, git rebase is just an automated way to do lots of cherry-picks. You can replicate its behavior by manually cherry-picking to get a bit more control over the process. It's less convenient and more prone to human error, but possible.
This is the approach I suggest:
- use
git rebaseto get to the commit after the merge (the child of the merge) - use
git reset --hard HEAD^to manually get to the merge - use
git commit --amendto repair the merge - use
git cherry-pickto get back to the commit after the merge - use
git rebase --continueto finish
Here are the specific steps:
- Note the SHA1 ID of the merge commit you want to modify. For discussion, suppose it is
deadbeef. - Note the SHA1 ID of the commit right after the merge commit you want to modify (the merge commit's child). Suppose it is
facef00d. - Run
git rebase -i deadbeef. - Select
facef00dfor editing. - When rebase returns you to a prompt to edit
facef00d, rungit reset --hard HEAD^. You should now be atdeadbeef(git rev-parse HEADshould printdeadbeef). - Make your edits to fix the incorrect merge conflict and use
git addto stage them. - Run
git commit --amendto fuse the staged fix with the bad merge commit. The result will now have a different SHA1 (notdeadbeef). - Run
git cherry-pick facef00dto apply the changes made byfacef00dto the fixed merge commit. - Run
git rebase --continueto finish.
回答2:
May be easier to create a fixup commit 'D' then use 'git rebase -p -i <blah>' to reorder 'D' right after 'B' and squash it into 'B'.
pick A
pick B <- merge commit to ammend
fixup D
pick C
来源:https://stackoverflow.com/questions/9930637/edit-a-merge-commit-with-git-rebase