[Git-4] Git分支管理

发布时间:2026/10/11 7:19:05
[Git-4] Git分支管理 一、认识分支1、引入分支前面讲过每次commit提交都会创建一个git对象这些git对象按时间先后串成一条线可以先简单将这条线理解为分支。前面的所有操作都是在一条线上进行的我们称这条线为主分支即master或main分支。这就是我们前面不管是提交还是查看日志都经常看到master的原因因为我们当前的操作默认就是在master分支上。你和你的朋友正在开发一个游戏你们使用Git来管理版本。如果你们从头到尾都在这个master分支上做工作新功能还没有测试完成就进入主分支如果有错误就影响了以前的稳定版本。还有一个问题假设你和朋友同时修改了player.cpp文件都想提交到master分支但是事先没有商量好到底采用哪个版本一个版本可能覆盖另一个版本。基于以上问题我们引入新分支保证master分支稳定每个开发者在自己的分支开发并且新的测试工作可以独立测试最后审查没问题之后再合并到主分支。2、什么是分支我们提到每执行一次git commitGit都会创建一个新的commit对象。多个commit按照提交顺序连接起来形成一条提交历史。前面说将这条线简单理解为分支但是Git中的分支并不是这条线本身。Git分支本质上是一个指向commit对象的可移动引用Reference。就像图中画的一样master和main就是一个分支名保存了某个commit的位置。可移动就是当前分支会自动向前移动指向最新的commit对象。创建新的dev分支后dev其实和main一样都指向同一个commit对象只不过在dev分支下产生一次新的提交后dev就指向了当前分支的最新commit对象。3、HEAD与分支的关系HEAD通常指向当前分支而不是直接指向commit对象。比如当前库中有main和dev分支我想在main分支下工作HEAD就得指向main要想测试新功能就要切换到dev分支下怎么切换就是让HEAD指针指向dev分支。4、图示化分支其实Git可以使分支如上图一样图示化打印gitlog--graph--abbrev-commit --graph以图示分支commit提交 --abbrev-commit缩写commitid二、创建分支我们说一个仓库可以有多个分支那如何查看当前存在的分支使用如下指令gitbranch创建新分支使用如下指令gitbranchbranch name创建好分支后我们可以看到dev分支被打印出来前面的 * 就是指当前的HEAD指针指向哪个分支也就是当前的工作分支。创建好分支后我们看到 .git/refs/head 目录下多了一个dev代表分支创建完成。我们再看看这两个分支文件的内容是什么我们发现两个分支都是指向同一个Commit ID。这是因为新分支默认指向当前HEAD指针指向的提交。三、切换分支分支创建好了要想切换到该分支上工作使用如下指令gitcheckoutbranch name我们将工作分支切换到dev可以看到 * 号跑到dev前面了。工作分支变了其实就是HEAD指针指向变化了我们后面的提交操作都是在dev分支上进行的。当我们切换到dev分支下再对test.txt文件进行修改master分支能看到吗其实是看不到的当我们在dev分支下对一个文件进行修改并提交该提交记录其实只是记录到dev分支下master分支是看不到此次提交的。此时的分支示意图如下四、合并分支1、合并操作我们上面说在dev分支上进行的提交master分支是看不到的。假设dev分支上的提交检查无误后想进入master稳定版本我们就要进行分支合并操作。gitmerge dev 由于我们想将dev合并进master所以我们首先一定要切换回master分支然后再进行合并。合并成功后就可以看到dev分支上的修改。终端的提示信息中有一个Fast-forward这是一种合并模式后面会详细介绍几种合并模式。此时有没有觉得有点奇怪因为以此时的状态图来看此次新提交看不出来到底是master自己提交的还是合并自其他分支的。这就是Fast-forward合并模式的特点。2、合并冲突在实际开发过程中合并是很容易发生冲突的不能想合并就合并。合并冲突是Git在整合两个分支的改动时无法自动确定某些文件的最终内容需要开发人员来决定。比如创建一个新分支对test.txt文件进行了修改并commitmaster分支也对其进行修改并提交此时合并Git就不知道该保留哪个修改就产生了冲突。此时状态图如下发现test.txt存在冲突后可以打开该文件查看内容。Git会使用 、、 标记双方发生冲突的内容。此时需要根据实际需求手动调整代码保留正确的内容并删除所有冲突标记。修改完成后先执行 git add test.txt 将文件标记为已解决再执行 git commit 提交合并结果。⚠️ 必须提交解决结果才能完成本次合并。3、合并策略当两个分支已经分叉需要整合各自的改动时Git通常会比较共同祖先、当前分支和待合入分支三个版本。版本身份内容Base共同祖先两个分支分叉前的提交AthemelightOurs当前一侧当前master分支的提交BthemedarkTheirs待合入一侧feature分支的提交CthrmeblueGit根据共同祖先判断两边分别做了什么改动然后尝试组合这些改动。这就是通常所说的“三方合并”。如果只有master把light改成dark而feature没有修改这一处Git通常可以直接采用dark。但两边都修改了同一处且结果不同Git无法判断产品究竟应该使用深色主题还是蓝色主题于是报告冲突。因此两个分支修改过同一个文件并不意味着一定冲突。它们修改不同区域时Git通常可以自动合并两边做出相同修改时也通常不需要人工决定。这里的区域通常就是按改动片段算如果两处改动之间有未改动行那么未改动行就会把两处改动隔开分为两个改动区域共同祖先 master feature a a a b B b c c c d d D e e e // 合并后两处改动均合并保存 a B c D e如果一个分支改 b另一个改紧挨着的 c两个改动片段就贴在一起。Git将它们作为一个冲突区域处理。冲突也不只有同一行改成两个不同内容这一种情况常见情况需要决定什么双方修改同一处内容最终代码或文本是什么一边修改文件另一边删除文件保留修改后的文件还是删除两边新增同名文件内容不同采用哪份内容或如何整合两边对文件进行不兼容的重命名最终文件名和位置图片等二进制文件冲突选择哪一版或用对应软件重新制作因此有些冲突不会在文件中出现 标记。判断是否解决应以 git status 为入口。如果暂时不想处理且合并还没有提交可以执行下面的指令它会中止本次合并并尝试恢复合并前的状态。gitmerge--abort在日常开发中master分支为稳定版本开发工作应该在其他分支上进行。4、合并模式前面我们提到过合并模式Git的默认合并模式就是Fast-forward模式在ff模式下Git 不会创建新的合并提交。删除dev分支后提交记录仍然保留但历史呈现为一条直线无法仅凭提交历史区分哪些提交原本来自dev也看不出这次合并发生的位置。这和前面的提交状态图差不多不好区分。为了方便区分合并和提交我们可以使用no-ff模式。这和前面合并冲突解决后的状态图很像。no-ff表示禁用Fast-forward模式。在需要合入新历史时即使满足快进条件Git也会创建一个新的合并提交记录双方历史的汇合关系。可以使用 -m 参数指定这次合并的提交说明。gitmerge --no-ff-mmerge with no-ffdev这样做的好处是提交历史中会保留明确的合并记录。例如即使删除了之前创建的 dev1 分支仍然可以通过提交图中的分叉与合并关系看出这组改动是如何合入 master 的。还有ff-only和squash等模式可以自行查阅。我们推荐no-ff模式因为可以清晰区分该部分修改是谁做的方便追溯。五、删除分支dev分支作为临时分支它的修改被合并到master分支下此时dev分支就没有用了我们应该删除它。gitbranch-ddev⚠️ 删除某个分支则一定不能在当前待删除分支下必须切换到其他分支下。推荐完成某个任务在分支下完成合并后删除速度很快更安全。还有一种场景就是当前dev分支的修改提交确定不需要了使用上面的指令无法删除我们要强行删除应该使用下面的指令gitbranch-Ddev六、修复主分支BUG假设你正在dev分支上开发新功能突然发现主分支上有BUG需要修复此时我们应该再开一个临时分支进行BUG修复。那此时有一个问题我前面dev分支所做的工作怎么办1、保存工作现场我们可以使用如下指令将当前工作区的信息临时存起来以便后续恢复。gitstash存储好以后工作区就变干净了我们就可以切换回master分支创建新的临时分支进行BUG修改。stash可以理解为本地仓库中的临时工作储藏区git stash用于临时保存尚未提交的工作包括工作区和暂存区中的改动。它会把当前改动保存为一条本地快照记录并撤回未被保存的改动方便我们切换分支或处理其他任务。之后可以恢复这些改动继续开发。每次保存都会生成一条stash记录可以通过列表查看和管理。stash只可以存储已经被Git追踪管理的文件新创建未add的文件无法保存。要想同步保存则可以加上 -u 选项。2、恢复工作现场此时BUG修复好了我们重新切换回dev分支继续之前的开发。由于stash可以存储多个记录我们可以使用如下指令查看有哪些gitstash liststash{0}就是最新的stash记录。继续开发使用如下指令恢复工作区同时会删除stash记录gitstash popgitstash popstash{0}⚠️ 我们在恢复工作现场时一定要注意所处分支与stash记录的分支是否匹配。此时处于dev1分支但最新记录为dev2分支所保存直接恢复是把dev2的记录恢复到dev1分支上。如果不想恢复时就删除stash记录可以使用下面指令分别实现恢复现场和删除记录gitstash applygitstash drop 上述所有指令默认选择整个仓库中最新的那条即stash{0}都可以指定选择某个记录。3、恢复冲突BUG修复之后进行了一次合并提交此时master分支的最新提交已不再是新建dev时基于master分支的那次提交。直接将dev分支并入master可能会与fix_bug分支所修改的内容存在冲突。我们直接在master分支合并dev然后解决冲突吗这样做其实有个问题在实际开发中代码量都是很大的你不能保证你解决冲突一次就能对有可能最后提交的结果还有BUG。如果以这种方式来解决冲突本质上还是在master分支上工作。我们换个思路在dev分支上合并master分支解决冲突并测试无误之后再由master分支合并dev分支这样工作就切换到dev分支上不影响master分支。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询