目录
[1. 确保本地仓库是最新的](#1. 确保本地仓库是最新的)
[2. 切换到目标分支(需要被更新的分支)](#2. 切换到目标分支(需要被更新的分支))
[3. 合并另一个分支](#3. 合并另一个分支)
[4. 将合并后的分支推送到远程仓库](#4. 将合并后的分支推送到远程仓库)
[方法一:使用 git update-index --skip-worktree(永久忽略本地修改)](#方法一:使用 git update-index --skip-worktree(永久忽略本地修改))
[Q1:执行 git pull 时报错 "Your local changes would be overwritten by merge"](#Q1:执行 git pull 时报错 “Your local changes would be overwritten by merge”)
[Q2:使用 --skip-worktree 后,我想临时允许更新其中一个文件怎么办?](#Q2:使用 --skip-worktree 后,我想临时允许更新其中一个文件怎么办?)
[Q3:另一台服务器上执行 git pull 时提示 "not a git repository" 或 "no tracking information"](#Q3:另一台服务器上执行 git pull 时提示 “not a git repository” 或 “no tracking information”)
前言
团队协作中,经常遇到这样的场景:你在一个分支上开发,另一个分支有重要的更新需要合并过来;同时,在多台服务器上运行同一套代码,但每台服务器又有自己的配置文件(如环境变量、启动参数)。如何优雅地合并分支,又能在拉取最新代码时保护本地配置不被覆盖?本文将通过一个真实案例,手把手教你完成这些操作。
一、问题背景
假设我们有一个 Git 仓库,包含两个分支:
-
sop_cip_maf_260612:当前正在使用的分支(已在本地克隆) -
tianjin-cb/sop_cip_maf_v1.4.0_260610:同事/另一个团队做了大量修改的分支
需求 :
将 tianjin-cb/sop_cip_maf_v1.4.0_260610 分支的代码更新合并到 sop_cip_maf_260612 分支中。
进一步需求 :
在另一台服务器上,之前克隆的是旧版本的 sop_cip_maf_260612,现在需要拉取最新代码。但该服务器上本地修改了两个配置文件:run.sh 和 .env_A6000(例如修改了镜像名、运行参数等)。我们希望拉取最新代码时,这两个文件保留服务器本地的配置,不被远程版本覆盖。
二、第一步:在本地完成分支合并
首先,在最初克隆代码的机器上(我们称为"开发机"),将两个分支合并。
1. 确保本地仓库是最新的
bash
git fetch origin
2. 切换到目标分支(需要被更新的分支)
bash
git checkout sop_cip_maf_260612
3. 合并另一个分支
bash
git merge origin/tianjin-cb/sop_cip_maf_v1.4.0_260610
执行后,Git 会尝试自动合并。如果没有冲突,你会看到类似下面的输出:
html
Merge made by the 'ort' strategy.
conversation (10).json | 213 ------
result (7).json | 1 -
...
27 files changed, 754 insertions(+), 3065 deletions(-)

注意:本次合并删除了四个文件、三个 Python 模块,并重构了大量代码。说明两个分支差异较大。
如果出现冲突,需要手动解决冲突文件,然后执行 git add 和 git commit。
4. 将合并后的分支推送到远程仓库
只有推送后,其他服务器才能拉取到这次合并的结果。
bash
git push origin sop_cip_maf_260612
三、第二步:在另一台服务器上拉取最新代码并保护配置文件
另一台服务器(我们称为"生产机"或"运行服务器")上,之前通过 git clone 拉取了旧版本的 sop_cip_maf_260612 分支,并且本地修改了 run.sh 和 .env_A6000 两个文件。现在需要更新其他所有文件,但保留这两个文件的本地方案。
有三种常用方法,推荐使用第一种。
方法一:使用 git update-index --skip-worktree(永久忽略本地修改)
这个命令告诉 Git:这些文件本地的修改不要被 pull/merge 操作影响,并且不要提示冲突。
步骤:
bash
# 进入项目目录
cd /path/to/sop_cip_maf_260612
# 设置跳过工作树检查(忽略本地修改)
git update-index --skip-worktree run.sh .env_A6000
# 正常拉取最新代码
git pull origin sop_cip_maf_260612
此后,无论远程分支如何更新这两个文件,你的本地版本都会原封不动。其他文件会正常更新。
恢复跟踪(如果需要以后更新这两个文件):
bash
git update-index --no-skip-worktree run.sh .env_A6000
优点 :一次配置,后续所有 git pull 都自动保护这两个文件,非常方便。
缺点:你也无法看到远程对这些文件的修改(除非主动取消跳过)。
方法二:暂存本地修改,拉取后再恢复
如果你只是想这一次 拉取时保留本地配置,以后可能还想拉取远程更新,可以使用 stash。
bash
# 暂存这两个文件的修改
git stash push -- run.sh .env_A6000
# 拉取最新代码
git pull origin sop_cip_maf_260612
# 恢复本地修改(可能会冲突)
git stash pop
如果拉取时远程也修改了这两个文件,git stash pop 会提示冲突。此时选择保留本地版本:
bash
git checkout --ours -- run.sh .env_A6000
git add run.sh .env_A6000
git stash drop # 删除暂存记录
方法三:合并时不自动提交,手动恢复文件
bash
# 拉取并合并但不自动提交
git fetch origin
git merge --no-commit origin/sop_cip_maf_260612
# 强制用本地版本覆盖这两个文件
git checkout HEAD -- run.sh .env_A6000
# 完成合并提交
git commit
四、验证与后续工作
拉取完成后,建议检查:
-
配置文件是否保留 :
cat run.sh和cat .env_A6000,确认内容仍是服务器的定制配置。 -
其他文件是否更新 :例如查看之前被删除的文件
conversation (10).json是否已不存在(说明更新成功)。 -
运行项目测试:启动服务,确保合并后的代码与本地配置兼容。
五、常见问题及解决
Q1:执行 git pull 时报错 "Your local changes would be overwritten by merge"
这是因为 pull 会尝试合并,但 Git 检测到本地有未提交的修改且与远程文件冲突。解决方法:
-
如果确认要保留本地修改,按照上文的方法一或方法二处理。
-
如果不需要保留,可以强制丢弃本地修改:
git checkout -- run.sh .env_A6000后再pull。
Q2:使用 --skip-worktree 后,我想临时允许更新其中一个文件怎么办?
可以取消跳过、拉取、再重新跳过:
bash
git update-index --no-skip-worktree run.sh
git pull origin sop_cip_maf_260612 # 会尝试合并 run.sh
git update-index --skip-worktree run.sh
Q3:另一台服务器上执行 git pull 时提示 "not a git repository" 或 "no tracking information"
-
确保你在正确的项目目录下,并且之前是通过
git clone拉取的。 -
如果分支没有设置上游跟踪,可以使用
git pull origin sop_cip_maf_260612显式指定。
总结
-
分支合并 :使用
git merge将另一个分支的更新合并到当前分支,并推送到远程。 -
远程服务器同步 :使用
git pull拉取最新代码。 -
保护本地配置文件 :核心命令
git update-index --skip-worktree,让 Git 忽略特定文件的本地修改,避免被覆盖。
这套流程非常适合开发-测试-生产多环境部署场景:开发机完成合并,测试/生产服务器拉取最新代码,同时保留各自的环境配置(如不同 GPU 型号、不同端口、不同 API Key)。