拆分文件时保留git历史记录

wsewodh2  于 2023-06-20  发布在  Git
关注(0)|答案(6)|浏览(165)

我想从一个文件中取出一个函数,并将其放入另一个文件中,但保留错误历史记录。

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

但是如果我运行git blame b.php,我只看到它归咎于这个新的提交。

db2dz4w8

db2dz4w81#

维护责备历史的一般规则是在任何编辑之前先进行单独的 * 移动 * 提交。根据我的经验,这允许git blame在不需要-C选项的情况下工作。因此,在将文件拆分为新文件的情况下,这可以在两次提交中完成:
1.将原始文件复制到新目标,确保删除原始文件
1.从重复的文件中删除多余的部分
在所提供的示例中,这将是:

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
t5zmwmid

t5zmwmid2#

我稍微修改了Peter's answer to another question here,创建了一个可重用的、非交互式的shell脚本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"

它只是将源文件复制到一个新文件中,并且两个文件具有相同的历史记录。关于为什么这样做的解释可以在that other answer中看到

xj3cbfub

xj3cbfub3#

也许之前的这个问题可以提供信息:
How does git track source code moved between files?
套用公认的答案:从本质上讲,Git实际上并不"存储"移动的代码;当生成诸如对移动代码的责备之类的东西时,这是通过检查整个存储库从提交到提交的状态来完成的。

643ylb08

643ylb084#

尝试git blame -C -C b.php

brtdzjyr

brtdzjyr5#

仅供参考,我已经发布了一个NPM包(您可以通过npx命令直接调用它,它会为您拆分(复制)文件。它比shell脚本慢一点,但如果你使用npm,它很容易执行,不需要创建文件或在git repo中签入文件,以便与你的团队成员共享。
https://www.npmjs.com/package/swgh
你会的

npx swgh myFile.txt myDuplicatedFileWithHistory.someOtherExtensionIfYouWantTo
vcudknz3

vcudknz36#

这个版本是我在Lukas' answer上的迭代
它通过按名称添加特定文件进行了改进,并使用git reset --soft,因此工作目录中可以有文件,但它们不会受到git-split.sh的影响。

#!/bin/sh

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

git mv $1 $2
git add $2
git commit -m "renamed: $1 -> $2"
git branch temp-git-split
git reset HEAD~1 --soft
git mv $2 temp-git-split-file
git commit -m "renamed: $1 -> temp-git-split-file"
git merge temp-git-split
git add temp-git-split-file
git add $2
git rm $1
git commit -m "merging history"
git branch -d temp-git-split
git mv temp-git-split-file $1
git commit -m "renamed: temp-git-split-file -> $1"

相关问题