Keep git history when splitting a file Keep git history when splitting a file git git

Keep git history when splitting a file


The general rule to maintaining blame history is to make a separate move commit first before any edits. It has been my experience that this allows git blame to work without the need for the -C option. So in the case of splitting the file up into new files, this can be done in two commits:

  1. Duplicate the original to the new destinations, making sure to delete the original
  2. Remove the extra sections from the duplicated files

In the example provided, this would be:

cp a.php b.phpmv a.php c.phpgit add a.php b.php c.phpgit commitvim b.php  # delete everything but 1 functionvim c.php  # delete the 1 functiongit add b.php c.phpgit commit


I've slightly modified Peter's answer to another question here to create a reusable, non-interactive shell script called git-split.sh:

#!/bin/shif [[ $# -ne 2 ]] ; then  echo "Usage: git-split.sh original copy"  exit 0figit mv $1 $2git commit -n -m "Split history $1 to $2"REV=`git rev-parse HEAD`git reset --hard HEAD^git mv $1 tempgit commit -n -m "Split history $1 to $2"git merge $REVgit commit -a -n -m "Split history $1 to $2"git mv temp $1git commit -n -m "Split history $1 to $2"

It simply copies the source file into a new file, and both files have the same history. An explanation why this works can be seen in that other answer


Perhaps this previous SO question could be informative:

How does git track source code moved between files?

To paraphrase the accepted answer: essentially, Git doesn't actually "store" moved code; when generating things like blames for moved code, that's done ex post facto by examining the state of the entire repository from commit to commit.