# Git Submodule 开发工作流指南 ## 项目结构 你的开发环境: ``` /home/frank14f/ ├── CelerisLab/ # 独立仓库 - CFD库 │ ├── .git/ │ ├── src/ │ │ └── CelerisLab/ │ └── ... │ └── DynamisLab/ # 独立仓库 - ML框架 ├── .git/ ├── CelerisLab/ # 作为submodule指向上面的CelerisLab仓库 │ ├── .git # 这是软链接,指向真实的git仓库 │ └── ... ├── src/ ├── scripts/ └── ... ``` ## 开发工作流 ### 场景1:开发 CelerisLab(CFD功能) **在 `/home/frank14f/CelerisLab` 下工作** ```bash cd /home/frank14f/CelerisLab # 1. 创建功能分支(可选) git checkout -b feature/new-cfd-feature # 2. 修改代码 vim src/CelerisLab/driver.py # 3. 测试改动 python -c "from CelerisLab import FlowField; print('OK')" # 4. 提交改动 git add src/CelerisLab/driver.py git commit -m "feat: add new CFD feature" # 5. 推送到远程(双推送到GitHub和Gitea) git push origin main # 因为配置了双push URL,这会自动推送到两个远程 ``` ### 场景2:在 DynamisLab 中使用更新的 CelerisLab **方式A:更新submodule到最新版本** ```bash cd /home/frank14f/DynamisLab # 1. 进入submodule目录 cd CelerisLab # 2. 拉取最新的CelerisLab代码 git fetch origin git checkout main # 或特定的tag/branch git pull origin main # 3. 回到DynamisLab主目录 cd .. # 4. 提交submodule引用的更新 git add CelerisLab git commit -m "chore: update CelerisLab submodule to latest" # 5. 推送DynamisLab的更新 git push ``` **方式B:自动更新submodule** ```bash cd /home/frank14f/DynamisLab # 一行命令更新所有submodule到远程最新版本 git submodule update --remote --merge # 提交更新 git add CelerisLab git commit -m "chore: update CelerisLab submodule" git push ``` ### 场景3:同时开发 CelerisLab 和 DynamisLab **这是你问的核心场景!** #### 方法1:在独立目录开发(推荐) ```bash # Terminal 1: 开发CelerisLab cd /home/frank14f/CelerisLab # 修改 CFD 功能 vim src/CelerisLab/utils.py git commit -am "fix: improve config loading" git push # 推送到远程 # Terminal 2: 开发DynamisLab cd /home/frank14f/DynamisLab # 更新submodule获取最新CelerisLab git submodule update --remote CelerisLab # 修改ML代码使用新功能 vim src/environments/cfd_env.py git add CelerisLab src/ # 同时提交submodule更新和代码修改 git commit -m "feat: use new CelerisLab config feature" git push ``` #### 方法2:在DynamisLab的submodule中开发CelerisLab > ⚠️ **不推荐**:容易混淆,但技术上可行 ```bash cd /home/frank14f/DynamisLab/CelerisLab # 进入submodule # 这个目录实际上是一个完整的git仓库 git checkout -b feature/my-fix # 修改代码 vim src/CelerisLab/driver.py git commit -am "fix: bug in driver" # 推送到CelerisLab远程仓库 git push origin feature/my-fix # 回到DynamisLab主目录 cd .. git add CelerisLab git commit -m "chore: update CelerisLab with bug fix" git push ``` ### 场景4:克隆项目时的工作流 **新电脑/新环境上开始工作** ```bash # 1. 克隆DynamisLab(包含submodule) git clone --recurse-submodules https://github.com/frank14f/DynamisLab.git cd DynamisLab # 2. 安装CelerisLab cd CelerisLab pip install -e . cd .. # 3. 安装DynamisLab pip install -r requirements.txt pip install -e . # 4. 开始工作 python scripts/train_ppo.py --help ``` **如果忘记 `--recurse-submodules`** ```bash git clone https://github.com/frank14f/DynamisLab.git cd DynamisLab # 初始化submodule git submodule init git submodule update # 或简化为: git submodule update --init --recursive ``` ## 常用 Submodule 命令 ### 查看状态 ```bash cd /home/frank14f/DynamisLab # 查看submodule状态 git submodule status # 输出示例: # a1b2c3d4 CelerisLab (v0.2.0) # 前面的hash是当前指向的commit # 查看submodule的URL git config --file .gitmodules --get-regexp url ``` ### 更新 Submodule ```bash # 方法1:更新到远程最新版本 git submodule update --remote CelerisLab # 方法2:手动进入submodule更新 cd CelerisLab git pull origin main cd .. git add CelerisLab # 方法3:更新所有submodule并合并 git submodule update --remote --merge ``` ### 固定 Submodule 到特定版本 ```bash cd /home/frank14f/DynamisLab/CelerisLab # 切换到特定commit或tag git checkout v0.2.0 # 或 commit hash cd .. git add CelerisLab git commit -m "pin CelerisLab to v0.2.0" git push ``` ### 修改 Submodule URL ```bash # 如果CelerisLab的仓库地址变了 git config --file=.gitmodules submodule.CelerisLab.url https://new-url.git git submodule sync git submodule update --remote ``` ## Python 包安装策略 ### 开发模式(推荐) ```bash # 在DynamisLab下 pip install -e ./CelerisLab # submodule作为editable安装 pip install -e . # DynamisLab自己也是editable # 好处:修改代码立即生效,无需重新安装 ``` ### 环境变量方式 ```bash # 在 ~/.bashrc 中添加 export PYTHONPATH="/home/frank14f/DynamisLab/CelerisLab/src:$PYTHONPATH" # 重新加载 source ~/.bashrc ``` ## 推荐的工作流程 ### 日常开发循环 **CFD功能开发:** ```bash # === Terminal 1: CelerisLab === cd ~/CelerisLab # 1. 修改CFD代码 vim src/CelerisLab/utils.py # 2. 本地测试 python test_utils_only.py # 3. 提交 git commit -am "feat: smart config loading" git push # === Terminal 2: DynamisLab === cd ~/DynamisLab # 4. 拉取最新CelerisLab git submodule update --remote CelerisLab # 5. 测试集成 python scripts/train_ppo.py --total-timesteps 5 # 6. 如果工作正常,提交submodule更新 git add CelerisLab git commit -m "chore: update CelerisLab" git push ``` **ML功能开发:** ```bash cd ~/DynamisLab # 1. 修改ML代码 vim src/environments/cfd_env.py # 2. 测试 python scripts/train_ppo.py --total-timesteps 10 # 3. 提交 git commit -am "feat: improve reward function" git push # CelerisLab submodule保持不变 ``` ## VSCode 多仓库开发 ### Workspace 配置 创建 `~/DynamisLab.code-workspace`: ```json { "folders": [ { "path": ".", "name": "DynamisLab (Root)" }, { "path": "CelerisLab", "name": "CelerisLab (Submodule)" } ], "settings": { "python.analysis.extraPaths": [ "./CelerisLab/src" ], "git.detectSubmodules": true, "git.showSubmoduleStatus": true } } ``` 在VSCode中: 1. `File` → `Open Workspace from File` 2. 选择 `DynamisLab.code-workspace` 3. 左侧会显示两个文件夹,可以分别管理Git ## 常见问题排查 ### Q1: Submodule 显示 "modified content" ```bash cd CelerisLab git status # 查看有什么改动 # 如果不需要这些改动 git checkout . git clean -fd # 如果需要保存 git commit -am "local changes" ``` ### Q2: Submodule 指向错误的 commit ```bash cd DynamisLab # 查看submodule应该指向哪个commit git diff CelerisLab # 看HEAD和实际的差异 # 重置到正确的commit cd CelerisLab git fetch git checkout <正确的hash> cd .. git add CelerisLab ``` ### Q3: 推送时忘记推送 submodule 的改动 ```bash # 先推送submodule cd CelerisLab git push # 再推送主仓库 cd .. git push ``` 设置自动检查: ```bash git config --global push.recurseSubmodules check # 这样push主仓库时会检查submodule是否已推送 ``` ### Q4: 多人协作时 submodule 冲突 ```bash # 拉取主仓库 git pull # 更新submodule到正确版本 git submodule update --init --recursive ``` ## 版本发布策略 ### 发布 CelerisLab 新版本 ```bash cd ~/CelerisLab # 1. 更新版本号 vim src/CelerisLab/__init__.py # __version__ = '0.3.0' vim setup.py # version='0.3.0' # 2. 提交 git commit -am "chore: bump version to 0.3.0" # 3. 打tag git tag -a v0.3.0 -m "Release v0.3.0" git push origin main --tags ``` ### DynamisLab 使用特定 CelerisLab 版本 ```bash cd ~/DynamisLab/CelerisLab # 切换到tag git checkout v0.3.0 cd .. git add CelerisLab git commit -m "chore: pin CelerisLab to v0.3.0" git push ``` ## 最佳实践总结 ✅ **DO - 推荐做法** 1. ✅ 在独立的 `~/CelerisLab` 目录开发CFD功能 2. ✅ 开发完成后push,然后在 `~/DynamisLab` 中update submodule 3. ✅ 使用 `pip install -e` 安装两个包(开发模式) 4. ✅ 经常运行 `git submodule update --remote` 保持同步 5. ✅ CelerisLab稳定时打tag,DynamisLab引用tag而不是main 6. ✅ VSCode使用workspace配置同时管理两个仓库 ❌ **DON'T - 避免的做法** 1. ❌ 不要在 `~/DynamisLab/CelerisLab` submodule内直接开发(除非临时修复) 2. ❌ 不要忘记提交submodule引用的更新 3. ❌ 不要在DynamisLab中硬编码CelerisLab版本(用submodule管理) 4. ❌ 推送DynamisLab前确保CelerisLab的改动已推送 5. ❌ 不要手动复制粘贴代码在两个项目间,用git管理 ## 快速参考 ```bash # === 开发CelerisLab === cd ~/CelerisLab # 改代码 → commit → push # === 同步到DynamisLab === cd ~/DynamisLab git submodule update --remote git add CelerisLab git commit -m "update CelerisLab" git push # === 开发DynamisLab === cd ~/DynamisLab # 改代码 → commit → push # (submodule不变) # === 检查submodule状态 === git submodule status # === 重置submodule === git submodule update --init --recursive ``` --- 这样你就可以高效地在两个独立项目中开发,同时通过submodule保持它们的连接!🚀