0

我是 git 新手,我发出了嘘声。我开始了一个新的分支(poly_attr),检查了它,做了一些提交。当我还在那个分支时,我做了一些其他应该去另一个分支的事情。所以我提交了应该在 poly_attr 中的所有内容,然后创建并签出了一个新分支(issue1),提交了更改,并推送了两个分支。猜猜我忘了做什么?在创建 issue1 之前检查 master。所以我的 issue1 分支离开了 poly_attr。好的,很容易解决,我认为,检查 master 并将 issue1 重新设置为 master。不,现在我有一个来自 poly_attr(远程)的 issue1 分支和一个来自 master(本地)的分支。如何从 poly_attr 中获取 issue1 分支?

4

1 回答 1

2

套用一下,你从这个开始:

... - M5 - M6               <-- master, origin/master

也就是说,有一些系列的提交(我已经编号了)。您创建了一个新的分支名称,指向与提示相同的提交并进行了更多提交,我将对其进行标记:Mnpoly_attrmasterPn

... - 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 pushpoly_attrissue1你的遥控器(第二个傻瓜)。

遥控器现在有提交I0I1(在遥控器上具有与本地相同的分支标签),并且您不能从那里删除它们,除非您可以在那里登录并执行包括git gc. 更糟糕的是,假设 repo onorigin是共享的,其他人现在可能已经拥有它们。这反过来意味着,你如何解决这个问题取决于你对没有其他人拥有它们的确定程度,你对拥有它们的任何人有多大的影响和/或你有多渴望让最终的分支历史“看起来很简单” .

在您自己的 repo 中,运行git rebase -i master issue1并选择仅保留提交I0I1,甚至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旧的提交 ( I0and 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'issue1Pn

... - 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您在提交中进行更改时相同。当然,历史看起来完全不同,最好解释一下(在还原提交中)为什么会发生这种情况。但最终结果是一样的,你只是在链的末端添加了新的提交,这意味着其他有提交的人可以毫不费力地拿起新的东西。I0I1M6In

于 2013-08-07T05:43:18.870 回答