2

场景

我正在尝试从 git 存储库的整个历史记录中删除一些文件。他们都有几个共同的标准:

  • 他们在文件名中有“设置”。不过,它们也可能有各种前缀和后缀。
  • 它们将位于文件树中某个目录的深处两层。二级目录的名称各不相同。文件树中有更深的设置文件,不应删除。

那么,这里是文件树的一个示例:

root-directory/
  |-> apples/
  |     |-> bad-settings-alpha.txt
  |     |-> bad-settings-beta.txt
  |
  |-> oranges/
  |     |-> bad-settings-gamma.txt
  |     |-> bad-settings-delta.txt
  |     |-> navels/
  |           |-> good-settings.txt
  |
  |-> good-settings.txt

我需要bad-settings在保留文件的同时过滤掉所有good-settings文件。

我的方法

因此,使用GitHub 提供的教程,结合git-rm 的手册页,我制作了这个命令(分成两行):

git filter-branch -f --index-filter 'git rm --dry-run --cached \ 
--ignore-unmatch root-directory/*/*settings*.txt' --prune-empty -- --all

这里需要特别注意的是我使用的文件 glob:root-directory/*/*settings*.txt. 如果我将该文件 glob 与 一起使用ls,那么我将得到我想要删除的文件列表。所以,它应该工作,对吧?

显然不是。如果我用那个 glob 运行我的命令,它也会删除所有比两级更深的设置文件。在上面的文件树示例中,这意味着它root-directory/oranges/navels/good-settings.php会遭到破坏。


我试图自己解决这个问题,尝试文件 glob 的变体并--dry-run使用git-rm. 似乎没有任何效果——我所能做的就是改变开始删除设置文件的文件树深度。

我确实发现了一件事似乎与我的问题极为相关。在手册页中git-rm,有这个例子:

git rm Documentation/\*.txt
  Removes all *.txt files from the index that are under the Documentation
  directory and any of its subdirectories.

  Note that the asterisk * is quoted from the shell in this example; this
  lets git, and not the shell, expand the pathnames of files and
  subdirectories under the Documentation/ directory.

“从...目录及其任何子目录下的索引中删除所有...文件”与实际发生的情况一致。真正有趣的是提到引用的星号。我知道这可以git-rm处理文件 glob 扩展,而不是bash. 好的。但这留下了这些问题:

  • 我为什么要这样做?
  • 没有引用我的星号,所以bash应该进行扩展。如果这是真的,并且我的文件 glob 可以与 一起使用ls,那么为什么它不能与 一起使用git-rm呢?

我也看到了上面那个下面的例子,它似乎做了我想做的事情。然而,这不会发生在我身上,否则我不会在这里。不过,它似乎确实证实了我用 进行文件扩展bash

4

1 回答 1

0

为什么不使用find显示两级深度文件:

find . -maxdepth 2 -mindepth 2 -type f -name "bad-settings*"

这将为您提供只有两级深度导演的不良设置列表。您可以将它们git rm通过管道传送到xargs

find . -maxdepth 2 -mindepth 2 -type f -name "bad-settings*" | xargs git rm
于 2012-06-05T18:46:29.943 回答