6

I was reading about the difference in using a ~ vs ^ operator in git and I came across this question What's the difference between HEAD^ and HEAD~ in Git?

The one thing I could not find a good explanation for online after googling is how does git distinguish the first parent of a merge commit from the second one?

Is there a rule of thumb?

Take this example where a feature branch is merged into the develop branch, creating the merge commit G.

develop feature/foo
     A   D
     |   |
     B   E
     |   |
     C   F
      \ /
       G <- develop(HEAD)

Which one is the first parent of G? C or F? Why is it the first parent?

NOTE: This is not a request for the git command to determine the first or the second parent. I'm aware that it can be achieved using git show G^1 and git show G^2. I see that C is the first parent of G and F is the second parent. But, I do not understand why that is the case. Is it like the branch on which the merge commit is made determines the first parent?

Aditya Vikas Devarapalli
  • 3,186
  • 2
  • 36
  • 54

3 Answers3

8

Is it like the branch on which the merge commit is made determines the first parent?

Yes.

Referring to Git-Tools-Revision-Selection of Pro Git :

You can also specify a number after the ^ to identify which parent you want; for example, d921970^2 means “the second parent of d921970.” This syntax is useful only for merge commits, which have more than one parent — the first parent of a merge commit is from the branch you were on when you merged (frequently master), while the second parent of a merge commit is from the branch that was merged (say, topic):

And commands like git show G^1, git show G^2, git log -1 --pretty=%P G, and git rev-parse G^@, can prove it's the same as described. Besides, use git cat-file -p G to inspect the content of the commit object, and we can see the parents are recorded in the order.

LeGEC
  • 46,477
  • 5
  • 57
  • 104
ElpieKay
  • 27,194
  • 6
  • 32
  • 53
2

The first parent is usually the HEAD commit of the branch on which you perform the merge.

git commit uses the HEAD commit as the first parent (if there's no conflict, git merge will do the commit for you, or else you do it yourself. Same result either way). All the convenience commands follow this convention. You can build arbitrary commits yourself with git commit-tree and specify any parents you like, for any reason.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
jthill
  • 55,082
  • 5
  • 77
  • 137
-3

So, there is no parent of the commit as such. But you can say which one is the parent depending on the branch from which you ran the git merge

Rupesh
  • 530
  • 2
  • 14