[英]GIT change Base/Root Folder
我有一個很長的(〜2年)回購,有很多提交/分支,現在由於某些原因我需要將存儲庫的根文件夾更改為上面的一個文件夾。
一些例子來澄清這個概念。
我的存儲庫位於一個文件夾中:
c:\workspace\test\src\
所以在我的repo中有上述文件/子文件夾中的所有更改。
我想將存儲庫移動到:
c:\workspace\test
從現在開始可以添加測試文件夾中保存舊存儲庫歷史記錄的所有更改。
所以在文件夾"\\"
中標記的所有舊提交,現在應該在文件夾"\\src"
檢查
對於舊的提交,我可以或不可能(它確實無關緊要)文件夾的實際內容..
那可能嗎?
我希望我解釋的是可以理解的..
我認為你的意思是你的倉庫的頂級目錄是c:\\workspace\\test\\
,你希望c:\\workspace\\test\\src\\
成為新的頂級目錄。 首先,檢查是否是這種情況:
cd c:\workspace\test\src
git rev-parse --show-toplevel #print repo top-level directory
它應該打印像c:\\workspace\\test\\
這樣的東西,如果它真的是你的頂級目錄。
如果是,您可以使用git filter-branch
rebasing命令使'src'目錄成為新的頂級目錄。 請注意,這是您真正想要做的事情,因為它將破壞性地修改您的舊歷史! 任何影響此分支的提交都將被重新命名為包含src
文件夾作為新的頂級。 首先備份當前分支。
cd c:\workspace\test\
git branch oldRoot #this backs up your current branch to a new branch called "oldRoot"
git filter-branch --subdirectory-filter src HEAD #this modifies your history
警告!!! 注意:
有關詳細信息,請閱讀Git Book中的“ 使子目錄成為新根目錄 ”和“重新定位的危險 ”部分。
如果我正確理解你的問題,如果你從一個干凈的git repo開始( git status
說'沒有提交,工作目錄清理'),你只需要將.git
目錄從c:\\workspace\\test\\src\\
到c:\\workspace\\test\\
。
然后,您必須對新布局中的所有文件進行“大”提交。 Git將把這個新提交視為一個重大舉措。 不需要新內容,因為文件是相同的。 Git只會在他的.git
目錄中注冊新的樹布局(帶有src
)。
重新閱讀這個問題讓我覺得您可能希望在src
子目錄中提供舊的提交
如果是這種情況,您需要使用諸如git filter-branch --tree-filter '...'
類的內容完全重寫您的Git存儲庫歷史記錄git filter-branch --tree-filter '...'
聽起來你應該只需要這樣做:
c:\\workspace\\test\\src
重命名為c:\\workspace\\src
c:\\workspace\\test
,這可能是空的 c:\\workspace\\src
重命名為c:\\workspace\\test
git
存儲庫通常不會跟蹤其父目錄,因此將存儲庫從一個位置移動到另一個位置應該是無害的。 現在,無論您在存儲庫中擁有哪些腳本/構建文件/任何可能包含硬編碼路徑的文件都可能是完全不同的故事......
git filter-branch --index-filter '
git read-tree $(printf "040000 tree %s\tsrc\n" `git rev-parse HEAD:` | git mktree)
' -- --branches --tags
mv .git ..
cd ..
在這些命令中看到文檔; 用法非常簡單。 filter-branch
的文檔中關於讓它在tmpfs上工作的建議可能值得花兩年時間來處理。
您可能需要grep -ri c.workspace.test .git
來檢查grep -ri c.workspace.test .git
中的絕對路徑等,以驗證它們是否仍然有效。
首先,克隆您的倉庫,以便您可以單獨處理它,以便原始保持原樣,以防萬一出現問題。
git clone --no-hardlinks c:\workspace\test\src c:\sandbox
編寫一個腳本,在任何單個提交中進行適當的更改。 我不熟悉Windows腳本,但您希望您的腳本創建一個名為src
的新子目錄( 即 c:\\sandbox\\src
),然后移動除.git
目錄和任何.git*
文件之外的所有內容( 例如, .gitignore
)進入那個新的子目錄。 確保您的腳本在repo中的任何提交上都能正常工作,而不僅僅是當前狀態。 然后運行:
git filter-branch --tree-filter c:\absolute\path\to\your\script
這將導致git檢出repo中的每個提交,運行您的腳本,然后用最終結果替換commit。 接下來,如果您有任何被忽略或未提交的文件,您將需要將它們復制到新倉庫中的相應位置。 檢查以確保filter-branch具有預期效果,並且新repo看起來如何。 一旦確定自己滿意,請刪除c:\\workspace\\test
,然后將c:\\sandbox
移動到c:\\workspace\\test
。
我更喜歡使用--tree-filter
,如圖所示,而不是--index-filter
。 效率較低(因為它必須檢查每個提交而不是直接編輯索引),但我發現它更直觀。 如果需要,它還允許您更改repo中的文件內容(可能更新絕對路徑)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.