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:
- Duplicate the original to the new destinations, making sure to delete the original
- 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
精彩评论