2016-03-04 351 views
3

我正在處理我的回購的另一個分支,並需要從主分支中引入更改。我習慣做git rebase master,並且一切正常。然而,在最近的幾個項目中,我看到提交在日誌中重複,和墊底傾向於(大聲地)抱怨:git rebase,提交重複

$ git log --graph --abbrev-commit --decorate ... 
* 4988d49 - (2 hours ago) Merge branch 'branchname' of ... 3 
|\ 
| * e979be1 - (2 days ago) change verbiage 10 
| * 93a1c80 - (2 days ago) Merge branch 'branchname' of ... 2 
| |\ 
| | * 4e4e790 - (2 weeks ago) Merge branch 'branchname' of ... 1 
| | |\ 
| | | * 87cc232 - (8 weeks ago) change verbiage 3 
| | | * 3d5cf09 - (8 weeks ago) change verbiage 2 
| | | * aea4cbd - (9 weeks ago) change verbiage 1 
| | * | a7043ef - (2 weeks ago) change verbiage 6 
| | * | fa3413b - (2 weeks ago) change verbiage 5 
| | * | be038a7 - (2 weeks ago) change verbiage 4 
| | * | 37cb1e6 - (8 weeks ago) change verbiage 3 
| | * | 1ab71c6 - (8 weeks ago) change verbiage 2 
| | * | c4560f4 - (9 weeks ago) change verbiage 1 
| * | | d3211fd - (2 weeks ago) change verbiage 6 
| * | | 72a2a4a - (2 weeks ago) change verbiage 5 
| * | | ae1c123 - (2 weeks ago) change verbiage 4 
| * | | 8328c08 - (8 weeks ago) change verbiage 3 
| * | | e52588f - (8 weeks ago) change verbiage 2 
| * | | 114cbec - (9 weeks ago) change verbiage 1 
* | | | 38bd6ce - (2 hours ago) change verbiage 9 
* | | | 5aaf360 - (2 hours ago) change verbiage 8 
* | | | 2745790 - (2 days ago) change verbiage 7 
* | | | 7bb613f - (2 weeks ago) change verbiage 6 
* | | | 726a312 - (2 weeks ago) change verbiage 5 
* | | | 771dd7f - (2 weeks ago) change verbiage 4 
* | | | b451926 - (8 weeks ago) change verbiage 3 
* | | | 484d5dc - (8 weeks ago) change verbiage 2 
* | | | 630df34 - (9 weeks ago) change verbiage 1 

(我已經改變了提交信息爲簡單起見,這裏真的是隻儘管有四條「管線」,但我在這裏展示了一個分支)。我已經在這個項目上做了一些改版,我認爲它們可以根據重複(比如說)改變措詞1的次數來描述。

我以爲我正在通過重新合併來完成項目工作流程中的「最佳實踐」。我以爲至少有一個以前的rebase是用-no-ff完成的,但是我看不到行爲上的差異。

當提交重播時,它們發生衝突(顯然,將一個提交置於其本身之上是有問題的),所以我不得不做一個交互式重定位,刪除所有重複的提交。

缺乏對回購本身的訪問,這是我的工作流程的問題嗎?這是否表明分支機構存在其他問題?

回答

6

爲什麼?

它看起來像你修改了舊的提交與其他分支已經指出了。那麼,什麼情況是:

你有一個DAG,看起來像這樣:

* abc123 (master) Most recent commit 
| 
| * f00ba12 (foo, HEAD) Some feature you're working on 
| | 
|/ 
* 192837 Fix the things 
| 
* 348cc87 Remove Peter's garbage code 
| 
* 000a0a WOOOORRRDDDDDSSSS 

所以您目前所foo做一些事情,但你知道你仍然有一些彼得的垃圾代碼遺留下來的希望將其刪除。作爲一名優秀的程序員,您希望將這些更改與其他更改一起提交到348cc87。所以你要做一個基準重新回到這一點,並修改其中的變化。

