IDEA和GIT实现cherry pick拣选部分变更到新分支

前言

在工作中,当你出现一些情况,需要将一个分支的部分变动提取出来,只需要更新提取出来的情况就需要用到当前文章提到的git的功能

并且正常情况下,你工作是没有权限直接合并到生产分支,并且前一个需求还没合并到生产分支,如果你想要复用这部分的改动逻辑,那么就需要用到这个操作,也叫cherry-pick拣选

核心作用

核心作用是将一个或多个已有的提交(commit)复制到当前所在的分支上。

你可以把它想象成在一棵果树上,只挑选(pick)几颗你想要的,而不是把整根树枝都搬过来。

为什么需要它?

主要用于那些不需要合并整个分支,而只需要其中几个特定提交的情况。
将修复补丁应用到多个分支

这是最常见、最经典的场景。假设你有一个bugfix分支上修复了一个关键 bug,这个提交的 hash 是 a1b2c3d。现在你需要将这个修复同时应用到:

main 分支(生产环境)

develop 分支(开发环境)

可能还有旧的维护分支 v1.x

你不需要将整个 bugfix 分支合并到这些分支上,只需要在每个目标分支上执行:

bash 复制代码
git cherry-pick a1b2c3d

意外在错误的分支上进行了提交

你本来应该在 feature/login 分支上开发,但不小心在 main 分支上提交了代码。这时你可以:

在 feature/login 分支上,通过 git cherry-pick 将那个误提交"拿"过来。

回到 main 分支,用 git reset 撤销那个提交。

只想引入另一个分支上的某个特定功能

同事在 feature/A 分支上开发了 5 个新功能,但你目前只需要其中的第 3 个功能。你可以找到实现第 3 个功能的提交,然后用 cherry-pick 将其单独引入你的分支。

步骤

那么接下来我会列举下git操作和IDEA操作的方式,不过重点会讲IDEA操作的方式

IDEA方式

首先,我们先新建一个分支

IDEA切换该分支

在右下角,输入自己的分支,点击分支切换check out

GIT菜单栏检索Show Git Log 或者左下角点击Git面板

这里有三部分,在中间部分有
【输入框】 可以筛选提交hash,分支名,提交文本筛选git历史记录
【Branch:All】 根据分支筛选git提交记录,默认带出所有
【User:All】根据提交用户筛选git提交记录,默认带出所有
【Date:All】根据提交时间筛选git提交记录,默认带出所有
【Path:All】根据文件筛选git提交记录,默认带出所有
在这里筛选你需要拣选的分支,筛选之后,点击选中,右侧部分会带出本次git提交记录的变更文件记录

按照ctrl键,选中需要拣选的文件,然后在选中的文件右键选择Cherry-pick Selected Changes

然后会弹窗,加入到一个变更的列表
Name需要加入的变更列表,可以自定义命名
Comment 提交文本

然后点击OK,在我们的左侧Commit就会多出拣选的文件,然后我们正常git push 提交即可

GIT方式

git方式是比较通用的,哪怕脱离图形化工具我们也可以根据git命令执行拣选,但是按照我如下的IDEA方式会比较方便操作

基本语法实例

bash 复制代码
# 切换到目标分支
git checkout main

# 拣选单个提交
git cherry-pick abc1234

# 拣选单个提交并保留原提交信息
git cherry-pick -x abc1234

# 拣选但不立即提交(允许修改后再提交)
git cherry-pick -n abc1234

一次挑选多个提交实例

挑选不连续的多个提交
bash 复制代码
# 切换到目标分支
git checkout feature-branch

# 一次挑选多个不连续的提交
git cherry-pick commit1-hash commit2-hash commit3-hash

# 实际示例
git cherry-pick a1b2c3d e4f5g6h i7j8k9l
挑选连续的提交范围
bash 复制代码
# 方法1:使用范围语法(包含start-commit,不包含end-commit)
git cherry-pick start-commit^..end-commit

# 方法2:使用..语法
git cherry-pick older-commit..newer-commit

# 实际示例 - 拣选从提交A到提交D的所有提交
git cherry-pick a1b2c3d^..d4e5f6g

# 或者明确指定范围
git cherry-pick a1b2c3d..b2c3d4e..c3d4e5f..d4e5f6g

解决冲突的完整流程

当 cherry-pick 遇到冲突时的处理步骤:

bash 复制代码
# 1. 执行cherry-pick时遇到冲突
git cherry-pick a1b2c3d
# 输出:CONFLICT (content): Merge conflict in file.txt
# 输出:Automatic cherry-pick failed.

# 2. 查看冲突状态
git status
# 输出:Unmerged paths:
# 输出:  both modified:   file.txt

# 3. 手动解决冲突
# 编辑冲突文件,解决 <<<<<<<, =======, >>>>>>> 标记的部分
vim file.txt

# 4. 将解决后的文件标记为已解决
git add file.txt

# 5. 继续完成cherry-pick操作
git cherry-pick --continue

# 6. 如果需要放弃这次cherry-pick
git cherry-pick --abort

# 7. 如果冲突复杂,可以跳过当前提交
git cherry-pick --skip
  • 冲突解决示例
    假设 file.txt 内容冲突:
bash 复制代码
<<<<<<< HEAD
这是当前分支的内容
=======
这是要拣选的提交的内容
>>>>>>> a1b2c3d... 提交信息

