【问题标题】:Git: what is a graftcommit or a graft-id?Git:什么是graftcommit 或graft-id?
【发布时间】:2011-05-22 14:30:21
【问题描述】:

git-filter-branch上,据说:

将提交(通常位于另一个历史记录的顶端)设置为当前初始提交的父级,以便将其他历史记录粘贴到当前历史记录后面:

git filter-branch --parent-filter 'sed "s/^\$/-p <graft-id>/"' HEAD

(如果父字符串为空 - 当我们处理初始提交时会发生这种情况 - 添加 graftcommit 作为父字符串)。

这正是我想要的,即设置某些根提交(B)的父级(提交A)。有关相关问题,请参阅 here

但是该命令中的 graft-id 到底是什么?那是新的父母吗,即A

进一步,给出了一个更简单的例子来实现同样的效果:

甚至更简单:

echo "$commit-id $graft-id" >> .git/info/grafts
git filter-branch $graft-id..HEAD

同样,$graft-id 在这个例子中应该是什么?还有$commit-id = A,对吧?还是$commit-id = B$graft-id = A

我也读过this,但我仍然不明白为什么我需要这样的概念。为什么我不能只做git filter-branch A..HEAD 左右?


好的,我想我已经明白了,看看我自己的答案。

解释我为什么需要它:

在我们的项目 OpenLieroX 中,我们曾一度包含 Google Breakpad。

我们没有从官方 SVN 中获取它(因为当时它对我不起作用)而是从最新的 LastFM 稳定版中获取(它只是随机的,来自那里——我也有我的磁盘,知道 LastFM 的人可能拿了一些稳定的 Breakpad 版本)。

然后,随着时间的推移,我们将几个补丁应用到我们自己的 Google Breakpad 副本中。

现在,几个月后,我们想要清理一下历史记录,全面了解我们对 Breakpad 的所有补丁,也许还可以将它们上传到上游。最重要的是(对我们而言),我们想要更新我们的 Breakpad 副本。

所以,我认为最好的办法是创建一个新的 Git 存储库,从某个地方获取官方源历史记录,然后通过 git filter-branch 从我们的主存储库中获取所有 Breakpad 特定的内容。我使用this Breakpad mirror 作为基础。 filter-branch 也有点复杂,因为我们将整个 Breakpad 目录移动到 OpenLieroX 存储库中的某个位置。

所以我最终得到了三个分支:

  • breakpad-in-mainsrc: git filter-branch-first-run 为 Breakpad 在 src/breakpad/external 中的时间。
  • breakpad-in-libs: git filter-branch-second-run 为 Breakpad 在 libs/breakpad 中的时间。
  • official:来自Breakpad mirrormaster 的副本。

然后我在official 中搜索了与breakpad-in-mainsrc 中的根最接近的提交。我没有完美匹配,所以我使用了最接近的一个(写了一个小的 Python 脚本来解决这个问题)。这个现在被标记为olx-closest-initial-breakpad

然后我想将这三个历史合并在一起。上面描述的方式很好(下面给出了我自己的答案)。

结果在这里:OpenLieroX Google Breakpad on GitHub

【问题讨论】:

  • 您确定要重写历史记录吗?这意味着,如果您发现与 breakpad 相关的错误,并且您想了解它是什么时候出现的 - 这可能是不可能的,因为您发布的原始代码已经消失了。

标签: git git-filter-branch


【解决方案1】:

好的,它似乎按我预期的方式工作。回答我自己的问题:

  • graft-id 实际上就是一个提交 ID,即提交的 SHA1。
  • $commit-id = B(但它必须是 SHA1,没有标签左右)
  • $graft-id = A(同样,必须是 SHA1)

然后给定的更简单的方法按预期工作。

【讨论】:

  • 如果您自己回答这个问题,那么分享您的一些知识并解释您在做什么可能是有意义的。有许多关于历史重写和特别是嫁接点的警告(您无法撤消过滤分支以使嫁接永久化)
  • @sehe:我现在用一些背景信息扩展了我的问题。
【解决方案2】:

这是一个相当晦涩的功能。

如果你需要这个,你最好确保你确切地知道 git 在幕后是如何工作的,并且你知道你想要实现什么。

此外,还有一个更新的、可能更有用(至少更灵活)的功能,称为git replace (man page)

恕我直言,如果您真的需要,相同的文档包含充足的信息。

但是看到

  1. https://git.wiki.kernel.org/index.php/GraftPoint
  2. What are .git/info/grafts for?
  3. http://bugsquash.blogspot.com/2010/03/stitching-git-histories.html

【讨论】:

  • 是的,我了解 Git 的工作原理。它的工作方式与预期完全一样。看我自己的答案。我添加了一些解释为什么我需要它。
猜你喜欢
  • 2017-07-18
  • 2015-05-20
  • 2012-07-02
  • 1970-01-01
  • 2017-11-04
  • 2010-09-20
  • 1970-01-01
  • 2013-06-11
  • 2011-06-25
相关资源
最近更新 更多