2009-12-13 18 views
9

假設我在文件A中有函數X,並且我想將該函數移動到文件B.同時,其他人對文件A中的函數X進行了更改。git如何處理移動到不同文件的合併代碼?

當合並這兩個函數時,git會做些什麼特殊的事情嗎?變化?它會認識到相同的功能已移到文件B並在其中應用更改嗎?或者我們最終會失去更改還是在文件A和B中有兩個相同功能的副本?

我發現的大多數關於在git中移動代碼的文章主要是重命名整個文件,而不是文件內代碼塊。我發現的最接近的是一個blurb from Linus at kerneltrap

而且使用Git時,整個 「保持 代碼運動的變化分離」有一個更根本的原因: 的git可以跟蹤代碼運動(再次, 是否移動一個完整的文件或只是一個文件之間的函數),並且執行一個 'git blame -C'實際上會跟隨 代碼在文件之間移動。它 ,通過相似性分析,但它 確實意味着,如果同時移動 代碼,並在同一時間改變它, 混帳不能看到「哦,這個函數 從其他文件最初來自」 ,現在你會得到更糟的註釋 關於代碼實際來源。

所以看起來git會認識到代碼被移動到其他地方,但並沒有真正說明在合併過程中會發生什麼。

回答

6

不,git不會做這個級別的變化。當你移動整個文件時它會注意到;所以,舉例來說,如果您移動了文件,刪除了其中的所有內容,那麼它可能有機會接受更改。但它不會對每個子文件或任何類型的重構進行更改。

+0

這樣的變化到A中的X到我的分支中,我將X移動到B,我基本上會失去這些更改,因爲Git認爲我刪除了這些行?我想我只需要仔細看看差異,然後... – jtjin 2009-12-13 21:21:49

+2

你不會失去他們:你必須手工合併衝突。 – 2009-12-13 21:42:08

8

我不認爲以前的答案在一般情況下是正確的,因爲git並不真正關心文件 - 文件名被用作一些啓發式的基礎,但git認爲內容的方式不是'完全圍繞着文件的思想。與其他VCS不同,git會跟蹤內容,在這種情況下,內容恰巧已經移動,但它的內容爲,內容爲

因此,git應該能夠處理分支之間的合併,即使文件已經被重命名,或者代碼在文件之間移動,所以取決於你完成了什麼,它可能會處理合並罰款。

只要對X的更改不會導致合併衝突(如果您更改了原始版本重命名的版本,則可能發生這種衝突),X已移至B的事實不應該是'而且合併結果應該包含兩個變更的結果。如果有問題,則表示git沒有正確跟蹤代碼移動。

在實踐中,以前的答案可能是基於個人經驗,當檢測機械失敗時,在這種情況下https://git.wiki.kernel.org/index.php/GitFaq#How_to_manually_resolve_conflicts_when_Git_failed_to_detect_rename.3F可能會有所幫助。

2

我認爲AlBlue是正確的,而不是奈。

在我的簡單測試中,git 1.7.0.5無法自動合併兩個分支,其中一個分支插入一行到一個函數中,另一個將該函數移動到同一個文件中的新位置。似乎git沒有跟蹤比文件小的內容塊。

要解決合併衝突,合併的人必須知道兩個更改是如何工作的以及他們應該如何合併。

又見git merge: apply changes to code that moved to a different file

0

我認爲實際情況要複雜得多,但是從我都經歷過,混帳可以處理這種3路合併好。

例如:在支路A文件的

一個功能被移動到另一個位置在同一文件中,同時創建一個分支B到持有它。分支B和分支A之間的區別僅在於同一文件中的代碼位置更改。

分支C改變了該功能。

所以,如果你這樣做:

$ git rebase --onto B A C

它會自動,如果我合併的合併修改從分支C到該函數的新位置分支B.

相關問題