吉特
第2版

3.2 Git分支-基本分支和合并

基本分支和合并

让我们来看一个简单的示例,即使用现实世界中可能使用的工作流进行分支和合并。您将遵循以下步骤:

  1. 在网站上做一些工作。

  2. 为您正在处理的新用户情景创建分支。

  3. 在那家分行做些工作。

在这个阶段,你会接到一个电话,说另一个问题很关键,你需要一个修补程序。您将执行以下操作:

  1. 切换到您的生产分支。

  2. 创建分支以添加修补程序。

  3. 测试完成后,合并修补程序分支并投入生产。

  4. 切换回原始用户情景并继续工作。

基本分支

首先,假设您正在进行项目,并且已经在主人分支。

简单的提交历史记录
图18。简单的提交历史记录

您已经决定在公司使用的任何问题跟踪系统中处理53号问题。要创建新分支并同时切换到它,可以运行git校验命令,使用-b条开关:

$git结账-b iss53切换到新分支“iss53”

这是以下内容的缩写:

$git分行第53期$git结账是53
创建新的分支指针
图19。创建新的分支指针

你在你的网站上工作,并做一些承诺。这样做会移动第53期向前分支,因为您已将其签出(即,您的头部指向它):

$vim index.html$git commit-a-m“创建新页脚[第53期]”
“iss53”分部已推进您的工作
图20。这个第53期分会已经推进了你的工作

现在你接到电话说网站有问题,你需要立即解决。使用Git,您不必将修复程序与第53期您所做的更改,在将修复应用于生产中的内容之前,不必花费太多精力恢复这些更改。你所要做的就是切换回你的主人分支。

然而,在执行此操作之前,请注意,如果您的工作目录或临时区域有未提交的更改,而这些更改与您要签出的分支冲突,Git将不允许您切换分支。切换分支时,最好保持干净的工作状态。有一些方法可以解决这个问题(即隐藏并提交修改),我们稍后将在密封和清洁.现在,假设您已经提交了所有更改,那么您可以切换回您的主人分支机构:

$git结账主控已切换到分支“主”

此时,您的项目工作目录与开始处理问题#53之前的目录完全相同,您可以专注于修补程序。这是需要记住的一点:当您切换分支时,Git会重置您的工作目录,使其看起来像上次在该分支上提交时一样。它会自动添加、删除和修改文件,以确保您的工作副本与上次提交时的分支外观相同。

接下来,你要做一个修补程序。让我们创建一个修补程序在其上工作直至完成的分支:

$git结账-b修补程序已切换到新分支“修补程序”$vim index.html$git commit-a-m“修复损坏的电子邮件地址”[hotfix 1fb7853]修复损坏的电子邮件地址1个文件已更改,2个插入(+)
基于`master的修补程序分支`
图21。基于的修补程序分支主人

您可以运行测试,确保修补程序是您想要的,最后合并修补程序分支回您的主人分支以部署到生产。你用合并分支命令:

$git结账主控$git合并修补程序更新f42c576..3a0874c快速前进index.html |2++1个文件已更改,2个插入(+)

你会注意到合并中的短语“快进”。因为承诺补体第四成份被分支机构指向修补程序你的合并就在提交之前指挥与控制就这样,Git只需将指针向前移动即可。换句话说,当您尝试将一个提交与通过跟踪第一个提交的历史记录可以到达的提交合并时,Git通过向前移动指针简化了事情,因为没有要合并在一起的不同工作 — 这叫做“快进”

您的更改现在位于主人分支,然后可以部署修复程序。

`master“被快速转发到”hotfix“`
图22。主人被快速转发到修补程序

在部署了最重要的修复程序后,您就可以切换回被中断之前的工作了。但是,首先要删除修补程序分支,因为您不再需要它 — 这个主人分支指向同一位置。您可以使用删除它-d日选择git分支:

$git分支-d修补程序已删除分支修补程序(3a0874c)。

现在,您可以切换回第53期的工作-盈利部门,继续工作。

