個人博客https://www.yotroy.cool/,感謝關注~
圖片資源可能顯示不全,請前往博客查看哦!
============================================================
說來慚愧,這篇是AI幫助我解決實際問題后,又生成的一篇博客,效率特別高。
在開發中,我們常會遇到一個項目變大、拆分或者整合的需求。如果你想將一個已有 Git 提交歷史的小項目(例如:bbb/
)合并到另一個新的 Git 倉庫(例如 GitHub 上新建的倉庫 aaa
),并保留其所有提交歷史記錄,這篇博客將為你總結完整的操作流程和注意事項。
🧩 問題背景
我本地有一個項目叫 bbb/
,它是一個完整的 Git 倉庫,有自己的提交歷史。但我后來希望將它作為子目錄的形式遷入另一個新的倉庫 aaa/
中去,也就是想要實現結構如下:
aaa/
└── bbb/ # 原項目內容在這里,保留所有 commit 歷史
但是直接復制粘貼代碼會丟失原始提交歷史記錄;而直接合并 .git
會導致倉庫結構錯亂。
🧪 我遇到的問題
一開始,我使用了 git filter-repo
來把項目目錄轉換成子目錄的歷史,但目錄嵌套出現了問題,執行完:
python -m git_filter_repo --to-subdirectory-filter bbb --force
之后,目錄變成了:
bbb/bbb/your-files...
也就是說,子目錄又包了一層自己的名字,導致整個目錄嵌套了一層,不符合我的預期。
? 正確的操作流程
以下是正確的遷移流程,總結如下:
📁 假設目錄結構如下
/your-path/
├── bbb/ # 原項目,有完整 Git 歷史
🔨 步驟 1:在 GitHub 上創建新倉庫 aaa
比如:
-
倉庫名:
aaa
-
GitHub 地址:
git@github.com:yourname/aaa.git
🧪 步驟 2:在 bbb 目錄中運行 git filter-repo
需要安裝 git filter-repo
,教程可查看附錄。
這一步會把整個項目的 Git 歷史“包裹進” bbb/
子目錄中:
cd bbb
python -m git_filter_repo --to-subdirectory-filter bbb --force
執行完后,項目結構會變成:
bbb/
└── bbb/└── your-original-code...
(此時你的代碼被包進了 bbb/
)
🧼 步驟 3:整理目錄結構(可選)
這里你需要把 bbb/bbb/
中提交的數據拉回到 bbb/
中。
🌐 步驟 4:推送到遠程倉庫(aaa)
-
初始化 GitHub 倉庫(如果還沒 init 的話):
git remote add origin git@github.com:yourname/aaa.git
-
推送代碼及其歷史記錄:
git push -u origin main
如果你當前分支不是
main
,請先切換:git checkout -b main
。
🎉 最終效果
在 GitHub 上打開 aaa
倉庫,你將看到代碼出現在 bbb/
子目錄中,且每一次提交都被完整保留。
📎 附錄:如何安裝 git_filter_repo
git_filter_repo
是一個替代 git filter-branch
的高效工具,用于重寫 Git 歷史。由于它不是 Git 默認安裝的一部分,我們需要手動安裝。
? 方法一:通過 pip
安裝(推薦)
適合大多數開發者,只需要有 Python 環境即可。
pip install git-filter-repo
安裝后,你可以通過以下方式使用:
python -m git_filter_repo --help
?? 注意:如果你運行 git filter-repo
報錯(如 “git: ‘filter-repo’ is not a git command”),說明你的環境變量中沒有自動添加別名,建議直接使用:
python -m git_filter_repo ...
? 方法二:手動安裝腳本并加入 Git 命令目錄(進階)
適合想直接使用 git filter-repo
命令的用戶:
-
前往 GitHub 下載腳本:
👉 https://github.com/newren/git-filter-repo
-
下載
git-filter-repo.py
文件,重命名為git-filter-repo
(無后綴) -
將該文件放入 Git 的執行目錄中,例如:
C:\Program Files\Git\mingw64\libexec\git-core\
-
確保該目錄在系統環境變量 PATH 中
完成后,即可直接使用任一命令:
git filter-repo ...
python -m git_filter_repo ... //或使用Python命令