天天看点

Git系列(三)、Git分支管理一、什么是分支?二、分支管理的基本命令三、分支作用演示与

Git分支管理

  • 一、什么是分支?
  • 二、分支管理的基本命令
  • 三、分支作用演示与
    • 3.1、HEAD与master指向
    • 3.2、新建dev分支
    • 3.3、合并dev分支
    • 3.4、合并后,删除dev分支
    • 3.5、解决合并冲突

一、什么是分支?

几乎每一种版本控制系统都以某种形式支持分支。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。有人把Git的分支模型称为必杀技特性。而正是因为它,将Git从版本控制系统家族中区分出来了。

二、分支管理的基本命令

创建分支:

切换分支:

当你切换分支的时候,Git 会用该分支的最后提交的快照替换你的新分支工作目录的内容, 所以多个分支不需要多个目录,仍然保持与主分支

master

一致即可。

简化创建和切换分支:

我们注意到切换分支使用

git checkout <branch>

,而前面讲过的撤销修改则是

git checkout -- <file>

,同一个命令,有两种作用,确实有点令人迷惑。
实际上,创建和切换分支这个动作,用switch更科学。因此,最新版本的Git提供了新的

git switch

命令来切换分支:
$ git branch dev  #创建dev分支
$ git switch dev   #switch切换至dev分支
$ git switch -c dev  #也可以一步到位,-c代表create创建
           

列出本地所有分支:

$ git branch  #列出所有本地分支			
* dev       #星标代表是当前分支
  master 
           

列出远程仓库的所有分支:

$ git branch -r  #列出远程仓库的所有分支
  origin/HEAD -> origin/master
  origin/master
           

列出所有本地分支和远程分支:

$ git branch -a   #显示本地和远程的所有分支
* dev             #星标代表是当前分支
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
           

删除分支:

合并分支内容:

三、分支作用演示与

在前面我们已经学习了版本回退,也就是在每次提交的时候,Git都会把它们串成一条时间线,这条时间线就是一个分支。截至目前,只有一条时间线,在Git里这个分支叫做主分支,即

master

分支。

HEAD

严格来说不是指向提交,而是指向

master

master

才是指向提交的,

HEAD

指向的就是当前分支(

HEAD

指向的也就是最新提交的那个分支)。

3.1、HEAD与master指向

一开始的时候,

master

分支是一条线,Git用

master

指向最新的提交,再用

HEAD

指向

master

,就能确定当前分支,以及当前分支的提交点,如下图所示:

Git系列(三)、Git分支管理一、什么是分支?二、分支管理的基本命令三、分支作用演示与

每次提交,

master

主分支都会向前移动一步,随着不断提交,

master

主分支的时间线也会越来越长。

3.2、新建dev分支

当我们新建一个

dev

分支时,也就睡Git新建了一个指针叫

dev

,指向

master

相同的提交,我们切换至新建的

dev

分支上,

HEAD

指针会自动从

master

指向

dev

,就表示当前分支在

dev

上:

$ git checkout -b dev    #新建dev分支,并立即切换至dev
Switched to a new branch 'dev'
           
Git系列(三)、Git分支管理一、什么是分支?二、分支管理的基本命令三、分支作用演示与

Git创建分支很快,因为除了增加一个

dev

指针,就改了下

HEAD

的指向,工作区的文件没有任何变化!!!

我们上述已经切换至新的分支

dev

了,其实我们可以理解为,

dev

分支就是克隆的

master

主分支,当前

dev

分支中的所有文件内容都和

master

主分支一模一样,因为

master

主分支是一个本地仓库的模板,一般我们不允许直接在

master

主分支进行操作修改,后续我们也都是新建分支进行操作,经过测试调优,最终合并到本地的

master

主分支,然后再由

master

主分支推送到远程仓库的

master

主分支:

先看下master分支和dev分支的内容是否一致:

itwbs@matebook13-mini MINGW64 /d/gitspace/learngit (master)   #master主分支下查看
$ ls
readme.txt  test.txt  #内容一致

itwbs@matebook13-mini MINGW64 /d/gitspace/learngit (dev)   #dev分支下查看
$ ls
readme.txt  test.txt  #内容一致
           

**切换至dev分支,从现在开始,对工作区的修改和提交就是针对

dev

分支了,比如我们新建一个文件

test2.txt

,然后提交至本地仓库,查看

dev

指针走向: **

$ touch test2.txt  #新建test2.txt文件

$ ls
readme.txt  test.txt  test2.txt

$ git add test2.txt   #添加到暂存区

$ git commit -m "dev new add test2.txt"   #提交到dev本地仓库中
[dev 4229aad] dev new add test2.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test2.txt
           
Git系列(三)、Git分支管理一、什么是分支?二、分支管理的基本命令三、分支作用演示与

3.3、合并dev分支

假如我们在

dev

分支上的工作完成了,切换至

master

主分支,查看文件:

$ ls
readme.txt  test.txt    #发现没有dev分支建的test2.txt文件
           

这个时候,如果我们想要在

master

主分支也要有

dev

分支的内容,那就在当前

master

主分支合并

dev

分支,如下:

$ git merge dev   #在当前master主分支合并dev分支
Updating b1fe536..4229aad
Fast-forward
 test2.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test2.txt
 
 $ ls    #再次查看就有了test2.txt文件了
readme.txt  test.txt  test2.txt
           

注意到上面的

Fast-forward

信息,Git告诉我们,这次合并是“快进模式”,也就是直接把

master

指向

dev

的当前提交,所以合并速度非常快。当然,也不是每次合并都能

Fast-forward

,我们后面会讲其他方式的合并。

Git是怎么合并的呢?其实很好理解,就是直接把

master

