赞
踩
Git为我们提供了杀手级的武器之一,分支。通过上一次的博客分享可以知道,我们都是在主分支上操作的,所以说我们操作的都是在一条分支上操作,对应着只有⼀条时间线。
我们可以使用git log指令添加对应的参数可以查看到:
[xiyan@hecs-34711 git_space]$ git log --graph
我们在master分支上也能直接操作,为什么还要有分支?
首页要遵守一个原则:master主分支上的代码要求是稳定的! 因为在一个项目中放在线上跑的代码就是master分支中的代码!如果我们在master分支中直接修改代码,很难保证不会出现bug,我们可以创建其他的分支,通过测试之后确定没有致命的bug之后,在通过分支合并也能添加在原有的代码上添加功能,这就是分支带来的好处。
举个例子:
假如你会分身,那么你可以同时学习C++和Java当你合并你的分身,就可以同时拥有C++和Java的两门语言的技术。
使用git branch 分支名来创建分支:
[xiyan@hecs-34711 git_space]$ git branch # 查看本机上所有的分支
* master
[xiyan@hecs-34711 git_space]$ git branch dev # 创建分支
[xiyan@hecs-34711 git_space]$ git branch
dev
* master
我们创建一个dev分支, 而* 表⽰当前 HEAD 指向的分⽀是 master 分⽀。
[xiyan@hecs-34711 git_space]$ ls .git/refs/heads/
dev master
[xiyan@hecs-34711 git_space]$ cat .git/refs/heads/*
0c376930fcf814ee8b856bec05588e4cfa9fbd69
0c376930fcf814ee8b856bec05588e4cfa9fbd69
[xiyan@hecs-34711 git_space]$ cat .git/HEAD
ref: refs/heads/master
可以是一张图表示:
使用git checkout命令:
[xiyan@hecs-34711 git_space]$ git checkout dev
Switched to branch 'dev'
[xiyan@hecs-34711 git_space]$ git branch
* dev
master
[xiyan@hecs-34711 git_space]$ cat .git/HEAD
ref: refs/heads/dev
如图:
我们在dev分支修改write文件的内容,添加一行"updata msg in dev branch!":
[xiyan@hecs-34711 git_space]$ git branch * dev master [xiyan@hecs-34711 git_space]$ cat write 绝知此事要躬行! 劝君惜取少年时! 知行合一! updata msg in dev branch! [xiyan@hecs-34711 git_space]$ git checkout master Switched to branch 'master' [xiyan@hecs-34711 git_space]$ git branch dev * master [xiyan@hecs-34711 git_space]$ cat write 绝知此事要躬行! 劝君惜取少年时! 知行合一!
可以发现在dev分支上修改的代码在非dev分支,这里就是在master分支下演示,在没有合并的情况下不能查看到内容的修改。
git merge 命令⽤于合并指定分⽀到当前分⽀,我们在master分支上将dev修改的内容合并到master中。
[xiyan@hecs-34711 git_space]$ git branch dev * master [xiyan@hecs-34711 git_space]$ cat write 绝知此事要躬行! 劝君惜取少年时! 知行合一! [xiyan@hecs-34711 git_space]$ git branch dev * master [xiyan@hecs-34711 git_space]$ git merge dev Updating 7157a24..1c78662 Fast-forward write | 1 + 1 file changed, 1 insertion(+) [xiyan@hecs-34711 git_space]$ cat write 绝知此事要躬行! 劝君惜取少年时! 知行合一! updata msg in dev branch!
合并后的master指向了,dev提交的版本。
Fast-forward 代表“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度⾮常快。这样的方式来合并分支不能很好的反映,是哪一个分支提交了代码。
关于非Fast-forward模式在理解分支冲突后更好说明。
合并完成后, dev 分⽀存在就没有什么价值,我们可以将dev分支删除, 我们删除分支是如果当前正处于某分⽀下,就不能删除当前分⽀,如:
[xiyan@hecs-34711 git_space]$ git branch
* dev
master
[xiyan@hecs-34711 git_space]$ git branch -d dev
error: Cannot delete the branch 'dev' which you are currently on.
我们切换到master分支将dev分支经行删除:
[xiyan@hecs-34711 git_space]$ git checkout master
Switched to branch 'master'
[xiyan@hecs-34711 git_space]$ git branch
dev
* master
[xiyan@hecs-34711 git_space]$ git branch -d dev
Deleted branch dev (was 1c78662).
[xiyan@hecs-34711 git_space]$ git branch
* master
[xiyan@hecs-34711 git_space]$ cat .git/refs/heads/*
1c78662e550558d9542a2c2befa79d722de58a8f
因为创建、合并和删除分⽀⾮常快,所以Git⿎励你使⽤分⽀完成某个任务,合并后再删掉分⽀,这和直接在master分⽀上⼯作效果是⼀样的,但过程更安全。
这个地方我新创建了一个dev1然后在dev1上添加内容"write context: I am zhangsan!",然后在合并到master分支上,大家可以在按照上面的内容操作!
[xiyan@hecs-34711 git_space]$ cat write
绝知此事要躬行!
劝君惜取少年时!
知行合一!
千里之行始于足下!
updata msg in dev branch!
write context: I am zhangsan!
我们分别在master和dev1分支上将zhangsan的名字修改成,lisi,wangwu。
# 在master上修改 [xiyan@hecs-34711 git_space]$ git branch dev1 * master [xiyan@hecs-34711 git_space]$ vim write [xiyan@hecs-34711 git_space]$ git add write [xiyan@hecs-34711 git_space]$ git commit -m "modify name lisi" [master 6caa00b] modify name lisi 1 file changed, 1 insertion(+), 1 deletion(-) [xiyan@hecs-34711 git_space]$ cat write 绝知此事要躬行! 劝君惜取少年时! 知行合一! 千里之行始于足下! updata msg in dev branch! write context: I am lisi! # 在dev1上修改 [xiyan@hecs-34711 git_space]$ git branch * dev1 master [xiyan@hecs-34711 git_space]$ vim write [xiyan@hecs-34711 git_space]$ git add write [xiyan@hecs-34711 git_space]$ git commit -m "modify name wangwu" [dev1 11ba100] modify name wangwu 1 file changed, 1 insertion(+), 1 deletion(-) [xiyan@hecs-34711 git_space]$ cat write 绝知此事要躬行! 劝君惜取少年时! 知行合一! 千里之行始于足下! updata msg in dev branch! write context: I am wangwu!
上面我们修改了相同的内容在不同的分支上,如果我们合并分支,那么就会产生分支冲突的问题。
[xiyan@hecs-34711 git_space]$ git branch dev1 * master [xiyan@hecs-34711 git_space]$ git merge dev1 Auto-merging write CONFLICT (content): Merge conflict in write Automatic merge failed; fix conflicts and then commit the result. [xiyan@hecs-34711 git_space]$ cat write 绝知此事要躬行! 劝君惜取少年时! 知行合一! 千里之行始于足下! updata msg in dev branch! <<<<<<< HEAD write context: I am lisi! ======= write context: I am wangwu! >>>>>>> dev1
上面告诉我们HEAD(当前指向master)分支修改了lisi,dev1修改成了wangwu,产生冲突。我们就需要手动的修改,并重新提交(注意注意注意)!!!
[xiyan@hecs-34711 git_space]$ vim write
[xiyan@hecs-34711 git_space]$ git add write
[xiyan@hecs-34711 git_space]$ git commit -m "resolve merge conflict issue"
[master 56ad858] resolve merge conflict issue
[xiyan@hecs-34711 git_space]$ cat write
绝知此事要躬行!
劝君惜取少年时!
知行合一!
千里之行始于足下!
updata msg in dev branch!
write context: I am lisi!
write context: I am wangwu!
至此我们解决了分支冲突的问题
上面的状态图就是根据这个画的
[xiyan@hecs-34711 git_space]$ git log --graph --pretty=oneline --abbrev-commit
* 56ad858 resolve merge conflict issue
|\
| * 11ba100 modify name wangwu
* | 6caa00b modify name lisi
|/
* 01eae4d write context in dev1
* 1c78662 in dev commit msg
* 7157a24 the write updata
* 0c37693 the first commit write
当然合并完分支之后可以删除分支。
1.关于Fast-forward
我们在没有分支合并的情况下,默认是Fast-forward模式的。我们可以是使用–no-ff来强制禁用Fast-forward,在 merge 时⽣成⼀个新的 commit ,这样,从分⽀历史上就可以看出分⽀信息。
[xiyan@hecs-34711 git_space]$ git branch * master [xiyan@hecs-34711 git_space]$ git checkout -b dev2 #创建并切换分支 Switched to a new branch 'dev2' [xiyan@hecs-34711 git_space]$ git branch * dev2 master [xiyan@hecs-34711 git_space]$ vim write [xiyan@hecs-34711 git_space]$ git add . [xiyan@hecs-34711 git_space]$ git commit -m "write modify" [dev2 06afc8c] write modify 1 file changed, 1 insertion(+) [xiyan@hecs-34711 git_space]$ cat write 绝知此事要躬行! 劝君惜取少年时! 知行合一! 千里之行始于足下! updata msg in dev branch! write context: I am lisi! write context: I am wangwu! use --no-ff merge branch! [xiyan@hecs-34711 git_space]$ git checkout master Switched to branch 'master' [xiyan@hecs-34711 git_space]$ git branch dev2 * master [xiyan@hecs-34711 git_space]$ git merge --no-ff -m "merge with --no-ff" dev2 Merge made by the 'recursive' strategy. write | 1 + 1 file changed, 1 insertion(+) [xiyan@hecs-34711 git_space]$ git log --graph --pretty=oneline * 9a86419a4c36e6d0957e85888652554452a96d07 merge with --no-ff |\ | * 06afc8c5adb965827d538992a6dd845fde23b3b6 write modify |/ * 56ad85873d2b592ecac9dfbf19030e2050b403c5 resolve merge conflict issue
确实可以观察到分支修改的变化。
2.关于很多分支策略
如何在团队开发的过程中,创建了很多分支,如图:
我们创建分支的目的是为了让master分支保持稳定,但是我们前面的,都是在master上直接合并分支,这样还是不能保证master分支的稳定性,怎么办?
我们前面都是这样在master分支直接合并,是不好的做法,当参数分支冲突的时候我们手动的修改代码,然后没有经过测试直接就在master分支上,无法很好的保证master分支的稳定性。
更推荐下面的做法:
3.bug分支
场景:当我们在dev2分支上开发,现在代码开发到一半,现在master分支上有一个bug急需解决,那么我们就需要创建一个fix_bug的分支来修改bug,然后删除fix_bug分支。
那我们在dev2上写的代码还在工作区中,不好提交怎么办?
[xiyan@hecs-34711 git_space]$ vim write [xiyan@hecs-34711 git_space]$ cat write 绝知此事要躬行! 劝君惜取少年时! 知行合一! 千里之行始于足下! updata msg in dev branch! write context: I am lisi! write context: I am wangwu! user --no-ff merge branch! coding....... [xiyan@hecs-34711 git_space]$ git status # On branch dev2 # 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: write # no changes added to commit (use "git add" and/or "git commit -a") [xiyan@hecs-34711 git_space]$ git checkout -b fix_bug # 直接创建分支,把工作区的代码也携带了! M write Switched to a new branch 'fix_bug' [xiyan@hecs-34711 git_space]$ cat write 绝知此事要躬行! 劝君惜取少年时! 知行合一! 千里之行始于足下! updata msg in dev branch! write context: I am lisi! write context: I am wangwu! user --no-ff merge branch! coding....... [xiyan@hecs-34711 git_space]$ git branch dev2 fix_bug * master [xiyan@hecs-34711 git_space]$ git branch -d fix_bug # 删除 Deleted branch fix_bug (was 9a86419).
我们实验了,工作区的代码携带到了fix_bug分支中,这是我们不像看到的,使用git stash 命令,可以将当前的⼯作区信息进⾏储藏,被储藏的内容可以在将来某个时间恢复出来。
[xiyan@hecs-34711 git_space]$ git branch * dev2 master [xiyan@hecs-34711 git_space]$ git stash Saved working directory and index state WIP on dev2: 06afc8c write modify HEAD is now at 06afc8c write modify [xiyan@hecs-34711 git_space]$ git status # On branch dev2 nothing to commit, working directory clean [xiyan@hecs-34711 git_space]$ git checkout master Switched to branch 'master' [xiyan@hecs-34711 git_space]$ git branch dev2 * master [xiyan@hecs-34711 git_space]$ git checkout -b fix_bug Switched to a new branch 'fix_bug' [xiyan@hecs-34711 git_space]$ git branch dev2 * fix_bug master [xiyan@hecs-34711 git_space]$ cat write 绝知此事要躬行! 劝君惜取少年时! 知行合一! 千里之行始于足下! updata msg in dev branch! write context: I am lisi! write context: I am wangwu! user --no-ff merge branch! [xiyan@hecs-34711 git_space]$ cat .git/refs/heads/* 06afc8c5adb965827d538992a6dd845fde23b3b6 9a86419a4c36e6d0957e85888652554452a96d07 9a86419a4c36e6d0957e85888652554452a96d07
我们现在有了一个跟master分支状态一样的版本,我们就可以在fix_bug上修改bug,修改完毕过后,重新提交,然后就可以切换到master分支上经行合并,最好删除fix_bug分支。
这里的操作和前面的一样,如果大家跟着敲到这里,那么问题不大!
我们bug修改后我们来到dev2将⼯作现场恢复
[xiyan@hecs-34711 git_space]$ git checkout dev2 Switched to branch 'dev2' [xiyan@hecs-34711 git_space]$ git branch * dev2 master [xiyan@hecs-34711 git_space]$ git status # On branch dev2 nothing to commit, working directory clean [xiyan@hecs-34711 git_space]$ git stash list # 查看⼯作现场存到哪 stash@{0}: WIP on dev2: 06afc8c write modify [xiyan@hecs-34711 git_space]$ tree .git ...... └── refs ├── heads │ ├── dev2 │ ├── fix_bug │ └── master ├── stash └── tags
如何恢复现场,我们可以使⽤ git stash pop 命令,恢复的同时会把 stash 也删了,⽰例如下:
[xiyan@hecs-34711 git_space]$ git stash pop
# On branch dev2
# 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: write
#
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (66a75eb6bda32ca35c47bcdcafb6c77b5016e78f)
我们就又可以正常的开发代码了。
4.强制删除临时分⽀
场景:如果一个项目功能正在开发,突然被项目经理叫停,这个项目这个功能不用再做了,那么我们就要删除临时分支,创建一个dev3来演示一下:
[xiyan@hecs-34711 git_space]$ git branch fix_bug * master [xiyan@hecs-34711 git_space]$ git checkout -b dev3 M write Switched to a new branch 'dev3' [xiyan@hecs-34711 git_space]$ vim write [xiyan@hecs-34711 git_space]$ cat write 绝知此事要躬行! 劝君惜取少年时! 知行合一! 千里之行始于足下! updata msg in dev branch! write context: I am lisi! write context: I am wangwu! user --no-ff merge branch! in dev3 coding....... [xiyan@hecs-34711 git_space]$ git add write [xiyan@hecs-34711 git_space]$ git commit -m "modify in dev3" [dev3 dfc8c5f] modify in dev3 1 file changed, 1 insertion(+) [xiyan@hecs-34711 git_space]$ git checkout master Switched to branch 'master' [xiyan@hecs-34711 git_space]$ git branch -d dev3 # 无法删除 error: The branch 'dev3' is not fully merged. If you are sure you want to delete it, run 'git branch -D dev3'. [xiyan@hecs-34711 git_space]$ git branch dev3 * master [xiyan@hecs-34711 git_space]$ git branch -D dev3 Deleted branch dev3 (was dfc8c5f). [xiyan@hecs-34711 git_space]$ git branch * master
使用-D选项就可以删除已经提交过的但是没有合并的dev3分支。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。