2
我的回購中有幾個子樹(例如./sub1/
,./sub2/
,..),我想將其提取到單獨的回購中,保留提交歷史記錄和相同的目錄結構,即sub1
的新回購應具有./sub1/
子樹回購。我怎樣才能做到這一點?從git repo中提取子目錄到另一個repo並保留dir結構?
我的回購中有幾個子樹(例如./sub1/
,./sub2/
,..),我想將其提取到單獨的回購中,保留提交歷史記錄和相同的目錄結構,即sub1
的新回購應具有./sub1/
子樹回購。我怎樣才能做到這一點?從git repo中提取子目錄到另一個repo並保留dir結構?
你可以使用git的filter-branch和子樹過濾器。
步驟如下:
克隆的工作副本。這個操作會改變本地回購,所以我們必須先有一個工作副本。你可以像下面那樣做一個git clone,或者直接拷貝它。
git clone --no-hardlinks <original repository> <working copy>
使用子樹fileter。
cd <working copy>
git filter-branch --subdirectory-filter <subdir path to be splited> --prune-empty --tag-name-filter cat -- --all
# reset current working directory
git reset --hard
我們已經完成了我們的任務,這是更好地做一些清潔工作,因爲很多舊物變成無法訪問。
刪除舊遠程
git remote rm origin
刪除舊引用日誌
# clean unneeded reflog in order to free space
refbak=$(git for-each-ref --format="%(refname)" refs/original/)
if [ -n "$refbak" ];then
echo -n $refbak | xargs -n 1 git update-ref -d
fi
git reflog expire --expire=now --all
重新包裝和壓縮回購
# prune loose objects
git gc --aggressive --prune=now
這將使從
repo/
|-- sub1/
|-- sub11
|-- sub12
|-- sub2
回購結構變化
repo/
|-- sub11
|-- sub12
但是,看來你希望它成爲
repo/
|-- sub1/
|-- sub11
|-- sub12
然後,還有一個需要完成一步,用index-filter重寫git commit history。
# replace <subdir path> with the actual subdir path, for this case, it should be "sub1"
git filter-branch --index-filter 'git ls-files -s | sed "s-\t-&<subdir path>/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' HEAD