【Git】 -- Part2 -- 分支管理

news2025/2/8 16:29:22

1. 分支

在 Git 中,分支(Branch)是用于在项目中创建独立开发线路的机制。分支使得开发者可以在不影响主干(main 或 master)的情况下进行实验、开发新功能或修复 Bug。

举个例子:
分⽀就好像是科幻电影⾥⾯的平⾏宇宙,当你正在电脑前努⼒学习 C++ 的时候,另⼀个你正在另⼀个平⾏宇宙⾥ 努⼒学习 Python。

如果两个平⾏宇宙互不⼲扰,那对现在的你也没啥影响。不过,在某个时间点,两个平⾏宇宙合并了,结果,你既学会了 C++ ⼜学会了 Python!
image.png
现实世界,在Git分支对应得就是主分支,而平行时间,在Git里面对应得就是新创建得另一个分支。

在Git中,每进行一次提交(commit操作),Git都把它们串成⼀条时间线,这条时间线就可以理解为是⼀个分⽀。如果只有一条分支,在Git里,这个分支就是主分支,即master分支。

image.png

而HEAD,HEAD 严格来说不是指向提交,⽽是指向master,master才是指向提交的,所以,HEAD 指向的就是当前分⽀。

每次提交,master分⽀都会向前移动⼀步,这样,随着你不断提交,master分⽀的线也越来越⻓,⽽ HEAD只要⼀直指向master分⽀即可指向当前分⽀
image.png

1.1 创建分支

Git ⽀持我们查看或创建其他分⽀,在这⾥我们来创建第⼀个⾃⼰的分⽀ dev ,对应的命令为:

git branch 分支名

使用示例

  • 创建dev分支
git branch dev

image.png
然后使用git branch可以查看所有分支。

image.png
当我们创建新的分⽀后,Git 新建了⼀个指针叫 dev, * 表⽰当前 HEAD 指向的分⽀是 master分⽀。另外,可以通过⽬录结构发现,新的 dev分⽀和 master 指向同⼀个提交。

image.png
图解:

image.png

1.2 切换分支

使用 git checkout 分支名 命令切换到指定分支。

使用示例

比如切换到dev分支。

git checkout dev

image.png
切换到dev分支后,就可以看到*在dev分支前,表明当前分支是dev分支。

切换分支后,HEAD就指向到切换得分支下面了。
image.png
可以使用cat .git/HEAD进行验证

image.png

切换分支后,在dev分支下进行操作,比如新建一个文件test.txt,然后向其进行随便写入一些东西。

写入完成后,在dev分支下面进行一次提交操作

git add .
git commit -m "dev commit tset"

image.png
提交完成后,切换到master分支下面

git checkout master

image.png
切换到master分支后,就发现test.txt文件不存在了。 然后继续切回到dev分支下,发现,在dev分支下,test.txt文件还存在的。

image.png
出现这个现象的原因就是:我们是在dev分⽀上提交的,⽽master分⽀此刻的提交点并没有变。
使用命令可以查看他们的指向是不同的:

image.png
图解如下:

image.png
当切换到 master 分⽀之时,HEAD 就指向了 master,自然就看不到test.txt文件了。

1.3 合并分支

为了在 master 主分⽀上能看到新的提交,就需要将 dev 分⽀合并到 master 分⽀。
使用git merge⽤于合并指定分⽀到当前分⽀。

使用案例

将dev分支合并到master分支下。

  1. 必须切换到master分支下进行合并
  2. 使用git merge dev将dev分支合并到master分支下。

image.png
此时 就能在master分支下看到test.txt文件了。

Fast-forward 代表“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度⾮常快。

image.png
图解:

image.png

1.4 删除分支

合并完成后, dev 分⽀对于我们来说就没⽤了, 那么dev分⽀就可以被删除掉。

注意:不能在dev分支下删除dev分支,也就是不能自杀。

删除分支的命令
git branch -d 分支名

使用案例

  • 删除dev分支
git branch -d dev

image.png
删除后的图解:

image.png

因为创建、合并和删除分⽀⾮常快,所以Git官方建议使⽤分⽀完成某个任务,合并后再删掉分⽀,这和 直接在master分⽀上⼯作效果是⼀样的,但过程更安全。

