Search code examples
gitversion-controlgit-mergerebase

What is the safest way to merge a stable branch with the main Git branch?


I have the following git branches.

main -> origin/main (The local copy and origin/main are synchronized) dev/feature -> origin/dev_feature (A stable branch that is 36 commits ahead of the main branch. local dev/feature and origin/dev_feature are synchronized)

Since origin/dev_feature is stable, I want to bring all the changes to origin/main. If there is a conflict, origin/dev_feature changes should take priority over origin/main. I am the only one working on this project. What is the safest way to merge all the changes to the main branch?

I'm thinking about doing the following.

git checkout dev/feature
git rebase main

if I understand it correctly, now my local main is pointing to the c2 and the feature is at c3. c0 -> c1 -> c2 -> c3

git checkout master
git merge dev/feature

now both main and dev/features have the same set of changes.

git push origin main --force

Now the local copy and remote have the same set of changes.

Is this the correct way to do this? Are there any other safe alternatives to achieve this?


Solution

  • In the scenario you described, with dev/feature being fully ahead of main, it won't be possible to have conflicts when you merge. So your steps would be, first checkout main:

    git switch main # this is the same as the older command "checkout"
    

    Now merge in dev/feature in one of two ways:

    1. git merge dev/feature
    2. git merge dev/feature --no-ff

    Using #1 will "fast-forward" if possible, otherwise it will create a merge commit. Using #2 will force creating a merge commit even if fast-forward is possible. Note in your case a fast-forward is possible because dev/feature is fully ahead of main. (In other words the tip commit of main is in the history of dev/feature.)

    Which merge type you choose is up to you, and they will both have the same state, but with different graphs. If you are deploying main to production and wish to maintain a history of each deployment you did, perhaps forcing the merge commit is helpful. Or, you could let it fast-forward and tag the commit that you deploy. Both are popular choices.

    Side Note: if you let merging dev/feature into main do the fast-forward, it is identical to deleting main, and then creating a new branch called main from dev/feature. Another way of saying this is that branches are simply pointers to a commit, and when you merge with fast-forward you are simply repointing main to the commit that dev/feature is pointing to. Sometimes thinking about branches in this way helps conceptually.