481 lines
9.5 KiB
Markdown
481 lines
9.5 KiB
Markdown
# 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保持它们的连接!🚀
|