2016-11-12 84 views
0

我们有一个名为'develop'的主分支,所以无论我们何时开发一个功能,我们都会从'develop'制作一个本地功能分支,然后再合并开发。Git从另一个远程分支更新我的远程分支

现在的情况是,
1.用户1必须从'develop'(比如feature1)创建一个特性分支,并且他必须将它发布到Git。这个做完了。
所以现在'develop'和'feature1'是Git中的两个不同的分支,而'feature1'中的变化没有合并为'develop',因为'feature1'仍在开发中。
2.稍后,我开始实施的功能对'feature1'有一定的依赖性。所以我从git克隆了'feature1'分支,并决定更新我的更改,认为'feature1'已经从'develop'分支更新过。
3.但后来我发现'feature1'分支不会更新'develop'分支的最近更改。
4.现在我需要'develop'分支中的更改在'feature1'分支中更新,然后更新对它的更改。

任何可能的方式来做到这一点与GIT命令?

+0

正如旁注:*无*是“远程”分支。 (事实上​​,“远程分支”实际上并不是一个Git术语,有一种叫做远程跟踪分支的东西,这就是你所看到的名称,如“origin/develop”和“origin/master”。你的Git从其他Git获得的最后一次Git与其他Git的最后一次交谈这意味着你永远不会改变它当你的Git再次与其他Git交谈时,让你的Git更新它们,但是,只有其他Git应该以任何方式更改它们。) – torek

回答

4

从我收集的,这是在你的仓库情况:

    develop 
        ↓ 
A -- A -- B -- C -- C 
      \ 
      F -- F -- F 
         ↑ 
        feature1 

因此,提交A提交开发以前存在。 B开发的基础提交在创建特征分支时处于打开状态。F是在功能分支上提交的提交,并且C是在功能分支已经创建并正在处理之后在上开发的提交

现在,你想要做的是继续在功能分支上工作,同时取决于提交C引入的更改。是对的吗?

在这种情况下,假设你是不一样的开发者为用户1,引进这些变化为特征的分支最安全的方式是简单地将它们合并。因此,尽管有特征1查出来,只是合并发展使用`git merge develop *。然后,历史记录如下所示:

     develop 
         ↓ 
A -- A -- B ---- C ----- C 
      \    \ 
      F -- F -- F -- M 
          ↑ 
         feature1 

因此,您只需简单地合并更改,然后就可以继续使用它。事实上,你可以继续做这一行多次既是特征1发展成长:

         develop 
             ↓ 
A -- A -- B ---- C ----- C -- C -- C -- C 
      \    \   \ \ 
      F -- F -- F -- M -- F -- M -- M -- F 
               ↑ 
              feature1 

而且一旦你与功能分支了,你可以将其合并到发展

           develop 
               ↓ 
A -- A -- B ---- C ----- C -- C -- C -- C ------ M 
      \    \   \ \ /
      F -- F -- F -- M -- F -- M -- M -- F 

当然,这使历史看起来有点凌乱,但它代表了正确的特性分支是如何随着时间而演变,而相关的变化仍然发生在发展


如果你想避免这样的历史,有几种选择。如果您只需要很少的更改,例如有些是在单个提交中引入的,而其他提交与您无关,您也可以在功能分支上挑选那个提交。樱桃采摘允许你拷贝一个提交,基本上重用它,同时仍然作为一个单独的提交。

比方说,您只需要从上面显示的第一个图表中第一次提交C。然后,你可以做git cherry-pick C1超过它复制到新特性分支:

    develop 
        ↓ 
A -- A -- B -- C1 -- C2 
      \ 
      F -- F -- F -- C1' 
          ↑ 
         feature1 

这将创建一个副本C1'其中包括同样的变化其原有C1(但仍是一个不同的提交对象)。然后,您可以继续使用包含这些更改的功能分支进行工作。


最后,剩下的选择是rebasing。重订重写的历史,所以再次从第一个图开始,你可能最终与运行git rebase develop如下:

    develop 
        ↓ 
A -- A -- B -- C -- C 
        \ 
         F' -- F' -- F' 
            ↑ 
           feature1 

要记住的重要一点是,历史上真正改写,所以特性1上的所有提交都被修改,而被重新创建为。这导致它们是具有不同提交标识符的完全不同的对象,使它们与分支的先前状态不兼容。

这会导致其他开发人员(尤其是那些正在致力于功能部件的“用户1”)在分支上尝试合并您的更改时遇到冲突。修复这将需要他们手动修复它,除非你告诉他们,他们可能甚至没有注意到(使历史非常混乱,并因此而被破坏)。

所以,除非你知道你在做什么,否则你应该绝不会重新提交在之前发布的提交。即使这意味着你的历史看起来不太好。

2
  1. Rebase feature1 to develop in local repo。它将倒回feature1中的任何更改,将develop合并为feature1,然后重新执行更改。

git checkout feature1

git rebase develop

  • 强制推本地回购到主回购。
  • git push -f

  • 衍合分支(比如说,feature2)至feature1
  • git checkout feature2

    git rebase feature1


    参考:https://git-scm.com/book/en/v2/Git-Branching-Rebasing

    希望这有助于!

    编辑:读取poke's answer,因为这会使其他开发人员的本地回购有所损坏。

    +1

    由于有多个开发人员在功能分支上工作,并且分支已经发布,所以在这种情况下不应该重新分配。重新激活将彻底打破他们的本地分支,要求他们手动修复它。 – poke