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

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

问题描述

我刚刚将一个项目从 Mercurial 迁移到 Git.当您添加标签时,Mercurial 添加了空提交,因此我最终在 Git 中得到了我想删除的空提交.

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.

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

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

谢谢.

推荐答案

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

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).

注意 filter-branch 的所有常见警告.(另外,作为旁注,空提交"实际上与前一次提交具有相同的树:并不是它根本没有文件,而是它具有所有相同的文件,具有相同的模式,以及与其父提交相同的内容.这是因为 git 存储了每次提交的完整快照,而不是一次提交与下一次提交的差异.)

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

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

(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天全站免登陆