我有一个 SNMP 代理项目,与它一起开发了相关的 MIB 文件(*.smiv2 文件),但现在我希望它们在单独的 git 存储库中。
为了不丢失任何 MIB 文件历史记录,因为它们没有在现在的同一目录中启动,我不能只使用--subdirectory-filter
filter-branch,所以我尝试了--filter-index
基于这个问题的方法。这个想法是删除每个不以结尾的文件.smiv2
(显然是在原始项目的新克隆上,在过程结束时将被推送到我的新 MIB 存储库)。
为了使它更简单,我选择使用ls-files
over ls-tree
,而不是:
git filter-branch --prune-empty --index-filter 'git ls-tree -r --name-only \
--full-tree $GIT_COMMIT | grep -v ".smiv2$" | xargs git rm --cached \
--ignore-unmatch -r'
我用这个:
git filter-branch --prune-empty --index-filter 'git ls-files | \
grep -v ".smiv2$" | xargs git rm --cached --ignore-unmatch'
但是这些中的任何一个在第一次提交中都失败了,因为它似乎git rm
根本没有提供任何参数(我想--ignore-unmatch
如果找不到提供的参数会正常工作,但在没有提供参数的情况下不会):
$ git filter-branch --prune-empty --index-filter 'git ls-files | \
> grep -v ".smiv2$" | xargs git rm --cached --ignore-unmatch'
Rewrite 4cd2f1c98dbaa96bc103ae81fbd405bd1d991d9a (1/418)usage: git rm [options] [--] <file>...
-n, --dry-run dry run
-q, --quiet do not list removed files
--cached only remove from the index
-f, --force override the up-to-date check
-r allow recursive removal
--ignore-unmatch exit with a zero status even if nothing matched
index filter failed: git ls-files | \
grep -v ".smiv2$" | xargs git rm --cached --ignore-unmatch
我把它包装git rm
在一个脚本中,即使由于缺少参数而失败,它也会返回成功(保存在 中/usr/local/bin/gitrm_alt
):
#!/bin/sh
git rm --cached --ignore-unmatch "$@"
exit 0
然后调用它而不是git rm
:
git filter-branch --prune-empty --index-filter 'git ls-files | \
grep -v ".smiv2$" | xargs gitrm_alt'
但我发现这非常丑陋和笨重,所以我想问一下是否有更直接/正确的方法来做到这一点。