合并、变基或挑拣以应用更改
在 Git 中,有几种方法可以将一个分支的更改合并到另一个分支中:
合并分支
假设您创建了一个功能分支以处理特定任务,并希望在完成并测试该功能后将您的工作成果(F1、 F2、 F3 )集成到主代码库中:
合并您的分支到 main 是最常见的方法。
当您在功能分支中开发时,您的团队成员可能继续将他们的工作(C4、 C5 )提交到 main:
当您将功能分支 合并到 main 时,更改将被集成到目标分支的 HEAD 中:
Git 会创建一个新的提交,这被称为 merge 提交,该提交是通过将您的功能分支和 main 从两个分支分叉点合并而来的。
合并的主要优点是具备完全的可追溯性,因为合并到 main 代码库中的提交会保留其原始哈希和作者,且属于一个功能的所有提交可以被分组在一起。
此工作流适用于将更改提交到 main 代码库时需进行 pull 或 merge requests ,或需层级审批流程的项目,因为不会更改现有分支。
这种方法的主要缺点是每次需要合并更改时都会创建额外的合并提交,这会严重污染项目历史,使其难以阅读。
合并分支
在 分支 弹出窗口(主菜单 )或 分支 窗格中的 Git 工具窗口中,选择您想要集成更改的目标分支,并从上下文菜单中选择 签出 切换到该分支。
请执行以下操作之一:
如果您不需要为合并指定选项,请选择您要合并到当前分支的分支,然后从子菜单中选择 将 <branch_name> 合并到 <target_branch>。

如果您需要指定合并选项,请从主菜单中选择 以打开 合并 对话框:

选择您想合并到当前分支的分支,点击 修改选项 并从以下选项中选择:
--no-ff:无论在任何情况下都会创建一个合并提交,即使合并可以快速前进解决。--ff-only:合并只有在可能快进时才会解决。--squash:将在当前分支上创建一个包含所有拉取更改的单个提交。-m:您将可以编辑合并提交的消息。--no-commit:将执行合并,但不会创建合并提交,以便您可以在提交之前检查合并的结果。--no-verify:执行合并时忽略默认运行的 pre-merge 与 commit-message 钩子。--allow-unrelated-histories:执行合并,忽略不允许合并无共同祖先的历史记录的安全规则。
点击 合并。
如果您的工作树是干净的(意味着您没有未提交的更改),并且功能分支与目标分支之间没有冲突,Git 将合并这两个分支,合并提交将出现在 日志 选项卡中的 Git 工具窗口 Alt+9 中:

