我是 git 新手,我发出了嘘声。我开始了一个新的分支(poly_attr),检查了它,做了一些提交。当我还在那个分支时,我做了一些其他应该去另一个分支的事情。所以我提交了应该在 poly_attr 中的所有内容,然后创建并签出了一个新分支(issue1),提交了更改,并推送了两个分支。猜猜我忘了做什么?在创建 issue1 之前检查 master。所以我的 issue1 分支离开了 poly_attr。好的,很容易解决,我认为,检查 master 并将 issue1 重新设置为 master。不,现在我有一个来自 poly_attr(远程)的 issue1 分支和一个来自 master(本地)的分支。如何从 poly_attr 中获取 issue1 分支?
1 回答
套用一下,你从这个开始:
... - M5 - M6 <-- master, origin/master
也就是说,有一些系列的提交(我已经编号了)。您创建了一个新的分支名称,指向与提示相同的提交并进行了更多提交,我将对其进行标记:Mn
poly_attr
master
Pn
... - M5 - M6 <-- master, origin/master
\
P0 - P1 <-- poly_attr
issue1
然后你在末尾创建了一个新分支poly_attr
(不是你打算开始的地方),并进行了更多提交:
... - M5 - M6 <-- master, origin/master
\
P0 - P1 <-- poly_attr
\
I0 - I1 <-- issue1
然后你做了一个git push
推poly_attr
到issue1
你的遥控器(第二个傻瓜)。
遥控器现在有提交I0
和I1
(在遥控器上具有与本地相同的分支标签),并且您不能从那里删除它们,除非您可以在那里登录并执行包括git gc
. 更糟糕的是,假设 repo onorigin
是共享的,其他人现在可能已经拥有它们。这反过来意味着,你如何解决这个问题取决于你对没有其他人拥有它们的确定程度,你对拥有它们的任何人有多大的影响,和/或你有多渴望让最终的分支历史“看起来很简单” .
在您自己的 repo 中,运行git rebase -i master issue1
并选择仅保留提交I0
和I1
,甚至git rebase --onto master poly_attr issue1
可以保留I0
并且I1
无需编辑交互式 rebase 内容,这很容易。无论哪种情况,您的最终结果都是:
... - M5 - M6 <-- master, origin/master
|\
| P0 - P1 <-- poly_attr, origin/poly_attr
| \
| I0 - I1 <-- origin/issue1
\
I0' - I1' <-- issue1
请注意,I
提交链仍然存在,它们拥有的剩余标签是“远程分支” origin/issue1
。
如果您确定没有其他人issue1
从遥控器中抓取,并且您有足够的权限,则可以git push -f origin issue1:issue1
在执行 rebase 之后。这将发送新的提交I0'
,I1'
并使远程移动他的issue1
标签指向新分支I1'
的尖端。issue1
旧的提交 ( I0
and I1
) 仍然会存在一段时间,但没有人会看到它们,它们不会妨碍它们,最终它们会被垃圾收集:
... - M5 - M6 <-- master, origin/master
|\
| P0 - P1 <-- poly_attr, origin/poly_attr
| \
| I0 - I1 [invisible and eventually gc'd]
\
I0' - I1' <-- issue1, origin/issue1
即使别人抢了,如果你有足够的权限和权力,你也许可以强迫他们拿走你的零钱。(“对不起,伙计们,如果你克隆了问题 1,请注意我已经强行重新设置了它,你必须弄清楚如何修复你所做的任何依赖它的东西。”)
如果您不确定或没有许可或其他什么,您将不得不忍受一些更混乱的事情。而不是进行新的提交(那些),您只需在链的末尾添加取消每个提交效果的提交。您可以相当简单地做到这一点,从原始(非重新定位)链开始:In'
issue1
Pn
... - M5 - M6 <-- master, origin/master
\
P0 - P1 <-- poly_attr
\
I0 - I1 <-- issue1
只需用于git revert
应用系列中所做更改的倒数P
:
$ git checkout issue1
$ git revert master..poly_attr
这为您提供了新的链:
... - M5 - M6 <-- master, origin/master
\
P0 - P1 <-- poly_attr
\
I0 - I1 - RP1 - RP0 <-- issue1
whereRP1
是一个还原(reverses)的提交P1
,并且RP0
是一个还原的提交P0
。如果您在 中添加了一个文件P1
,它会在 中删除RP1
。如果您在 中删除了一行代码P0
,它会被放回RP0
. 这意味着最终结果,即您在签出时获得的文件,看起来与RP0
您在提交中进行更改时相同。当然,历史看起来完全不同,最好解释一下(在还原提交中)为什么会发生这种情况。但最终结果是一样的,你只是在链的末端添加了新的提交,这意味着其他有提交的人可以毫不费力地拿起新的东西。I0
I1
M6
In