2. 冲突

可是,在实际分⽀合并的时候,并不是想合并就能合并成功的,有时候可能会遇到代码冲突的问题。

下面就演示一下这种场景:
先创建一个测试分支dev
使用git checkout -b dev创建切换分支。这个命令就是切换到dev分支,如果分支不存在,就创建。

image.png
在dev分支下,修改test.txt文件。向test.txt文件写入一行新文本modify by dev

image.png
在dev分支下进行提交。(先add添加,在使用commit进行提交)

image.png

切换到master分支下。

image.png
在master分支下,查看test.txt文件中的内容,此时是没有更新的。

在master分支下,也对test.txt文件中进行修改如下:

image.png

修改完成后,在master分支下进行提交。

image.png
现在,master和dev分支下都分别有了自己新的提交。图示如下:

image.png
在这种情况下,Git只能试图把各⾃的修改合并起来,但这种合并就可能会产生合并冲突。

在master分支下合并dev分支,下面这种情况就出现了合并冲突。
image.png
此时 查看test.txt文件中的内容就会看到,git会用指定的字符<<<<<<<,=======, >>>>>>> 来标记不同分支出现冲突的内容。如下:

image.png

2.1 合并冲突

当发生合并冲突的时候,就需要我们手动调整冲突的代码,保留需要的一部分,删除不需要的一部分。然后再次进行提交调整后的代码。(必须要再次提交)

image.png
此时,图示状态如下:

image.png
使用git log也能查看分支合并的情况。

git log --graph --pretty=oneline --abbrev-commit

image.png
合并完了,dev分支也就不用了,删除即可。使用git branch -d dev删除dev分支即可。

image.png

3. 分支管理策略

在合并分支的时候,Git一般会采用Fast forward模式,直接把master指向dev的当前提交。如果采用Fast forwrad模式后,形成的合并结果如下:

image.png
在这种 Fast forward 模式下,删除分⽀后,查看分⽀历史时,会丢掉分⽀信息,看不出来最新提 交到底是 merge 进来的还是正常提交的。

但在合并冲突部分,我们也看到通过解决冲突问题,会再进行⼀次新的提交,得到的最终状态为:
image.png
那么这就不是 Fast forward 模式了,这样的好处是,从分⽀历史上就可以看出分⽀信息。

Git ⽀持我们强制禁⽤ Fast forward 模式,那么就会在 merge 时⽣成⼀个新的 commit ,这样, 从分⽀历史上就可以看出分⽀信息。

使用示例 - 非Fast forward模式进行合并

1、创建一个新的dev分支,切换到新分支下。
git checkout -b dev

image.png

2、修改test.cc,并提交⼀个新的 commit

image.png
3、切换到master分支,开始合并。

image.png

–no-ff 参数,表⽰禁⽤ Fast forward 模式。禁⽤ Fast forward 模式后合并会创建 ⼀个新的 commit ,所以加上 -m 参数,把描述写进去。

4、合并后,查看历史分支日志

image.png
这样,在合并分支的时候,加上 --no-ff 参数就可以⽤普通模式合并,合并后的历史有分⽀,能看出来曾 经做过合并,⽽ Fast Forward 合并就看不出来曾经做过合并。

3.1 分支策略

在实际开发中,应该按照以下⼏个基本原则进⾏分⽀管理:

  • ⾸先,master分⽀应该是⾮常稳定的,也就是仅⽤来发布新版本,平时不能在上⾯⼲活;
  • ⼲活都在dev分⽀上,也就是说,dev分⽀是不稳定的,到某个时候,⽐如1.0版本发布 时,再把dev分⽀合并到master上,在master分⽀发布1.0版本
  • 团队里每个⼈都在dev分⽀上⼲活,每个⼈都有⾃⼰的分⽀,时不时地往dev分⽀上合并就 可以了。
  • 团队合作的分支看起来就像下图一样:

image.png

4. Bug分支

假如我们现在正在 dev 分⽀上进⾏开发,开发到⼀半,突然发现 master 分⽀上⾯有 bug,需要解决。在Git中,每个bug都可以通过⼀个新的临时分⽀来修复,修复后,合并分⽀,然后将临时分⽀删除。

