1

我做了坏事..我不知道我做了什么,但我现在有两个没有父母的提交。据我所知,我只应该有一个,这是初始提交。

每当我责备时,时髦提交之前的所有更改都指向提交 2139f47。

这是我的 reflog 的时髦部分:

...
49d0d22 HEAD@{313}: commit (merge): unused questions widget removed
2139f47 HEAD@{314}: commit: unused questions widget removed
e548c10 HEAD@{315}: commit: unused questions widget removed
e7d174b HEAD@{316}: pull: Fast-forward
...

内部链接看起来像这样:

  HEAD
   |
  ...         e548c10
   |             |
49d0d22 -----+   |
   |         |   |
2139f47     e7d174b
   |           |
  nil         ...
               |
            initial

合并提交对象(49d0d22)的内容是:

tree c3989e79c49df4b141b080502192bf0be0f67195
parent 2139f479dac242ad2ef757519aef77f3003ca996
parent e7d174bef4ab7e89b96f8c3de3551d0b760c80f8
author Michael Andersen <***> 1345190024 +0200
committer Michael Andersen <***> 1345190024 +0200

unused questions widget removed

没有父级的时髦提交 (2139f47) 的内容是:

tree 4cfebc6b5a2a525bc255e4e095008b6aa8b106cc
author Michael Andersen <***> 1345189769 +0200
committer Michael Andersen <***> 1345189918 +0200

unused questions widget removed

似乎没有对象指向(e548c10)的提交的内容是:

tree 0ae0960fccee7faec86ce7a82dd30af70f9c225a
parent e7d174bef4ab7e89b96f8c3de3551d0b760c80f8
author Michael Andersen <***> 1345189769 +0200
committer Michael Andersen <***> 1345189769 +0200

unused questions widget removed

所以我的问题是:

我可以删除时髦的提交吗?以及这如何影响我的程序员同事的起源和本地存储库?

- - 编辑 - -

我不在乎丢失一些提交对象。如我所见,我需要去掉 2139f47 和 e548c10。我怎么做?

4

2 回答 2

2

您可以执行以下操作:

  1. 使用与 相同的树创建提交49d0d22,但具有单个父级,e7d174b。这一步需要一个不是每天都使用的“管道”命令。

  2. 将的后代重新定位49d0d22到此新提交。这使您HEAD再次可用。

  3. 警告您的同事您即将执行非快进推送。(如果 repo 被定制为拒绝非快进推送,请与 repo 管理员联系以暂时启用它。)执行推送。

  4. 确保您的同事更新他们的树git pull --rebase,这样他们就不会尝试与您的旧合并HEAD。为了验证这一点,让他们git merge-base HEAD 49d0d22在拉动后运行——它应该是空的。

实现这些步骤的命令应如下所示:

# 0.
git checkout master # or whatever your working branch is called

# 1.
commit=$(git commit-tree -m "unused questions widget removed" -p e7d174b 49d0d22:)

# $commit should now identify the new commit; you should be able to see it
# with git log $commit or any other git inspection tool.

# 2.
git rebase 49d0d22 --onto $commit
# now your HEAD should be in a valid state.
# git merge-base HEAD 49d0d22 should output nothing

# 3.
git push origin master

git checkout master # or whatever your main branch is called

至于提交e548c10——忽略它。删除引用它的本地和远程分支,并告诉其他人也忽略它。因为这个提交没有以2139f47任何方式引用,所以这个步骤完全独立于上面的手术。

于 2012-09-22T07:29:12.627 回答
1

使用一些移植物或替换物为您的 repo 提供正确的外观(链接),然后使用过滤器分支使其永久化。

这假设那些时髦的部分尚未与其他依赖它的人一起发布。


编辑 不久前,我问了如何做 git-grafts-and-replace-differ,现在不推荐使用 grafts 了吗?关于这两种技术。

在实践中,我发现移植物更容易设置。它只是您想要尊重的提交-父对的列表,而不是提交中列出的现有父对。

这意味着,例如,您可以使用一对绕过错误提交的提交链来中断提交链(请记住,所有提交都只是快照;-)。

在您的情况下,您可以通过将必要的链接添加到移植文件中来使任何提交看起来在提交链中的任何位置。您甚至可以使用移植物(两个父母在线)创建“假”合并。

因此,创建列出您希望更改的链接的列表(grafts 文件),然后它将以您想要的方式显示(看起来)。那时您可能希望将其永久化,因此只需运行git filter-branch以重写这些部分。只要确保任何同事都知道会发生什么,这样他们就不会“感到惊讶”。

于 2012-09-21T21:27:34.443 回答