Git学习笔记(二)

本文主要讲解分支管理

Git学习笔记(一)


目录

一、概念

二、创建与合并分支

2.1 简介

2.2 配图示例

2.3 命令小结

三、解决冲突

四、分支管理策略

五、Bug分支

5.1 stash功能 

5.2 小结


一、概念

分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习SVN。如果两个平行宇宙互不干扰,那对现在的你也没啥影响。不过,在某个时间点,两个平行宇宙合并了,结果,你既学会了git又学会了SVN!

分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。

二、创建与合并分支

2.1 简介

Git把我们之前每次提交的版本串成一条时间线,这条时间线就是一个分支。截止到目前只有一条时间线,在git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支

  • ​​​​​​一开始的时候,master分支是一条线,git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点
  • 当我们创建新的分支,例如dev时,git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上

git创建一个分支很快,因为除了增加一个dev指针,改变HEAD的指向,工作区的文件都没有任何变化

  • 不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变
  • 假如我们在dev上的工作完成了,就可以把dev合并到master上。git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并

git合并分支也很快,就改改指针,工作区内容也不变

  • 合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支

2.2 配图示例

执行git branch可以查看当前有几个分支并且看到在哪个分支下工作,执行git checkout -b dev创建一个分支dev并将HEAD指向dev在其上进行工作

xm@ubuntu:~/xm-git/git_test$ git branch 
* master
xm@ubuntu:~/xm-git/git_test$ git checkout -b dev
Switched to a new branch 'dev'
xm@ubuntu:~/xm-git/git_test$ git branch 
* dev
  master

配置如下

修改code.txt内容在里面添加一行,并进行提交

xm@ubuntu:~/xm-git/git_test$ vi code.txt 
xm@ubuntu:~/xm-git/git_test$ cat code.txt 
this is the first line
this is the second line
this is the third line
this is the forth line
add one line
xm@ubuntu:~/xm-git/git_test$ git add code.txt
xm@ubuntu:~/xm-git/git_test$ git commit -m 'dev branch submission'
[dev b246a46] dev branch submission
 1 file changed, 1 insertion(+)

配图如下

dev分支的工作完成后就可以切换会master分支

xm@ubuntu:~/xm-git/git_test$ git checkout master 
Switched to branch 'master'
xm@ubuntu:~/xm-git/git_test$ git branch 
  dev
* master
xm@ubuntu:~/xm-git/git_test$ cat code.txt 
this is the first line
this is the second line
this is the third line
this is the forth line

配图如下

现在我们把dev分支的工作成果合并到master分支上,git merge命令用于合并指定分支到当前分支。合并后,再查看code.txt的内容,就可以看到,和dev分支的最新提交是完全一样的

xm@ubuntu:~/xm-git/git_test$ git merge dev
Updating ce6352f..b246a46
Fast-forward
 code.txt | 1 +
 1 file changed, 1 insertion(+)
xm@ubuntu:~/xm-git/git_test$ cat code.txt 
this is the first line
this is the second line
this is the third line
this is the forth line
add one line

配图如下

注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快,合并完成后,就可以放心地删除dev分支了,删除后,查看branch,就只剩下master分支了

xm@ubuntu:~/xm-git/git_test$ git log --pretty=oneline 
b246a46d2317c14daae590c8a29f98ecf2a90f83 (HEAD -> master, dev) dev branch submission
ce6352fdd1ad277c10ffd008e21c2242acf87dad rm code2.txt
7dfafe0ec234807ce5cc6d5db33d66f45bd6f1aa verson 4
85984321ceebb6b56fb336d11c3b287e966072d2 verson 3
399f3d2c26af9e11434460b3a71403f56d1e6bf7 verson 2
2522dc5642ded17edaeca49f4c31b46c6d65cca5 verson 1
xm@ubuntu:~/xm-git/git_test$ git branch -d dev 
Deleted branch dev (was b246a46).
xm@ubuntu:~/xm-git/git_test$ git branch 
* master

配图如下

2.3 命令小结

查看分支git branch
创建分支git branch <name>
切换分支git checkout <name>
创建+切换分支git checkout -b <nmae>
合并某分支到当前分支git merge <name>
删除分支git branch -d <name>

