使用git filter-branch删除不需要的文件的正确方法,不用git rm失败 [英] Proper way to remove unwanted files with git filter-branch without git rm failing
问题描述
我有一个SNMP代理项目,其中有相关的MIB文件(* .smiv2文件)与它一起开发,但现在我希望它们在单独的git存储库中。
为了不丢失任何MIB文件历史记录,因为它们现在不在同一个目录中启动,所以我不能只使用 - subdirectory-filter
filter-branch,所以我尝试了 - filter-index
方法,它基于这个问题。这个想法是删除所有不以 .smiv2
结尾的文件(很明显,在原始项目的新克隆中,它将被推送到我的新MIB库回放
为了简单起见,我选择了使用 ls-files
over ,所以不是:
git filter-branch --prune-空--index-filter'git ls-tree -r --name-only \
--full-tree $ GIT_COMMIT | grep -v.smiv2 $| xargs git rm --cached \
--ignore-unmatch -r'
I使用此:
git filter-branch --prune-empty --index-filter'git ls-files | \
grep -v.smiv2 $| xargs git rm --cached --ignore-unmatch'
但是其中的任何一个在第一次提交时失败,因为它看起来 git rm
根本没有提供参数(我猜想 - ignore-unmatch
会正常工作if提供的参数没有找到,但没有提供参数):
$ 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空运行
-q,--quiet不列出被删除的文件
--cached只从索引中删除
-f,--force覆盖up-最新的检查
-r允许递归删除
--ignore-unmatch出口,即使没有匹配,也是零状态
索引过滤失败:git ls-files | \
grep -v.smiv2 $| xargs git rm --cached --ignore-unmatch
我得到了包装 git rm
在脚本中返回成功,即使它由于缺少参数而失败(保存在 / usr / local / bin / gitrm_alt
):
$ b $ pre $ #!/ 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'
但我发现非常丑陋和笨重,所以我想问问是否有一个更直接/正确的方法来做到这一点。
最简单的解决方案是将一个伪参数添加到 git rm
,这样它总是至少有一个文件参数。
例如
... | xargs git rm --cached --ignore-unmatch DoesNotExistInMyProject
I have a project of an SNMP agent where the related MIB files (*.smiv2 files) were developed along with it, but now I want them in a separate git repository.
In order not to lose any of the MIB files history, since they didn't start in the same directory they are now, I couldn't just use --subdirectory-filter
filter-branch, so I tried the --filter-index
approach, based on this question. The idea would be to remove every file which doesn't end with .smiv2
(obviously on a fresh clone of the original project, which shall be pushed to my new MIBs repo by the end of the process).
To make it simpler, I chose using ls-files
over ls-tree
, so instead of:
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'
I used this:
git filter-branch --prune-empty --index-filter 'git ls-files | \
grep -v ".smiv2$" | xargs git rm --cached --ignore-unmatch'
but any of these failed in the first commit, since it appears git rm
was fed no arguments at all (I suppose --ignore-unmatch
will work fine if the supplied arguments are not found, but not in the case no arguments are supplied):
$ 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
I got it working wrapping git rm
in a script which returns success even when it fails due to lack of arguments (saved it in /usr/local/bin/gitrm_alt
):
#!/bin/sh
git rm --cached --ignore-unmatch "$@"
exit 0
and then calling that instead of git rm
:
git filter-branch --prune-empty --index-filter 'git ls-files | \
grep -v ".smiv2$" | xargs gitrm_alt'
but I found that extremely ugly and clunky, so I'd like to ask if there's a more direct/proper way to do this.
The simplest solution would be to add a dummy argument to git rm
so that it always has at least one file parameter.
E.g.
... | xargs git rm --cached --ignore-unmatch DoesNotExistInMyProject
这篇关于使用git filter-branch删除不需要的文件的正确方法,不用git rm失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!