开发者

Keep git history when splitting a file

开发者 https://www.devze.com 2023-01-19 00:15 出处:网络
I want to take a function out of one file and put it into 开发者_如何学Canother, but keep the blame history.

I want to take a function out of one file and put it into 开发者_如何学Canother, 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.


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.php
mv a.php c.php
git add a.php b.php c.php
git commit
vim b.php  # delete everything but 1 function
vim c.php  # delete the 1 function
git add b.php c.php
git 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/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


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.


try git blame -C -C b.php


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
0

精彩评论

暂无评论...
验证码 换一张
取 消