2015-03-02 67 views
3

我想了解更多關於我們團隊最近擁有的git問題。我們有分支機構的幾層:在現有提交哈希已更改時重新編址

-> Master 
    |-> Feature Branch 
     |-> Individual developer branches 

小開發組工作過一個特性分支,我們有幾個不同的特性分支去一次。

當其中一個與Master合併時,功能分支所有者將rebase他們的功能分支。每隔一段時間,他們都會將合併到單個開發人員的功能分支中的任何工作與衝突合併。

修復合併衝突通常會在變基期間更改提交哈希。

當個人開發者則不會關注的分支衍合到他們的開發分支,目前在技術上已經2犯中修正了該項目的哈希值:

  • 老犯哈希(預變基/合併衝突)仍然保留在開發者分支上
  • 新的提交哈希(post-rebase)現在存在於功能分支上。

當此開發人員嘗試與功能分支進行比較時,舊提交被視爲一項新工作,並「拉扯」拉取請求。

我可以通過讓他們從最新的功能分支創建一個新的分支並挑選他們的工作來輕鬆「解決方法」。這會丟棄舊的提交哈希,但這不是有效的。

有沒有什麼辦法可以改變我們的練習或rebase的不同,這樣我們就可以在開發者分支中排除「改變」的提交散列?

+0

你提到了一個拉請求,你對這些使用什麼? Github上?你可以通過「弄髒請求」來擴展你的意思嗎? – Schwern 2015-03-02 20:02:34

+0

我們使用github企業,但這與問題無關。開發者分支和功能分支的比較會顯示一個已經存在的提交列表 - 這僅僅是git不能識別提交散列。 – helion3 2015-03-02 20:09:48

回答

1

TL; DR版本:有沒有人使用git pull --rebase


如果我理解正確,就有這種情況。

A - B - C [m] 
    \ 
     D - E - F [f] 
      \ 
      G - H - I [d] 

m爲主,f爲特徵分支,d爲開發分支。您希望能夠將f重新分配給m,並將其重新分配給新的f。

     G1 - H1 - I1 [d] 
        /
      D1 - E1 - F1 [f] 
     /
A - B - C [m] 
    \ 
     D - E - F 
      \ 
      G - H - I 

答案是有大家git pull --rebase這相當於一個git fetch加上git rebase。這是如何工作的。這是存儲庫在推送到主服務器之後的樣子(提交C)的樣子。

origin 
A - B - C [m] 
    \ 
     D - E - F [f] 
      \ 
      G - H - I [d] 

feature branch maintainer 
A - B [m][o/m] 
    \ 
     D - E - F [f][o/f] 
      \ 
      G - H - I [o/d] 

dev branch maintainer 
A - B [m][o/m] 
    \ 
     D - E - F [o/f] 
      \ 
      G - H - I [d][o/d] 

特徵分支維護者決定更新它的時間,所以他們git pull --rebase origin master。這是一個git fetch origin加上git rebase origin/master。造成這種情況。

feature branch maintainer 
      D1 - E1 - F1 [f] 
      /
A - B [m]- C [o/m] 
    \ 
     D - E - F [o/f] 
      \ 
      G - H - I [o/d] 

然後,他們git push origin(我相信他們會需要強制),這是結果。

origin 
      D1 - E1 - F1 [f] 
      /
A - B - C [m] 
    \ 
     D - E 
      \ 
      G - H - I [d] 

feature branch maintainer 
      D1 - E1 - F1 [f][o/f] 
      /
A - B [m]- C [o/m] 
    \ 
     D - E 
      \ 
      G - H - I [o/d] 

dev branch maintainer 
A - B [m][o/m] 
    \ 
     D - E - F [o/f] 
      \ 
      G - H - I [d][o/d] 

現在開發分支維護人員想要更新,幸福地不知道任何事情發生在功能分支。他們git pull --rebase相當於git fetch origingit rebase origin/feature。取回後它看起來像這樣。

dev branch maintainer 
      D1 - E1 - F1 [o/f] 
      /
A - B [m]- C[o/m] 
    \ 
     D - E 
      \ 
      G - H - I [d][o/d] 

然後git rebase origin/feature

dev branch maintainer 
         G1 - H1 - I1 [d] 
         /
      D1 - E1 - F1 [o/f] 
      /
A - B [m]- C[o/m] 
    \ 
     D - E 
      \ 
      G - H - I [o/d] 

他們可以推動,可能與--force

你會注意到開發分支在F1上,而不是E1,因爲它原來是。如果你想保持,你必須專門到E1。


如果混帳無法弄清楚,d和E是不是真正的Dev分支的一部分,你可能會風與此。

dev branch maintainer 
         D2 - E2 - G1 - H1 - I1 [d] 
         /
      D1 - E1 - F1 [o/f] 
      /
A - B [m]- C[o/m] 
    \ 
     D - E 
      \ 
      G - H - I [o/d] 

的Git應該能想出解決辦法使用「修補程序ID」,這就像提交身份證,但他們只檢查剩下的內容和無法比擬的。如果不行,請嘗試更新Git並查看是否有幫助。如果它仍然無法做到,那麼你在git-rebase文檔中稱之爲「困難的情況」。你必須拼出Git,你需要使用--onto來兌換。幸運的是,reflog將特徵分支的前一個位置包含爲f @ {1},您可以將其用作參考。

git rebase --onto f [email protected]{1} 

即說變基當前分支(d)到女,但從d只變基至f @ {1}(這是其中f曾經是)。


我已經git pull --rebase別名爲git repull。我幾乎完全這樣做,這是相當安全的,通常是正確的。您可以使用git config --global pull.rebase true將其配置爲默認值。

欲瞭解更多信息,請參閱Recovering From An Upstream Rebase in the git-rebase docs

+0

我不確定這是否解決了核心問題。我們已經在使用'git fetch [remote]'和'rebase [remote/branchname]'。當git rebase時,它需要確定哪些提交是「新工作」,並且尚未存在於正在從中進行更改的「上游」分支上。因爲提交哈希已經發生了變化,因爲提交已經在兩者上都存在,git認爲這是一個新的提交,並試圖「重新應用」這些更改。顯然,合併衝突比比皆是。 – helion3 2015-03-02 20:31:49

+0

@ helion3 Git應該可以使用修補程序ID來完成此操作,修補程序ID就像提交ID一樣,但只涉及內容更改。我所描述的是git-rebase文檔中的「簡單案例」。你正在描述「困難的情況」。你使用的是什麼版本的Git?在[Pro Git *]的Rebasing部分查看「Rebasing的風險」和「Rebase When You Rebase」(http://www.git-scm.com/book/en/v2/Git-Branching-Rebasing) 。 – Schwern 2015-03-02 20:36:47

+0

@ helion3我已經更新了答案,以解釋如何處理「困難的情況」。 – Schwern 2015-03-02 20:46:43