如何运行样式检查器并提交更改而不破坏 Git blame 历史记录?

3
让我先说一下,我已经四处搜寻,但并没有找到一个好的答案。如果我的更改只是将制表符转换为空格,或运行一个自动执行所有操作的脚本,那么这个就可以工作:git: change styling (whitespace) without changing ownership/blame?。我想运行一个任意的交互式清理程序,例如运行样式检查器,然后采取人工步骤来解决问题,那么我如何在不影响 git blame 的情况下进行提交呢?我看到有 --reset-author 选项,但结果证明它会将一切都重置为该提交的作者,而不是这种情况所需的。

2个回答

1
你仍然可以使用链接问题中概述的一般想法,但是你将无法直接使用git filter-branch来运行它。可以通过学习filter-branch脚本来了解它如何设置每个新提交,以便保留作者和提交者的姓名、电子邮件地址和时间戳,并了解它如何运行树过滤器。
不管怎样,你都需要编写一些不完全复杂的代码,来运行你的样式检查器,然后获得所需的帮助。我看到有两条明显的路径可以实现这一点:
复制 filter-branch 的逻辑,但在多次运行中保留状态(例如将状态保存在文件中)。这样,您可以启动它,告诉它运行直到需要交互的时候,并在那一点上终止。现在,您可以修复问题并使用“continue”选项调用它,让它运行直到再次需要帮助,然后再次停止。重复直到完成。
编写或修改一个 filter-branch 脚本,在您的 --tree-filter(这将是要使用的脚本)期间,如果遇到需要人工干预的情况,它会暂停。(也许在此时,您的 tree-filter 从命名管道中读取指令。该指令可以仅限于“继续”:即在告知其继续之前,它实际上不会继续。)
当它暂停时,您手动进入包含树的临时目录并进行修复。当准备好后,您向命名管道发送“continue”指令,然后您的树过滤器将控制权返回给 filter-branch,filter-branch 继续进行过滤。
这种第二种方法意味着您不必保存和加载筛选分支状态——现有的git filter-branch代码仍然可以正常工作;只是似乎运行的tree-filter有时非常缓慢,需要几分钟而不仅仅是几秒钟。

哦,太糟糕了。Git没有“commit --retain-original-author”选项。我认为我们问题的真正答案是在提交代码之前运行我们已经同意的linter,否则git blame会在后续的清理中出现问题。 - SwimBikeRun

0
如何在不影响 Git blame 的情况下进行提交?
你可以非常接近实现这个目标,我认为补偿手动修改并不值得付出这样的代价,但忽略自动格式化更改很容易:git blame 应用您指定的任何文本转换到文件内容中,因此请告诉它在检查结果以查找有责任的更改之前,在全自动模式下运行您的 linter 进行预处理。
以下是一个测试案例,其中“样式 linter”只是将“REFORMATTED”添加为第二行的第一个单词。通过运行(幂等版本的)文本转换,Git 被指示将其视为不需要追究责任的更改。
进入垃圾目录并将其复制到文件 temp 中。
find ! -name temp -delete; git init
doit() { eval "$@"; shift $(($#-1)); git add .; git commit -m "$*"; }
(
doit '>file'
doit echo '>>file' line1
doit echo '>>file' line2
doit '>B'
doit sed -i "'s/line2/REFORMATTED line2/'" file '#' 'REFORMATTED line2'
doit echo '>>file' line3
) >/dev/null

set -x
git log --oneline --graph --decorate

git blame file

git config diff.REF.textconv 'awk '\''NR==2 && $1!="REFORMATTED" {$1="REFORMATTED "$1 }1'\'
mkdir .git/info
echo file diff=REF >.git/info/attributes

git blame file

然后执行sh temp。你的元数据将会因为时间戳和ID而改变,但是除此之外你应该能看到

$ sh temp
Initialized empty Git repository in /home/jthill/src/snips/test/.git/
+ git log --oneline --graph --decorate
* 282c142 (HEAD -> master) line3
* ee58923 REFORMATTED line2
* d8558d2 >B
* 6801a1d line2
* 030e551 line1
* f912c83 >file
+ git blame file
030e5517 (jthill 2019-02-23 18:41:36 -0800 1) line1
ee589239 (jthill 2019-02-23 18:41:36 -0800 2) REFORMATTED line2
282c142d (jthill 2019-02-23 18:41:36 -0800 3) line3
+ git config diff.REF.textconv 'awk '\''NR==2 && $1!="REFORMATTED" {$1="REFORMATTED "$1 }1'\'''
+ mkdir .git/info
+ echo file diff=REF
+ git blame file
030e5517 (jthill 2019-02-23 18:41:36 -0800 1) line1
6801a1d6 (jthill 2019-02-23 18:41:36 -0800 2) REFORMATTED line2
282c142d (jthill 2019-02-23 18:41:36 -0800 3) line3

...特别注意对于line2责任的变化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接