7:Git的分支

介绍分支

很多版本控制系统都是某一种形式支持分支的,分支类似于项目的复制,比如你做了
一个代码写得很好的项目,现在需要一个新的功能,你不可能是在你写得很好的项目
里面进行修改添加的,而是应该复制整个项目进行编写代码,而分支就是实现这样的
功能,分支名称就是你复制的大量代码起的名字.
使用分支可以将工作从开发主线上面分离出来,避免影响主线的开发.
但是很多的版本控制系统的分支是个低效的,他们完全创建一个源代码的目录副本
,对于大项目,这样很浪费时间,而Git的分支模型就很高效,分支是Git的一个亮点.

分支的位置

前面讲过Git的目录,部分如下
在这里插入图片描述
其中有两个是和分支有关的,其实分支的名称就是类似一个变量的指针,指针指向的是提交对象hash值,而默认的主分支就是master,例如下面的图片
在这里插入图片描述
Git目录中的HEAD保存的就是当前的分支是什么,
而refs里面保存的是每一个分支的最后提交的提交对象的hash值
在这里插入图片描述

分支的使用

  1. 创建分支:git branch 分支名
    就是创建一个可以移动的新的指针,这个就是分支,当然,这个指针指向的是当前所在的提交对象
    你会发现,虽然创建了一个指针,HEAD指向的还是master,不会自动切换到新的分支上
    在这里插入图片描述

  2. 切换分支:

git checkout 分支名 切换分支
git checkout 什么参数都没有,就是显示分支得列表
git checkout -b 分支名 前面的步骤,需要先新建分支,然后再切换过去,这样麻烦,这个命令就是一步完成,新建分支并且切换过去

在这里插入图片描述
切换分支需要注意的点:
①:切换分支会改变三个地方:HEAD,暂存区,工作目录
HEAD改变成切换的分支名
暂存区变成切换的分支的最后暂存区的样子
工作目录变成切换分支的最后的样子
所以因为上面的原因,在切换分支的时候,确保当前的分支是已提交的状态,就是
在执行git status的时候全部显示已提交状态.
这里说一下三种切换分支的情况:
①: 就是你在一个分支上新建了一个文件,但是你没有跟踪它,在没有跟踪的情况
切换回主线或者切换到其他的分支,这时这个新建的文件就会跟踪你去到主线或者
其他分支,本来这个文件不属于主线或者其他分支的,这样就会造成代码污染主线
或其他分支.而这个新建的文件为什么会跟着你去到主线或者其他分支呢,是因为你没有跟着它,所以它不在git的管理范围,所以切换分支,工作目录就不会对它进行删除
②: 就是你已经跟踪的新建的文件,但是没有提交,这时切换分支.本来已经跟踪的肯定是会在暂存区的,
你切换分支新建文件进入暂存区的也会被带到新的分支上,而且工作目录的新建文件也会被带到新的
分支上,这样也会污染新的分支.
③: 就是已经提交过的文件,现在升级需要修改,修改后的文件你没有跟踪和提交,就想切换分支
这样git是不会给你切换的,因为修改前的文件已经在这个分支提交过,那么修改后git认为修改后的文件一定属于这个分支,所以就强制不给你切换,得让你提交后再能切换.
在这里插入图片描述

  1. 删除分支(不能自己删除自己,得先切换到其他目录上)
git branch -d 分支名 这个是删除已经合并的分支,如果分支没有合并,删除就会报错
git branch -D 分支名 这个是强制删除分支,没有合并的分支也可以删除掉
git log --oneline --decorate --graph --all 这个是可以看整个项目得完整历史,因为切换到主线上,很多主线后面的分支的提交看不了,这个代码就可以看了
  1. 其他
git branch -v 以查看每一个分支的最后一次提交
git branch 分支名 提交对象的hash值 新建一个分支并且使分支指向对应的提交对象 ,利用这个可以实现版本的回退,比如你的提交对象的hash值是第一个版本的,那么就回退到第一个版本
git config --global alias.别名 “命令” 这个是当git的命令很长的时候,我们可以给他配一个别名,注意:alias.后面直接加别名,不能空格,后面的命令是写git后面的命令,不用加git,命令要用""括起来,例如:git config --global alias.st status,配置后直接敲git st 和git status一样
git reflog 就是在版本库里面看所有的提交,包括删除的

