2014-03-28 119 views
5

承諾的差異我有兩個分支:masterdevelop。當從develop的變化完成後,它們合併爲mastergit merge說已經是最新的,但在分支

此時,分支應該同步。但是,我注意到master中缺少一個文件,但在develop分支上。 (它看起來就像是不小心刪除,但我無法找到這個使用git log -- myfile.txt命令的任何證據。

我試圖合併developmaster但它說,沒有什麼合併。

> git checkout master 
> git merge --no-ff develop 
Already up-to-date 

如何?我是一個缺少的文件,是我們develop分支重新融入我們的master分支

回答

3

你不合並這在所有;相反,你只提取從develop分支您想要的文件,並在提交其master分支。 (我假定「丟失」文件從未合併過,也許是由於誰做出了最後一個錯誤 - 任何合併,或者故意錯誤)。從另一個分支中提取文件,而在master上:

# run "git status" here to make sure you're on master 
# and have no other changes you want to commit first! 
git checkout develop -- path/to/file 

由於這種結賬通過索引寫入,現在新文件已暫存並準備好提交到分支master

下面的討論。


合併實際上並沒有同步分支(更確切地說,這並不意味着他們將有相同的工作樹,以任何方式)。所有git merge確實是通過提交歷史來查看更改,如果有的話,應該合併。這意味着它必須找到最近的通用歷史。讓我們畫一些提交圖片段來說明這一點。

git checkout master 

拿起一些具體的承諾,那麼:

git merge <sha1-or-other-identifier-like-develop> 

告訴混帳開始在鑑定SHA-1,並看到一個分支,最後「連同」 master。這是SHA-1了「合併基地」:

...-o-*-o-o-o <-- master 
     \ 
     o-o  <-- develop 

的合併基礎是這裏提交標記*,並有*develop確定後再行提交使不上確定的行通過master,所以這個序列需要合併。

然而:

...-o-*-o-o-o <-- master 
     `---___ 
       `---- develop 

這裏,develop點直接提交*(合併基,再次)。自之後沒有任何提交,在master之下也沒有提交。所以這是Already up-to-date。同樣爲:

...-o-o-o-M <-- master 
    \ /
     o-*  <-- develop 

這是什麼樣的情況下,你會看到,如果develop最近相當合併:有一個合併提交上master,我已經打上M。合併基礎仍然是承諾*;直接針對該提交開發點,合併提交M也一樣。所以再次沒有什麼可以合併的(develop沒有提交,master尚未提交,合併提交M提供)。

如果(GIT認爲)合併需要,混帳將會給出的基地(*提交)對最新提交關於當前分支(的master尖),也diff的反對提交你的基地要求合併(在這種情況下,develop的小費)。然後(實質上)查看兩個差異,對第二個差異進行任何變化,然後將它們應用於工作樹。

如果一切順利,git通常會在此時進行合併提交(儘管您可以禁止它)。如果沒有,它會停止併發衝突並使您自己解決問題,之後您將自己執行「git commit」來提交合並。

合併提交的工作樹由任何git自動解析組成,再加上你在之後執行的任何操作,如果手動執行了提交。一旦合併提交本身存在,提交圖將是這樣的,git會認爲不需要後續合併(例如,直到更多提交被添加到develop舉例)。

如果(git認爲)合併是而不是需要它當然不會做任何事情。


對於最後兩個例證:

...-*-----M1--M2 <-- master 
    \ //
     A-B-C-D  <-- develop 

這種模式出現在master做兩git merge --no-ff develop s轉換master,中間沒有提交後:

第一合併開始*作爲共同合併基地(M1M2尚不存在),所以它發現*B之間的變化。 *與自身之間沒有變化,因此合併很容易:git將這些更改添加到*(給出與B相同的工作樹)並進行合併提交M1

第二次合併以提交B作爲合併基礎(M2尚不存在)開始。所以它採用了BM1之間的區別,以及BD之間的差異,這是develop上的新發展。然後將這些差異合併,將它們應用於樹M1,並進行新的合併提交M2M2的樹與D的樹相同。

然而,這是一個有點不同:

...-*-o---M1--M2 <-- master 
    \ //
     A-B-C-D  <-- develop 

在這種情況下,公共基礎爲*和以前一樣,但版本比較*o可能產生的一些東西。 Diff *B顯示分支develop上發生了什麼。 Git通過將第二個變更集合到o的工作樹來合併這兩者,以使合併提交M1合併。 M1的工作樹可能與B的工作樹不同,因爲它也包含在提交o處發生的任何事情。但它可能是相同的,因爲git「結合」的變化。

具體地,如果從oB的差異包括相同變化從*o的DIFF,樹爲M1將匹配樹B。如果沒有,它不會。也就是說,git只保留一個相同更改的副本。 (這裏的「同義詞」意思是「就git可以說的」而言:它不是特別聰明,如果一個變化是添加單詞「閃亮金屬」而另一個變化是添加單詞「閃亮的金屬」,git認爲。這些是不同的)

在任何情況下,第二合併重複圖案:比較工作樹木B VS M1,和B VS D。無論第二個變化發生在第一個變化中,都將其應用於M1的工作樹,並將結果用於製作M2的工作樹。

相關問題