问题
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?
回答1:
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.
回答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.
回答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
来源:https://stackoverflow.com/questions/62527864/how-to-determine-which-parent-is-the-first-one-for-a-merge-commit-in-git