天天看點

如何将 git倉庫 中指定的檔案夾 附帶送出日志 遷移到另一個倉庫?

假設:我們要将 source 倉庫(repo)下的 foo 檔案夾 移動到 destination 倉庫下,除了檔案内容遷移外,還包括相關的所有日志。

source倉庫: https://github.com/user/source.git

destination倉庫: https://github.com/user/destination.git

步驟1

為了不改變目前克隆出來的版本,我們需要重新克隆一個原始備份出來,在原始備份裡進行操作,依次執行如下指令

mkdir backup

cd backup

git clone https://github.com/user/source.git

cd source

步驟2

将我們需要複制的檔案夾更改到目前備份克隆裡的根目錄下,這裡 git 提供了 git filter-branch 指令允許我們調整整個倉庫的目錄結構:隻保留過濾器指定的檔案及相關日志, 删除其他檔案内容。

為了防止我們誤操作導緻覆寫線上倉庫的内容,我們需要先解除備份倉庫與線上倉庫的關系,是以此步驟依次執行如下指令

git remote rm origin

git filter-branch --subdirectory-filter foo -- --all

這裡如果存在 tag 被覆寫(rewritten),則會報警告要求使用 "--tag-name-filter cat", 不過可以忽略不管。當然,如果要複制的目錄存在分支(branch)或者标簽(tag),不确定是不是也能一起複制過去,但按照最終複制過去是一個分支的做法,可能并沒有,沒有試驗過(了解的同學可以告知下)。

另外,filter指令要在根目錄下執行,foo如果是子目錄下的檔案夾,則需要使用相對路徑,而不是隻有一個檔案夾名。

步驟3(可選)

如果我們需要将目錄原封不動複制過去,包含它的檔案夾,那麼我們還需要建立一個同樣名字的目錄到根目錄下,将 步驟2 中過濾到根目錄下的所有檔案移動到該目錄下,最後添加并送出到本地。指令依次如下

mkdir foo

mv * foo

git add .

git commit

如果我們不需要原目錄,隻需要它裡面的内容,那麼就直接跳過此步驟即可

這裡 commit時會要求輸入日志, 使用的是 vim, 使用相關指令編輯即可。

謹記,目前所有的操作都是臨時操作,不會影響到線上倉庫的。

步驟4

有了步驟3的臨時倉庫,接下來就是将其合并到目标倉庫中去。

假設目标倉庫已經克隆到 "projects/destination" 裡面,依次執行如下指令

cd ../../projects/destination

git remote add modified-source ../../backup/source

git pull modified-source master --allow-unrelated-histories

git remote rm modified-source

上述操作, 将臨時倉庫添加為目标倉庫的一個分支(modified-source), 然後将其(master分支)合并到主幹(注意,紅色字型為一體,即拉的是modified-source的master到目前分支),最後移除臨時分支(modified-source)

步驟5

檢查目标倉庫是否符合自己的需求,确定後送出即可

最後,可以直接删除備份倉庫。