Git系列Git分支管理
Posted 一宿君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Git系列Git分支管理相关的知识,希望对你有一定的参考价值。
Git分支管理
一、什么是分支?
几乎每一种版本控制系统都以某种形式支持分支。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。有人把Git的分支模型称为必杀技特性。而正是因为它,将Git从版本控制系统家族中区分出来了。
二、分支管理的基本命令
创建分支:
$ git branch dev #创建分支
切换分支:
$ git checkout dev #切换至dev分支
当你切换分支的时候,Git 会用该分支的最后提交的快照替换你的新分支工作目录的内容, 所以多个分支不需要多个目录,仍然保持与主分支master
一致即可。
简化创建和切换分支:
$ git checkout -b dev #表示创建dev分支,并立即切换至dev分支;如果存在dev,则直接切换
我们注意到切换分支使用
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 branch -d (branchname) #删除指定分支
合并分支内容:
$ git merge dev #意思是在当前分支下,合并分支dev的内容
三、分支作用演示与
在前面我们已经学习了版本回退,也就是在每次提交的时候,Git都会把它们串成一条时间线,这条时间线就是一个分支。截至目前,只有一条时间线,在Git里这个分支叫做主分支,即master
分支。HEAD
严格来说不是指向提交,而是指向master
,master
才是指向提交的,HEAD
指向的就是当前分支(HEAD
指向的也就是最新提交的那个分支)。
3.1、HEAD与master指向
一开始的时候,master
分支是一条线,Git用master
指向最新的提交,再用HEAD
指向master
,就能确定当前分支,以及当前分支的提交点,如下图所示:
每次提交,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创建分支很快,因为除了增加一个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
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
分支的当前最新提交,就完成了合并,如下图:
可以看出合并分支也是非常快的,就改了改指针,工作内容也不变!
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
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
,如下图:
这个时候我们在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 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
以上是关于Git系列Git分支管理的主要内容,如果未能解决你的问题,请参考以下文章