While refactoring source code, sometimes you need to move big blocks of text inside a file, or even to a new file. You create a branch refactored
and commit away:
$git checkout master
$git branch refactored
$git checkout refactored
<move code around>
$git commit -m "refactored code"
However, people may commit on top of the old pre-refactor branch, changing the code that was moved:
$git checkout master
<change code that was moved elsewhere on branch refactored>
$git commit -m "bugfix"
On branch refactored
, you then want to incorporate changes made in master
:
$git checkout refactored
$git merge master
<giant merge conflict>
This leads to a large merge conflict. If there was a way to tell git that the content was simply moved, it should be possible to merge automatically.
The worse part is that, even after resolving the conflict and commiting it, git still can't use the resolution to figure out further merges:
<fix conflicts>
$git commit -m "merge master into refactored"
$git checkout master
<change more code>
$git commit -m "bugfix2"
$git checkout refactored
$git merge master
<another giant merge conflict>
Is this avoidable at all? I've tried git rerere
and it can't resolve the conflicts here. Is there any way git can see moving a block of text as a actual move, instead of a deletion and insertion? If it can't, what's the best approach to minimizing merge conflicts, if you need to keep the two parallel branches for a while?
While this is easy enough for moving the contents of a complete file, I couldn't find information on moving only part of it, or moving inside the same file.
Also, if there's a solution for this, what would be the behaviour of git blame
on the refactored
code? Would it point to the refactoring commit, or ignore it? Is there a way to achieve the later?
In case anyone's interested, I've put a base64 encoded tar.gz of the (very minimal) repository I'm using for testing on pastebin
Potential Solutions
One potential solution might be performing the merge by applying a (automatically) edited patch with the changes in the pre-refactored branch. Is there software developed to do this? Using this approach I guess that, since this is transparent to git, git blame
would point to the refactoring commit.
I've found the same question, applied to diff. There's no mention to any existing non-proprietary implementation, but there mention to a algorithm that tracks block movement