Key question — Q1: which commit would have multiple parents?
— scenario 1a:
- Suppose your feature branch brA has a commit hash1 at its tip; and master branch has tip at hashJJ, which is the parent of hash1
- Then you decide to simply q[ git merge brA ] into master
In this simple scenario, your merge is a fast-forward merge. The updated master would now show hash1 at the tip, whose only parent is hashJJ.
A1: No commit would have multiple parents. Simple result. This is the default behavior of git-merge.
Note this scenario is similar to https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-merges#rebase-and-merge-your-pull-request-commits
However, github or bit-bucket pull-request flow don’t support it exactly.
— scenario 1b:
Instead of simple git-merge, what about pull request? A pull-request uses q[ git merge –no-ff brA ] which (I think) unconditionally creates a merge-commit hashMM on maser.
A1: now hashMM has two parents. In fact, git-log shows hashMM as a “Merge” with two parent commits.
Result is unnecessarily complex. Therefore, in such simple scenarios, it’s better to use git-merge rather than pull request.
https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-merges explains the details.
— Scenario 2: What if ( master’s tip ) hashJJ is Not parent of hash1?
Now maser and brA have diverged. I think you can’t avoid a merge commit hashMM.
A1: hashMM
— Scenario 3: continue from Scenario 1b or Scenario2.
3. Then you commit on brA again , creating hash2.
Q: What’s the parent node of hash2?
A: I think git actually shows hash1 as the parent, not hashMM !
Q: is hashMM on brA at all?
A: I don’t think so but some graphical tools might show hashMM as a commit on brA.
I think now master branch shows hashMM having two parents (hash1+hashMM), and brA shows hash1 -> hash2.
I guess that if after the 3-way-merge, you immediately re-create (or reset) brA from master, then hash2’s parent would be hashMM.
Note
- direct-commit on master is implicitly fast-forward, but merge can be fast-forward or non-fast-forward.
- fast-forward merge can be replaced by a rebase as in Scenario 1a. Result is same as direct-commit.
- fast-forward merge-commit (Scenario 1b) and 3way merge (Scenario 2) both create a merge-commit.
- git-pull includes a git-merge without –no-ff