git分支管理策略

git的基础操作以及常用命令在上篇博客哦~
git原理与基本使用

1.分支管理

1.主分支

版本回退⾥,我们已经知道,每次提交,Git都把它们串成⼀条时间线这条时间线就可以理解为是⼀个分⽀。截⽌到⽬前,只有⼀条时间线,在Git⾥,这个分⽀叫主分⽀,即 master 分⽀
HEAD 严格来说不是指向提交,⽽是指向mastermaster才是指向提交的,所以,HEAD 指向的就是当前分⽀
在这里插入图片描述
在这里插入图片描述
主线可以理解为master主分支,根据master就可以获得这条时间线
既然存在主分支,那么是不是也存在其他的分支,就像下面这样:
在这里插入图片描述

2.分支管理命令

1.查看当前本地所有分支

# 查看当前本地所有分支
git branch

创建本地仓库会创建一个master分支,此时HEAD默认指向master分支,但是HEAD并非只能指向master分支
HEAD可以指向任意分支,HEAD所指的分支才是当前的工作分支
在这里插入图片描述

2.创建分支

# 新建一个dev分支
git branch [分支名]

在这里插入图片描述
在这里插入图片描述
dev指向最新提交,是因为dev是在当前版本上创建的分支

3.将HEAD指向指定分支

# 切换HEAD指针到指定分支
git checkout [分支名]
# 查看当前HEAD所指分支
git branch

在这里插入图片描述
此时就如下图所示
在这里插入图片描述

4.在分支上修改文件并将其提交至版本库

# 修改ReadeMe文件
vim Reade
# 保存并推出
:wq
# 提交至暂存区
git add ReadeMe
# 提交至版本库
git commit -m"在dev上的commit"
# 此时切换回master分支
git checkout master
# 查看当前所指分支
git branch
# 查看ReadeMe文件
cat ReadeMe
// 此时发现在dev分支上添加的代码不见了
# 切换回dev分支
git checkout dev
# 重新查看ReadeMe文件
cat ReadeMe
// 此时发现修改的文件又回来了,那么这是因为什么呢?

因为我们是在dev分⽀上提交的,⽽master分⽀此刻的提交点并没有变,查看.git文件中的Head指向就可以发现master分支依然指向之前HEAD指向master时的最新版本,如下图所示
在这里插入图片描述

5.合并分支

为了在 master 主分⽀上能看到新的提交,就需要将 dev 分⽀合并到 master 分⽀

# 将HEAD指向master分支
git checkout master
# 在master分支下合并分支dev
git merge dev
# 在master分支下查看ReadeMe文件
cat ReadeMe
// 此时发现可以看见最新的修改了

Fast-forward 代表“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度⾮常快
当然,也不是每次合并都能 Fast-forward,我们后⾯会讲其他⽅式的合并

在这里插入图片描述
合并后,master 就能看到 dev 分⽀提交的内容了,此时的状态如图如下所⽰
在这里插入图片描述

6.删除分支

合并完成后, dev 分⽀对于我们来说就没⽤了, 那么dev分⽀就可以被删除掉,注意如果当前正处于某分⽀下,就不能删除当前分⽀

# 切换当前HEAD指向master分支
git checkout master
# 在master分支上删除dev分支
git branch -d dev
# 查看当前所有分支
git branch
// 此时就只剩下master分支了

此时的状态如图如下所⽰:
在这里插入图片描述
因为创建、合并和删除分⽀⾮常快,所以Git⿎励你使⽤分⽀完成某个任务,合并后再删掉分⽀,这和直接在master分⽀上⼯作效果是⼀样的,但过程更安全

7.分支冲突

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

我们按照下面的步骤进行操作:

# 创建本地分支dev1
git branch dev1
# 切换dev1分支
git checkout dev1
# 上面两行操作可以合并成一个,创建并且切换分支
git checkout -b dev1
# 修改ReadeMe文件为dev1
vim ReadeMe
# 将ReadeMe文件提交至暂存区
git add ReadeMe
# 将ReadeMe文件提交至版本库
git commit -m"在dev1中修改ReadeMe为dev1dev1"
# 此时切换为master分支
git checkout master
# 在master分支下修改ReadeMe文件为master
vim ReadeMe
# 将ReadeMe文件提交至暂存区
git add ReadeMe
# 将ReadeMe文件提交至版本库
git commit -m"在master中修改ReadeMe为master"

此时状态如下图所示:
在这里插入图片描述