三、解决冲突

合并分支不一定是一帆风顺的,举例如下

再创建一个新分支dev,修改conde.txt内容并进行提交,切换会master分支,在master的code.txt添加一行内容并进行提交

xm@ubuntu:~/xm-git/git_test$ git checkout -b dev
Switched to a new branch 'dev'
xm@ubuntu:~/xm-git/git_test$ vi code.txt 
xm@ubuntu:~/xm-git/git_test$ cat code.txt 
this is the first line
this is the second line
this is the third line
this is the forth line
add one line
add one more line
xm@ubuntu:~/xm-git/git_test$ git add code.txt
xm@ubuntu:~/xm-git/git_test$ git commit -m 'dev branch submission2'
[dev 3263a42] dev branch submission2
 1 file changed, 1 insertion(+)
xm@ubuntu:~/xm-git/git_test$ git checkout master 
Switched to branch 'master'
xm@ubuntu:~/xm-git/git_test$ vi code.txt 
xm@ubuntu:~/xm-git/git_test$ cat code.txt 
this is the first line
this is the second line
this is the third line
this is the forth line
add one line
one more line in master
xm@ubuntu:~/xm-git/git_test$ git add code.txt 
xm@ubuntu:~/xm-git/git_test$ git commit -m 'dev branch submission to master'
[master 953868d] dev branch submission to master
 1 file changed, 1 insertion(+)

现在,master分支和dev分支各自都分别有新的提交,配图如下

这种情况下,git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,执行如下命令尝试将dev分支合并到master分支上来,执行git status可以告诉我们冲突的文件为code.txt

xm@ubuntu:~/xm-git/git_test$ git merge dev
Auto-merging code.txt
CONFLICT (content): Merge conflict in code.txt
Automatic merge failed; fix conflicts and then commit the result.
xm@ubuntu:~/xm-git/git_test$ 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:   code.txt

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

查看code.txt,it用<<<<<<<,=======,>>>>>>>标记出不同分支的内容

xm@ubuntu:~/xm-git/git_test$ cat code.txt 
this is the first line
this is the second line
this is the third line
this is the forth line
add one line
<<<<<<< HEAD
one more line in master
=======
add one more line
>>>>>>> dev

修改code.txt的内容如下所示,重新提交备注为解决冲突

xm@ubuntu:~/xm-git/git_test$ vi code.txt 
xm@ubuntu:~/xm-git/git_test$ cat code.txt 
this is the first line
this is the second line
this is the third line
this is the forth line
add one line
one more line in master
add one more line
xm@ubuntu:~/xm-git/git_test$ git add code.txt 
xm@ubuntu:~/xm-git/git_test$ git commit -m 'conflict resolution'
[master 19cf625] conflict resolution

现在,master和dev变成了如下所示

用带参数的git log也可以看到分支的合并情况,最后工作完成,可以删除dev分支

xm@ubuntu:~/xm-git/git_test$ git log --graph --pretty=oneline 
*   19cf6254482bd1c207d14a8a8bc0d813c14ff5a1 (HEAD -> master) conflict resolution
|\  
| * 3263a421f212758333513d68018017774ee5f13a (dev) dev branch submission2
* | 953868d46d2f8b3536efc575b79a283c0ad9e0d1 dev branch submission to master
|/  
* b246a46d2317c14daae590c8a29f98ecf2a90f83 dev branch submission
* ce6352fdd1ad277c10ffd008e21c2242acf87dad rm code2.txt
* 7dfafe0ec234807ce5cc6d5db33d66f45bd6f1aa verson 4
* 85984321ceebb6b56fb336d11c3b287e966072d2 verson 3
* 399f3d2c26af9e11434460b3a71403f56d1e6bf7 verson 2
* 2522dc5642ded17edaeca49f4c31b46c6d65cca5 verson 1
xm@ubuntu:~/xm-git/git_test$ git branch -d dev 
Deleted branch dev (was 3263a42).

四、分支管理策略

通常,合并分支时,如果可能,git会用fast forward模式,但是有些快速合并不能成而且合并时没有冲突,这个时候会合并之后并做一次新的提交。但这种模式下,删除分支后,会丢掉分支信息

