Here's the workflow that our teams are using:
main
branch which to which feature branches are squash-merged; this is handled by team Abig-feature
branch which is used by team B which was branched frommain
- team B will have smaller feature-branches from
big-feature
; they are using regular fast-forward merges when they pull in their feature branches tobig-feature
The problem: every once in a while team B wants to get the latest changes from main
to their big-feature
. So they do the following:
- fetch all changes from origin, and pull all changes to their local
main
- create a
merge-with-main
branch frombig-feature
- merge
main
intomerge-with-main
Now, I'd expect they should only get conflicts in files that they've made changes to that were also changed on main
. However, they currently get over 250 merge conflicts, and most (if not all) of them are in files they have not changed at all. Looking at the conflicts in Visual Studio it's clear "their" file is, for example, some initial version of the file with plenty of NotImplementedException
instances when a stub file was committed to the main
branch, and "incoming" is the same file with some implementation. Again - same file, clearly not changed by team B, but marked as a conflict.
Currently team B is manually resolving these conflicts (usually using the "take theirs" option), but with 250 files it's really a hassle. What's going on here and why are these conflicts happening and what can be done to prevent / easily resolve them?
EDIT: I do believe squash-merges used on main
might be the culprit, BUT AFAIK they should only be an issue if big-feature
gets some changes from a feature branch from team A - then GIT would indeed "lose" track of it, since when team A commits then the source branch is, essentially, gone. BUT team B is only getting stuff directly from main
(aside from their own changes when their working on their own feature of course), and the changes in main
should have a source, no?
Again, squash merges are only used when team A pulls in a small feature-branch
to main
, and it's something done by the Azure DevOps PR system.
CodePudding user response:
If you squash-merge, then the branch is not merged, but a new commit is created in place of the branch. If you subsequently merge the branch again, Git cannot compute the merge base and tries to re-merge (some of) the changes again, resulting in conflicts.
If you need to periodically merge a branch into another branch, do not use squash-merge, but a regular merge. If you use a squash-merge, you have to rebase all child-branches onto the new squashed-commit.