# 现在我们合并的时候git就没办法知晓我们到底需要保存哪个版本的文件,就会发生合并冲突
git merge dev1 

这种情况下,Git 只能试图把各⾃的修改合并起来,但这种合并就可能会有冲突,就像下面这样:
在这里插入图片描述
此时我们查看ReadeMe文件就会发现:
在这里插入图片描述

8.手动解决冲突

# 打开ReadeMe文件,手动修复文件
vim ReadeMe
# 将ReadeMe文件提交至暂存区
git add ReadeMe
# 将ReadeMe文件提交至版本库
git commit -m"在master中修改ReadeMe为master"

(不要忘了提交哦!!!)到这⾥冲突就解决完成,此时的状态变成了
在这里插入图片描述最后,不要忘记 dev1 分⽀使⽤完毕后就可以删除了:

# 在master分支上删除dev1分支
git branch -d dev1

9.git log参数意义

# 查看历史提交日志
# --graph 图示的意思
# --abbrev-commit 将commit id缩写
git log --graph --abbrev-commit

在这里插入图片描述

10.分⽀管理策略

通常合并分⽀时,如果可能,Git 会采⽤ Fast forward 模式。还记得如果我们采⽤ Fast forward 模式之后,形成的合并结果是什么呢?回顾⼀下:
在这里插入图片描述
在这种 Fast forward 模式下,删除分⽀后,查看分⽀历史时,会丢掉分⽀信息,看不出来最新提交到底是 merge 进来的还是正常提交


但在合并冲突部分,我们也看到通过解决冲突问题,会再进⾏⼀次新的提交,得到的最终状态为:
在这里插入图片描述
那么这就不是 Fast forward 模式了,这样的好处是,从分⽀历史上就可以看出分⽀信息。例如我们现在已经删除了在合并冲突部分创建的 dev 分⽀,但依旧能看到 master 其实是由其他分⽀合并得到:

11.不使用Fast forward进行合并(建议使用)

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

# --no--ff 不使用Fast forward进行合并
# -m"" 并且进行提交
git merge --no-ff -m"提交时的信息" [需要合并的分支]

可以看到,不使⽤ Fast forward 模式,merge后就像下图这样:
在这里插入图片描述
所以在合并分⽀时,加上 --no-ff 参数就可以⽤普通模式合并,合并后的历史有分⽀,能看出来曾经做过合并,⽽ fast forward 合并就看不出来曾经做过合并

2.分⽀策略

1.团队合作分支管理

在这里插入图片描述
在实际开发中,我们应该按照⼏个基本原则进⾏分⽀管理
⾸先,master分⽀应该是⾮常稳定的,也就是仅⽤来发布新版本,平时不能在上⾯⼲活
那在哪⼲活呢?
⼲活都在dev分⽀上,也就是说,dev分⽀是不稳定的,到某个时候,⽐如1.0版本发布时,再把dev分⽀合并到master上,在master分⽀发布1.0版本;
你和你的⼩伙伴们每个⼈都在dev分⽀上⼲活,每个⼈都有⾃⼰的分⽀,时不时地往dev分⽀上合并就可以了。
所以,团队合作的分⽀看起来就像这样:
在这里插入图片描述

2.bug 分⽀

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

可现在 dev2 的代码在⼯作区中开发了⼀半,还⽆法提交,怎么办?
在这里插入图片描述

# 切换到dev2分支上
git checkout dev2
# 在dev2分支上开发代码
vim ReadeMe
# 切换到master分支
git checkout master
# 查看ReadeMe文件
cat ReadeMe

此时我们发现master分支上可以看见dev2分支对ReadeMe文件的修改
因为是在工作区中查看,并且master和dev2指向同一个版本

但是我们不想让dev2影响到master分支,应该怎么办呢?

3.将工作区中的信息进行储藏

Git 提供了 git stash 命令,可以将当前的⼯作区信息进⾏储藏,被储藏的内容可以在将来某个时间恢复出来

# 切换到dev2分支
git checkout dev2
# 将dev2工作区中的内容保存
git stash
# 查看工作区状态
git status

在这里插入图片描述

储藏 dev2 ⼯作区之后,由于我们要基于master分⽀修复 bug,所以需要切回 master 分⽀,再新建临时分⽀来修复 bug

# 切换到master分支
git checkout master
# 创建并切换分支
git checkout -b fix_bug
# 修复BUG
vim ReadeMe
# 别忘记add以及commit
git add ReadeMe
git connit -m"修复BUG版本"
# 切换回master
git checkout master
# 不使用fast合并分支
git merge --no-ff -m"修复bug" fix_bug
# 查看ReadeMe
cat ReadeMe
# 删除分支
git branch -d fix_bug
# 切换回dev2分支
git checkout dev2
# 查看文件
cat ReadeMe

