Files
ctms/docs/GIT_SYNC_GUIDE.md
T

610 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Git 仓库同步与在线更新指南
本文档包含两部分:
1. **在线更新功能**:使用 `scripts/update.sh` 从远程仓库拉取代码并自动部署
2. **双仓库推送配置**:配置 CTMS 项目的 GitHub 和 Gitea 双仓库同步
---
# 第一部分:在线更新功能
## 功能特性
### 🔐 安全保障
- **项目身份验证**:自动检测项目特征文件,防止拉取错误仓库
- **自动备份**:拉取前创建 Git tag 备份点,支持一键回滚
- **工作目录保护**:检测未提交更改,提供暂存或放弃选项
- **多种认证方式**:支持 SSH 密钥、Personal Access Token、用户名密码
### ✨ 易用性
- **交互式操作**:友好的提示和参数预览
- **自动化支持**`--yes` 模式适配 CI/CD 流程
- **灵活配置**:支持命令行参数和环境变量
---
## 快速开始
### 基础用法
```bash
# 交互式更新开发环境(会提示输入仓库地址和凭证)
bash scripts/update.sh dev
# 更新测试环境并指定仓库
bash scripts/update.sh main --repo-url https://github.com/user/ctms-dev.git
# 更新生产环境(指定分支)
bash scripts/update.sh release --repo-url https://gitea.example.com/team/ctms.git --branch main
```
### 认证方式
#### 1. SSH 密钥(推荐,无需输入密码)
```bash
# 前提:已配置 SSH 公钥到 GitHub/Gitea
bash scripts/update.sh dev --repo-url git@github.com:user/ctms-dev.git
```
#### 2. Personal Access Token(推荐用于 HTTPS
```bash
# GitHub 生成 TokenSettings → Developer settings → Personal access tokens
# Gitea 生成 TokenSettings → Applications → Generate New Token
# 交互式输入(用户名输入 git 用户名,密码输入 Token)
bash scripts/update.sh main --repo-url https://github.com/user/ctms-dev.git
# 或通过环境变量(适合自动化)
export GIT_USERNAME="your-username"
export GIT_PASSWORD="ghp_xxxxxxxxxxxxxxxxxxxx" # GitHub Token
bash scripts/update.sh main --repo-url https://github.com/user/ctms-dev.git --yes
```
#### 3. 用户名密码(不推荐,安全性低)
```bash
# 交互式输入
bash scripts/update.sh dev --repo-url https://gitea.example.com/user/ctms.git
# 按提示输入用户名和密码
```
---
## 命令选项
### 环境参数(必需)
- `dev` - 本地开发环境
- `main` - 内网测试/预发布环境
- `release` - 生产环境
### 可选参数
| 参数 | 说明 | 示例 |
|------|------|------|
| `--repo-url <url>` | Git 仓库地址(HTTPS 或 SSH | `--repo-url https://github.com/user/repo.git` |
| `--branch <name>` | 指定拉取的分支(默认当前分支) | `--branch main` |
| `--yes` | 跳过所有交互确认 | `--yes` |
| `--force` | 强制覆盖本地更改(`git reset --hard` | `--force` |
| `--skip-backup` | 跳过自动备份 tag(不推荐) | `--skip-backup` |
| `--skip-build` | 透传给 install.sh:跳过镜像构建 | `--skip-build` |
| `--skip-migrate` | 透传给 install.sh:跳过数据库迁移 | `--skip-migrate` |
| `--verbose` | 透传给 install.sh:显示详细输出 | `--verbose` |
---
## 使用场景
### 场景 1:开发环境日常更新
```bash
# 拉取最新代码并重新部署
bash scripts/update.sh dev --repo-url https://github.com/team/ctms-dev.git
```
**流程**
1. 检查工作目录状态(如有未提交更改,提示处理方式)
2. 创建备份 tag(如 `pre-update-20260623-143022`
3. 拉取远程代码
4. 验证项目身份
5. 自动调用 `install.sh` 重新构建容器和迁移数据库
### 场景 2:生产环境版本升级
```bash
# 使用 Personal Access Token 自动化更新
export GIT_USERNAME="deploy-bot"
export GIT_PASSWORD="ghp_xxxxxxxxxxxxxxxxxxxx"
bash scripts/update.sh release \
--repo-url https://github.com/company/ctms.git \
--branch v1.2.0 \
--yes \
--base-url https://ctms.example.com
```
**注意**:生产环境更新建议:
- 提前在测试环境验证
- 使用 `--branch` 指定稳定版本标签
- 备份数据库(脚本会自动创建 Git tag)
- 准备回滚方案
### 场景 3:强制覆盖本地更改
```bash
# 场景:本地有修改但需要强制同步远程版本
bash scripts/update.sh main --repo-url https://gitea.internal/team/ctms.git --force
```
**警告**`--force` 会执行 `git reset --hard`,所有本地未提交更改将丢失。
### 场景 4CI/CD 自动部署
```yaml
# GitHub Actions 示例
name: Deploy to Main
on:
push:
branches: [main]
jobs:
deploy:
runs-on: self-hosted
steps:
- name: Update CTMS
env:
GIT_USERNAME: ${{ secrets.DEPLOY_USERNAME }}
GIT_PASSWORD: ${{ secrets.DEPLOY_TOKEN }}
run: |
cd /opt/ctms
bash scripts/update.sh main \
--repo-url https://github.com/${{ github.repository }}.git \
--branch main \
--yes \
--skip-backup
```
---
## 故障排查
### 问题 1:认证失败
**症状**
```
✖ 出错 拉取失败,请检查网络连接和仓库权限
```
**解决方案**
1. 确认仓库地址正确
2. 检查凭证是否有效(Token 是否过期)
3. 确认账号有仓库访问权限
4. 对于私有仓库,确保 Token 有 `repo` 权限
### 问题 2:项目身份验证失败
**症状**
```
✖ 出错 项目身份验证失败:未检测到足够的 CTMS 项目特征文件
```
**原因**:拉取的仓库不是 CTMS 项目
**解决方案**
1. 检查 `--repo-url` 是否正确
2. 确认远程仓库确实是 CTMS 项目
3. 检查 `--branch` 参数是否指向正确分支
### 问题 3:合并冲突
**症状**
```
✖ 出错 合并失败,可能存在冲突
```
**解决方案**
**方法 1:手动解决冲突**
```bash
# 查看冲突文件
git status
# 手动编辑解决冲突
vim <conflict-file>
# 完成合并
git add .
git commit -m "Resolve merge conflict"
# 重新运行更新
bash scripts/update.sh dev
```
**方法 2:强制覆盖**
```bash
bash scripts/update.sh dev --force
```
### 问题 4:回滚到更新前版本
```bash
# 查看备份 tag
git tag | grep pre-update
# 回滚(示例)
git reset --hard pre-update-20260623-143022
# 重新部署
bash scripts/install.sh dev --skip-migrate
```
---
## 安全最佳实践
### 1. Personal Access Token 管理
**GitHub**
- 生成路径:Settings → Developer settings → Personal access tokens → Tokens (classic)
- 最小权限:`repo`(私有仓库)或 `public_repo`(公开仓库)
- 设置过期时间,定期轮换
**Gitea**
- 生成路径:User Settings → Applications → Manage Access Tokens
- 权限选择:`read:repository`
### 2. 环境变量保护
```bash
# 不要在脚本中硬编码密码
# ❌ 错误
export GIT_PASSWORD="my-secret-token"
# ✅ 正确:从加密的配置管理系统读取
export GIT_PASSWORD="$(vault kv get -field=token secret/git/deploy)"
```
### 3. 生产环境更新检查清单
- [ ] 已在测试环境验证更新
- [ ] 已备份数据库(除了 Git tag 备份)
- [ ] 已通知相关人员计划维护窗口
- [ ] 准备回滚脚本
- [ ] 确认 `--base-url` 参数正确
- [ ] 使用 `--branch` 指定稳定版本
---
## 常见问题
**Q: 更新会丢失 `.env` 配置吗?**
A: 不会。`.env``.gitignore` 中,不会被 Git 覆盖。
**Q: 更新会清空数据库吗?**
A: 不会。数据库数据持久化在 `pg_data` 目录,不受更新影响。更新只会执行增量迁移(`alembic upgrade head`)。
**Q: 如何跳过数据库迁移?**
A: 使用 `--skip-migrate` 参数:
```bash
bash scripts/update.sh dev --skip-migrate
```
**Q: 支持 GitLab 吗?**
A: 支持。GitLab 使用 HTTPS/SSH 认证方式与 GitHub/Gitea 相同。
**Q: 能否在更新前先查看远程有哪些更新?**
A: 可以手动执行:
```bash
git fetch origin
git log HEAD..origin/main # 查看即将合并的提交
```
---
# 第二部分:双仓库推送配置
本部分说明如何配置 CTMS 项目的 GitHub 和 Gitea 双仓库推送与拉取。
## 仓库信息
- **GitHub 仓库**: `https://github.com/chengchengzhou7/CTMS.git`
- **Gitea 仓库**: `http://119.29.208.238:8080/zhouchengcheng/ctms.git`
- **项目分支**: `main` (主分支)、`dev` (开发分支)、`release` (发布分支)
## 一、配置双推(同时推送到两个仓库)
### 1.1 查看当前配置
```bash
git remote -v
```
### 1.2 配置双推 URL
```bash
# 设置 fetch 源为 GitHub(用于拉取)
git remote set-url origin https://github.com/chengchengzhou7/CTMS.git
# 添加 GitHub 的 push URL
git remote set-url --add --push origin https://github.com/chengchengzhou7/CTMS.git
# 添加 Gitea 的 push URL
git remote set-url --add --push origin http://119.29.208.238:8080/zhouchengcheng/ctms.git
```
### 1.3 验证配置
```bash
git remote -v
```
预期输出:
```
origin https://github.com/chengchengzhou7/CTMS.git (fetch)
origin https://github.com/chengchengzhou7/CTMS.git (push)
origin http://119.29.208.238:8080/zhouchengcheng/ctms.git (push)
```
## 二、账号密码管理
### 2.1 保存凭据(推荐)
使用 Git 凭据管理器保存账号密码,避免每次都输入:
**macOS:**
```bash
git config --global credential.helper osxkeychain
```
**Linux:**
```bash
git config --global credential.helper store
```
**Windows:**
```bash
git config --global credential.helper manager
```
### 2.2 针对不同仓库配置不同凭据
如果 GitHub 和 Gitea 使用不同的账号密码,可以在 `.git/config` 中配置:
```bash
# 编辑 Git 配置
vim .git/config
```
添加凭据辅助配置:
```ini
[credential "https://github.com"]
username = chengchengzhou7
[credential "http://119.29.208.238:8080"]
username = zhouchengcheng
```
## 三、日常操作
### 3.1 推送代码(自动双推)
推送当前分支到两个仓库:
```bash
git push
```
推送指定分支:
```bash
# 推送 dev 分支
git push origin dev
# 推送 main 分支
git push origin main
# 推送 release 分支
git push origin release
```
首次推送新分支需要设置上游:
```bash
git push -u origin <branch-name>
```
### 3.2 拉取代码(从 GitHub
```bash
# 拉取当前分支
git pull
# 拉取指定分支
git pull origin dev
git pull origin main
git pull origin release
```
### 3.3 获取远程更新
```bash
# 获取所有远程分支的更新
git fetch origin
# 查看所有分支(包括远程)
git branch -a
```
## 四、分支管理
### 4.1 切换分支
```bash
# 切换到开发分支
git checkout dev
# 切换到主分支
git checkout main
# 切换到发布分支
git checkout release
```
### 4.2 创建新分支
```bash
# 基于 dev 创建新功能分支
git checkout -b feature/new-feature dev
# 推送到两个远程仓库
git push -u origin feature/new-feature
```
### 4.3 分支合并
```bash
# 将 dev 合并到 release
git checkout release
git merge dev
git push
# 将 release 合并到 main
git checkout main
git merge release
git push
```
## 五、常见问题
### 5.1 其中一个仓库推送失败怎么办?
如果双推时其中一个仓库失败,可以单独推送到失败的仓库:
```bash
# 单独推送到 GitHub
git push https://github.com/chengchengzhou7/CTMS.git dev
# 单独推送到 Gitea
git push http://119.29.208.238:8080/zhouchengcheng/ctms.git dev
```
### 5.2 如何只推送到一个仓库?
临时推送到指定仓库:
```bash
# 只推送到 GitHub
git push https://github.com/chengchengzhou7/CTMS.git
# 只推送到 Gitea
git push http://119.29.208.238:8080/zhouchengcheng/ctms.git
```
### 5.3 密码输入错误或需要更新
清除已保存的凭据:
```bash
# macOS
git credential-osxkeychain erase
host=github.com
protocol=https
[按两次回车]
# 或者使用
git credential reject
host=github.com
protocol=https
[按两次回车]
```
### 5.4 Gitea 首次推送需要创建仓库
如果 Gitea 仓库不存在,需要先在 Gitea 网页上创建空仓库:
1. 访问 `http://119.29.208.238:8080`
2. 登录后点击「新建仓库」
3. 仓库名设置为 `ctms`
4. 不要初始化 README
5. 创建后再执行 `git push`
## 六、配置文件示例
当前项目的 `.git/config` 配置示例:
```ini
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = https://github.com/chengchengzhou7/CTMS.git
fetch = +refs/heads/*:refs/remotes/origin/*
pushurl = https://github.com/chengchengzhou7/CTMS.git
pushurl = http://119.29.208.238:8080/zhouchengcheng/ctms.git
[branch "main"]
remote = origin
merge = refs/heads/main
[branch "dev"]
remote = origin
merge = refs/heads/dev
[branch "release"]
remote = origin
merge = refs/heads/release
```
## 七、工作流建议
### 7.1 日常开发流程
```bash
# 1. 切换到 dev 分支
git checkout dev
# 2. 拉取最新代码
git pull
# 3. 创建功能分支
git checkout -b feature/xxx
# 4. 开发并提交
git add .
git commit -m "feat: 添加新功能"
# 5. 推送功能分支
git push -u origin feature/xxx
# 6. 合并到 dev(通过 PR 或直接合并)
git checkout dev
git merge feature/xxx
git push # 自动推送到 GitHub 和 Gitea
```
### 7.2 发布流程
```bash
# 1. 将 dev 合并到 release
git checkout release
git pull
git merge dev
git push # 双推到两个仓库
# 2. 测试通过后,合并到 main
git checkout main
git pull
git merge release
git push # 双推到两个仓库
# 3. 打标签
git tag -a v1.0.0 -m "Release version 1.0.0"
git push origin v1.0.0 # 推送标签也会双推
```
---
**最后更新**: 2026-06-23
**维护者**: Cheng Zhou