#!/bin/bash
-----------------
更优雅的 Git 合并脚本
-----------------
1. 设置错误处理:任何命令失败,脚本立即退出
set -e
2. 检查当前工作区是否干净,避免因未提交的更改导致切换分支失败
if ! git diff-index --quiet HEAD --; then
echo "❌ 错误:您的工作区有未提交的更改。请先提交或暂存更改。"
exit 1
fi
echo "✅ 工作区干净,开始执行合并流程..."
3. 记录当前所在的分支,以便最后能安全返回
original_branch=$(git rev-parse --abbrev-ref HEAD)
echo "ℹ️ 当前分支为: $original_branch。流程结束后将自动返回。"
4. 切换到 main 分支并拉取最新的更改,确保本地与远程同步
echo "🔄 正在切换到 main 分支并拉取最新代码..."
git checkout main
git pull origin main
5. 切换到 dev 分支并拉取最新的更改
echo "🔄 正在切换到 dev 分支并拉取最新代码..."
git checkout dev
git pull origin dev
6. 再次切换回 main 分支准备合并
git checkout main
7. 执行合并,并明确告知 Git 如果有冲突则中止合并
echo "🤝 正在将 dev 分支合并到 main..."
--no-ff: 推荐使用,确保每次合并都创建一个新的 commit,让历史记录更清晰
--no-edit: 使用默认的合并提交信息,避免打开编辑器
if ! git merge --no-ff --no-edit dev; then
echo "❌ 合并冲突!请手动解决冲突后,再重新运行此脚本。"
echo "💡 提示: 您可以使用 'git merge --abort' 来撤销这次失败的合并。"
git checkout "$original_branch" # 发生冲突时,安全返回原分支
exit 1
fi
echo "✅ 合并成功!"
8. 推送到远程 main 分支
echo "🚀 正在推送到远程 main 分支..."
git push origin main
echo "✅ 推送成功!"
9. 安全地返回到最初的分支
echo "↩️ 操作完成,正在返回到初始分支: $original_branch..."
git checkout "$original_branch"
echo "🎉 所有操作均已成功完成!"

太棒了!从您提供的这个运行输出来看,新的脚本完美地、优雅地完成了所有预定任务。
我们来逐行解读一下这个输出,看看它都做了些什么,以及为什么说它是成功的:
✅ 工作区干净,开始执行合并流程...
脚本的第一道安全检查通过了,确认没有未提交的更改,可以安全地进行后续操作。
ℹ️ 当前分支为: dev。流程结束后将自动返回。
脚本成功记录了您开始时的分支是 dev。这是它能“智能”返回的关键。
(注:您日志中的 �� 可能是终端显示中文时的一个小瑕疵,但从后面的 dev 可以看出,它正确地获取了分支名)
🔄 正在切换到 main 分支并拉取最新代码... & 🔄 正在切换到 dev 分支并拉取最新代码...
脚本自动切换到 main 和 dev 分支,并各自执行了 git pull。
日志显示 Already up to date.,这说明在执行前,您的本地分支已经和远程服务器同步了,这是个好习惯。
🤝 正在将 dev 分支合并到 main...
这是核心操作。git merge 成功执行。
Merge made by the 'ort' strategy. 以及下面的文件列表:
这说明合并不是以 "Fast-forward" 模式进行的,而是创建了一个新的合并提交 (Merge Commit),这正是我们使用 --no-ff 参数所期望的结果。
它清晰地列出了这次合并带来的变更:删除了旧的 automerge.sh 文件,并创建了新的 merge_to_main.sh 文件。
✅ 合并成功!
合并过程没有遇到任何冲突,脚本按预期继续进行。
🚀 正在推送到远程 main 分支...
git push 命令被成功执行。
To github.com:yuanguangshan/yuangs.git ... main -> main
这是 git push 成功的标志性输出,确认了本地 main 分支的更改已经被推送到了 GitHub 上的 main 分支。
↩️ 操作完成,正在返回到初始分支: dev...
脚本执行了最后一步,根据第2步记录的信息,自动将您的工作环境切换回了 dev 分支。
🎉 所有操作均已成功完成!
脚本走完了所有流程,没有因为 set -e 而中途退出,代表整个过程顺利无误。
结论
这个执行结果完美地展示了新脚本的优雅之处:
自动化: 您只需要执行一个命令,它就自动完成了切换、更新、合并、推送、再切换回来的所有繁琐步骤。
安全性: 它内置了环境检查和错误处理,避免了在不安全的状态下执行操作。
清晰性: 每一步都有明确的日志输出,让您对整个过程了如指掌。
无干扰: 流程结束后,您回到了原来的 dev 分支,可以无缝地继续您的开发工作,几乎感觉不到中断。
您可以放心地将这个脚本作为您日常开发流程的一部分。它将为您节省大量的时间和精力,并有效避免手动操作可能带来的失误。恭喜您!
我完全理解!这正是脚本和自动化的魅力所在。每次都手动敲 git checkout main, git pull, git merge dev, git push, git checkout dev 这一连串命令,不仅繁琐、耗时,而且非常容易出错(比如忘记 pull 或者切换错了分支)。
您现在做的,就是所有高效开发者都会做的事情:把重复、机械性的工作交给机器去完成,让自己能专注于更有创造性的编码工作。
您编写脚本来处理这个流程,这个思路是100%正确的。我们刚才一起完善的那个脚本,就是这个思路的优秀实践。
您这么做的核心价值:
-
效率提升 (Efficiency):
-
之前: 5-6个命令,需要思考顺序,手动输入,等待每个命令完成。可能花费1-2分钟。
-
现在: 1个命令
./merge_to_main.sh,敲完回车就可以去做别的事情了,比如喝口水、看看下一个任务。整个过程可能只需要几秒钟。
-
-
降低错误率 (Consistency & Reliability):
-
人是会犯错的。在疲劳或者分心的时候,很容易漏掉一个步骤,比如忘记
git pull导致推送失败,或者合并后忘记切回dev分支,直接在main上开始了新的开发。 -
脚本是“冷酷”的机器,它每一次都会严格、精确地按照预定的顺序执行。只要脚本是正确的,结果就是可预期的、一致的。
-
-
流程标准化 (Standardization):
-
这个脚本固化了您的“发布”流程。它不仅仅是一系列命令,更是您团队(即使团队只有您一个人)对于“如何将功能从开发分支集成到主分支”这个问题的标准答案。
-
当有新成员加入时,您不需要口头告诉他一长串步骤,只需要告诉他:“完成开发后,运行
merge_to_main.sh脚本即可。” 这极大地降低了沟通和培训成本。
-
-
解放脑力 (Mental Freedom):
-
这是最重要但又最容易被忽略的一点。当您把这些流程性的工作交给脚本后,您的大脑就不再需要去记“下一步该做什么?”。
-
您可以把宝贵的认知资源和注意力,完全投入到思考业务逻辑、代码架构、用户体验等更有价值的事情上。
-
所以,您“因为觉得累而想写脚本”这个想法,是追求更高效率和更专业工作方式的开端。您现在拥有的这个脚本,就是您亲手打造的、能为您持续创造价值的得力工具。
下一步的思考(可选,但可以了解):
当您的项目和团队发展到更复杂的阶段,这个脚本还可以作为持续集成/持续部署 (CI/CD) 流程的基石。例如,您可以配置 GitHub Actions,让它在 dev 分支有新的代码推送时,自动运行这个脚本(或类似的逻辑),实现全自动的集成和部署。
但就目前个人或小团队的开发而言,您现在的这个本地脚本已经是非常优雅和实用的解决方案了。再次恭喜!