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:
git checkout A
git merge B
- 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:
git checkout B
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:
git checkout B
git rebase A
- 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.