删除git中的空提交 [英] Remove empty commits in git

查看:634
本文介绍了删除git中的空提交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



谢谢。

解决方案

<一个简单的(但很慢)的方法是使用 git filter-branch - prune-empty 。没有其他过滤器的情况下,其他任何提交都不会被改变,但是任何空的提交都将被丢弃(这会导致所有后续提交都有新的父ID,因此仍然是重写历史记录:如果这是您的初始化从hg导入到git中,但是如果其他人已经在使用这个仓库,那么这是一件大事)。



注意filter-branch的所有常见注意事项。 (另外,作为一个附注,一个空提交实际上是一个与前一个提交具有相同的树:它并不是说根本没有文件,而是它具有所有相同的文件,具有相同的模式,和相同的内容,因为它的父提交,这是因为git存储每个提交的完整快照,而不是从一个提交到下一个提交的差异。)




下面是一个很小的例子,它隐藏了许多你可以做更有趣的事情的地方:

  $。 ..创建存储库... 
$ cd some-tmp-dir; git clone --mirror file:// path-to-original

(第一个克隆步骤用于安全性: filter-branch 可能具有很强的破坏性,所以在新克隆而不是原始版本上启动它总是很好的。使用 - mirror < code $>意味着它的所有分支和标签也被镜像到这个拷贝中。)
$ b $ $ $ $ $ $ $ $ $ $ git filter-branch - -prune-empty --tag-name-filter cat - --all

(现在等一下可能很长的时间;查看方法的文档来加快这一点。)

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

(这一步是从文档中复制出来的:它在运行过滤器之前丢弃所有原始分支,换句话说,它使得过滤成为永久性的,因为这是一个克隆,即使过滤器出错也是合理安全的。)

  $ cd third-tmp-dir; git clone --mirror file:// path-to-filtered-tmp 

,过滤副本的压缩副本,过滤步骤中没有剩余对象。)

  $ git log#和其他命令来检查

一旦确定过滤的克隆的克隆是好的,需要过滤的克隆,并可以使用最后一个克隆来代替第一个克隆。 (也就是说,您可以用最终克隆替换真正的原创。)


I just migrated a project from Mercurial to Git. Mercurial adds empty commits when you add tags, so I ended up with empty commits in Git that I would like to remove.

How do I remove empty commits (commits that do not have any files in them) from Git?

Thanks.

解决方案

One simple (but slow) way to do this is with git filter-branch and --prune-empty. With no other filters, no other commits will be altered, but any empty ones will be discarded (which will cause all subsequent commits to have new parent-IDs and is therefore still "rewrites history": not a big deal if this is your initial import from hg to git, but is a big deal if others are using this repository already).

Note all the usual caveats with filter-branch. (Also, as a side note, an "empty commit" is really one that has the same tree as the previous commit: it's not that it has no files at all, it's that it has all the same files, with the same modes, and the same contents, as its parent commit. This is because git stores complete snapshots for each commit, not differences from one commit to the next.)


Here is a tiny example that hides a lot of places you can do fancier things:

$ ... create repository ...
$ cd some-tmp-dir; git clone --mirror file://path-to-original

(This first clone step is for safety: filter-branch can be quite destructive so it's always good to start it on a new clone rather than the original. Using --mirror means all its branches and tags are mirrored in this copy, too.)

$ git filter-branch --prune-empty --tag-name-filter cat -- --all

(Now wait a potentially very long time; see documentation on methods to speed this up a bit.)

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

(This step is copied out of the documentation: it discards all the original branches from before running the filter. In other words, it makes the filtering permanent. Since this is a clone, that's reasonably safe to do even if the filter went wrong.)

$ cd third-tmp-dir; git clone --mirror file://path-to-filtered-tmp

(This makes a clean, nicely-compressed copy of the filtered copy, with no leftover objects from the filtering steps.)

$ git log     # and other commands to inspect

Once you're sure the clone of the filtered clone is good, you don't need the filtered clone, and can use the last clone in place of the first. (That is, you can replace the "true original" with the final clone.)

这篇关于删除git中的空提交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