嗯,我想有一種方法可以做到這一點。他指出了一些東西給後人第一...
注意事項
既然你在談論使用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
。
'git filter-branch'用於*複製現有的提交*,同時對每個進行一些轉換(在創建新副本之前)。 filter-branch的參數提供了轉換並告訴它要更新哪些分支*名稱,以將它們指向新複製的提交,而不是它們原始的(現在被複制的)提交。它不會創建任何新的分支名稱。 – torek
所以這聽起來像'git-filter-branch'可以用於幾乎櫻桃挑選從一個地方到另一個地方?這是否意味着如果我將SVN中的repo轉換爲git,並且在git更改完成之前svn repo中有更改,那麼可以使用'git-filter-branch'來僅移動這些特定的提交? – user3270760
你當然可以濫用'git filter-branch'來做這樣的事情(櫻桃採摘),但這不是它的設計目的。 (當然也可以參考馬克阿德爾斯伯格的答案。) – torek