我在外部脚本中使用git filter-branch
执行复杂的--tree-filter
。在该脚本中,我可以根据特定条件添加,删除或移动文件。一个特定过滤提交的最终结果可能是,与之前的提交相比,只有一个特定文件会发生变化。我们调用该文件foo
。如果仅更改了foo
,那么根本不会发生任何更改,从而导致提交一个空的变更集,该变更集将被--prune-empty
选项删除。
使用git ls-files --modified --others
,您可以找到修改(添加,更改,删除)的文件。这在正常的交互式git操作中按预期工作,但在filter-branch期间会产生意外的结果。
我从
开始if [ -f foo ]; then
UpdateFoo
fi
(如果文件foo
存在,则执行UpdateFoo
)
我把它改为
CHANGED=$(git ls-files --modified --others)
if [ -f foo -a "$CHANGED" != "foo" ]; then
UpdateFoo
fi
预期结果
这里的意图是当UpdateFoo
的值 <{1}}时,$CHANGED
不会被执行,即foo
是foo
只在变更集中存档。
实际结果
在过滤器分支期间,$CHANGED
包含提交中的所有文件,因此我最终提交了foo
是唯一更改的文件的提交。
如何在一个过滤器分支步骤中获取所有已更改文件的列表?
修改
我有一个想法,我还没有实现,这很可能会使运行脚本所需的时间翻倍。当前迭代大约需要20分钟来过滤~800次提交。
.git
目录。像/tmp/diff/new
。/tmp/diff/new
与/tmp/diff/old
foo
,则将/tmp/diff/old/foo
复制到工作目录/tmp/diff/old
/tmp/diff/new
重命名为/tmp/diff/old
这听起来像是一块巨大的垃圾,但此刻我无法想出更好(更快)的方式。
无论如何,作为一个团队,我们决定保留仅改变foo
的提交。它是一个永远不会离开公司的私人存储库,所以有点可以接受。如果它被推送到GitHub,我们会有更高的标准。
(我可以稍后将此编辑转换为答案。)