我是git的新手,我做了一个嘘声。我开始了一个新的分支(poly_attr),检查了它,做了一些提交。当我还在那个分支的时候,我还做了一些应该去另一个分支的事情。所以我提交了应该在poly_attr中的所有内容,然后创建并检出了一个新分支(issue1),提交了更改,并推送了两个分支。猜猜我忘了做什么?在创建issue1之前检查master。所以我的issue1分支脱离了poly_attr。好的,简单的修复,我认为,检查master和rebase issue1到master。不,现在我有一个问题1分支关闭poly_attr(远程),一个关闭主(本地)。 如何从poly_attr获取issue1分支?
答案 0 :(得分:2)
换句话说,你从这开始:
... - 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
在内的事情。更糟糕的是,假设共享origin
上的回购,其他人可能现在拥有它们。这反过来意味着,你如何解决这个问题取决于你没有其他人拥有它们的程度,你对 拥有它们的人有多大影响,和/或你是多么绝望终极分支历史“看起来很简单”。
在您自己的仓库中,您可以轻松运行git rebase -i master issue1
并选择仅提交提交I0
和I1
,甚至git rebase --onto master poly_attr issue1
以继承{{1}并且I0
无需编辑交互式rebase内容。在任何一种情况下,您的最终结果是:
I1
请注意,... - 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
和I0'
发送,并使远程移动他的I1'
标签指向issue1
,即新I1'
分支的提示。旧提交(issue1
和I0
)仍然存在一段时间,但没有人会看到它们,它们不会妨碍,最终它们将被垃圾收集:
I1
即使其他人已经抓住它,如果你有足够的权限和权力,你也许可以强迫他们接受你的改变。 (“对不起,伙计们,如果你克隆并得到问题1,请注意我已经强行重新设置它,你必须弄清楚如何修复你做的那些依赖它的东西。”)
如果你不确定或没有许可或其他什么,你将不得不忍受更糟糕的事情。您只需要在... - M5 - M6 <-- master, origin/master
|\
| P0 - P1 <-- poly_attr, origin/poly_attr
| \
| I0 - I1 [invisible and eventually gc'd]
\
I0' - I1' <-- issue1, origin/issue1
链的末尾添加撤消每个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
是一个恢复(反转)RP1
的提交,P1
是一个恢复RP0
的提交。如果您在P0
中添加了文件,则会在P1
中删除该文件。如果您删除RP1
中的一行代码,则会将其放回P0
。这意味着,在结帐RP0
时,您获得的最终结果是文件,就像您在RP0
和I0
上进行了更改一样提交的顶部I1
。当然,历史看起来非常不同,并且(在恢复提交中)解释为什么会发生这种情况是个好主意。但最终结果是一样的,你只是在M6
链的末尾添加新的提交,这意味着其他拥有提交的人可以毫不费力地获取新的东西。