Search code examples
gitgithubgit-mergegit-commit

Why is the difference in commits of two branches is just stacking up when being merged? How to resolve?


Our team has our staging branch and our main branch for a specific project. And we are using GitHub. Now everytime we have to merge the changes from the staging to the main branch, the commit differences are just stacking up when we compare the branches the two branches instead of just showing the recent commits and the recent file changes. What is happening is that, on our next pull request of staging to main branch, after we merged the recent changes, when comparing the two branches, the previous changes and commits are still there stacking up with our most recent changes. Which it seems the previous changes are not merged. But it is. The fact is the merge commits are now working on the main branch. Even you manually look the codes in the main branch, you can see that the changes was merged.

This comparison or differences between the two branches which is seen everytime we need to merge a pull request gives us confusion which causes doubt and uncertainty in merging the new changes. Is there any way to resolve this issue?

Please bear with my English as it is not my native language. And I am not sure with the exact terminology to use in this situation so I might have interchanged the use of the terms. But I hope I have at least delivered the message. If not, please feel free to ask more details you need.

We tried using different merging, like squash and merge and create a merge commit.


Solution

  • So.... the problem is that you are squash-merging. squash-merging must be avoided if you are merging long-running branches.... if you are merging a feature branch, it's ok to squash-merge because the branch will die right there so not much of a problem.

    Suppose you have something like this:

    * JJJ (branch1)
    * III
    * HHH Merge of branch2 up to DDD
    | * GGG (branch2)
    | * FFF
    | * EEE
    | * DDD
    | * CCC
    |/
    * BBB
    * AAA
    

    To explain the problem of the squash.... consider what the last common ancestor between branch1 and branch2 is. It's BBB, that's why every time you try to merge, you get all that big diff that you have gone over already with multiple conflicts every time.

    So.... now, how can you get out of the situation easily for the next merge without having to redo all previous work, right? Ok... then let's try this:

    git checkout -b temp HHH # create branch temp over the last squashed merge commit in branch1
    git merge -s ours DDD -m "Merging DDD again"
    

    Side note: Thanks to @knittl for providing the merge strategy there (One can still learn even after getting a nice git gold badge!).

    After that is done, now temp is almost what the branch should have been like when you merged branch2 into branch1 the last time (I included HHH as a parent so it's not exactly the same that would have come up from the merge but alas).

    * JJJ (branch1)
    * III
    | * ZZZ (temp) merging DDD again
    |/|
    * | HHH Merge of branch2 up to DDD
    | | * GGG (branch2)
    | | * FFF
    | | * EEE
    | |/
    | * DDD
    | * CCC
    |/
    * BBB
    * AAA
    

    Now, if you checked tempyou will see that it includes both HHH and DDD as parents in the chart, just what we wanted..... now follow your normal workflow to get temp merged (real merge!!!) into branch1 so that you get this:

    * KKK (branch1) merge of temp into branch1
    |\
    * | JJJ
    * | III
    | * ZZZ (temp) merging DDD again
    |/|
    * | HHH Merge of branch2 up to DDD
    | | * GGG (branch2)
    | | * FFF
    | | * EEE
    | |/
    | * DDD
    | * CCC
    |/
    * BBB
    * AAA
    

    And, now... what is the latest common ancestor between branch1 and branch2? Here's a tip: it's not BBB. It's DDD.

    And from now on, do real merges between branch1 and branch2 and you won't be dealing with this problem again.