Flimm Flimm - 1 month ago 5
Git Question

How do I swap the order of two parents of a Git commit?

A merge commit is a commit with at least two parents. These parents are in specific order.

If I'm currently on the branch

master
, and I merge in the branch
feature
, I create a new commit with its first parent being the commit from
master
, and the second commit being the commit from
feature
. This order is especially evident by running
git log --first-parent
.

* The merge commit
|\
| * The commit from `feature`
* | The commit from `master`


Say I now realise that the order is the wrong way round: I intended to merge the branch
master
into
feature
by running
git checkout feature; git merge master
. I want to swap the order of the parents of a merge commit, but I do not want to go through the hassle of resolving all the merge conflicts again. How can I do this?

* The merge commit
|\
* | The commit from `feature`
| * The commit from `master`

Answer

Actualy, there's a really cool command I learned recently that will do exactly what you want:

git commit-tree -p HEAD^2 -p HEAD^1 -m "Commit message" "HEAD^{tree}" 

This will create a new commit based on what is currently HEAD, but pretend that it's parents were HEAD^2,HEAD^1 (note this is the reversed order).

git-commit-tree prints the new revision as output, so you might combine it with a git-reset-hard:

git reset --hard $(git commit-tree -p HEAD^2 -p HEAD^1 -m "New commit message" "HEAD^{tree}")