git rebase和远程推送

时间:2013-08-07 04:19:26

标签: git branch

我是git的新手,我做了一个嘘声。我开始了一个新的分支(poly_attr),检查了它,做了一些提交。当我还在那个分支的时候,我还做了一些应该去另一个分支的事情。所以我提交了应该在poly_attr中的所有内容,然后创建并检出了一个新分支(issue1),提交了更改,并推送了两个分支。猜猜我忘了做什么?在创建issue1之前检查master。所以我的issue1分支脱离了poly_attr。好的,简单的修复,我认为,检查master和rebase issue1到master。不,现在我有一个问题1分支关闭poly_attr(远程),一个关闭主(本地)。 如何从poly_attr获取issue1分支?

1 个答案:

答案 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_attrissue1推送到你的遥控器(第二次蠢)。

遥控器现在提交了I0I1(遥控器上的分支标签与您当地的分支标签相同),除非您可以登录,否则无法从那里删除它们在那里做包括git gc在内的事情。更糟糕的是,假设共享origin上的回购,其他人可能现在拥有它们。这反过来意味着,你如何解决这个问题取决于你没有其他人拥有它们的程度,你对 拥有它们的人有多大影响,和/或你是多么绝望终极分支历史“看起来很简单”。

在您自己的仓库中,您可以轻松运行git rebase -i master issue1并选择仅提交提交I0I1,甚至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:issue1I0'发送,并使远程移动他的I1'标签指向issue1,即新I1'分支的提示。旧提交(issue1I0)仍然存在一段时间,但没有人会看到它们,它们不会妨碍,最终它们将被垃圾收集:

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时,您获得的最终结果是文件,就像您在RP0I0上进行了更改一样提交的顶部I1。当然,历史看起来非常不同,并且(在恢复提交中)解释为什么会发生这种情况是个好主意。但最终结果是一样的,你只是在M6链的末尾添加新的提交,这意味着其他拥有提交的人可以毫不费力地获取新的东西。