Git分支合并与远程服务器同步实战:保留关键配置文件

Source

目录

前言

一、问题背景

二、第一步:在本地完成分支合并

1. 确保本地仓库是最新的

2. 切换到目标分支(需要被更新的分支)

3. 合并另一个分支

4. 将合并后的分支推送到远程仓库

三、第二步:在另一台服务器上拉取最新代码并保护配置文件

方法一:使用 git update-index --skip-worktree(永久忽略本地修改)

方法二:暂存本地修改,拉取后再恢复

方法三:合并时不自动提交,手动恢复文件

四、验证与后续工作

五、常见问题及解决

Q1:执行 git pull 时报错 “Your local changes would be overwritten by merge”

Q2:使用 --skip-worktree 后,我想临时允许更新其中一个文件怎么办?

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. 确保本地仓库是最新的

git fetch origin

2. 切换到目标分支(需要被更新的分支)

git checkout sop_cip_maf_260612

3. 合并另一个分支

git merge origin/tianjin-cb/sop_cip_maf_v1.4.0_260610

执行后,Git 会尝试自动合并。如果没有冲突,你会看到类似下面的输出:

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. 将合并后的分支推送到远程仓库

只有推送后,其他服务器才能拉取到这次合并的结果。

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 操作影响,并且不要提示冲突。

步骤:

# 进入项目目录
cd /path/to/sop_cip_maf_260612

# 设置跳过工作树检查(忽略本地修改)
git update-index --skip-worktree run.sh .env_A6000

# 正常拉取最新代码
git pull origin sop_cip_maf_260612

此后,无论远程分支如何更新这两个文件,你的本地版本都会原封不动。其他文件会正常更新。

恢复跟踪(如果需要以后更新这两个文件):

git update-index --no-skip-worktree run.sh .env_A6000

优点:一次配置,后续所有 git pull 都自动保护这两个文件,非常方便。
缺点:你也无法看到远程对这些文件的修改(除非主动取消跳过)。

方法二:暂存本地修改,拉取后再恢复

如果你只是想这一次拉取时保留本地配置,以后可能还想拉取远程更新,可以使用 stash

# 暂存这两个文件的修改
git stash push -- run.sh .env_A6000

# 拉取最新代码
git pull origin sop_cip_maf_260612

# 恢复本地修改(可能会冲突)
git stash pop

如果拉取时远程也修改了这两个文件,git stash pop 会提示冲突。此时选择保留本地版本:

git checkout --ours -- run.sh .env_A6000
git add run.sh .env_A6000
git stash drop   # 删除暂存记录

方法三:合并时不自动提交,手动恢复文件

# 拉取并合并但不自动提交
git fetch origin
git merge --no-commit origin/sop_cip_maf_260612

# 强制用本地版本覆盖这两个文件
git checkout HEAD -- run.sh .env_A6000

# 完成合并提交
git commit

四、验证与后续工作

拉取完成后,建议检查:

  1. 配置文件是否保留cat run.sh 和 cat .env_A6000,确认内容仍是服务器的定制配置。

  2. 其他文件是否更新:例如查看之前被删除的文件 conversation (10).json 是否已不存在(说明更新成功)。

  3. 运行项目测试:启动服务,确保合并后的代码与本地配置兼容。

五、常见问题及解决

Q1:执行 git pull 时报错 “Your local changes would be overwritten by merge”

这是因为 pull 会尝试合并,但 Git 检测到本地有未提交的修改且与远程文件冲突。解决方法:

  • 如果确认要保留本地修改,按照上文的方法一或方法二处理。

  • 如果不需要保留,可以强制丢弃本地修改:git checkout -- run.sh .env_A6000 后再 pull

Q2:使用 --skip-worktree 后,我想临时允许更新其中一个文件怎么办?

可以取消跳过、拉取、再重新跳过:

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 显式指定。


总结

  1. 分支合并:使用 git merge 将另一个分支的更新合并到当前分支,并推送到远程。

  2. 远程服务器同步:使用 git pull 拉取最新代码。

  3. 保护本地配置文件:核心命令 git update-index --skip-worktree,让 Git 忽略特定文件的本地修改,避免被覆盖。

这套流程非常适合开发-测试-生产多环境部署场景:开发机完成合并,测试/生产服务器拉取最新代码,同时保留各自的环境配置(如不同 GPU 型号、不同端口、不同 API Key)。