问题
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
edit
command in front ofB
commit, - git rebase stops right after
B
commit 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 rebase
to 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 --amend
to repair the merge - use
git cherry-pick
to get back to the commit after the merge - use
git rebase --continue
to 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
facef00d
for editing. - When rebase returns you to a prompt to edit
facef00d
, rungit reset --hard HEAD^
. You should now be atdeadbeef
(git rev-parse HEAD
should printdeadbeef
). - Make your edits to fix the incorrect merge conflict and use
git add
to stage them. - Run
git commit --amend
to fuse the staged fix with the bad merge commit. The result will now have a different SHA1 (notdeadbeef
). - Run
git cherry-pick facef00d
to apply the changes made byfacef00d
to the fixed merge commit. - Run
git rebase --continue
to 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