⼯作区是⼲净的,刚才的⼯作现场存到哪去了?⽤ git stash list 命令看看:

# 查看存储区
git stash list

⼯作现场还在,Git 把 stash 内容存在某个地⽅了,但是需要恢复⼀下,如何恢复现场呢?我们可以使⽤ git stash pop 命令,恢复的同时会把 stash 也删了

4.恢复存储区的代码

# 恢复存储区的代码
git stash pop

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

但我们注意到了,修复 bug 的内容,并没有在 dev2 上显⽰。此时的状态图为
在这里插入图片描述

Master 分⽀⽬前最新的提交,是要领先于新建 dev2 时基于的 master 分⽀的提交的,所以我们在 dev2 中当然看不⻅修复 bug 的相关代码

我们的最终⽬的是要让 master 合并 dev2 分⽀的,那么正常情况下我们切回 master 分⽀直接合并即可,但这样其实是有⼀定⻛险

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

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

5.修复bug流程

# 将dev2上的代码进行存储
git stash
# 切换到master分支
git checkout branch
# 新建一个修复bug的分支,并切换到bug分支上
git checkout -b fix_bug
# 在bug分支上修复bug
vim ReadeMe
# 别忘记add和commit
git add ReadeMe
git commit -m"修复bug"
# 切换回master分支
git checkout master
# 不使用master合并修复bug的分支
git merge --no-ff -m"合并bug分支" fix_bug
# bug修复完成,删除fix_bug分支
git branch -d fix_bug
# 回到dev2工作分支
git checkout dev2
# 恢复存储
git stash pop
# 开发完成进行提交
git add ReadeMe
git commit -m"在dev2上开发完成ReadeMe"
# 在dev2分支合并master
git merge --no-ff -m"在dev2分支上合并master" master
# 切换到master
git checkout master
# 在master分支上合并dev2
git merge --no-ff -m"在master分支上合并dev2" dev2
# bug修复彻底完成

6.删除临时分⽀

在这里插入图片描述

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

# 强制删除分支
git branch -D [分支名]

7.总结:分支的作用

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

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

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

相关文章

C++ 滑翔翼

小T和小K都是OIER,入选省队后有幸去苏州参加JSOI集训,训练之余,他们相约一起去苏州乐园玩。 苏州乐园里有一个非常热门的游乐项目叫双人滑翔翼。小T想和小K一起乘双人滑翔翼,但是排在他们前面的一大群人却为了搭配问题而争执不休&…

【go】切片截取总结

