参考博文:廖雪峰Git教程
分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
1 [root@mini05 zhangtest]# pwd
2 /opt/git_repository/zhangtest
3 [root@mini05 zhangtest]# git checkout -b dev
4 Switched to a new branch 'dev'
git checkout
命令加上-b
参数表示创建并切换,相当于以下两条命令:
1 $ git branch dev # 创建分支
2 $ git checkout dev # 使用分支
3 Switched to branch 'dev'
查看当前分支
1 [root@mini05 zhangtest]# git branch # 当前分支前面会标一个*号
2 * dev
3 master
在当前分支提交信息
1 [root@mini05 zhangtest]# cat test.info
2 111
3 222
4 333
5 where are you from? # 增加的内容
6 [root@mini05 zhangtest]# git add test.info
7 [root@mini05 zhangtest]# git commit -m "add test.info"
8 [dev 068d030] add test.info
9 1 file changed, 1 insertion(+)
OK,现在 dev
分支的工作完成,我们就可以切换回master
分支
切回master分支
1 [root@mini05 zhangtest]# git checkout master
2 Switched to branch 'master'
3 [root@mini05 zhangtest]# git branch
4 dev
5 * master
6 [root@mini05 zhangtest]# cat test.info
7 111
8 222
9 333
切换回master
分支后,再查看一个test.info文件,刚才添加的内容不见了!因为那个提交是在dev
分支上,而master
分支此刻的提交点并没有变
合并dev分支
把dev
分支的工作成果合并到master
分支上
1 [root@mini05 zhangtest]# git merge dev
2 Updating c752e64..068d030
3 Fast-forward
4 test.info | 1 +
5 1 file changed, 1 insertion(+)
6 [root@mini05 zhangtest]# cat test.info
7 111
8 222
9 333
10 where are you from?
合并后,再查看test.info的内容,就可以看到,和dev
分支的最新提交是完全一样的。
1 [root@mini05 zhangtest]# git branch -d dev # 删除分支
2 Deleted branch dev (was 068d030).
3 [root@mini05 zhangtest]# git branch
4 * master
因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master
分支上工作效果是一样的,但过程更安全。
1 [root@mini05 zhangtest]# git checkout -b feature1
2 Switched to a new branch 'feature1'
3 [root@mini05 zhangtest]# tail -n3 README.md # 最后一行为新加的
4 ccc
5 ddd
6 Creating a new branch is quick AND simple.
添加并提交到本地仓库
1 [root@mini05 zhangtest]# git add README.md
2 [root@mini05 zhangtest]# git commit -m "RE new line"
3 [feature1 75b1490] RE new line
4 1 file changed, 1 insertion(+)
切换到master分支
1 [root@mini05 zhangtest]# git checkout master
2 Switched to branch 'master'
3 Your branch is ahead of 'origin/master' by 1 commit.
4 (use "git push" to publish your local commits)
在master
分支上把readme.txt
文件的最后添加一行并提交
1 [root@mini05 zhangtest]# tail -n3 README.md # 最后一行为添加
2 ccc
3 ddd
4 Creating a new branch is quick & simple.
5 [root@mini05 zhangtest]# git add README.md
6 [root@mini05 zhangtest]# git commit -m "ma commit"
7 [master 41de15c] ma commit
8 1 file changed, 1 insertion(+)
现在,master
分支和feature1
分支各自都分别有新的提交,变成了这样
尝试合并feature1
1 [root@mini05 zhangtest]# git merge feature1
2 Auto-merging README.md
3 CONFLICT (content): Merge conflict in README.md
4 Automatic merge failed; fix conflicts and then commit the result.
查看冲突的文件
1 [root@mini05 zhangtest]# git status
2 # On branch master
3 # Your branch is ahead of 'origin/master' by 2 commits.
4 # (use "git push" to publish your local commits)
5 #
6 # You have unmerged paths.
7 # (fix conflicts and run "git commit")
8 #
9 # Unmerged paths:
10 # (use "git add <file>..." to mark resolution)
11 #
12 # both modified: README.md
13 #
14 no changes added to commit (use "git add" and/or "git commit -a")
直接查看冲突内容并修改
1 [root@mini05 zhangtest]# cat README.md # 查看冲突内容
2 # zhangtest
3 zhangtest
4 张三
5 Git is a distributed version control system.
6 Git is free software.
7 111
8 222
9 Git tracks changes.
10 aaa
11 bbb
12 ccc
13 ddd
14 <<<<<<< HEAD
15 Creating a new branch is quick & simple.
16 =======
17 Creating a new branch is quick AND simple.
18 >>>>>>> feature1
修改后保留的内容并再次提交
1 [root@mini05 zhangtest]# cat README.md
2 # zhangtest
3 zhangtest
4 张三
5 Git is a distributed version control system.
6 Git is free software.
7 111
8 222
9 Git tracks changes.
10 aaa
11 bbb
12 ccc
13 ddd
14 Creating a new branch is quick AND simple.
15 [root@mini05 zhangtest]# git add README.md
16 [root@mini05 zhangtest]# git commit -m "conflict fixed"
17 [master 56c6e0c] conflict fixed
现在,master
分支和feature1
分支变成了下图所示:
用带参数的git log
也可以看到分支的合并情况
1 [root@mini05 zhangtest]# git log --graph --pretty=oneline --abbrev-commit
2 * 56c6e0c conflict fixed
3 |\
4 | * 75b1490 RE new line
5 * | 41de15c ma commit
6 |/
7 * 068d030 add test.info
8 * c752e64 add info
9 * 3b7db1c add aaa.txt
10 * c795cfc del aaa.txt
11 * 6d0226b add aaa.txt
12 * b293c46 git tracks changes
13 * 53f0f2e understand how stage works
14 * 65a58f2 add info
15 * d4fb57e Update README.md
16 * e730676 Initial commit
1 [root@mini05 zhangtest]# git branch -d feature1
2 Deleted branch feature1 (was 75b1490).
通常,合并分支时,如果可能,Git会用Fast forward
模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward
模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
下面我们实战一下 --no-ff
方式的git merge
1 [root@mini05 zhangtest]# git checkout -b dev
2 Switched to a new branch 'dev'
修改readme.txt文件,并提交.
1 [root@mini05 zhangtest]# tail -n3 README.md # 最后一行为新增行
2 Creating a new branch is quick AND simple.
3 feature2
4 dev brach new
5 [root@mini05 zhangtest]# git add README.md
6 [root@mini05 zhangtest]# git commit -m "dev brach new"
7 [dev ef9042a] dev brach new
8 1 file changed, 1 insertion(+)
切回到master分支
1 [root@mini05 zhangtest]# git checkout master
2 Switched to branch 'master'
3 Your branch is ahead of 'origin/master' by 5 commits.
4 (use "git push" to publish your local commits)
5 [root@mini05 zhangtest]# git branch
6 dev
7 * master
准备合并dev
分支,请注意 --no-ff
参数,表示禁用Fast forward
:
1 [root@mini05 zhangtest]# git merge --no-ff -m "merge with no-ff" dev
2 Merge made by the 'recursive' strategy.
3 README.md | 1 +
4 1 file changed, 1 insertion(+)
因为本次合并要创建一个新的commit,所以加上-m
参数,把commit描述写进去。
合并后,我们用git log
看看分支历史:
1 [root@mini05 zhangtest]# git log --graph --pretty=oneline --abbrev-commit
2 * aadf8b4 merge with no-ff
3 |\
4 | * ef9042a dev brach new
5 |/
6 * 31230a8 feature2
7 * 56c6e0c conflict fixed
8 |\
9 | * 75b1490 RE new line
10 * | 41de15c ma commit
11 |/
12 * 068d030 add test.info
13 * c752e64 add info
14 * 3b7db1c add aaa.txt
15 ………………
可以看到,不使用Fast forward
模式,merge后就像这样:
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master
分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev
分支上,也就是说,dev
分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev
分支合并到master
上,在master
分支发布1.0版本;
你和你的小伙伴们每个人都在dev
分支上干活,每个人都有自己的分支,时不时地往dev
分支上合并就可以了。
所以,团队合作的分支看起来就像这样: