Splitting files while preserving history in git
Have you ever had a file in your git repository which you would like to split, but you also would like to preserve the history of the file?
Here's a way how to do it.
The Problem
We want to move a (two-line) file a.txt
inside a git repository to b.txt
and
c.txt
, whereas b.txt
contains the first lines of the original file and the
c.txt
file the second one. You want to preserve the history of these two
lines, as a simple git mv a.txt b.txt && cp b.txt c.txt
or something similar
would cause at least one of the files (the c.txt
one in this case) to be a
completely new file to git, and therefor have a single commit as history – the
creation of it.
I also tested some other ideas, for example a
git mv a.txt b.txt && git checkout HEAD a.txt
. It results in the same issue.
The solution...
... is a merge conflict! Yuck, you say? No, not at all! It's a really simple merge conflict!
First, you create a branch which causes the merge-conflict later on. Then, you
do git mv a.txt b.txt && git commit
. You moved the a.txt
file now to
b.txt
, obviously! Now, go to your new branch. The file is still a.txt
there.
Do a git mv a.txt c.txt && git commit
. Maybe you guess what comes next.
Create a merge-conflict by going back to your branch and merging the temporary
created branch git merge --no-ff <conflict-branch>
. A merge conflict will come
up, as you moved a.txt
to b.txt
one time and to c.txt
another time. Now,
simply, take both files.
Of course there is also the possibility to delete code in the files inside the
branches. Then, you “splitted” the a.txt
file into two files but preserved the
history.
Awesome!
tags: #git