我做了一些不好的事情......我不知道我做了什么,但我现在有两个提交没有父母。据我所知,我只应该有一个,这是最初的提交。
每当我责怪时, funky 提交之前的所有更改都指向提交2139f47。
这是我的reflog的 funky 部分:
...
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)的 funky 提交的内容是:
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。我该怎么做?
答案 0 :(得分:2)
您可以执行以下操作:
使用与49d0d22
相同但具有单个父级e7d174b
的树创建提交。这是需要每天不使用的“管道”命令的步骤。
将49d0d22
的后代重新引用到此新提交中。这使您的HEAD
可以再次使用。
警告您的同事即将执行非快进推送。 (如果自定义回购以拒绝非快进推送,请与回购管理员联系以暂时启用它。)执行推送。
确保您的同事使用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
,所以此步骤完全独立于上述手术。
答案 1 :(得分:1)
使用一些移植物或替换物为您提供正确的外观(链接),然后使用过滤器分支使其永久化。
这假设那些时髦的部分还没有与其他部分一起发布。
编辑前一阵子我问how-do-git-grafts-and-replace-differ, are-grafts-now-deprecated?这两种技术。
在实践中,我发现移植物更容易设置。它只是一个你想要被尊重的提交 - 父对的列表,而不是提交中列出的现有父对象。
这意味着,例如,您可以使用绕过错误提交的对来中断提交链(请记住所有提交只是快照; - )。
在这种情况下,您可以通过向grafts文件中添加必要的链接,使任何提交看起来都在提交链中的任何位置。你甚至可以用贪婪创造'假'合并(两个父母在线)。
因此,创建列表(移植文件),列出您想要更改的链接,然后它将显示(看起来像)你想要的方式。此时您可能希望将其永久化,因此只需运行git filter-branch
即可重写这些部分。只要确保任何同事知道会发生什么,这样他们就不会“感到惊讶”。