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.
- main: where all the future development is being done (unstable version)
- production-branch: where the current version of the site is kept (stable version)
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:
- We have some changes/improvements in the production-branch that needs to be moved into main. however, if I create a pull request to main from the production-branch it merges in both directions which contaminates the production-branch with code from main (which is less stable)
The question is:
- How do I PR my production-branch to main without contaminating the production-branch?
- Is there another avenue I am missing that we should be exploring?
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
mainintoproduction-branchso that you can resolve conflicts.Before you begin, since my recommendations are local operations, use
git fetchto make sure all of your remote branches are up to date. Also delete your local copies ofmainandproduction-branchto 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-branchintomain:Option 1: Merge directly to
mainand push itNote the
git pushin the last line. There are 2 possible reasons that that push ofmaincould 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.mainsince 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 currentmainwhich 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
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
mainwith 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 intomain. The reason is that will flip the first-parent history which leads to pain and suffering for all.