在这里插入图片描述
在这里插入图片描述

  1. 一个使用例子
    现在是主分支上面已经有两个稳定的代码就是Jane1.txt和jane2.txt,现在主分支
    master指向jane2.txt,
    然后你需要修改一个bug,所以创建了一个jing1的分支,在jing1分支上面打了代码jing1.txt和jing.txt,如下图:
    在这里插入图片描述
    然后现在你需要立即解决另外一个bug,所以你需要返回到主分支上面
    再新建一个分支urgent,在里面打了jane3.txt和修改了jane1.txt,将这个紧急bug
    修改好后测试没问题,应该合并到主分支上,如下图
    在这里插入图片描述
    这里因为urgent和master是在同一条线上的,就是master分支要合并的分支是在master的前面,这样子git就会简单地将HEAD指针向前移动,指向urgent最后的提交对象上面,这样合并不需要处理分歧,也叫做快进
    现在处理完了urgent的问题,又回到jing1分支继续写代码,修改了jane1.txt的代码
    完成后你又要将jing1分支和master合并,
    这时合并就出现了问题了,因为jing1的jane1.txt代码在urgent分支修改过,在jing1分支也修改过,合并的时候就会出现分歧,
    而且对于合并过urgent分支的master主分支来说,jing1分支就是过时的,因为master
    已经升级过了,
    这时jing1和master合并也叫典型合并,需要处理冲突,合并后会提示需要处理的
    是哪一个文件代码,你对它进行修改,add,commit后就可以了
    上面的逻辑代码如下:
镜风@▒龵 MINGW64 /g/git/workspace/1 (master)
$ git log --oneline --decorate --graph --all
* b238c63 (jing1) jing1.txt comitt for jing1
* a2e2d45 (HEAD -> master) jane2
* 7942d53 jane1

镜风@▒龵 MINGW64 /g/git/workspace/1 (master)
$ git checkout jing1
Switched to branch 'jing1'

镜风@▒龵 MINGW64 /g/git/workspace/1 (jing1)
$ git ls-files -s
100644 eeaa10d7dbd999222fb0557b3b8d7c1bd2c465d4 0       jane1.txt
100644 32b22f6bd6e40627e9502847ec7cf36a3bc87420 0       jane2.txt
100644 d82550eebd096160ee791e84cc4053c6214bf183 0       jing1.txt

镜风@▒龵 MINGW64 /g/git/workspace/1 (jing1)
$ git checkout master
Switched to branch 'master'

镜风@▒龵 MINGW64 /g/git/workspace/1 (master)
$ git checkout -b urgent
Switched to a new branch 'urgent'

镜风@▒龵 MINGW64 /g/git/workspace/1 (urgent)
$ git ls-files -s
100644 eeaa10d7dbd999222fb0557b3b8d7c1bd2c465d4 0       jane1.txt
100644 32b22f6bd6e40627e9502847ec7cf36a3bc87420 0       jane2.txt

镜风@▒龵 MINGW64 /g/git/workspace/1 (urgent)
$ vim jane1.txt

镜风@▒龵 MINGW64 /g/git/workspace/1 (urgent)
$ echo "jane3.txt" > jane3.txt

镜风@▒龵 MINGW64 /g/git/workspace/1 (urgent)
$ git add ./
warning: LF will be replaced by CRLF in jane1.txt.
The file will have its original line endings in your working directory
warning: LF will be replaced by CRLF in jane3.txt.
The file will have its original line endings in your working directory

镜风@▒龵 MINGW64 /g/git/workspace/1 (urgent)
$ git commit -m "jane1.txt的修改和jane3.txt增加 to urgent"
[urgent 114582a] jane1.txt的修改和jane3.txt增加 to urgent
 2 files changed, 2 insertions(+)
 create mode 100644 jane3.txt

