2017-06-05 69 views
0

我有一個Git分支,它包含了許多,我想拉平到所有新枝目錄的拼合git的子目錄。它看起來有點像這樣:由迪爾斯轉換爲新的分支機構

混帳的/ dev /我們 - >我們一,美國二,美國三

我想它最終會是這樣的:

混帳的/ dev/us-one git/dev/us-two etc

它看起來像這是可能的使用git-filter-branch,但我不知道如何使用它與所有的目錄。我可以做類似:

for branch in `find . -type d -d 1`; do 
    git filter-branch --subdirectory-filter $branch --prune-empty -- --all 
done 
+0

'git filter-branch'用於*複製現有的提交*,同時對每個進行一些轉換(在創建新副本之前)。 filter-branch的參數提供了轉換並告訴它要更新哪些分支*名稱,以將它們指向新複製的提交,而不是它們原始的(現在被複制的)提交。它不會創建任何新的分支名稱。 – torek

+0

所以這聽起來像'git-filter-branch'可以用於幾乎櫻桃挑選從一個地方到另一個地方?這是否意味着如果我將SVN中的repo轉換爲git,並且在git更改完成之前svn repo中有更改,那麼可以使用'git-filter-branch'來僅移動這些特定的提交? – user3270760

+0

你當然可以濫用'git filter-branch'來做這樣的事情(櫻桃採摘),但這不是它的設計目的。 (當然也可以參考馬克阿德爾斯伯格的答案。) – torek

回答

2

嗯,我想有一種方法可以做到這一點。他指出了一些東西給後人第一...

注意事項

既然你在談論使用filter-branch,我想你已經通過了這些分支的創建單獨的歷史的影響想。爲了以防萬一,我會指出,使用舊回購的人可能很難在新回購中找到相應的代碼版本。另外,如果跨目錄進行的更改得到協調,那麼這些協調將會丟失(除非您執行某些操作來重新創建它們)。

可能與最後一點,如果在這些目錄的結構都非常相似,這是有道理的,那麼如果沒有他們有時會讓人感到意外需要「分享」的變化。如果這確實是一個問題,那麼你描述的「現狀」結構以及你所要求的「目標狀態」都不會真正支持這一結構。

但是,你會怎麼做呢?

在你剛剛得到了簡單的情況下一個分支你想「突圍」爲每個目錄。這意味着你的問題,但以防萬一我會提供一個更適用於多個分支的一般程序。

所以首先,你需要真正創建所有你到底想要的分支。如果你有標籤,你可能也想複製它們,但我會回到那個。

對於您的每個分支:

git checkout `branchA` 
git branch `branchA-one` 
git branch `branchA-two` 
... 
git checkout `branchB` 
git branch `branchB-one` 
git branch `branchB-two` 
... 
... 

然後你就可以在每一組裁判的運行filter-branch。你一定會使用一個subdirectory-filter,如果你有標籤來保存你要一個tag-name-filter爲好。如果典型的變化會影響一些(但不是全部)子目錄,那麼您需要決定是否希望(a)保留並行歷史,或(b)使filter-branch消除空提交

因此,在最簡單的情況下

git filter-branch --subdirectory-filter dir-one -- branchA-one branchB-one ... 

如果你想保留的標籤,最簡單的辦法就是將它們複製到每一個新的歷史(使用相同後綴的分支機構),所以

git filter-branch --subdirectory dir-one --tag-name-filter 'sed s/$/-one' -- branchA-one branchB-one 

而且你可以在--prune-empty如果扔你想刪除提交不影響分支的子樹。

filte-branch每次運行都會產生一些「備用裁判」,你會想清理(refs/original/...

請注意,這是什麼提供,最有可能的,是一個共同的根源提交。您將以回購的字面獨立歷史結尾。通常這並不重要。如果您稍後決定將其拆分成不同的回購方式,則很方便。如果您曾預見過這些歷史的合併,那麼這樣做不太方便。

在最後一種情況下,大多數情況下可以解決獨立歷史記錄(例如合併中的--allow-unrelated-histories),但如果您不想要,那麼您將修改上述過程。在做之前,filter-branches您將創建一個空的「共享根」

git branch --orphan newRoot 
git rm -r * 
git commit --allow-empty 

然後你將包括一個parent-filter嫁接每一根改寫到newRoot