【Git】分支管理

server/2024/9/22 16:32:42/
http://www.w3.org/2000/svg" style="display: none;">

本篇博客的环境为 Ubuntu/linux

文章目录

  • 前言
  • 分支基础操作
    • 创建分支
    • 切换分支
    • 合并分支
    • 删除分支
  • 合并冲突
  • 分支管理策略
  • 分支策略
  • bug 分支

前言

在 Git 中,分支(branch)是一个独立的开发线路。允许在不影响主线(通常是mainmaster分支)的情况下进行修改和开发
主线就是实际发布的版本,但一个项目可能需要更新迭代,开发新功能或者维护修bug,所以肯定会基于主线进行修改,但又不可能让用户使用还在开发的,不完全的版本,分支就可以解决这样并发开发的问题,当分支完成开发后,再合并到主线中。
.git目录结构中,HEAD指向当前分支,而master指向主分支的最近一次提交的commit id

分支可以理解为一条时间线,每一次提交都是一个时间点
https://i-blog.csdnimg.cn/direct/77cbce54a7f44552b934291ff5f35518.png" alt="在这里插入图片描述" />
如图,随着不断地提交,master分支都会向前移动一步,分支的线也会越来越长,而HEAD指向master分支,即当前分支

分支基础操作

创建分支

创建分支的命令为:

git branch [分支名]

查看有哪些本地分支

git branch

示例:

ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git branch
* master
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git branch dev
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git branchdev
* master

