Imagine the following git flow:
R1 refactoring #1
/ \
/ \
---A------M1---M2--- master
\ /
\ /
R2----- refactoring #2
The code in the A-snapshot looks like
x1++;
y1++;
count++;
x2++;
y2++;
Both R1 and R2 commits are refactorings trying to make the code look a bit nicer.
R1 converts the A-snapshot code to:
count++;
x1++;
y1++;
x2++;
y2++;
R2 converts the A-snapshot code to:
x1++;
y1++;
x2++;
y2++;
count++;
You probably expect the second merge (M2) to let you resolve the merge conflict.
Surprise: git does not see a conflict here, merge M2 is silent, its result is:
count++;
x1++;
y1++;
x2++;
y2++;
count++;
Both R1 and R2 are correct, but their merge result is obviously incorrect, and we have not received any warning from git.
It would be natural to receive a conflict in M2 to have a possibility to solve the problem early.
My question:
How to convince git that moving a row (or moving a block of rows) is an atomic change (instead of independent delete + insert)?
P.S.:
Steps to reproduce the problem:
git init test
cd test
echo "x1++;" > file
echo "y1++;" >> file
echo "count++;" >> file
echo "x2++;" >> file
echo "y2++;" >> file
git add .
git commit -m"A"
git checkout -b R1
echo "count++;" > file
echo "x1++;" >> file
echo "y1++;" >> file
echo "x2++;" >> file
echo "y2++;" >> file
git commit -am"R1"
git checkout -b R2 master
echo "x1++;" > file
echo "y1++;" >> file
echo "x2++;" >> file
echo "y2++;" >> file
echo "count++;" >> file
git commit -am"R2"
git checkout master
git merge --no-ff R1
git merge --no-ff R2