镜风@▒龵 MINGW64 /g/git/workspace/1 (urgent)
$ git checkout master
Switched to branch 'master'

镜风@▒龵 MINGW64 /g/git/workspace/1 (master)
$ git merge urgent
Updating a2e2d45..114582a
Fast-forward
 jane1.txt | 1 +
 jane3.txt | 1 +
 2 files changed, 2 insertions(+)
 create mode 100644 jane3.txt

镜风@▒龵 MINGW64 /g/git/workspace/1 (master)
$ git checkout jing1
Switched to branch 'jing1'

镜风@▒龵 MINGW64 /g/git/workspace/1 (jing1)
$ ll
total 4
-rw-r--r-- 1 镜风 197121  7  3月  2 21:35 jane1.txt
-rw-r--r-- 1 镜风 197121  6  3月  2 14:04 jane2.txt
-rw-r--r-- 1 镜风 197121 30  3月  2 21:35 jing.txt
-rw-r--r-- 1 镜风 197121  8  3月  2 21:35 jing1.txt

镜风@▒龵 MINGW64 /g/git/workspace/1 (jing1)
$ vim jane1.txt

镜风@▒龵 MINGW64 /g/git/workspace/1 (jing1)
$ git commit -a -m "修改了jane1.txt to jing1分支"
[jing1 be620f2] 修改了jane1.txt to jing1分支
 1 file changed, 1 insertion(+)

镜风@▒龵 MINGW64 /g/git/workspace/1 (jing1)
$ git checkout master
Switched to branch 'master'

镜风@▒龵 MINGW64 /g/git/workspace/1 (master)
$ git merge jing1
Auto-merging jane1.txt
CONFLICT (content): Merge conflict in jane1.txt
Automatic merge failed; fix conflicts and then commit the result.

镜风@▒龵 MINGW64 /g/git/workspace/1 (master|MERGING)
$ vim jane1.txt

镜风@▒龵 MINGW64 /g/git/workspace/1 (master|MERGING)
$ git add ./

镜风@▒龵 MINGW64 /g/git/workspace/1 (master|MERGING)
$ git status
On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:
        modified:   jane1.txt
        new file:   jing.txt
        new file:   jing1.txt


镜风@▒龵 MINGW64 /g/git/workspace/1 (master|MERGING)
$ git commit -m "master合并jing1"
[master 37ea712] master合并jing1

镜风@▒龵 MINGW64 /g/git/workspace/1 (master)
$ git log --oneline --decorate --graph --all
*   37ea712 (HEAD -> master) master合并jing1
|\
| * be620f2 (jing1) 修改了jane1.txt to jing1分支
| * 22c6705 jing.txt的修改 to jing1
| * 83c7ef7 commit for jing.txt to jing1
| * b238c63 jing1.txt comitt for jing1
* | 114582a (urgent) jane1.txt的修改和jane3.txt增加 to urgent
|/
* a2e2d45 jane2
* 7942d53 jane1

典型合并后需要修改的代码的样子
在这里插入图片描述

分支模式

一般的分为长期分支和特性分支
在这里插入图片描述
上面这张图就很清晰明了,最上面的mater是全公司的人结合的稳定的代码
develop分支就是每一个程序员自己的代码,但是修改时不会直接在develop分支上面修改,而是再继续创建其他的分支修改
这里的master分支和develop分支都是相对稳定的,就是长期分支
下面的topic分支就是程序员为每一个功能或者bug创建的分支,是特性分支

分支的本质

其实分支就是一个有可变指针指向的提交对象,前面介绍过git的文件夹
里面有一个refs文件夹,里面就是保存分支的
在这里插入图片描述
比如这里就是保存了三个分支,每一个分支在这里就是一个文件,里面保存的是
每一个分支最后一个提交对象的hash值,
在目录中还有一个HEAD文件,里面保存的就是HEAD当前指向的分支
每一次有新的提交对象提交的时候,HEAD就会向前移动,同时HREAD指向的分支也会变化

发布了133 篇原创文章 · 获赞 37 · 访问量 4718

猜你喜欢

转载自blog.csdn.net/qq_43416157/article/details/104599694