2016-11-12 538 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