*的表示当前处于该分支,即HEAD指向的分支
新创建的分支都是基于当前的master分支

ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ ls .git/refs/heads/
dev  master
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat .git/refs/heads/*
eac56023195eaf5a3dad49e7d60f93cd2c4e6f6e
eac56023195eaf5a3dad49e7d60f93cd2c4e6f6e

可以看到devmaster都指向最新一次提交的commit id
https://i-blog.csdnimg.cn/direct/d2736fde9e48454894959a6942514191.png" alt="在这里插入图片描述" />

切换分支

切换分支命令如下:

git checkout [分支名]
git checkout -b [分支名] #创建分支并切换

示例:

ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git checkout dev
Switched to branch 'dev'
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git branch
* devmaster
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat .git/HEAD 
ref: refs/heads/dev

可以看到HEAD已经指向了dev分支
https://i-blog.csdnimg.cn/direct/3a5cf6a945654202a7569ffbca000be5.png" alt="在这里插入图片描述" />


接下来在dev分支下进行修改,并提交

ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ vim ReadMe 
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat ReadMe 
hello git
i am coding
i am coding
i am coding
coding on dev branch
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git add .
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git commit -m "md ReadMe:coding on dev branch"
[dev c8acfad] md ReadMe:coding on dev branch1 file changed, 1 insertion(+)
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git checkout master 
Switched to branch 'master'
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat ReadMe 
hello git
i am coding
i am coding
i am coding

我们会发现,在dev分支上提交的内容无法在master分支上观察到,这是因为二者指向的提交已经不一样了

ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat .git/refs/heads/dev
c8acfad3696bb5a7dd1a1cd11a2facb9e6bd4bda
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat .git/refs/heads/master 
eac56023195eaf5a3dad49e7d60f93cd2c4e6f6e

https://i-blog.csdnimg.cn/direct/8148798b24a44e888a52004ecd9e7912.png" alt="在这里插入图片描述" />
因为matser还指向原先的提交点,所以查看的也是之前的版本

合并分支

dev分支完成开发后,就需要将内容合并到master分支上,合并的命令如下:

git merge [分支]

使用该命令,就是将指定分支的提交内容合并到当前分支
示例:

ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git checkout master
Already on 'master'
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git merge dev
Updating eac5602..c8acfad
Fast-forwardReadMe | 1 +1 file changed, 1 insertion(+)
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat ReadMe 
hello git
i am coding
i am coding
i am coding
coding on dev branch

Fast-forward代表快进模式,也就是直接把master指向dev的当前提交,所以合并速度很快,还有其他模式的合并方式,后续讲解
https://i-blog.csdnimg.cn/direct/d23c616b8325482d97a3e0e4389250f9.png" alt="在这里插入图片描述" />

删除分支

当一个分支完成开发,master分支也将其内容合并后,该分支的任务就完成了,那么可以将该分支删除,减少分支数,便于管理。
注意如果处于某分支下,是不能删除当前分支的
删除分支的命令如下:

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

示例:

ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git branch -d dev
Deleted branch dev (was c8acfad).
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git branch
* master

此时状态图如下:
https://i-blog.csdnimg.cn/direct/4396a5e820ed4d6e8c02bf2dd34c196f.png" alt="在这里插入图片描述" />
因为创建、合并和删除分支都很快,所以 Git 鼓励使用使用分支完成某个任务,并合并后删除分支,这和直接在master分支上工作效果一样,但过程更安全

可能会出现分支还没合并到主分支,但该分支开发内容被弃用的情况,-d删除该分支会提示分支未合并
此时需要使用-D选项强制删除

合并冲突

在实际开发中,可能存在很多分支
https://i-blog.csdnimg.cn/direct/7ba65c9927994e268d853176faec2ce4.png" alt="在这里插入图片描述" />
如图,dev1dev2基于同一个master主支线的提交进行后续开发,dev1先完成开发,并合并进了master。此时master的内容已经和dev2保存的不同,此时合并就会出现合并冲突,Git 不知道要保留哪些代码

示例:

  1. 创建dev分支完成开发
#查看ReadMe内容
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat ReadMe
hello git
#创建并切换分支
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git checkout -b dev
Switched to a new branch 'dev'
#完成开发并提交
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ vim ReadMe 
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat ReadMe 
hello git
dev branch coding...
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git add .
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git commit -m "md ReadMe:dev branch coding"
[dev 0e0b57d] md ReadMe:dev branch coding1 file changed, 1 insertion(+)
  1. master 也同步进行开发
#切换回master分支
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git checkout master 
Switched to branch 'master'
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat ReadMe 
hello git
#完成开发并提交
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ vim ReadMe 
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat ReadMe 
hello git
master branch coding...
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git add .
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git commit -m "md ReadMe:master branch coding"
[master e0afb54] md ReadMe:master branch coding1 file changed, 1 insertion(+)

此时状态图如下:
https://i-blog.csdnimg.cn/direct/b49b17e7b85041f4a5f45aa1e5b63802.png" alt="在这里插入图片描述" />
3. 使用master合并dev

ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git branch dev
* master
#合并
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git merge dev
Auto-merging ReadMe
CONFLICT (content): Merge conflict in ReadMe
Automatic merge failed; fix conflicts and then commit the result.
#合并发生冲突,Git标记冲突部分
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat ReadMe 
hello git
<<<<<<< HEAD
master branch coding...
=======
dev branch coding...
>>>>>>> dev

发生合并冲突后,Git 并不知道要保留哪部分代码,所以索引都保留,然后标记出冲突的部分
Git 使用 <<<<<<========>>>>>>>>标记不停分支的冲突内容
我们必须手动调整冲突代码,并且调整完后还需要再次提交修正后的结果(一定要再次提交!!!)

ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ vim ReadMe 
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat ReadMe 
hello git
master branch coding...
dev branch coding...
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git status
On branch master
You have unmerged paths.(fix conflicts and run "git commit")(use "git merge --abort" to abort the merge)Unmerged paths:(use "git add <file>..." to mark resolution)both modified:   ReadMeno changes added to commit (use "git add" and/or "git commit -a")
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git add .
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git commit -m "solve the merge conflict"
[master c132cde] solve the merge conflict

此时状态图如下:
https://i-blog.csdnimg.cn/direct/2c55b40428324d58ae2a5fc285df53f9.png" alt="在这里插入图片描述" />
使用带参数的git log可以看到分支的合并情况

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

https://i-blog.csdnimg.cn/direct/127bd92fb1394dbaab9c6be579e70801.png" alt="在这里插入图片描述" />
左侧有类似时间线的线段,*表示当时的工作分支

分支管理策略

通常合并分支时,Git 一般会采用Fast forward模式
直接将master指向合并分支的最新一次提交的commit id
Fast forward模式下,删除分支后,查看分支历史,会丢失分支信息,看不出来最新提交到底是 merge 的还是正常提交的
在合并冲突时,通过日志查看的明显不是Fast forward模式,从分支历史上可以很清晰的看到分支信息,新提交是通过 merge dev 分支进来的。该模式称为非Fast forward(no-ff)模式
Git 允许强制禁用Faste forward模式,就是在合并时带上--no-ff选项

git merge --no-ff -m "描述" [分支名]

下图是两种模式的状态图差异:
https://i-blog.csdnimg.cn/direct/7377e918832240d6956115732c6ce854.png" alt="在这里插入图片描述" />
对于没有合并冲突的合并,--no-ff模式可以保留合并信息,而Fast forword则没有合并信息

分支策略

实际开发有一些基本原则需要遵守

  1. master分支是主分支,实际发布的分支,应该是非常稳定的,不能直接在该分支上开发
  2. 每个新功能的开发/bug修改等都要新建分支完成,完成开发并测试再合并回 master
    3. 合并时,可以先在工作分支合并 master 分支,确认无误后,再切换到 master 分支合并指定分支

综上,团队合作的分支看起来就像这样:
https://i-blog.csdnimg.cn/direct/7c54092c5bd3464cbeb488671abb284d.png" alt="在这里插入图片描述" />

bug 分支

情景如下:
假如现在在dev2分支上开发,开发到一半,突然master分支上有bug,需要解决。在 Git 中,每个 bug 都可以通过一个新的临时分支来修复,修复后再合并分支,最后将临时分支删除


当前dev2的代码在工作区开发了一半,还无法提交。此时如果切换到master分支,会影响master分支的工作区内容

ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git checkout -b dev2
Switched to a new branch 'dev2'
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ vim ReadMe 
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git checkout master 
M	ReadMe
Switched to branch 'master'
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat ReadMe 
hello git
master branch coding...
dev branch coding...
i am coding...

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

ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git checkout dev2
M	ReadMe
Switched to branch 'dev2'
#使用stash存储工作区修改
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git stash
Saved working directory and index state WIP on dev2: c132cde solve the merge conflict
#此时工作区修改已经被存储起来,dev2和master都看不到修改
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat ReadMe 
hello git
master branch coding...
dev branch coding...
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git checkout master 
Switched to branch 'master'
ubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ cat ReadMe 
hello git
master branch coding...
dev branch coding...

使用如下命令查看存储

git stash listubuntu@VM-12-11-ubuntu:~/lesson/gitcode$ git stash list
stash@{0}: WIP on dev2: c132cde solve the merge conflict

使用如下命令恢复工作区修改,恢复的同时会把 stash 删除,只能恢复一次

git stash pop #类似队列那样,从小序号删除

也可以不删除 stash

git stash apply #恢复现场,但不删除stash
git stash drop #需要用该命令删除stash
git stash apply stash@{0} #指定恢复

以上就是本篇博客的所有内容,感谢你的阅读
如果觉得本篇文章对你有所帮助的话,不妨点个赞支持一下博主,拜托啦,这对我真的很重要。
https://i-blog.csdnimg.cn/blog_migrate/254b03b9d386a1a207e48847e2611629.gif#pic_center" alt="在这里插入图片描述" />


http://www.ppmy.cn/server/120354.html

相关文章

【VUE】快速上手

一、快速上手 创建HTML文件引入vue.js <script src"https://unpkg.com/vue3/dist/vue.global.js"></script> <script src"https://cdn.bootcdn.net/ajax/libs/vue/3.3.4/vue.global.prod.js"></script>按照vue.js的语法编写代码…

专业学习|动态规划(概念、模型特征、解题步骤及例题)

一、引言 &#xff08;一&#xff09;从斐波那契数列引入自底向上算法 &#xff08;1&#xff09;知识讲解 &#xff08;2&#xff09;matlap实现递归 &#xff08;3&#xff09;带有备忘录的遗传算法 &#xff08;4&#xff09;matlap实现带有备忘录的递归算法 “&#xff1…

tensorflow同步机制

tensorflow同步机制 在 TensorFlow 中&#xff0c;多算子&#xff08;operators&#xff09;和多核&#xff08;CPU 核或 GPU 核&#xff09;同步机制旨在提高深度学习模型的计算效率和资源利用率。主要涉及以下几个方面&#xff1a; 1. 多算子并行化 TensorFlow 通过数据流…

讨论人机交互研究中大语言模型的整合与伦理问题

概述 论文地址&#xff1a;https://arxiv.org/pdf/2403.19876.pdf 近年来&#xff0c;大规模语言模型发展迅速。它们给研究和教育领域带来了许多变化。这些模型也是对人机交互&#xff08;HCI&#xff09;研究过程的有力补充&#xff0c;可以分析定性和定量数据&#xff0c;再…

【java面试每日五题之基础篇一】(仅个人理解)

1. 怎么理解面向对象编程&#xff08;Object Oriented Programming&#xff0c;OOP&#xff09; 面向对象编程是一种编程范式&#xff0c;核心思想是将真实世界中的事物都抽象为对象&#xff0c;通过与代码中的对象进行交互从而实现各种需求&#xff0c;对于OOP中关键概念的理解…

MELON的难题- 华为OD统一考试(E卷)

2024华为OD机试&#xff08;C卷D卷&#xff09;最新题库【超值优惠】Java/Python/C合集 题目描述 MELON 有一堆精美的雨花石&#xff08;数量为 n&#xff0c;重量各异&#xff09;&#xff0c;准备送给 S和 W&#xff0c;MELON 希望送给俩人的雨花石重量是一致的。请你设计一…

免密执行远程服务命令

1&#xff1a;生成密钥对 要在本地使用SCP命令从远程主机复制文件而无需输入密码&#xff0c;你可以使用SSH密钥认证。以下是具体步骤&#xff1a; 生成SSH密钥对&#xff1a;在本地机器上打开终端&#xff0c;执行以下命令生成SSH密钥对&#xff1a; ssh-keygen -t rsa 不用…

erlang学习:Linux常用命令2

目录操作命令 对目录进行基本操作 相关cd切换目录之类的就直接省去了&#xff0c;以下操作中都会用到 查看当前目录下的所有目录和文件 ls 列表查看当前目录下的所有目录和文件&#xff08;列表查看&#xff0c;显示更多信息&#xff09; ls -l 或 ll 在当前目录下创建一个…