如何有选择地合并(摘取)另一个分支的改动
选择性合并的手段:整个提交用 git cherry-pick;单个文件用 git checkout 分支 -- 路径;文件内部分改动用 git checkout -p 交互挑选;不想提交先合试用 git merge --no-commit --no-ff。
按粒度选工具:要整个提交 → git cherry-pick;要单个文件 → git checkout 分支 -- 路径;要文件里的部分改动 → git checkout -p 分支 -- 路径 交互挑选;要试合整个分支但先不提交 → git merge --no-commit --no-ff。
粒度一:摘提交
git cherry-pick a1b2c3d
git cherry-pick A^..B # 连续一段
粒度二:拿文件
这是复制该分支的文件快照,不是三方合并;先保存当前改动。checkout 默认 overlay,不会因来源中缺少文件而自动删除目标文件。
git checkout feature-x -- src/utils.js # 整文件覆盖
git checkout feature-x -- src/config/ # 整目录
粒度三:挑改动块
git checkout -p feature-x -- src/app.js
# 逐块选择 y/n;显式指定分支时会同时更新暂存区和工作区
粒度四:试合再裁剪
git merge --no-commit --no-ff feature-x
# 合并结果停在暂存区,手工删掉不要的部分
git restore --source=HEAD --staged --worktree src/不要的部分/
git commit -m "选择性合入 feature-x"
常见问题(FAQ)
Q:这些方式后续 merge 整个分支时会冲突吗?
可能。cherry-pick/checkout 复制内容并不记录整个分支已合并,之后 merge 仍可能冲突。若采用“试合再裁剪”并创建 merge commit,Git 会记录整个分支的祖先关系,被裁掉的旧改动不会在下次 merge 时自动再次提出。
Q:想看两个分支差异再决定摘什么?
git diff main...feature-x(三点语法)看该分支引入的全部改动,挑好目标再动手。
Q:能不能"反着摘"——合并但排除某文件?
可以:在 merge 尚未提交时,用 git restore --source=HEAD --staged --worktree -- 要排除的路径 还原到本次合并前的当前分支快照,再提交;不要假定 origin/main 与合并前状态相同。此 merge commit 仍记录整个分支已合并。