Continuous Integration.
To understand why CI helps consider that in order to experience a merge conflict the change(s) in that branch need to conflict with one or more changes on master:
A B C
master *--*--*--*--*
\ /
feature-x *--------
The longer the branch exists for the more changes will be made on master, and therefore the higher the chance that one of those changes will cause a conflict (even if the change on the branch is very small):
A B C D E F G H
master *--*--*--*--*--*--*--*--*--*
\ /
feature-x *-----------------------
There are various things we can do to lower the chance of any 2 changes conflicting (like avoiding reformatting, or carefully organizing work to avoid multiple developers working on the same area), but the simplest approach is to just merge in changes more quickly, reducing the number of changes made on master, and in turn the chance of a conflict:
A B C
master *--*--*--*--*--*
\ / \ /
feature-x *-- *--
If you are practicing CI properly then everyone should be committing to a shared branch multiple times per day, i.e. once every few hours. That's quick enough that a lot of the time there won't be any changes on master, let alone conflicting changes. Whats even better is that even if you do see a conflict your changes will be small and so resolving the conflict should be relatively straightforward - in the worst case scenario (where you need to completely discard and re-implement your change) you have lost at most a couple of hours work.
In the comments its been suggested that developers should regularly merge from master instead of to master, which definitely helps, but not as much as continuous integration. For example in the following graph each commit on master (A, B and C) has a chance to conflict with any of the commits on the branch (X, Y or Z), for a total of 9 potential conflicts. Merging once into master at the end means all 9 potential conflicts need to be resolved at the same time:
A B C
master *--*--*--*--*
\ /
feature *--*--*--
X Y Z
If instead we merge from master into our feature branch after each change on master:
A B C
master *--*-----*-----*---*
\ \ \ \ /
feature *--*--*--*--*--*
X Y Z
Then each time we merge we need to deal with the following conflicts:
- In the first merge we must resolve any conflicts between commits A and X
- In the second merge we resolve any conflicts between B and X, B and Y
- In the last merge we resolve any conflicts between C and X, C and Y, C and Z
Note though that we never needed to resolve conflicts between A and Y, because change A was merged into our feature branch before change Y was made. In total we managed to avoid 3 out of the 9 potential merge conflicts by regularly merging from master.
Also note that each time we merged the number of potential conflicts increased - the longer the feature branch exists the more changes (and therefore potential conflicts) will be made on master, but the real killer here is that each change we make on the feature branch has a multiplicative effect on the number of potential conflicts each time we merge.
Now lets consider what might have happened if we were practicing CI:
A B C
master *--*--*--*--*--*--*
\ / \ / \ /
feature *-- *-- *--
X Y Z
This time we had to deal with the following merge conflicts:
- When merging change X into master, we had to resolve any conflicts between A and X
- When merging change Y, we had to resolve any conflicts between X and V
- When merging Z, we had to resolve any conflicts between Z and C
As before, we never needed to resolve any conflicts between A and Y, as change A was already merged into our feature branch before we made change Y, but this time we also didn't need to merge changes X and B, X and C, or Y and C, avoiding 6 out of the 9 potential conflicts.
See this question for more information / guidance on regular merging into master:
Is it better to merge “often” or only after completion do a big merge of feature branches?
Good coders don't have to deal with merge conflicts.
-- That statement is ridiculous. There are all sorts of factors that conspire against having freedom from merge conflicts.*Alone coders don't have to deal with merge conflicts.
dev
is refactored, the feature is restarted and here we go again.