Amedee Van Gasse
Amedee Van Gasse

Reputation: 7634

Find the right parent of a merge commit in a non-interactive way

I'm preparing a svn2git migration and while https://github.com/nirvdrum/svn2git has been incredibly useful, I still ended up with a couple of shenanigans. I've been able to clean up most of them, but one still remains. I have a history that looks like this:

A1 - B1 - C1 - E1 - F1
             \
A2 - B2 - C2 - D1

A1-C1 and A2-C2 are identical, except for an additional subdirectory level. A2-C2 is really an artifact of the svn migration and of previous git-filter-branch operations, I made sure of that. D1 is a merge commit that was tagged as release_2_0_4.

I want to get rid of A2-C2. I see two ways of doing that:

  1. Untag D1, tag C1, reflog expire and garbage collect. Poof! A2-C2 is gone.
  2. I could also rewrite D1's parents so it only has C1 as a parent, with a bit of git-filter-branch magic.

I could use the first method because the file content of C1 and D1 is identical (checked with git diff C1 release_2_0_4), but then I would lose commit date, author and message.

The second method would be:

git filter-branch --tag-name-filter cat --parent-filter 'test $GIT_COMMIT = [sha of release_2_0_4] && echo "-p [sha of FIRST parent of release_2_0_4]" || cat' -- --all

I already tried it in a manual way with hard coded SHA, and it works. But I need to script it, without knowing the SHA.

I know how to find the parents of D1, they can be referenced with the caret notation: release_2_0_4^1 and release_2_0_4^2 (found that here: Get parents of a merge commit in git), but I am not sure how I can find out which is which. I am doing this in a script, not in an interactive way, and other git-filter-branch operations may change the SHA hashes, so I need to find a way to determine which of the two commits I need. The only clue I have is that C1 has 2 child commits while C2 has only one child commit.

To summarize, my questions are:

PS: I don't need to worry about upstream, none of the git repos out there that may contain this code are considered official and they won't be until I give the green light for the svn2git migration.

Upvotes: 2

Views: 158

Answers (1)

Amedee Van Gasse
Amedee Van Gasse

Reputation: 7634

I found that there is no reliable way to do this, because git sees each parent as an equal, and it just uses them in whatever order it gets them.

So I ended up doing it manually, as described above.

Upvotes: 1

Related Questions