可现在 dev分支的代码在⼯作区中开发了⼀半,还⽆法提交。比如下面这种情况:

image.png

针对这种情况,Git 提供了git stash命令。可以将工作区的信息进行储藏,,被储藏的内容可以在将来某个时间恢复出来。比如在dev分支下,将当前的工作区进行储藏。

image.png

储藏之后,查看工作区的状态就是干净的了。

image.png

储藏dev分支后,就要对master分支下的bug进行修复了。所以需要切回到master分支下。在创建临时分支修复bug。

image.png
修复完bug后,在dev分支下 重新add commit。

image.png
然后切换到master分支下,完成合并。最后删除bug分支即可。

image.png

至此,bug修复的工作已经完成,继续回到dev分支下进行开发。首先切换到dev分支下。
由于修复bug之前,将dev分支下的工作区代码进行储藏了,现在就要对其进行恢复了。

image.png
使⽤ git stash pop 命令进行恢复,恢复的同时会把 stash 也删了。

image.png

这样,dev分支下的工作区就之前的写的代码就被恢复了。

image.png

恢复现场也可以采⽤ git stash apply 恢复,但是恢复后,stash内容并不删除,需要⽤ git stash drop 来删除。

也可以多次stash,恢复的时候,先⽤ git stash list 查看,然后恢复指定的stash,⽤命令 git stash apply stash@{0}。

恢复完代码后,就可以继续完成开发了,开发完成后进行提交即可。

image.png
但是,在dev分支下,修复bug的内容,并没有在dev分支下显示,此时的状态图如下:

image.png
现在要切换到master分支下合并dev分支。正常情况下,切回到master分支下,直接合并即可。但这样其实是有⼀定⻛险的。

是因为在合并分⽀时可能会有冲突,⽽代码冲突需要我们⼿动解决(在 master 上解决)。我们⽆法 保证对于冲突问题可以正确地⼀次性解决掉,因为在实际的项⽬中,代码冲突不只⼀两⾏那么简单, 有可能⼏⼗上百⾏,甚⾄更多,解决的过程中难免⼿误出错,导致错误的代码被合并到 master 上。 此时的状态为:

image.png

解决这个问题的⼀个好的建议就是:最好在⾃⼰的分⽀上合并下 master ,再让 master 去合并 dev ,这样做的⽬的是有冲突可以在本地分⽀解决并进⾏测试,⽽不影响 master 。此时的状态为:

image.png
dev分支下合并master,就算合并有问题,也可以在dev分支下进行多次修改测试,不会影响master分支下的代码。

然后再去master分支下去合并dev分支。此时冲突在dev分支下已经解决了,在master分支下进行合并就无需解决冲突了~。

image.png
实操如下:

image.png

image.png

5. 删除临时分支

添加⼀个新功能时,你肯定不希望因为⼀些实验性质的代码,把主分⽀搞乱了,所以,每添加⼀个新功能,最好新建⼀个分⽀,我们可以将其称之为 feature 分⽀,在上⾯开发,完成后,合并,最后,删除该 feature 分⽀。

可是,如果我们今天正在某个 feature 分⽀上开发了⼀半,被产品经理突然叫停,说是要停⽌新功能的开发。虽然⽩⼲了,但是这个 feature 分⽀还是必须就地销毁,留着⽆⽤了。这时使⽤传统 的 git branch -d命令删除分⽀的⽅法是不⾏的。

比如:在新的feature分支下开发新功能。

image.png
此时新功能被叫停,切回master分支准备删除feature分支。

image.png

根据提示也可以看到,要使用-D选项进行删除。

image.png

6. 总结

⽀在实际中有什么⽤呢?

  • 你准备开发⼀个新功能,但是需要两周才能完成,第⼀周你写了50% 的代码,如果⽴刻提交,由于代码还没写完,不完整的代码库会导致别⼈不能⼲活了。
  • 如果等代码全部写完再⼀次提交,⼜存在丢失每天进度的巨⼤⻛险。
  • 现在有了分⽀,就不⽤怕了。你创建了⼀个属于你⾃⼰的分⽀,别⼈看不到,还继续在原来的分⽀上正常⼯作,⽽你在⾃⼰的分⽀上⼲活,想提交就提交,直到开发完毕后,再⼀次性合并到原来的分⽀ 上,这样,既安全,⼜不影响别⼈⼯作。
  • 并且 Git ⽆论创建、切换和删除分⽀,Git在1秒钟之内就能完成!⽆论你的版本库是1个⽂件还是1万个⽂件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1850713.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件开发教学:在线教育系统源码解析及教育培训小程序搭建实战

