2010-06-24 58 views
2

我有以下問題: 我們有一個大的產品,它在主分支。此外,我們還有其他只有少數文件的分支,這些分支僅限於此分支。每個分支都代表主要產品的插件。因此,例如,當您獲得主要產品時,您會收到大量文件,安裝它們等,稍後當您決定獲得插件時,您會收到一個僅包含多個文件的包,並通過上傳這些文件(並替換原始文件)你會得到安裝的插件。Git:如何合併修改後的文件

讓我們在master分支(以及許多其他文件)中有payment.php。我有paypal分支,其中只有一個文件是payment.php。現在我修復了master的payment.php中的一個錯誤,並且想要將此修復合併到paypal分支中。但是,當我運行合併時,絕對所有文件都被添加到該分支。所以最後,貝寶分支有來自主分支的所有文件。你偶然知道如何解決這個問題嗎?我希望GIT合併僅存在於此分支中的文件,因此在上面的示例中,貝寶​​分支應該仍然只有一個文件(payment.php),並將錯誤修復合併。

+0

正如其他人所說,你可能不希望有一個缺少所有文件的分支。如果您確實想單獨跟蹤插件,它應該是一個單獨的存儲庫,可能包含在主項目中的子模塊中。如果你不希望它是單獨的,那麼當然,它可以有自己的開發分支,但作爲項目存儲庫的一個分支,該分支應該包含整個項目,而不僅僅是一個插件。 – Cascabel 2010-06-24 14:55:12

回答

4

這就是爲什麼它很重要很好地管理你的分支,尤其是使用主題分支並向上合併。

你應該做一個主題分支修復,從中將需要修復的所有分支的共同祖先分叉,然後將其合併到主,貝寶:

x - x - x - x ------------- X (master) 
|\       | 
| x - x - x ---- X (paypal) | 
\   /  /
    x (bugfix) --------------- 

如果你已經取得了你的bug修正,你誤使它的主人,而不是從適合的合併基礎,並在掌握歷史尚未發佈,你應該摘櫻桃或重訂其到合適的位置:

# If the bugfix commit is not at the tip of master, you can rebase to get it there: 
git rebase -i <commit before the bugfix> master 
# rearrange the list of commits to put the bugfix at the tip, save and quit 

# Now either cherry-pick or rebase the commit to the right place 
# (rebase is easier if the bugfix is actually several commits) 

# Cherry-pick 
# make a branch and cherry-pick 
git checkout -b bugfix <SHA1 of merge base> 
git cherry-pick <SHA1 of bugfix> 
# remove the commit from master, assuming it's still on the tip 
git checkout master 
git reset --hard master^ 

# or rebase 
# make the bugfix branch (assuming it's still on the tip) 
git branch bugfix master 
# and remove the commit from master (assuming it's still on the tip) 
git checkout master 
git reset --hard master^ # or if the bugfix is composed of n commits, master~n 
# rebase the bugfix branch to the right place 
git rebase --onto <SHA1 of merge base> master bugfix 

如果歷史已經公佈,所有你能做的就是櫻桃挑bug修正到貝寶分支,記得把事情做對,下一次:

git checkout paypal 
git cherry-pick <SHA1 of bugfix> 
+0

嗨,我正在考慮讓貝寶的分支,並不時合併主人。所以,當我需要實現新功能或修復錯誤時,我會在主文件中執行此操作,然後在發佈之前我將合併貝寶分支中的更改(以便貝寶可以擁有新的修復程序和功能)。我對這個東西很新,所以如果我沒有看到一些隱藏的問題,請糾正我。早些時候,我一直在手動完成這項工作。所以我在master中實現新功能,然後手動將這些代碼複製到paypal分支。 – Eugene 2010-06-25 14:22:42

+0

在上面的例子中,兩個分支似乎非常不同(所有那些在分支點之後提交),而我的分支通常只有一個區別(例如,paypal功能)。其餘的都是一樣的,主要工作是保持新的代碼修改始終進入兩個分支。當然,我有時只針對paypal分支進行修復,但這很少見,因爲這段代碼在這個時候已經很好的測試了。 – Eugene 2010-06-25 14:26:00

+0

@Eugene:我真的不確定你在這些評論中想要問什麼。無論如何,您始終可以從右分支點進行修改,然後將其合併到需要它們的所有分支中。不管這些分支有多不同,只要你的補丁仍然適用... – Cascabel 2010-06-25 14:42:07

1

爲什麼不你的其他分支機構包括所有的部分文件的主分支?通過去除所有其他文件的麻煩,你只會讓自己更加困難。特別是如果您以後最終需要更改您已刪除的某個其他文件。

0

你可以做一些類似這樣的:http://nvie.com/git-model

(我希望這個作品)

master將繼續成爲你的主要分支。您創建了名爲bugfix的第二個分支。您創建了第三個分支,名爲plugin-foo

在plugin-foo中,您刪除了所有不需要的文件。現在,只要對不在插件分支中的文件進行更改,就可以在主分支上執行這些操作。所有bug修復都進入bugfix分支。您定期將錯誤修復分支合併到主服務器和插件分支中。這導致錯誤修正進入這兩個分支。

1

你做錯了。你應該擁有分支中的所有文件。

Git的工作是跟蹤哪些文件在分支之間不同,而不是你自己。 這就是使用VCS的一個要點。

如果您只想分發不同分支之間的文件,可以通過腳本輕鬆提取這些文件。

+1

嗨,謝謝你的回覆。我目前正在測試此解決方案,並且很可能會使用它。 – Eugene 2010-06-25 14:17:09

0

在你自己的git repo中分離你的插件可以讓你在父項目上獨立地對它們進行改進。

但是,如果你需要他們直接包含在你的項目,最近的Git版本(git1.7.11,2012年6月),包括git subtree script(以前apenwarrdeveloped on GitHub,現併入主線GIT)

這樣,你可以在另一個合併一個回購(和它的歷史),保留選項以後提取它的歷史(而不是子樹合併)。
這可以看作是git子模塊的替代方案。

另一種替代方法是git slave,以保持父代回購和子模塊緊密同步。