创建并切换到dev分支下,新建一个文件code3.txt并提交一个commit,切换回master分支,编辑code.txt并进行提交一个commit

xm@ubuntu:~/xm-git/git_test$ git branch -d dev 
Deleted branch dev (was 3263a42).
xm@ubuntu:~/xm-git/git_test$ git checkout -b dev
Switched to a new branch 'dev'
xm@ubuntu:~/xm-git/git_test$ touch code3.txt 
xm@ubuntu:~/xm-git/git_test$ git add code3.txt 
xm@ubuntu:~/xm-git/git_test$ git commit -m 'creat code3.txt'
[dev b5a77c2] creat code3.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 code3.txt
xm@ubuntu:~/xm-git/git_test$ git checkout master 
Switched to branch 'master'
xm@ubuntu:~/xm-git/git_test$ vi code.txt 
xm@ubuntu:~/xm-git/git_test$ cat code.txt 
this is the first line
this is the second line
this is the third line
this is the forth line
add one line
one more line in master
add one more line
a line
xm@ubuntu:~/xm-git/git_test$ git add code.txt 
xm@ubuntu:~/xm-git/git_test$ git commit -m 'creat new line'
[master 12de830] creat new line
 1 file changed, 1 insertion(+)

这时我们再进行合并dev分支的内容到master分支,出现如下提时,这是因为这次不能进行快速合并,所以git提示输入合并说明信息,输入之后合并内容之后git会自动创建一次新的提交

使用分支命令查看分支信息,并删除dev分支

xm@ubuntu:~/xm-git/git_test$ git log --pretty=oneline --graph 
*   0941e3a0e2f621d7b7114717861d9e47caf87456 (HEAD -> master) Merge branch 'dev'
|\  
| * d3aa0e2106991361978ce47109fd933ab1b88096 (dev) creat code3.txt
* | 12de8303cc2a03a5cbef58a55055b9a78afadfda creat new line
|/  
*   19cf6254482bd1c207d14a8a8bc0d813c14ff5a1 conflict resolution
|\  
| * 3263a421f212758333513d68018017774ee5f13a dev branch submission2
* | 953868d46d2f8b3536efc575b79a283c0ad9e0d1 dev branch submission to master
|/  
* b246a46d2317c14daae590c8a29f98ecf2a90f83 dev branch submission
* ce6352fdd1ad277c10ffd008e21c2242acf87dad rm code2.txt
* 7dfafe0ec234807ce5cc6d5db33d66f45bd6f1aa verson 4
* 85984321ceebb6b56fb336d11c3b287e966072d2 verson 3
* 399f3d2c26af9e11434460b3a71403f56d1e6bf7 verson 2
* 2522dc5642ded17edaeca49f4c31b46c6d65cca5 verson 1
xm@ubuntu:~/xm-git/git_test$ git branch -d dev 
Deleted branch dev (was d3aa0e2).

如果要强制禁用fast forward模式,git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息,示例如下

创建并切换到dev分支,修改code.txt内容,并提交一个commit,切换回master分支,准备合并dev分支,注意加上--no-ff参数,表示禁用Fast forward,因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去

xm@ubuntu:~/xm-git/git_test$ git branch -d dev 
Deleted branch dev (was d3aa0e2).
xm@ubuntu:~/xm-git/git_test$ git checkout -b dev
Switched to a new branch 'dev'
xm@ubuntu:~/xm-git/git_test$ vi code.txt 
xm@ubuntu:~/xm-git/git_test$ git add code.txt 
xm@ubuntu:~/xm-git/git_test$ git commit -m 'creat new line'
[dev 2dfc772] creat new line
 1 file changed, 1 insertion(+)
xm@ubuntu:~/xm-git/git_test$ git checkout master 
Switched to branch 'master'
xm@ubuntu:~/xm-git/git_test$ git merge --no-ff -m 'forbid fast forward' dev
Merge made by the 'recursive' strategy.
 code.txt | 1 +
 1 file changed, 1 insertion(+)

合并后,我们用git log看看分支历史,可以看到,不使用Fast forward模式,merge后就像这样

