我已经使用git filter-branch
清理了我的存储库,并使用以下命令删除了一些文件夹:
git filter-branch --force --index-filter 'git rm -r --cached --ignore-unmatch folder' \
--prune-empty --tag-name-filter cat -- --all
此后,我仍然有一些提交仅与现在删除的文件有关。有没有办法解决此问题,即删除不再在历史记录中的文件上的提交?
答案 0 :(得分:0)
如果确实有一些过滤器,则可以使用--prune-empty
运行否则为空的第二个过滤器分支以丢弃它们。
此后,我还有一些提交仅与现在删除的文件有关。
那应该很少见,因为您包括了:
--prune-empty
指示filter-branch
省略任何与其父项匹配的简单(非合并)提交。
您可能有一些合并,合并了在输入点原本相同的两个分支,但是由于它们合并了原本相同的分支,因此无法删除这些提交。
例如,假设在过滤之前我们具有以下分支结构:
B--C
/ \
...--o--A M--o--...
\ /
D--E
提交M
是一个合并,必须保留(照原样),但是假设A
-vs-B
消失了,因为经过过滤,B
与{ {1}}和A
-vs-C
(或vs-B
)也由于相同的原因而消失,给出:
A
(字母后面的勾号或撇号表示它们是原始提交的副本-如果以前没有任何更改,则可能...--o--A'-----M'-o--...
\ /
D'-E'
是 A'
,但是这涵盖了更一般的情况)。即使在没有原始删除文件的情况下进行提交,实际上A
仍需要保持逻辑结构,即使可以进行快速转发。
更有趣的情况是M
和D
自己崩溃了,因为现在E
仍然是过滤分支过程的输入,并且仍然有两个父级,但是两个父母都映射为自己提交M
。我不确定,如果不看,这里会发生什么:过滤分支是否可以将A'
的两次提交列为A'
的两个父项来进行合并提交?如果尝试这样做,M'
是否将提交git commit-tree
写入为普通的非合并提交?测试说不:
M'
因此,看来天真的$ mkdir mtest
$ cd mtest
$ git init
Initialized empty Git repository in ...
$ echo test commit-tree > README
$ git add README
$ git commit -m initial
[master (root-commit) 1db1f76] initial
1 file changed, 1 insertion(+)
create mode 100644 README
$ echo log msg | git commit-tree -p HEAD -p HEAD HEAD^{tree}
error: duplicate parent 1db1f76a4e7217d5198c0f178464b7a087e94078 ignored
44f91061b7bd08c39a4dc9e8ebb1f4f7c588ea9e
会尝试做出filter-branch
并将其作为单亲提交:
M'
其中...--o--A'-M'-o--...
和M'
没有区别。过滤器分支代码对此进行了检查:
A'
(如果您提供自己的父级过滤器,则会在检查之后发生,因此您需要重新进行检查。)
因此,如果您得到这种 for parent in $parents; do
for reparent in $(map "$parent"); do
case "$parentstr " in
*" -p $reparent "*)
;;
*)
parentstr="$parentstr -p $reparent"
;;
esac
done
done
的结果,则仅使用...--A'-M'-...
的第二个过滤器分支将把它们扔掉。
答案 1 :(得分:0)
我在此页的第6步中找到了答案:https://github.com/epics-modules/motor/wiki/Creating-a-standalone-driver-module
git filter-branch --prune-empty --parent-filter 'sed "s/-p //g" | xargs -r git show-branch --independent | sed "s/\</-p /g"'