手动解决后:

bash 复制代码
这是合并后的新内容

然后执行:

bash 复制代码
git add file.txt
git cherry-pick --continue

挑选某个分支的某次变更的某个文件

方法一:使用 git checkout(推荐)
bash 复制代码
# 步骤1:切换到目标分支
git checkout main

# 步骤2:从源分支的特定提交中检出单个文件
git checkout feature-branch -- path/to/specific-file.js

# 或者直接使用提交hash
git checkout a1b2c3d -- src/utils/helper.js

# 步骤3:提交这个文件
git add src/utils/helper.js
git commit -m "feat: 从feature-branch的提交a1b2c3d中拣选helper.js"
方法二:使用 cherry-pick + reset
bash 复制代码
# 步骤1:切换到目标分支
git checkout main

# 步骤2:执行cherry-pick但不提交
git cherry-pick -n a1b2c3d

# 步骤3:重置暂存区,保留工作区改动
git reset HEAD

# 步骤4:只添加需要的单个文件
git add src/utils/helper.js

# 步骤5:提交
git commit -m "feat: 拣选helper.js from a1b2c3d"

# 步骤6:清理不需要的改动(可选)
git checkout -- .

挑选某个分支的某次变更的多个文件

方法一:使用 git checkout 检出多个文件
bash 复制代码
# 步骤1:切换到目标分支
git checkout main

# 步骤2:检出多个特定文件
git checkout feature-branch -- src/components/Button.js src/styles/theme.css src/utils/constants.js

# 步骤3:提交这些文件
git add .
git commit -m "feat: 从feature-branch拣选多个UI组件文件"
方法二:使用 cherry-pick + 选择性添加
bash 复制代码
# 步骤1:切换到目标分支
git checkout develop

# 步骤2:cherry-pick但不提交
git cherry-pick -n b2c3d4e

# 步骤3:重置暂存区
git reset HEAD

# 步骤4:查看哪些文件被修改了
git status

# 步骤5:选择性添加需要的多个文件
git add src/components/Modal.js src/hooks/useModal.js

# 步骤6:提交选中的文件
git commit -m "feat: 拣选Modal组件及相关hook"

# 步骤7:丢弃不需要的文件改动
git checkout -- .
方法三:创建临时分支(最安全的方法)
bash 复制代码
# 步骤1:创建临时分支
git checkout -b temp-cherry-pick

# 步骤2:执行完整cherry-pick
git cherry-pick c3d4e5f

# 步骤3:重置到cherry-pick之前的状态,但保留文件改动
git reset HEAD^

# 步骤4:检查并选择需要的文件
git status

# 步骤5:添加需要的多个文件
git add src/api/user.js src/store/auth.js

# 步骤6:提交
git commit -m "feat: 拣选用户认证相关文件"

# 步骤7:回到目标分支并合并临时分支
git checkout main
git cherry-pick temp-cherry-pick

# 步骤8:删除临时分支
git branch -D temp-cherry-pick

综合实战示例

场景:从修复分支挑选特定修复文件
bash 复制代码
# 假设在hotfix-branch上有多个提交,我们只需要其中的安全修复

# 查看hotfix-branch的提交历史
git log hotfix-branch --oneline -5
# 输出:
# f1e2d3c 修复支付漏洞
# e2d3c4b 更新文档
# d3c4b5a 修复安全权限
# c4b5a6b 样式调整
# b5a6b7c 功能增强

# 我们只需要安全相关的修复:d3c4b5a 和 f1e2d3c

# 方法1:逐个拣选需要的提交
git checkout main
git cherry-pick d3c4b5a
git cherry-pick f1e2d3c

# 方法2:批量拣选但只保留特定文件
git checkout main
git cherry-pick -n d3c4b5a f1e2d3c
git reset HEAD
git add src/security/permissions.js src/payment/processor.js
git commit -m "security: 应用关键安全修复"
git checkout -- .

结语

如上实现了DEA和GIT实现cherry pick拣选部分变更到新分支

相关推荐
Elastic 中国社区官方博客9 小时前
Simple MCP Client - 连接到 Elasticsearch MCP 并进行自然语言搜索
大数据·人工智能·elasticsearch·搜索引擎·ai·全文检索
Chan169 小时前
流量安全优化:基于 Sentinel 实现网站流量控制和熔断
java·spring boot·安全·sentinel·intellij-idea·进程
会飞的小蛮猪9 小时前
ELK运维之路(Logstash测试案例1)
elasticsearch·kibana·logstash
刘志辉11 小时前
git指令
git
tcwgq11 小时前
Centos Stream 8 搭建Cas Server
linux·elasticsearch·centos
yumgpkpm13 小时前
CMP (类Cloudera) CDP7.3(400次编译)在华为鲲鹏Aarch64(ARM)信创环境中的性能测试过程及命令
大数据·hive·hadoop·python·elasticsearch·spark·cloudera
2501_9167665413 小时前
【Git学习】初识git:简单介绍及安装流程
git·学习
yumgpkpm16 小时前
大数据综合管理平台(CMP)(类Cloudera CDP7.3)有哪些核心功能?
hive·hadoop·elasticsearch·zookeeper·big data
Zhsh-716 小时前
centos配置ES和MYSQL自动备份
mysql·elasticsearch·centos