This is a scenario I've run into multiple times: suppose you have a feature branch, and you then need to merge in the develop branch and resolve conflicts prior to your PR being merged. You merge develop, fix all the conflicts, run and test your code, and find you made one very small mistake in fixing the merge conflicts. You make one small commit fixing that incorrect merge conflict resolution. Now, you want to clean things up and squash this last commit into the previous commit, which is a merge commit. Is there any way to do this without having to manually redo all of your merge conflict resolution?
4 Answers
If you just committed your last fix commit that you talked about, you can do this:
git reset --soft HEAD~ # keep the pigtail
git commit --amend --no-edit
Voilá!
1 Comment
If the merge you want to fixup is at the tip of a branch, you can amend the commit:
- Make sure the merge commit is the currently checked out commit using
git status,git logetc - Make your required change and use
git addas required - Run
git commit --amend; if you want to keep the original message, add--no-edit - Verify the result with
git show HEADorgit log --graph- you should see that the current commit is still listed as a merge of the original two parents
This behaviour is explicitly documented:
The new commit has the same parents and author as the current one (the --reset-author option can countermand this).
If there are other commits after the merge, this is slightly more difficult; however, if there are no other merges after the one you want to fix, you could rewind to just after the merge, then replay the remaining commits on top.
e.g. if your branch is called my-feature and the merge commit to fix is abc123def
- Create a temporary branch from the merge commit:
git switch -c temp-to-fix-merge abc123def - Make your changes, and use
git commit --amendas above - Switch back to your original branch:
git switch my-feature - Replay commits after the merge onto the new version of the merge:
git rebase abc123def --onto temp-to-fix-merge - Tidy up the temp branch:
git branch -d temp-to-fix-merge
Comments
Just completing @IMSoP's answer: here is a way to use git rebase -i and add a "break" instruction to manually "stitch together" the fixup and the merge commit:
[mybox] (left)$ git log --oneline --graph
* 7e4759e (HEAD -> left) create h.txt
* 9bcd31b create g.txt
* 21d3b5c add fix to merge commit (update e.txt)
* fc44140 Merge branch 'right' into left
|\
| * 49d3a5d (right) create f.txt
| * 9d7cc54 create e.txt
* | e5f7da7 create d.txt
* | d8c7457 create c.txt
|/
* 8be599b create b.txt
* f137b07 create a.txt
* 1e8ac8d first commit
[mybox] (left)$ git rebase -i fc44140 # <- the merge commit
### an editor opens:
#pick 21d3b5c add fix to merge commit (update e.txt)
#pick 9bcd31b create g.txt
#pick 7e4759e create h.txt
#
## Rebase fc44140..7e4759e onto fc44140 (3 commands)
## ...
### add a 'break' line right after the 'add fix' commit:
#pick 21d3b5c add fix to merge commit (update e.txt)
#break # <- here
#pick 9bcd31b create g.txt
#pick 7e4759e create h.txt
#
### save & exit
Stopped at 21d3b5c (add fix to merge commit (update e.txt))
# ammend the merge commit:
[mybox] (left|REBASE 2/4)$ git reset --soft HEAD~ && git commit --amend --no-edit
# proceed with the rebase:
[mybox] (left|REBASE 2/4)$ git rebase --continue
2 Comments
break after a commit and edit on that commit?git rebase --continue: with edit, git will execute the git commit --amend for you ; with break, you will get a message stating "you have staged changes in your working tree ... please run git commit --amend". (if you have unstaged changes, both variants will show the same error message "You must edit all merge conflicts [and run git add]")Unfortunately, no. I don't think it’s possible for you to squash a commit into a merge commit using git standard tool (rebase commit --amend) without redoing the resolution manually. But you can recreate the merge from scratch this time very cleanly using --no-commit. Alternatively, you can avoid this by fixing everything before committing the merge.