Github still shows differences between branches after sucessfull merge

后端 未结 2 1718
清酒与你
清酒与你 2021-01-14 06:58

Recently I merged a huge pull request (140 commits) from the feature branch to master:

I can see the merge in the github overiew on the master branch:

2条回答
  •  臣服心动
    2021-01-14 07:40

    It looks like you're using two long-running branches and using a squash merge. That's a bit of a problem, and here's why.

    When Git performs a merge, it considers exactly three points: the two heads you're merging, and a third point, called the merge base, which is usually their common ancestor. The result of the merge is the sum of the changes between the merge base and each head.

    If you merge two branches with a normal merge commit, then you create a new common ancestor, so future merges start at that base. You don't have to worry about conflicts from things you've already merged because Git doesn't even consider them.

    When you merge two branches with a squash merge, you create a single commit on one branch that includes all of the changes from the other, but you don't create a new common ancestor. As a result, Git looks at all the changes on both sides when you try to merge again and you can end up with a lot of conflicts. This only gets worse if you keep squash merging the two branches.

    As a result, you really must use a normal merge commit to integrate two long-running branches unless you really want to resolve lots of conflicts all the time. Squash merges won't work here.

    If feature doesn't need to be long-running, then simply recreate it from master. Git is great at creating feature branches that you can then throw away once they're merged. That's the simplest way to solve this problem. Since you have a commit on it that needs to be included, then just follow the steps similar to those eftshift0 outlined:

    $ git checkout feature
    $ git rebase --onto master HEAD^
    # optionally:
    $ git push origin +feature
    

    Otherwise, here's the easiest way to solve this problem. Take the commit on master immediately before your squash merge and call it A. Take the commit on feature that you merged and call it B.

    $ git checkout -b temp A
    $ git merge B
    $ git checkout master
    $ git merge temp
    

    This creates a branch called temp which looks exactly like the squash merge, but with a real merge commit, and then merges it into master. This merges is a no-op because both sides are completely identical, so you don't have to resolve any conflicts. However, both sides now share a new common ancestor on which future merges can be based, which solves the problem. You can then use normal merge commits when integrating the two branches.

提交回复
热议问题