主分支的指针指向了

dev

分支的当前最新提交,就完成了合并,如下图:

Git系列(三)、Git分支管理一、什么是分支?二、分支管理的基本命令三、分支作用演示与

可以看出合并分支也是非常快的,就改了改指针,工作内容也不变!

3.4、合并后,删除dev分支

合并完分支后,就可以放心的删除

dev

分支了,删除

dev

分支就是把

dev

指针的指向给删除掉,然后就只剩下

master

分支了,而且

HEAD

又重新指向了

master

主分支,如下图:

$ git branch  #查看本地仓库所有分支
  dev
* master   #星标代表是当前指向master注分支

$ git branch -d dev   #删除dev分支
Deleted branch dev (was 4229aad).

$ git branch   #然后dev分支就么了
* master
           
Git系列(三)、Git分支管理一、什么是分支?二、分支管理的基本命令三、分支作用演示与

3.5、解决合并冲突

合并分支往往不是一帆风顺的,也会存在冲突!!!

新建

feature

分支:

$ git switch -c feature    #新建feature分支,并立即切换
Switched to a new branch 'feature'
           

向test2.txt文件新添加内容:

$ vim test2.txt  #编辑test2.txt文件,添加如下内容
Create a new branch is quick AND simple.
           

提交到本地Git仓库:

$ git add test2.txt   #添加暂存区
warning: LF will be replaced by CRLF in test2.txt.
The file will have its original line endings in your working directory

$ git commit -m "feature commit test2.txt"    #提交到本地仓库
[feature ebc5a6f] feature commit test2.txt
 1 file changed, 1 insertion(+)
           

这个时候我们切换到

master

主分支:

$ git switch master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
           
可以看出,Git告诉我们我们当前本地仓库中的

master

主分支,超前远程仓库的

master

主分支一个提交。

在master分支中,向test2.txt文件也添加一行内容

$ vim test2.txt  #编辑

$ cat test2.txt  #查看内容
Creating a new branch is quick & simple.
           

也提交到本地仓库:

$ git add test2.txt   #添加到暂存区
warning: LF will be replaced by CRLF in test2.txt.
The file will have its original line endings in your working directory

$ git commit -m "master commit test2.txt update & simple"   #提交到本地仓库
[master 53a6882] master commit test2.txt update & simple
 1 file changed, 1 insertion(+)
           

仔细看哈,目前连个分支都有了新的提交

commit

,如下图:

Git系列(三)、Git分支管理一、什么是分支?二、分支管理的基本命令三、分支作用演示与

这个时候我们在

master

主分支把

feature

分支合并了,看会出现啥情况:

$ git merge feature   #合并feature分支
Auto-merging test2.txt
CONFLICT (content): Merge conflict in test2.txt
Automatic merge failed; fix conflicts and then commit the result.
           

可以看出test2.txt文件 发生冲突了,查看当前状态

git status

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

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:   test2.txt

no changes added to commit (use "git add" and/or "git commit -a")
           

可以看出原因是test2.txt文件

both

两者都修改了,然后合并的时候就导致

HEAD

不知道该指向谁了,然后就冲突了!!!

此时我们查看

test2.txt

文件的内容:

$ cat test2.txt  #查看内容
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Create a new branch is quick AND simple.
>>>>>>> feature
           

那啥,如果发生冲突,Git会自动帮我们在冲突文件中记录是哪些操作导致的冲突,上述表达的很明显了,就是由于

HEAD

最新指向的master主分支,修改了内容为

Creating a new branch is quick & simple.

,而

feature

分支修改内容为

Create a new branch is quick AND simple.

Git用

<<<<<<<

=======

>>>>>>>

记录不同分支的不同操作,此时我们为了结局冲突,可以手动编辑

test2.txt

文件,为如下内容(其实也就是我们希望看到的最终合并版本),然后再做一次提交:

$ vim test2.txt  #重新编辑test2.txt文件为我们想要的最终合并结果

$ cat test2.txt
Creating a new branch is quick & simple.   #master主分支做的修改
Create a new branch is quick AND simple.   #feature分支做的修改

$ git add test2.txt  #再次添加到暂存区

$ git commit -m "conflict fixed"   #再次提交到本地仓库
[master 29e8de2] conflict fixed
           
Git系列(三)、Git分支管理一、什么是分支?二、分支管理的基本命令三、分支作用演示与

真的解决了吗?可以查看当前状态:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 4 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
           

没毛病,真解决了,而且Git还告诉你,当前本地仓库的

master

主分支比远程仓库的

master

超前了4个

commit

,提示你将本地仓库最新版本推送到远程并合并。

而且还可以使用命令查看分支的合并情况:

$ git log --graph --pretty=oneline --abbrev-commit
*   29e8de2 (HEAD -> master) conflict fixed
|\
| * ebc5a6f (feature) feature commit test2.txt
* | 53a6882 master commit test2.txt update & simple
|/
* 4229aad dev new add test2.txt
* b1fe536 (origin/master, origin/HEAD) update test.txt.
* cd180c8 update test.txt.
* 1d07bf6 add new test.txt
* 89789d5 Git tracks changes of files
* bf9deee git tracks changes
* 4f489e7 append GPL
* 0931364 wrote a readme file
           

没办法就是那么强大!!!

当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。

解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。

小结:

  • Git鼓励大量使用分支:
  • 查看分支:

    git branch

  • 创建分支:

    git branch <name>

  • 切换分支:

    git checkout <name>或者git switch <name>

  • 创建+切换分支:

    git checkout -b <name>或者git switch -c <name>

  • 删除分支:

    git branch -d <name>

  • 合并某分支到当前分支:

    git merge <name>

  • 查看分支合并图:

    git log --graph