GIT_SUBMODULE_GUIDE.md
8.61 KB
Git 子模块处理指南
问题说明
当前 third-party/clip-as-service 是一个 Git 子模块,指向远程仓库:
- 原始仓库: https://github.com/jina-ai/clip-as-service.git
- 问题: 你修改了代码,但不想/无法提交到原仓库
- 目标: 将修改纳入自己的主项目管理
解决方案
我们提供三个方案,根据你的需求选择:
方案 A:移除子模块,直接纳入主项目(推荐)
适用场景:
- 你不需要跟随上游更新
- 你想完全控制这些代码
- 你会修改这些代码
优点:
- ✅ 简单直接,完全控制
- ✅ 所有代码在一个仓库中,易于管理
- ✅ 修改可以直接提交到主项目
缺点:
- ❌ 无法方便地获取上游更新
- ❌ 会增加主仓库大小
操作步骤:
# 1. 进入主项目目录
cd /data/tw/SearchEngine
# 2. 移除 Git 对子模块的追踪
git rm --cached third-party/clip-as-service
# 3. 删除 .gitmodules 中的配置(如果有)
# 编辑 .gitmodules 文件,删除 clip-as-service 相关部分
# 4. 删除子模块的 Git 仓库
rm -rf third-party/clip-as-service/.git
# 5. 将子模块目录作为普通目录添加到 Git
git add third-party/clip-as-service/
# 6. 提交更改
git commit -m "feat: 将 clip-as-service 从子模块转为普通目录"
# 7. 推送到远程仓库
git push origin main
后续操作:
- 之后对
third-party/clip-as-service的任何修改都可以正常提交 - 使用
git add和git commit就可以了
方案 B:切换到自己的 Fork
适用场景:
- 你需要跟随上游更新
- 你想保持 Git 历史记录
- 你可能向原仓库贡献代码
优点:
- ✅ 可以合并上游更新
- ✅ 保持 Git 追踪
- ✅ 可以参与上游社区
缺点:
- ❌ 需要 Fork 并维护自己的仓库
- ❌ 操作相对复杂
操作步骤:
# 1. 在 GitHub 上 Fork 原仓库
# 访问 https://github.com/jina-ai/clip-as-service
# 点击 Fork 按钮,创建你自己的副本
# 2. 克隆你的 Fork(替换为你的用户名)
# 注意:这里使用 --mirror 保留所有分支和标签
git clone --mirror https://github.com/YOUR_USERNAME/clip-as-service.git
# 3. 进入主项目目录
cd /data/tw/SearchEngine
# 4. 更新 .gitmodules 文件
# 编辑 .gitmodules,将 URL 改为你的 Fork:
# [submodule "third-party/clip-as-service"]
# path = third-party/clip-as-service
# url = https://github.com/YOUR_USERNAME/clip-as-service.git
# 5. 初始化新的子模块
git submodule deinit -f third-party/clip-as-service
git submodule update --init --remote third-party/clip-as-service
# 6. 进入子模块目录,设置你的 fork 为默认远程
cd third-party/clip-as-service
git remote set-url origin https://github.com/YOUR_USERNAME/clip-as-service.git
git remote add upstream https://github.com/jina-ai/clip-as-service.git
# 7. 创建并切换到你的分支
git checkout -b custom-cnclip-support
# 8. 提交你的修改
git add .
git commit -m "feat: 添加 CN-CLIP 自定义配置"
# 9. 推送到你的 Fork
git push origin custom-cnclip-support
# 10. 回到主项目,更新子模块引用
cd /data/tw/SearchEngine
git add third-party/clip-as-service
git commit -m "chore: 更新子模块到自定义版本"
git push origin main
后续操作:
- 在子模块目录中修改代码
- 提交到你的分支:
git push origin custom-cnclip-support - 合并上游更新:
bash cd third-party/clip-as-service git fetch upstream git merge upstream/main git push origin custom-cnclip-support cd .. git add third-party/clip-as-service git commit -m "chore: 合并上游更新"
方案 C:使用 Git Subtree 替代 Submodule
适用场景:
- 你想要子模块的灵活性,但不想处理 submodule 的复杂性
- 你想直接在主项目中管理代码
优点:
- ✅ 比 submodule 更易用
- ✅ 可以直接提交到主项目
- ✅ 可以获取上游更新
缺点:
- ❌ 命令相对复杂
- ❌ 重写现有历史
操作步骤:
# 1. 移除现有子模块
cd /data/tw/SearchEngine
git submodule deinit -f third-party/clip-as-service
git rm -f third-party/clip-as-service
rm -rf .git/modules/third-party/clip-as-service
# 2. 使用 subtree 添加远程仓库
git subtree add --prefix=third-party/clip-as-service \
https://github.com/jina-ai/clip-as-service.git \
main --squash
# 3. 提交
git commit -m "chore: 使用 git subtree 替代 submodule 添加 clip-as-service"
# 4. 推送
git push origin main
后续操作:
- 修改代码后直接在主项目中提交
- 获取上游更新:
bash git subtree pull --prefix=third-party/clip-as-service \ https://github.com/jina-ai/clip-as-service.git \ main --squash
推荐方案
根据你的情况,我推荐方案 A,原因如下:
- 你的需求明确:修改 CN-CLIP 配置,提供推理服务
- 不需要上游更新:CLIP-as-service 已经很稳定
- 最简单直接:不需要维护额外的仓库
- 易于管理:所有代码在一个地方
执行方案 A 的详细步骤
#!/bin/bash
# 这个脚本会自动执行方案 A 的所有步骤
set -e
echo "=========================================="
echo "将 clip-as-service 从子模块转为普通目录"
echo "=========================================="
cd /data/tw/SearchEngine
# 1. 备份当前状态(可选)
echo "步骤 1: 备份当前配置..."
if [ -f ".gitmodules" ]; then
cp .gitmodules .gitmodules.backup
echo "✓ 已备份 .gitmodules"
fi
# 2. 移除 Git 对子模块的追踪
echo "步骤 2: 移除子模块追踪..."
git rm --cached third-party/clip-as-service || true
# 3. 删除 .gitmodules 中的子模块配置
echo "步骤 3: 清理 .gitmodules..."
if [ -f ".gitmodules" ]; then
# 使用 sed 删除 clip-as-service 相关的配置块
sed -i '/clip-as-service/,+3 d' .gitmodules
# 如果文件为空,删除它
if [ ! -s ".gitmodules" ]; then
rm .gitmodules
echo "✓ 已删除空的 .gitmodules 文件"
else
echo "✓ 已更新 .gitmodules"
fi
fi
# 4. 删除子模块的 Git 仓库
echo "步骤 4: 删除子模块 Git 仓库..."
rm -rf third-party/clip-as-service/.git
echo "✓ 已删除子模块 Git 仓库"
# 5. 将子模块目录作为普通目录添加
echo "步骤 5: 将目录添加到 Git..."
git add third-party/clip-as-service/
git add .gitmodules 2>/dev/null || true
echo "✓ 已添加到 Git"
# 6. 显示状态
echo ""
echo "=========================================="
echo "操作完成!当前状态:"
echo "=========================================="
git status
echo ""
echo "=========================================="
echo "下一步:"
echo "=========================================="
echo "1. 检查修改: git diff --cached"
echo "2. 提交更改: git commit -m 'feat: 将 clip-as-service 从子模块转为普通目录'"
echo "3. 推送到远程: git push origin main"
echo ""
验证转换成功
转换后,你应该可以:
# 1. 正常查看文件状态
git status
# 2. 修改文件后直接添加
# 编辑 third-party/clip-as-service/server/clip_server/torch-flow.yml
git add third-party/clip-as-service/server/clip_server/torch-flow.yml
git commit -m "config: 更新 CN-CLIP 配置"
# 3. 推送到远程
git push origin main
# 4. 其他人克隆你的仓库后,不需要特殊的子模块命令
# git clone https://your-repo-url
# cd SearchEngine
# 所有文件都已经存在,包括 third-party/clip-as-service
常见问题
Q: 转换后会增加仓库大小吗? A: 会。clip-as-service 大约几十 MB。如果你担心仓库大小,可以使用 Git LFS 或 .gitignore 排除不必要的文件(如模型权重)。
Q: 如何后续获取原仓库的更新? A: 使用方案 A 后,需要手动合并更新:
cd third-party/clip-as-service
git remote add upstream https://github.com/jina-ai/clip-as-service.git
git fetch upstream
git merge upstream/main
Q: 我可以回退到子模块吗? A: 可以,但会比较复杂。建议在转换前提交一个保存点:
git branch backup-before-submodule-removal
Q: 其他协作者需要注意什么? A: 他们需要重新克隆仓库,或者:
# 删除旧的子模块引用
git submodule deinit -f third-party/clip-as-service
rm -rf .git/modules/third-party/clip-as-service
# 重新拉取
git pull origin main
总结
- 推荐: 方案 A(移除子模块)
- 适用: 你的使用场景
- 优势: 简单、直接、易于管理
- 成本: 略微增加仓库大小
如果需要帮助执行这些步骤,请告诉我!