本篇文章&#xff0c;笔者将以“从零开始的软件开发教学”为主题&#xff0c;详细解析在线教育系统的源码&#xff0c;并通过实际操作来搭建一个教育培训小程序。 一、在线教育系统概述 在线教育系统是一个综合性的网络平台&#xff0c;旨在通过互联网提供教育资源和服务。该系…

http和https的区别在哪

HTTP&#xff08;超文本传输协议&#xff09;和HTTPS&#xff08;超文本传输安全协议&#xff09;之间存在几个关键区别主要涉及安全性、端口、成本、加密方式、搜索引擎优化&#xff08;SEO&#xff09;、身份验证等方面 1、安全性&#xff1a;HTTP&#xff08;超文本传输协议…

Day5(和为s的两个数字)双指针

输入一个递增排序的数组和一个数字s&#xff0c;在数组中查找两个数&#xff0c;使得它们的和正好是s。如果有多对数字的和等于s&#xff0c;则输出任意一对即可。 二、思路 1.首先&#xff0c;将不符合要求的值给排除&#xff0c;有以下三种&#xff1a; 数组元素个数不足两个…

ArrayList知识点(面试)

上一篇我们说了hashmap的相关知识点&#xff0c;这一篇我们再说一些ArrayList的相关知识&#xff0c;因为ArrayList也是我们项目中比较常用的。 ArrayList(底层是数组) 底层工作原理 首先&#xff0c;在构造ArrayList的时候会先看有没有指定容量&#xff0c;如果没有&#xf…

Flutter【组件】可折叠文本组件

简介 flutter 可折叠文本组件。 点击展开&#xff0c;收起折叠文本。支持样式自定义 github地址&#xff1a; github.com/ThinkerJack… pub地址&#xff1a;https://pub.dev/packages/jac_uikit 展开收起文本 使用方式&#xff1a; ExpandableText(content: 测试 * 50,ma…

一文搞懂Linux信号【下】

目录 &#x1f6a9;引言 &#x1f6a9;阻塞信号 &#x1f6a9;信号保存 &#x1f6a9;信号捕捉 &#x1f6a9;操作信号集 1.信号集操作函数 2.其它操作函数 &#x1f6a9;总结&#xff1a; &#x1f6a9;引言 在观看本博客之前&#xff0c;建议大家先看一文搞懂Linux信…

JR-8000系列机架式多路4K超高清光端机

集中式 4K超高清光传输设备 1 产品特性 ⚫ 支持高达 8 通道 SMPTE 全格式 SDI 信号输入 ⚫ 发送端带有 LOOPOUT 环出端口&#xff0c;具备消抖动功能&#xff0c;可作为信号调理或级联信号源使用 ⚫ 接收端支持双输出端口 ⚫ 支持传输速率&#xff1a;143Mbps-11.88Gbps ⚫…

INVS利用gatearray实现post-mask的function ECO

随着现代IC的设计发展&#xff0c;设计的规模和复杂度逐步增加&#xff0c;对于验证完备性的挑战越来越大&#xff0c;加之TO的时间压力&#xff0c;芯片设计通常会出现下列的场景&#xff1a; 芯片回片一次点亮大部分的case都可以顺利通过小部分的功能需要修正 对于重要的特…

赵丽颖纯白茉莉绽放温柔之美

赵丽颖纯白茉莉&#xff0c;绽放温柔之美在这个繁忙喧嚣的娱乐圈&#xff0c;赵丽颖以其独特的魅力&#xff0c;成为了无数人心中的白月光。近日&#xff0c;赵丽颖工作室发布了一组live图&#xff0c;她身着一袭温柔白裙&#xff0c;宛如一朵盛开的纯白茉莉花&#xff0c;美得…