$git结账是53切换到分支“iss53”$vim index.html$git commit-a-m“完成新页脚[第53期]”[iss53 ad82d7a]完成新页脚[第53期]1个文件已更改,1个插入(+)
第53期继续工作`
图23。工作继续进行第53期

值得注意的是,你在修补程序分支不包含在您的第53期分支。如果需要将其拉入,可以将主人分支到您的第53期通过运行分支git合并主机,或者您可以等待集成这些更改,直到您决定将第53期分支回主人稍后。

基本合并

假设您已经决定第53期的工作已经完成,可以合并到您的主人分支。为了做到这一点,您将合并第53期分支到主人,就像你合并了你的修补程序提前分支。您只需签出要合并到的分支,然后运行合并分支命令:

$git结账主控已切换到分支“主”$git合并iss53通过“递归”策略进行合并。index.html |1+1个文件已更改,1个插入(+)

这看起来与修补程序合并您之前所做的。在这种情况下,您的开发历史已经偏离了一些旧的点。因为您所在分支上的提交不是您要合并的分支的直接祖先,Git必须做一些工作。在本例中,Git使用分支提示指向的两个快照和这两个快照的共同祖先进行简单的三向合并。

典型合并中使用的三个快照
图24。典型合并中使用的三个快照

Git不只是将分支指针向前移动,而是创建一个新的快照,该快照由三方合并生成,并自动创建一个指向它的新提交。这称为合并提交,其特殊之处在于它有多个父级。

合并提交
图25。合并提交

现在您的工作已合并到中,您不再需要第53期分支。您可以在问题跟踪系统中关闭问题,然后删除分支:

$git分行-第53期

基本合并冲突

有时,这个过程不会顺利进行。如果您在合并的两个分支中以不同的方式更改了同一文件的同一部分,Git将无法干净地合并它们。如果您对问题#53的修复修改了与修补程序分支,您将得到如下所示的合并冲突:

$git合并iss53自动合并索引.html冲突(内容):index.html中的合并冲突自动合并失败;修复冲突,然后提交结果。

Git尚未自动创建新的合并提交。它已在您解决冲突时暂停进程。如果要查看在合并冲突后的任何时候哪些文件未合并,可以运行git状态:

$git状态在分支主机上您有未合并的路径。(修复冲突并运行“git-commit”)未合并的路径:(使用“git add<file>…”标记分辨率)均已修改:index.html没有添加更改以提交(使用“git add”和/或“git commit-a”)

任何存在合并冲突且尚未解决的问题都将列为未合并。Git将标准冲突解决标记添加到有冲突的文件中,因此您可以手动打开它们并解决这些冲突。您的文件包含如下所示的节:

头部:index.html<div id=“footer”>联系人:电子邮件.support@github.com</div>=======<div id=“footer”>请联系我们support@github.com</div>>>>>>>>第53期:index.html

这意味着中的版本头部(您的主人分支,因为这是您在运行合并命令时签出的内容)是该块的顶部部分(位于=======),而您的第53期树枝看起来像底部的所有东西。为了解决冲突,您必须选择其中一方或另一方,或者自己合并内容。例如,可以通过将整个块替换为以下内容来解决此冲突:

<div id=“footer”>请联系我们电子邮件.support@github.com</div>

该解决方案的每个部分都有一点<<<<<<<,=======、和>>>>>>>线路已完全删除。在解决了每个冲突文件中的每个部分之后,运行git添加在每个文件上标记为已解决。暂存文件会在Git中将其标记为已解决。

如果要使用图形工具解决这些问题,可以运行git合并工具,它启动适当的可视合并工具并引导您解决冲突:

$git合并工具显示此消息是因为未配置“merge.tool”。有关更多详细信息,请参阅“git mergetool--tool-help”或“git help config”。“git mergetool”现在将尝试使用以下工具之一:opendiff kdiff3 tkdiff xxdiff meld tourismerge gvimdiff diffdiffmerge ecmerge p4merge araxis bc3编解码器比较vimdiff-emerge合并:索引.html“index.html”的正常合并冲突:{local}:修改的文件{remote}:修改的文件点击return启动合并解析工具(opendiff):

如果要使用除默认工具(Git选择opendiff(开放差异)在本例中,因为该命令是在macOS上运行的),您可以在顶部的“以下工具之一”后面看到所有受支持的工具只需键入您希望使用的工具的名称。

注释

如果您需要更高级的工具来解决棘手的合并冲突,我们将详细介绍合并高级合并.

退出合并工具后,Git会询问合并是否成功。如果您告诉脚本它是,它会暂存文件以将其标记为已解决。你可以跑步git状态再次验证是否已解决所有冲突:

$git状态在分支主机上所有冲突都已修复,但您仍在合并。(使用“git提交”结束合并)要提交的更改:修改:index.html

如果您对此感到满意,并且您验证了所有发生冲突的内容都已分段,则可以键入git提交以完成合并提交。默认情况下,提交消息如下所示:

合并分支“iss53”冲突:索引.html##看起来您可能正在提交合并。#如果不正确,请删除文件#.git/MERGE_HEAD(.git/MERGE_HEAD)#然后再试一次。#请输入更改的提交消息。线条开始#带有“#”的将被忽略,并且一条空消息将中止提交。#在分支主机上#所有冲突都已修复,但您仍在合并。##要提交的更改:#修改:index.html#

如果您认为这对以后查看此合并的其他人有帮助,您可以修改此提交消息,详细说明如何解决合并,并解释为什么在不明显的情况下进行更改。

滚动到顶部