文章目录 1.获取切片的第i个元素2.获取切片的第i个至第j个元素3.各种切片截取操作 1.获取切片的第i个元素 func main() {s : []int{1, 2, 3, 4, 5}fmt.Println("第一个元素为:", s[0])fmt.Println("最后一个元素为:", s[len(s)-1])…

aws的s3匿名公开访问

点击桶权限 ,添加策略 {"Version": "2012-10-17","Statement": [{"Sid": "AddPerm","Effect": "Allow","Principal": "*","Action": "s3:GetObject&qu…

Docker原理详细剖析-Namespace

一、简介 docker容器技术从2013年开始火了以后,2014年左右当时有幸在学校能和学院教授一起做些项目以及学习。其中docker技术在当时来说还算是比较新的技术,国内关于这块的资料以及使用也才刚刚开始,讨论docker技术,算是相对时髦的…

mysql表锁死怎么办?事务锁sql超时被锁死怎么办?

不要慌!不要慌!两句命令教你做人 一、mysql表锁死 1、查询所有进程: SHOW PROCESSLIST; 2、找到进程号kill掉 kill 3269987 2、事务锁 sql超时被锁死 1、查询所有执行中的sql select t.*,to_seconds(now())-to_seconds(t.trx_started) id…

智能手表:华米稳、华为猛

随着科技的进步与发展,消费电子产品的功能和品类越来越丰富,人们也愈发习惯使用消费电子产品了。消费电子产品一词听起来陌生,实际上却离人们很近,比如智能手机、笔记本电脑等等,都属于消费电子产品。现如今&#xff0…

SQL存储过程中 SET ANSI_NULLS ON 和 SET QUOTED_IDENTIFIER ON的作用和详解

今天在写SQL Server存储过程中遇到的,做个整理归纳 USE [ABInbevDB] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO实际上,我们在创建存储过程的时候,这几行的代码是会自动创建出来的,那么先解释下两个标准的概念。 两个…

【办公自动化】使用Python批量处理Excel文件并转为csv文件

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…

C++ Qt 中QMimeDatabase类详细介绍以及应用场景

C Qt 中QMimeDatabase类详细介绍以及应用场景 文章目录 C Qt 中QMimeDatabase类详细介绍以及应用场景一、QMimeDatabase类是什么?二、QMimeDatabase类中的关键功能和特点三、QMimeDatabase的用法四、QMimeDatabase的应用场景 一、QMimeDatabase类是什么?…

Hbase文档--架构体系

阿丹: 基础概念了解之后了解目标知识的架构体系,就能事半功倍。 架构体系 关键组件介绍: HBase – Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起…

WordArt Designer:基于用户驱动与大语言模型的艺术字生成

AIGC推荐 FaceChain人物写真开源项目,支持风格与穿着自定义,登顶github趋势榜首! 前言 本文介绍了一个基于用户驱动,依赖于大型语言模型(LLMs)的艺术字生成框架,WordArt Designer。 该系统包含四个关键模块:LLM引擎、…

19.CSS雨云动画特效

效果 源码 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Cloud & Rain Animation</title><link rel="stylesheet" href="style.css"> </head> <bo…

数字证书有什么作用,为什么要用数字证书?

数字证书是一种用于加密和验证数据的安全工具&#xff0c;它在现代通信和互联网领域起着重要的作用。下面安策给大家介绍一下数字证书的几个主要作用和为什么要使用数字证书的原因&#xff1a; 身份认证&#xff1a;数字证书可用于在线交互中验证身份。通过使用证书进行身份认证…

VB房屋租凭管理系统设计与实现

摘要 随着我国市场经济的快速发展和人们生活水平的不断提高,简单的租凭服务已经不能满足人们的需求。如何利用先进的管理手段,提高房屋租凭管理水平,是当今社会所面临的一个重要课题。本文通过用VB6.0编写房屋租赁管理系统,利用软件工程原理,采用面向对象的编程方法,其开…

【LeetCode】394.字符串解码

题目 给定一个经过编码的字符串&#xff0c;返回它解码后的字符串。 编码规则为: k[encoded_string]&#xff0c;表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的&#xff1b;输入字符串中没有额外的空格&#x…

在 Spring Boot 中集成 MinIO 对象存储

MinIO 是一个开源的对象存储服务器&#xff0c;专注于高性能、分布式和兼容S3 API的存储解决方案。本文将介绍如何在 Spring Boot 应用程序中集成 MinIO&#xff0c;以便您可以轻松地将对象存储集成到您的应用中。 安装minio 拉取 minio Docker镜像 docker pull minio/minio创…

GEE/PIE遥感大数据处理与典型案例丨数据整合Reduce、云端数据可视化、数据导入导出及资产管理、机器学习算法等

目录 ​专题一&#xff1a;初识GEE和PIE遥感云平台 专题二&#xff1a;GEE和PIE影像大数据处理基础 专题三&#xff1a;数据整合Reduce 专题四&#xff1a;云端数据可视化 专题五&#xff1a;数据导入导出及资产管理 专题六&#xff1a;机器学习算法 专题七&#xff1a;…

适配器设计模式

目录 一、适配器模式1.类适配器模式2.对象适配器模式3.接口适配器 二、适配器模式应用场景三、适配器模式的优缺点 一、适配器模式 B站&#xff1a;java架构师 定义&#xff1a;适配器模式把一个类的接口变换成客户端所期待的另一种接口&#xff0c;从而使原本因接口不匹配而…

vue 孙组件给爷组件传递数据,本质层层传递

1 子传父 例子 vue 子组件 emit传递事件和事件数据给父组件_tenc1239的博客-CSDN博客 2 子传父 父传爷 层层套娃1中例子 2.1 定义传递事件 传值data // 孙组件 methods: {sendDataToGrandpa() {const data hello;this.$emit(sendDataToGrandpa, data);} } 2.2 中间父组件…

C# Unity 一个Key对应多个值的字典

C# Unity 一个Key对应多个值的字典 1.目的 C# 中没有提供一个Key对应多个值的容器&#xff0c;需要自己封装一层&#xff0c;实现方式很多&#xff0c;可以使用链表去实现&#xff08;分区域划分一个链表即可&#xff09;但是这样做比较复杂但是频繁插入要比使用List性能好一…