I'm working on a project where we have the following branches:
- dev
- test
- main
The way we're creating feature branches is branching of main
into feature/<id>
. We then later create a PR from feature/<id>
to dev
. If everything is ok etc we proceed with feature/<id>
to test
and then to main
.
The problem is that sometimes we have conflicts from feature/<id>
to dev
. We never want to merge dev
into the feature branch (to avoid sending all dev code to test). So, to solve conflicts we're using Azure interface (which sucks) to solve the merge conflicts. By using this tool, it does not merge dev
into the feature, it does exactly what we want which is feature
-> dev
(in some temporary state which keeps the PR open).
To do the same locally the only alternative we have found so far is to create a temporary branch from dev
, merge the feature into this new branch and remake a PR with temp
->dev
.
Is there a better way to handle conflicts in this scenario?
CodePudding user response:
This is a common problem, and by the way, the fact that you have 3 branches doesn't matter; only 2 branches are required for this issue to occur. If you use the workflow that the Git project uses this can happen often with just next
and main
. The way to minimize the problem is to periodically reset next
to main
, or in your case you could consider periodically resetting both dev
and test
to main
, to remove all the previous old code that never made its way into main
.
Between resets though, I can only think of 3 good options (2 of which you already mentioned):
- Resolve the conflicts in the online tool.
-
To do the same locally the only alternative we have found so far is to create a temporary branch from dev, merge the feature into this new branch and remake a PR with temp->dev.
Making the temp branch is probably the most common way to go. It's slightly annoying because you have to maintain two branches from then on until you promote your branch or dev
gets reset. A secondary annoyance is if you didn't notice you had conflicts until after you created the PR from feature into dev
, you have to abandon that PR and create a new one for the temp branch, which leads to a possible 3rd option, though I only recommend this if you're comfortable with interactive rebase:
- Squash merge
dev
into your working feature branch to resolve conflicts. Essentially you'll mergedev
into your branch locally, but with a squash, and make the commit message something like, "delete-me: Squash merge in dev".
Note you are tainting your branch here, but this makes it easier to remove the merges later when you're ready to promote your branch. Once you're ready to promote, which in your case is test
, you would interactive rebase and drop all those "delete-me" commits.
Side Note: I can't tell for sure from your description, but if you merge feature branches into test
, and then separately merge those feature branches into main
later, then it's possible you'll have the same problem on test
and you'll need to repeat the process before going into main
. (The alternative would be for test
when ready, to be merged into main
, and if you do that you shouldn't have this issue. If you merge feature branches separately, then you'll probably want to periodically reset test
as well.)
Tip: Don't merge dev
into your feature branch with a regular merge. Either maintain two branches or use squash merge. Come promotion time you don't want to deal with manually cherry-picking multiple commits which are spread out across your branch.
What I do: I used to switch between #2 and #3, but nowadays I mostly do something else which could possibly be Option #4: I branch off of dev
first, add some commits, merge into dev
, add more commits, merge into dev
, etc. While I'm doing this I don't rewrite any commits on my branch; I only add new ones. If I manage to do this without any conflicts on dev
, then when I'm ready to promote, I rewrite my branch to a few good commits that I'm happy with, and then I rebase it (with --onto
) to the new target branch. If during that process I had conflicts and I could no longer simply add new commits to my branch, that's when I decide to go with #2 or #3.