如何在一个git filter-branch --tree-filter步骤

时间:2018-01-03 16:25:04

标签: git bash

我在外部脚本中使用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不会被执行,即foofoo只在变更集中存档。

实际结果

在过滤器分支期间,$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,我们会有更高的标准。

(我可以稍后将此编辑转换为答案。)

0 个答案:

没有答案