如果您的分支与目标分支之间发生冲突,系统会提示您解决这些冲突(请参阅 解决冲突)。 如果合并后仍存在未解决的冲突, 合并冲突 节点将显示在 Commit 工具窗口的相应更改列表中 Alt+0 ,并附有解决链接。
如果您有被合并覆盖的本地更改,RubyMine 会建议执行 智能合并。 如果您选择此选项,RubyMine 将 暂存未提交的更改,执行合并,然后取消暂存这些更改。
变基分支(git-rebase)
当您 rebase 一个分支到另一个分支时,您将第一个分支的提交应用到第二个分支的 HEAD 提交之上。
假设您创建了一个用于处理某个特定任务的功能分支,并在该分支上进行了数次提交(F1、 F2、 F3):
当您在自己的分支进行开发时,您的团队成员继续将他们的工作(C4、 C5 )提交到 main:
为了将团队成员所做的更改(C4、 C5 )集成到您的功能分支,您可以将您的分支 rebase到 main 上。 通过这样做,您的提交将应用在 main 中当前 HEAD 提交之后:
变基的主要好处是,您将获得一个干净的项目历史,便于他人阅读和理解。 您的日志不包含由 merge 操作产生的不必要的合并提交,您将获得易于导航和搜索的线性历史记录。
在决定采用此工作流时,务必注意 rebase 会重写项目历史记录,因为它会为原始功能分支中的每个提交创建新的提交(用 F1' 替代 F1 ),因此它们将具有不同的哈希值,进而影响可追溯性。
将分支变基到另一个分支之上
从主菜单中选择

从列表中选择您想要变基当前分支的目标分支:

如果您需要从特定提交开始变基源分支,而不是变基整个分支,请点击 修改选项 并选择 --onto。
在源分支字段中,输入您希望从中开始将当前分支应用于新的基准的提交哈希值:

如果您想要变基的分支当前没有检出,请点击 修改选项 ,点击 选择另一个分支以进行变基 ,然后从出现的列表中选择一个分支:

RubyMine 将在开始变基操作之前检出此分支。
根据您的具体情况,从 修改选项 列表中选择其他选项:
--rebase-merges:在将要 rebase 的提交中保留分支结构。请注意,这些 merge 提交中已解决的合并冲突或手动更改需要手动重新解决或重新应用。
--keep-empty:保留空提交,即从其父提交中未做任何更改的提交。--root:rebase 分支中可达的所有提交。--update-refs:自动强制更新指向正在 rebase 的提交的任何分支。
点击 变基。
如果您不需要为 rebase 指定选项,您可以在不调用 rebase 对话框的情况下启动 rebase。 在 分支 弹出窗口或 分支窗格中的 Git工具窗口中选择一个分支并执行以下操作之一:

检出并变基到 <current_branch_name> (适用于远程和本地分支)以检出所选分支并将其变基到当前检出的分支之上。 如果远程分支在本地不存在,RubyMine 将会静默地创建一个受跟踪的本地分支,切换到该分支并进行变基。
将 <current_branch_name> 变基到 <selected_branch_name> (适用于远程和本地分支)将当前检出的分支变基到所选分支之上。
使用变基将更改拉取到 <current_branch_name> (用于远程分支)以 获取所选分支的更改并在这些更改的基础上变基当前分支。
观看此视频以更好地了解如何执行 rebase 操作:
通过执行交互式 rebase 编辑 Git 历史记录
通过在 RubyMine 中集成 Git,您可以通过执行 交互式 rebase来编辑历史记录,使其更线性且有意义。 这使您可以在将功能分支中的更改集成到其他分支之前,通过修改单个提交、更改它们的顺序、将多个提交压缩为一个、跳过包含无关更改的提交等方式来清理提交历史。
编辑当前分支的历史
RubyMine 允许您在将更改应用到不同分支之前编辑当前分支的提交历史。
打开 Git 工具窗口 Alt+9 并切换到 日志 选项卡。
将日志过滤为仅显示当前分支的提交:

请选择您要编辑的一系列提交中的最早提交,右键点击它并选择 从这里开始交互式变基。
该 交互式变基 对话框将显示当前分支中在所选提交之后进行的所有提交的列表:

如果 从这里开始交互式变基 选项被禁用了,这可能是由于以下原因之一:
所选提交有多个父母
所选提交不在当前分支中
所选提交已推送到 protected branch
若要识别原因,请将鼠标悬停在上下文菜单中的操作上,并查看状态栏中的消息:

您可以对分支记录执行以下更改:
更改提交的应用顺序 :使用
和
按钮在列表中向上或向下移动提交。
选择一个提交 :这是所有提交的默认状态。 如果您需要撤销已经在提交上执行的操作,请点击 挑选
,使此提交按原样应用。
编辑: 点击 停止编辑
,这样当您开始 rebase 时,会停在此提交,以便进行编辑。
当变基在某个提交处停止时,RubyMine 窗口右下角会弹出通知,允许您继续或终止变基:

您可以在继续进行 rebase 之前,使用上下文操作(例如 还原、 撤销、 修改 等)来修改此 commit。 如果您不执行任何操作,此提交将按原样应用。
如果您已经关闭了通知,请从主菜单中选择 Git | 继续变基 以恢复它。
重新措辞提交消息 :点击 改写 或双击一次提交,并在打开的小编辑器中编辑文本。
将两个提交合并为一个 :选择您要与前一个合并的提交,然后点击 合并 或 合并 按钮旁边的箭头,然后 修正。
如果您点击 合并 ,默认情况下两个提交的消息将被合并,因此如果您未修改生成的提交消息,此操作将在分支历史记录中反映。
如果您点击 修正 ,修正提交的提交信息将被丢弃,因此此更改在分支历史记录中将不可见。
在这两种情况下,您都可以在应用这些操作时,打开的迷你编辑器中编辑提交消息。
忽略提交 :点击 丢弃 以便未应用所选提交中的更改。
撤销所有更改 :点击 重置 以放弃您对提交所应用的所有操作。
因此, 变基提交 对话框显示了一个图表,说明了您在分支中对提交所执行的所有操作,以便您在开始变基之前进行审查:

点击 开始变基。
编辑分支历史并将其集成到另一个分支
RubyMine 允许您在另一个分支之上 rebase一个分支,并在应用更改之前编辑源分支的历史记录。
从主菜单中选择

点击 修改选项 并选择 --interactive。
从列表中选择您想要变基当前分支的目标分支:

如果您需要从特定提交开始变基源分支,而不是变基整个分支,请点击 修改选项 并选择 --onto。
在源分支字段中,输入您希望从中开始将当前分支应用于新的基准的提交哈希值:

如果您想要变基的分支当前没有检出,请点击 修改选项 ,点击 选择另一个分支以进行变基 ,然后从出现的列表中选择一个分支:

RubyMine 将在开始变基操作之前检出此分支。
根据您的具体情况,从 修改选项 列表中选择其他选项:
--rebase-merges:在将要 rebase 的提交中保留分支结构。请注意,这些 merge 提交中已解决的合并冲突或手动更改需要手动重新解决或重新应用。
--keep-empty:保留空提交,即从其父提交中未做任何更改的提交。--root:rebase 分支中可达的所有提交。--update-refs:自动强制更新指向正在 rebase 的提交的任何分支。
点击 Rebase。
交互式变基 对话框将显示包含当前分支中所有在所选提交之后进行的提交列表。

您可以对分支记录执行以下更改:
更改提交的应用顺序 :使用
和
按钮在列表中向上或向下移动提交。
选择一个提交 :这是所有提交的默认状态。 如果您需要撤销已经在提交上执行的操作,请点击 挑选
,使此提交按原样应用。
编辑: 点击 停止编辑
,这样当您开始 rebase 时,会停在此提交,以便进行编辑。
当变基在某个提交处停止时,RubyMine 窗口右下角会弹出通知,允许您继续或终止变基:

您可以在继续进行 rebase 之前,使用上下文操作(例如 还原、 撤销、 修改 等)来修改此 commit。 如果您不执行任何操作,此提交将按原样应用。
如果您已经关闭了通知,请从主菜单中选择 Git | 继续变基 以恢复它。
重新措辞提交消息 :点击 改写 或双击一次提交,并在打开的小编辑器中编辑文本。
将两个提交合并为一个 :选择您要与前一个合并的提交,然后点击 合并 或 合并 按钮旁边的箭头,然后 修正。
如果您点击 合并 ,默认情况下两个提交的消息将被合并,因此如果您未修改生成的提交消息,此操作将在分支历史记录中反映。
如果您点击 修正 ,修正提交的提交信息将被丢弃,因此此更改在分支历史记录中将不可见。
在这两种情况下,您都可以在应用这些操作时,打开的迷你编辑器中编辑提交消息。
忽略提交 :点击 丢弃 以便未应用所选提交中的更改。
撤销所有更改 :点击 重置 以放弃您对提交所应用的所有操作。
因此, 变基提交 对话框显示了一个图表,说明了您在分支中对提交所执行的所有操作,以便您在开始变基之前进行审查:

点击 开始变基。
挑选单独提交
有时候,您只需要将单个 commit 应用到不同的分支,而不是重新调整基底或合并整个分支。 例如,当您在功能分支中工作且需要集成已在两个分支分叉之后提交的 main 中的 hotfix 时,此操作可能非常有用。 或者您可能希望将修复程序移植到先前的发布分支。 您可以通过使用 拣选 操作来完成此操作。
cherry-pick 操作的状态显示在状态栏中。 您始终可以通过在 中止优选 弹出窗口中选择 Git 分支 来中止正在进行的 cherry-pick。

将提交应用到另一个分支
在 分支 弹出窗口中(主菜单 ),选择您想要将更改集成到的目标分支,然后从弹出菜单中选择 签出 以切换到该分支。
打开 Git 工具窗口 Alt+9 并切换到 日志 选项卡。
找到包含您想要 cherry-pick 的更改的提交。
您可以按分支、用户或日期过滤提交。 您还可以点击工具栏上的
并选择 高亮 | 未选择的提交 选项,以将已应用于当前分支的提交置灰。 如果您知道提交哈希或正在查找标记的提交,您还可以使用 前往 Hash / 分支 / 标签 操作(在 日志 选项卡的 Git 工具窗口 Alt+9 中按 Ctrl+F ,或点击工具栏上的
)。
选择所需的提交。 请使用 提交详情 区域中的信息来确认这些是您想要转移到另一个分支的更改。
请点击 拣选
工具栏。 RubyMine 将对目标分支应用并提交更改。
如果 cherry-pick 操作因冲突而失败,所选更改将显示在 Changes 区域中,您可以在 Commit 工具窗口 Alt+0 中查看该区域。 您可以稍后查看这些更改并在必要时提交。
如果您希望 RubyMine 在 cherry-pick 失败时自动创建变更列表,请在 中开启相应的设置。
将更改推送到目标分支。
以下视频将帮助您了解 cherry-pick 的工作原理:
应用单独更改
设想您对一个文件进行了更改,并希望将这些更改应用到另一个分支,但这些更改与其他修改的文件一起被提交了。 RubyMine 让您应用单独的更改,而不是挑选整个提交。
在 分支 弹出窗口中(主菜单 ),选择您想要将更改集成到的目标分支,然后从弹出菜单中选择 签出 以切换到该分支。
打开 Git 工具窗口 Alt+9 并切换到 日志 选项卡。
找到包含您想应用的更改的提交。
您可以按分支、用户或日期过滤提交。 您还可以点击工具栏上的
并选择 高亮 | 未选择的提交 选项,以将已应用于当前分支的提交置灰。 如果您知道提交哈希或正在查找标记的提交,您还可以使用 前往 Hash / 分支 / 标签 操作(在 日志 选项卡的 Git 工具窗口 Alt+9 中按 Ctrl+F ,或点击工具栏上的
)。
在右侧的 提交详细信息 窗格中,选择包含您要应用到目标分支的更改的文件,并从上下文菜单中选择 拣选选定的更改。
在打开的对话框中,选择一个现有的 changelist 或输入一个新 changelist 的名称,然后点击 确定。
提交更改,然后将其推送到目标分支。
应用独立文件
除了对单个文件应用单独的更改,您还可以将整个文件的内容复制到不同的分支。 例如,如果您想应用的文件在目标分支中不存在,或其变更是在多个提交中进行的,这可能会很有用。
切换到将应用更改的分支。
在 分支 弹出窗口(主菜单 )或 分支 窗格中的 Git 工具窗口中,选择包含您想要应用的文件的分支,并从上下文菜单中选择 显示与工作树的差异。
Changes 工具窗口显示了所选分支与当前检出的分支中不同的所有文件列表:

在选定分支中存在但在当前分支中缺失的文件将标记为灰色。
当前分支中存在但在所选分支中缺失的文件将标记为绿色。
选定分支与当前分支之间存在差异的文件将用蓝色标记。
您可以点击 交换分支 链接更改被视为基线的分支,与之比较其他分支。
选择要应用到当前分支的文件,然后在上下文菜单中选择 从 Branch 获取 ,或单击工具栏上的
。
提交并推送更改。 RubyMine 将把文件的全部内容复制到当前分支。