删除git中的空提交

Gre*_*eso 22 git version-control git-commit

我刚刚将一个项目从Mercurial迁移到Git.当你添加标签时,Mercurial会添加空提交,所以我最终在Git中提交了我要删除的空提交.

如何从Git中删除空提交(其中没有任何文件的提交)?

谢谢.

tor*_*rek 29

一个简单(但缓慢)的方法是使用git filter-branch和--prune-empty.没有其他过滤器,任何其他提交都不会被更改,但任何空提交都将被丢弃(这将导致所有后续提交都有新的父ID,因此仍然"重写历史记录":如果这是您的初始值,那么这不是什么大问题从hg导入到git,但如果其他人已经在使用这个存储库,这是一个大问题.

注意所有过滤分支的常见警告.(另外,作为旁注,"空提交"实际上是与前一次提交具有相同树的那个:它不是根本没有文件,而是它具有所有相同的文件,具有相同的模式,与父提交相同的内容.这是因为git为每个提交存储完整的快照,而不是从一个提交到下一个提交的差异.)


这是一个很小的例子,隐藏了很多你可以做的更好的地方:

$ ... create repository ...
$ cd some-tmp-dir; git clone --mirror file://path-to-original
Run Code Online (Sandbox Code Playgroud)

(这个第一个克隆步骤是为了安全:filter-branch可能非常具有破坏性,因此在新克隆而不是原始克隆上启动它总是好的.使用--mirror意味着它的所有分支和标签也会在此副本中进行镜像.)

$ git filter-branch --prune-empty --tag-name-filter cat -- --all
Run Code Online (Sandbox Code Playgroud)

(现在等待可能很长时间;请参阅有关加快这一点的方法的文档.)

$ git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
Run Code Online (Sandbox Code Playgroud)

(此步骤是从文档中复制出来的:它会在运行过滤器之前丢弃所有原始分支.换句话说,它会使过滤永久化.因为这是一个克隆,即使过滤器出错,这也是相当安全的. )

$ cd third-tmp-dir; git clone --mirror file://path-to-filtered-tmp
Run Code Online (Sandbox Code Playgroud)

(这会对过滤后的副本进行干净,精心压缩的副本,而过滤步骤中没有剩余的对象.)

$ git log     # and other commands to inspect
Run Code Online (Sandbox Code Playgroud)

一旦确定已过滤的克隆的克隆是好的,您就不需要过滤的克隆,并且可以使用最后一个克隆代替第一个克隆.(也就是说,您可以用最终克隆替换"真实原始".)


ben*_*erd 5

使用--commit-filter应该比使用--prune-empty更快

$ git filter-branch --tag-name-filter cat --commit-filter 'git_commit_non_empty_tree "$@"' -- --all

然后按照torek的答案清理备份参考

$ git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d

来自此处:Git-使用filter-branch删除具有空变更集的提交