Keep git history when splitting a file

Viewed 14040

I want to take a function out of one file and put it into another, but keep the blame history.

cp a.php b.php

vim b.php
# delete everything but 1 function

vim a.php
# delete the 1 function

git add a.php b.php
git commit

But if I run git blame b.php I only see it blaming to this new commit.

5 Answers

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

#!/bin/sh

if [[ $# -ne 2 ]] ; then
  echo "Usage: git-split.sh original copy"
  exit 0
fi

git mv $1 $2
git commit -n -m "Split history $1 to $2"
REV=`git rev-parse HEAD`
git reset --hard HEAD^
git mv $1 temp
git commit -n -m "Split history $1 to $2"
git merge $REV
git commit -a -n -m "Split history $1 to $2"
git mv temp $1
git 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

Just an FYI, I've published an NPM package (which you could call directly via the npx command, which does the splitting (duplicating) of the file for you. It's a bit slower than a shell script, but if you're working with npm, it's easily executable, without the need of creating the file or for checking in the file in your git repo, in order to share it with your team mates.

https://www.npmjs.com/package/swgh

You would do

npx swgh myFile.txt myDuplicatedFileWithHistory.someOtherExtensionIfYouWantTo
Related