切换分支执行git pull后,为何会合并其他分支文件?
问题分析与解决
问题场景
我在Jenkins中使用以下脚本更新分支并生成补丁:
git -C $PROJECT fetch strTmp=$(git -C $PROJECT diff origin/$BRANCH..origin/master --name-only) echo "strTmp = $strTmp" if [ -n "$strTmp" ]; then git -C $PROJECT reset --hard git -C $PROJECT checkout $BRANCH git -C $PROJECT pull fi
但偶尔会出现异常:切换到新分支release/DEV-19999后,执行git pull时,之前的release/DEV-11111分支的文件被合并到当前分支。相关日志如下:
HEAD is now at dac33 Merge remote-tracking branch 'origin/master' into release/DEV-11111 branch 'release/DEV-19999' set up to track 'origin/release/DEV-19999'. Switched to a new branch 'release/DEV-19999' Merge made by the 'ort' strategy. CHK_CL_IP | 28 ++++++++++++++++ RED_IP | 29 +++++++++++++++++ CR_P_IP | 46 +++++++++++++++++++++++++++ IP | 29 +++++++++++++++++ 4 files changed, 132 insertions(+) CHK_CL_IP RED_IP CR_P_IP IP
我预期切换分支后仅更新当前远程分支的内容,为何会出现旧分支文件被合并的情况?
原因解析
问题出在git checkout $BRANCH的执行逻辑:
- 当本地不存在
$BRANCH对应的分支时,Git会基于当前所在分支的HEAD创建本地分支。在你的场景中,git reset --hard执行后,当前分支还是release/DEV-11111,所以新创建的release/DEV-19999本地分支起点是release/DEV-11111的提交。 - 随后执行
git pull时,Git会将远程origin/release/DEV-19999的内容与本地基于旧分支创建的分支合并,导致release/DEV-11111的文件被带入当前分支。
解决方案
修改脚本,确保本地分支直接与远程分支对齐,避免基于旧分支创建新分支:
方案1:强制让本地分支跟踪并同步远程分支
将git checkout $BRANCH替换为git checkout -B $BRANCH origin/$BRANCH,该命令会:
- 如果本地已存在
$BRANCH分支,强制将其重置为origin/$BRANCH的状态 - 如果本地不存在,直接基于
origin/$BRANCH创建本地分支并跟踪它
修改后的脚本:
git -C $PROJECT fetch strTmp=$(git -C $PROJECT diff origin/$BRANCH..origin/master --name-only) echo "strTmp = $strTmp" if [ -n "$strTmp" ]; then git -C $PROJECT reset --hard git -C $PROJECT checkout -B $BRANCH origin/$BRANCH # 此时本地分支已与远程一致,若要确保同步可使用rebase避免不必要的合并提交 git -C $PROJECT pull --rebase fi
方案2:使用git switch(Git 2.23+ 支持)
如果你的Git版本在2.23及以上,推荐用更清晰的git switch命令:
git -C $PROJECT fetch strTmp=$(git -C $PROJECT diff origin/$BRANCH..origin/master --name-only) echo "strTmp = $strTmp" if [ -n "$strTmp" ]; then git -C $PROJECT reset --hard git -C $PROJECT switch --force-create $BRANCH origin/$BRANCH git -C $PROJECT pull --rebase fi
额外优化
- 可以去掉
git pull,因为checkout -B或switch --force-create已经将本地分支同步到远程状态,若需要确保最新,fetch后直接重置即可。 - 使用
git pull --rebase代替默认的git pull,可以避免生成不必要的合并提交,保持分支历史整洁。
内容的提问来源于stack exchange,提问作者peseji8972
相关产品推荐
相关产品推荐

