# 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 生成 Token:Settings → Developer settings → Personal access tokens # Gitea 生成 Token:Settings → 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 ` | Git 仓库地址(HTTPS 或 SSH) | `--repo-url https://github.com/user/repo.git` | | `--branch ` | 指定拉取的分支(默认当前分支) | `--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`,所有本地未提交更改将丢失。 ### 场景 4:CI/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 # 完成合并 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 ``` ### 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