xm@ubuntu:~/xm-git/git_test$ git log --pretty=oneline --graph 
*   a6dc3c330eb66d7410925f6ad1c73c6b5fde8a14 (HEAD -> master) forbid fast forward
|\  
| * 2dfc7722d535abeb905ec3fda716628a829bab2d (dev) creat new line
|/  
*   0941e3a0e2f621d7b7114717861d9e47caf87456 Merge branch 'dev'
|\  
| * d3aa0e2106991361978ce47109fd933ab1b88096 creat code3.txt
* | 12de8303cc2a03a5cbef58a55055b9a78afadfda creat new line
|/  
*   19cf6254482bd1c207d14a8a8bc0d813c14ff5a1 conflict resolution
|\  
| * 3263a421f212758333513d68018017774ee5f13a dev branch submission2
* | 953868d46d2f8b3536efc575b79a283c0ad9e0d1 dev branch submission to master
|/  
* b246a46d2317c14daae590c8a29f98ecf2a90f83 dev branch submission
* ce6352fdd1ad277c10ffd008e21c2242acf87dad rm code2.txt
* 7dfafe0ec234807ce5cc6d5db33d66f45bd6f1aa verson 4
* 85984321ceebb6b56fb336d11c3b287e966072d2 verson 3
* 399f3d2c26af9e11434460b3a71403f56d1e6bf7 verson 2
* 2522dc5642ded17edaeca49f4c31b46c6d65cca5 verson 1
xm@ubuntu:~/xm-git/git_test$ git branch -d dev

配图如下

五、Bug分支

软件开发中,bug就像家常便饭一样。有了bug就需要修复,在git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。

  • 当你接到一个修复一个代号001的bug的任务时,很自然地,你想创建一个分支bug-001来修复它,但是,等等,当前正在dev上进行的工作还没有提交,并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug,怎么办?
xm@ubuntu:~/xm-git/git_test$ git checkout -b dev
Switched to a new branch 'dev'
xm@ubuntu:~/xm-git/git_test$ ls
code3.txt  code.txt
xm@ubuntu:~/xm-git/git_test$ vi code.txt 
xm@ubuntu:~/xm-git/git_test$ git status 
On branch dev
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   code.txt

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

5.1 stash功能 

  • git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作,首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支,现在修复bug,把 the new line删掉,然后提交,修复完成后,切换到master分支,并完成合并,最后删除bug-001分支
xm@ubuntu:~/xm-git/git_test$ git stash 
Saved working directory and index state WIP on dev: a6dc3c3 forbid fast forward
xm@ubuntu:~/xm-git/git_test$ git checkout master 
Switched to branch 'master'
xm@ubuntu:~/xm-git/git_test$ git checkout -b bug-001
Switched to a new branch 'bug-001'
xm@ubuntu:~/xm-git/git_test$ vi code.txt 
xm@ubuntu:~/xm-git/git_test$ git add code.txt 
xm@ubuntu:~/xm-git/git_test$ git commit -m 'repair bug'
[bug-001 e21708f] repair bug
 1 file changed, 1 deletion(-)
xm@ubuntu:~/xm-git/git_test$ git checkout master 
Switched to branch 'master'
xm@ubuntu:~/xm-git/git_test$ git merge --no-ff  -m 'repair bug' bug-001 
Merge made by the 'recursive' strategy.
 code.txt | 1 -
 1 file changed, 1 deletion(-)
xm@ubuntu:~/xm-git/git_test$ git branch -d bug-001 
Deleted branch bug-001 (was e21708f).
  • 现在bug-001修复完成,是时候接着回到dev分支干活了!工作区是干净的,刚才的工作现场存到哪去了?用git stash list命令看看,工作现场还在,git把stash内容存在某个地方了,但是需要恢复一下

xm@ubuntu:~/xm-git/git_test$ git checkout dev 
Switched to branch 'dev'
xm@ubuntu:~/xm-git/git_test$ git status 
On branch dev
nothing to commit, working tree clean
xm@ubuntu:~/xm-git/git_test$ git stash list
stash@{0}: WIP on dev: a6dc3c3 forbid fast forward
xm@ubuntu:~/xm-git/git_test$ git stash pop
On branch dev
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   code.txt

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (df469b06e8d88e939793b29b0919fd732f3b0090)

5.2 小结

修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;

当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,恢复工作现场。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值