企业级WordPress开发 – 创建企业级网站的优秀技巧

目录 1 “企业级”一词是什么意思&#xff1f; 2 使用 WordPress 进行企业级 Web 开发有哪些好处&#xff1f; 3 使用 WordPress 进行企业级开发的主要好处 3.1 WordPress 可扩展、灵活且价格实惠 3.2 WordPress 提供响应式 Web 开发 3.3 WordPress 提供巨大的可扩展…

github-chinese,跟英文GitHub说拜拜

背景 对于我们程序员来说,Github是一个常逛的web网站,里面学习资源众多,不管是查问题还是查资料都离不开他。 但是Github作为一个国际化的网站,语言主要是英语,所以对于一些英语似懂非懂的同学来说还是有一些难处。 想过找一个国内中文的Github作为一个平替网站,但是资…

Linux基础指令(三)

目录 shell 权限指令&#xff1a; 文件的操作权限&#xff1a; 对文件进行操作的用户分类&#xff1a; 用户对文件进行的操作分类&#xff1a; 所有者、所属组、其他的访问权限&#xff1a; 创建用户 沾滞位 匹配查找指令&#xff1a; grep find shell shell&#x…

联想Y7000P 2023款拆机教程及升级内存教程

0.电脑参数介绍 联想Y7000P 2023电脑&#xff0c;笔者电脑CPU为i7-13700H&#xff0c;14核20线程&#xff1b;标配内存为三星的DDR5-5600MHz-8GB*2&#xff0c;由于电脑CPU限制&#xff0c;实际内存跑的频率为5200MHz; 2个内存插槽&#xff0c;2个固态硬盘插槽。每个内存插槽最…

Linux检查端口nmap

yum install -y nmap # 查看本机在运行的服务的端口号 nmap 127.0.0.1 补充&#xff1a;netstat netstat -tunlp | grep 3306

堆排序的实现原理

一、什么是堆排序&#xff1f; 堆排序就是将待排序元素以一种特定树的结构组合在一起&#xff0c;这种结构被称为堆。 堆又分为大根堆和小根堆&#xff0c;所谓大根堆即为所有的父节点均大于子节点&#xff0c;但兄弟节点之间却没有什么严格的限制&#xff0c;小根堆恰恰相反&a…

百度ai人脸识别项目C#

一、项目描述 本项目通过集成百度AI人脸识别API&#xff0c;实现了人脸检测和识别功能。用户可以上传图片&#xff0c;系统将自动识别人脸并返回识别结果。 二、开发环境 Visual Studio 2019或更高版本.NET Framework 4.7.2或更高版本AForge.NET库百度AI平台人脸识别API 三、…

09--keepalived高可用集群

前言&#xff1a;高可用集群配置是大型网站的一个基础&#xff0c;网站可用性的基础保障之一&#xff0c;这里将对应的概念知识和实操步骤进行整理与收集。 1、基础概念详解 1.1、高可用集群 高可用集群&#xff08;High Availability Cluster&#xff0c;简称HA Cluster&am…

已解决java.security.acl.AclNotFoundException异常的正确解决方法,亲测有效!!!

已解决java.security.acl.AclNotFoundException异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 出现问题的场景 报错原因 解决思路 解决方法 分析错误日志 检查ACL文件路径和名称 确认系统权限 修改代码逻辑 确保ACL文…

什么是微分和导数?

文章目录 设立问题微分特性指数特性线性特性常数特性 多项式微分导数 在机器学习领域&#xff0c;有多种解决最优化问题的方法&#xff0c;其中之一就是使用微分。 通过微分&#xff0c;可以得知函数在某个点的斜率&#xff0c;也可以了解函数在瞬间的变化。 设立问题 请想象一…

C++/Qt 小知识记录7

工作中遇到的一些小问题&#xff0c;总结的小知识记录&#xff1a;C/Qt 小知识7 编译FFMPEG遇到的问题CMakeLists.txt配置FFMPEG的依赖方式&#xff1a; x264在Windows下编译生成*.libVS编译Qt工程时&#xff0c;遇到提示Change Qt Version的情况在QtOsg的窗口上嵌入子窗口&…