這看起來不錯吧?事情是,你已經改變了348cc87,所以它不再是348cc87了。現在它的111222,因爲記住提交散列是從項目的樹中計算出來的,除此之外。其他事情之一是父母提交散列(000a0a)。因此,由於348cc87現在爲111222,'192837'重新計算爲999999f00ba12更改爲ba12f00。所以,現在你的日誌,從頭部看起來像

* ba12f00 (foo, HEAD) Some feature you're working on 
| 
| 
* 999999 Fix the things 
| 
* 111222 Remove Peter's garbage code 
| 
* 000a0a WOOOORRRDDDDDSSSS 

這將成爲因爲abc123仍然在192837指向一個問題,它的工作原理是因爲commit對象192837在Git中仍然存在。這是因爲從git的角度來看,192837abc123是明顯不同的提交,它們恰好具有相同的日誌消息。

所以,現在你的混帳DAG的樣子:

* abc123 (master) Most recent commit 
| 
| * f00ba12 (foo, HEAD) Some feature you're working on 
| | 
| * 999999 Fix the things 
* | 192837 Fix the things 
| | 
| * 111222 Remove Peter's garbage code 
* | 348cc87 Remove Peter's garbage code 
|/ 
* 000a0a WOOOORRRDDDDDSSSS 

現在,當你完成的工作在你的foo分支,並準備合併你

* 5f93da (master) Merge 'foo' into 'master' 
|\ 
* | abc123 Most recent commit 
| | 
| * f00ba12 (foo, HEAD) Some feature you're working on 
| | 
| * 999999 Fix the things 
* | 192837 Fix the things 
| | 
| * 111222 Remove Peter's garbage code 
* | 348cc87 Remove Peter's garbage code 
|/ 
* 000a0a WOOOORRRDDDDDSSSS 

這樣做了很多,你最終會在目前的情況下。

但凱爾,我該如何解決這個問題?抓住你的馬r2evans,我到了那裏。

如何解決

有幾個方法,你可以解決這個問題,所有我知道的是溫和的紛繁複雜給予一定的情況下,那些的。

  • 你可以把很多東西壓在一起,這樣提交的次數就會減少,但是你失去了一些我不喜歡的歷史。

  • 你可以做一些更多的重新鑲嵌魔術來改變你的'abc123'提交,讓新的999999作爲它的父項提交。你可以使用--onto參數。取決於這種情況下的提交次數,這可能是具有挑戰性的。

  • 您可以保持原樣。只要主人的提示處於正確的狀態,這不是可怕的,但讓您回顧歷史相當困難。

這是一個問題?

是的。這看起來像是您的工作流程的問題。出於這個原因,編輯歷史往往不是一個好主意,你通常應該避免它。

對我而言,master追蹤什麼是公開的。這是我自己和我的隊友都將我們的變更建立在基礎之上的代碼。我從不修改master中的提交。首先是因爲我們的內部git repo不會允許我推動這樣的變化(即使使用--force),其次是因爲這會混淆我的隊友的代碼(並將它們放到您的位置)。

我創造過的master特定功能特性分支,所以我將有分支機構foobarfizz和關老爺的buzz都作爲單獨的分支,不交相輝映。這使我可以獨立工作。我通常不會從功能分支中分支出來,但是當我這樣做時,我通常不會對提交歷史進行任何編輯。這是因爲我通常會在合併之前清理分支,所以我不需要。

+0

非常好的答案,謝謝凱爾。另一個問題(我忘了提及)是我在repo服務器上有分支,所以'git push origin'幾乎總是需要強制性提交才能推送。也許我提出的Dag最大的「問題」是它只有一個時顯示四個分支;我寧願保持一個「乾淨」的DAG,而不顯着重複提交消息。知道這是「正常行爲」有幫助。 – r2evans

+1

如果整個歷史已經出現在世人眼前,而人們正在消費它,那就留下吧。這不是很好或者什麼,但是你不應該因爲傷害其他開發者而混淆公共回購。所以一旦你推動起源,你應該做出新的提交,而不是變成舊的提交。 –