I am working on a web application project. Our objective is to upgrade an existing application by adding new pages and functionality.
We have completed the first phase of the project that upgraded the part of their application currently in use.
At this point we have two branches.
My goal is to keep a stable branch that we can seldom use for bug fixes and minor features. And use the main branch to continue development. I would like to be able to move fast and break things, deploying to our testing environment, while keeping a stable version available at any point for bug fixes.
The problem is:
The question is:
How do I merge
production-branch
tomain
without contaminating theproduction-branch
? (with code frommain
)
There are many ways to achieve this. (In fact most ways would normally achieve this.) From the comments we've learned that you didn't realize you used a reverse merge of main
into production-branch
so that you can resolve conflicts.
Before you begin, since my recommendations are local operations, use git fetch
to make sure all of your remote branches are up to date. Also delete your local copies of main
and production-branch
to ensure you're working with the latest versions from the remote. (And this assumes you don't care about any local commits you may have added to those branches and never pushed.) The below options assume you have already fetched and don't have out-of-date local copies of these branches.
Here are some options to properly merge production-branch
into main
:
Option 1: Merge directly to main
and push it
git switch main
git merge production-branch
# resolve conflicts and stage the files
git merge --continue
# Modify the commit message as needed
git push
Note the git push
in the last line. There are 2 possible reasons that that push of main
could fail:
main
. In this case you (or an admin) can temporarily give you the permission to push, and after you push, you can remove that permission.main
since when you last fetched. If this happened then you won't be able to push, and of course you don't want to force push a shared branch either. So now you could either fetch again and start over, or, you could go use option 2 below by creating a temp branch based off of your current main
which has the merge in it, and then push it out and create a PR.Option 2: Create a temporary branch so you can use a PR
# create a temporary branch pointing to main, but don't track main
git switch -c merge-production-branch-into-main origin/main --no-track
git merge production-branch
# resolve conflicts and stage the files
git merge --continue
# Modify the commit message as needed
git push origin merge-production-branch-into-main
# Now create a PR from merge-production-branch-into-main into main
With this PR method, make sure you use a regular merge when completing the PR. (Do not squash or rebase!) In theory, if it were available, you could also fast-forward but only if you merged in the correct direction as described above. With the regular merge you will actually be adding 2 new merge commits to main
; one for the conflict-resolution merge, and one for the PR merge. This is completely fine.
Since you are using a temp branch with a PR, if you complete the PR with a regular merge, then the direction you do the temp branch conflict-resolution merge actually doesn't matter. The way I described above is probably slightly better, however, the reverse merge that you did actually would work in this case as well, but only if you do it on a temp branch and merge that temp branch into main
with a new merge commit. The exception to this, as mentioned in the previous paragraph, is even on a temp branch, you do not want to do the reverse merge if you are going to then fast-forward this branch back into main
. The reason is that will flip the first-parent history which leads to pain and suffering for all.