2015-10-17 139 views
1

初步方案:Git的合併與--squash同時保持每個日誌提交

A (master) 
\ 
B - C - D (development) 

我想合併後--squash:

A  -  E (master/development) 
\  /
B - C - D 

分支mastergit log

commit E 
    Squashed commit of the following: 
    commit D 
    commit C 
    commit B 
commit A 

繼續在分支上開發development

A  -  E (master) 
\  /\   
B - C - D F - G - H (development) 

合併與壁球再次:

A  -  E  -  I(master/development) 
\  /\  /
B - C - D F - G - H 

分支mastergit log

commit I 
    Squashed commit of the following: 
    commit H 
    commit G 
    commit F 
commit E 
    Squashed commit of the following: 
    commit D 
    commit C 
    commit B 
commit A 

分支developmentgit log

Commit I 
Commit H 
Commit G 
Commit F 
Commit E 
Commit D 
Commit C 
Commit B 
Commit A 

竟被我d希望合併在master上被壓縮的提交,同時保留development的所有提交。

我不知道如何實現這一點。我的問題是,我不知道如何在第一次合併時將D指向E,並且I將僅包含B,C,D,E,F,G,H而不是F,G,H

+0

你爲什麼要這樣做?這似乎使歷史更加複雜。你的日誌結果也不會像你想象的那樣。 master的日誌會顯示所有提交。 – Schwern

回答

2

你不能根據你所顯示的結構得到你想要的日誌結果(git log --merges master會這樣做)。這個結構會給你你想要的日誌打敗點。最後,這是與Git合作的一種自我毀滅的方式。


的願望是能夠運行git log master只看到了壓扁的提交。這不起作用。 Git不知道某些提交是用於master,有些用於development。我們來看看建議的結構。

A  -  E  -  I [master] [development] 
\  /\  /
B - C - D F - G - H 

在這一點上,masterdevelopment指向同犯。至於Git歷史他們是相同的。分支只不過是指向提交的標籤。 提交不記得他們致力於哪個分支git log mastergit log development將生成相同的日誌,顯示從A到I的所有提交。E和I壓縮的提交日誌將是多餘的。

可以得到你想要的東西與git log --merges master(或development),只顯示合併提交,但會顯示任何合併提交,即使是那些做了作爲development一部分。所以它並不真正起作用。

這整個想法是不必要的複雜,閱讀。


要得到你想要的日誌結果,你應該打破這兩個分支之間的關係。

A  -  E  -  I [master] 
\     
B - C - D - F - G - H [development] 

你可以在某種程度上做功,但沒有意義。 git log master包含所有相同的日誌消息,因此它只會與git log development一樣長,但它們會被粉碎在一起。您不能使用git log master來進行代碼考古(即「爲什麼這樣寫這樣的行」),因爲這些更改全部搗毀成一個差異,從而難以將一行更改與特定的提交消息相關聯。由於masterdevelopment的歷史已解除關聯,因此無法確保開發中的所有內容都已將其變爲主內容,反之亦然(例如對主內容進行修復)。

git log master提供比git log development信息較少和它的更難理解masterdevelopment沒有關聯,並且失去了保留合併歷史的所有好處。維護這個複雜的設置沒有意義。


相反,使用git merge --no-ff合併功能分支(而不是一個連續的「發展」的分支),並保持分支歷史,方便考古學。

   G - J [feature/tacos] 
      /
A  -  E  -  K [master] 
\  /\  /
B - C - D F - H - I 

E和K是正常合併提交產生git merge --no-ff。沒有連續的development分支,即由功能分支處理。功能分支一次性使用,一旦合併就刪除。關於功能分支的信息保存在合併提交中,並且保證分支結構被保存。 feature/tacos是一個功能分支,用於處理尚未合併的炸玉米餅。

git log --graph --decorate master將顯示master的完整歷史記錄,合併提交顯示特性何時結束,以及顯示分支歷史記錄的行。 GUI Git歷史記錄工具(如GitX)是另一種將歷史作爲圖形讀取的方式。

最後,Git歷史記錄是一個圖表。如果你學習如何使用這個圖表,使用Git的生活會容易得多。如果你想讓Git的歷史線性化,就像一大堆煎餅一樣,你就是在擊敗Git的角色併爲自己和其他人創造額外的工作。

0

那麼,你不可能得到正好你所要求的,就好像你合併了分支,你會看到提交日誌中的兩個分支的提交。你可能想是這樣的事情:

A  -  E (master) 
\   
B - C - D (development) 

您剛剛從development分支櫻桃挑提交,壁球他們和應用上的master頂部。

最簡單的方法來獲得,這是類似的東西:

git checkout development && git rebase -i master HEAD 

然後你更換所有的動作,除了第一個,與squash。結果你會得到一個分離的頭部,指向被壓扁的提交,應用於master之上。您只需將master重置爲此提交,即可完成。

我猜,提交消息並不是你想要的,因爲它會保存所有提交的提交消息,而不是他們的哈希值,但是你可以使用--exec選項掛鉤提交消息生成。

一切都有點過於人工,但您可以編寫腳本並創建一個別名。我相信,這是最接近你可以使用git本身,而不是在一些更高級別的編程語言重寫所有內容。