'Creating merge commit in git with reversed parents order

In Weblate we're sometimes creating merge commits which get in the end pushed to the upstream repository. I'd like them to be constructed with parent commits in different order, so that tools like GitHub would show Weblate changes instead of changes in upstream repository when displaying the merge commit (they always treat first parent as current branch and second one as merged one).

You can see example here - that is pretty much git diff 4a4f5aaa8...bb81599ac, while I'd like to get git diff bb81599ac...4a4f5aaa8 instead. So what I need is to have different order of parent commits in the merge commit.

How it currently works:

git clone https://github.com/WeblateOrg/weblate.git
edit translations
git commit -a -m 'Translated using Weblate'
git remote update origin
git merge orgin/master  
# Now we have merge commit in case there are changes in upstream meanwhile

As an obvious workaround (instead of plain git merge orgin/master), we could create temporary branch, do the merge there and merge back:

# Create local branch for upstream
git branch tmp origin/master
# Checkout upstream branch
git checkout tmp
# Merge current Weblate changes, this can lead to conflict
git merge master
# Checkout branch with Weblate changes
git checkout master
# Merge temporary branch (this is fast forward so does not create merge commit)
git merge tmp
# Delete temporary branch
git branch -d tmp

This way the merge commit would be constructed in a way I want, however it seems quite complex way to do this. Is there simpler way to achieve the same?



Solution 1:[1]

Your method is probably the best and least prone to error because it only uses porcelain commands. Your other option is to use a bit of plumbing, which will require some hash juggling.

Merge without a commit, using the squash option over the no-commit object as suggested below:

git checkout master
git merge --squash branch

Then create a tree object for your index using git-write-tree and craft your commit manually using git-commit-tree:

git write-tree
git commit-tree -p parent1 -p parent2 -m "message" <tree-hash>

This method should be scriptable without too much difficulty.

Solution 2:[2]

You can do this using detached head instead of a temporary branch.

git checkout origin/master
git merge master
git checkout -B master

This 1) detaches HEAD at origin/master, then 2) performs the merge in the desired direction, and finally 3) fast-forwards the master branch and checks it out.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2