kaizer
kaizer

Reputation: 490

Why does sometimes GitHub do circular merge?

I did a merge the other day:

  1. I opened a pull request on GitHub
  2. I clicked the merge button on GitHub
  3. GitHub told me that there were conflicts, so I followed their instructions:
    1. git checkout A
    2. git merge B
    3. git checkout B
    4. git merge --no-ff A
    5. git push origin B

Afterwards, I realised that branch A was successfully merged into the branch B.

But when I switched back to branch A I realised that the branch B got merged into the branch A as well.

Why is that happening?

Upvotes: 1

Views: 1016

Answers (1)

Chris
Chris

Reputation: 136909

Let's take a look.

You have two branches, A and B, and merging them generates conflicts. That might look something like this:

*---*---*---* [A]
     \
      *---*   [B]

You create a pull request on GitHub to merge B into A (or A into B, it doesn't really matter in this case). GitHub tells you that the merge generates conflicts that must be resolved and therefore can't be done automatically.

Following GitHub's instructions you run the following commands locally:

  1. git checkout A
  2. git merge B
  3. Resolve conflicts and complete the merge

Now your local copy looks something like this:

*---*---*---*---x [A]
     \         /
      *-------*   [B]

Here x is a new commit that resolves the conflict between A and B. Then you run the following commands:

  1. git checkout B
  2. git merge --no-ff A

Since x is a new commit not already included in B (and especially since you've included --no-ff) this generates a new commit y:

*---*---*---*---x   [A]
     \         / \
      *-------*---y [B]

Another option to resolve the conflicts without creating this "circular merge" is to rebase B onto A and resolve the conflicts that way:

  1. git checkout B
  2. git rebase A
  3. Resolve conflicts and complete the rebase

This generates something like

*---*---*---*         [A]
             \
              o---o   [B]

The two newest commits in B marked as o are new (their hashes have changed) so you'll have to force push B back to GitHub using --force-with-lease, but now you can complete the merge using GitHub's pull request UI without creating a "circular merge".

Make sure to read about the implications of rewriting commits and force pushing (o here) before doing this, especially if you work on a team.

Upvotes: 2

Related Questions