分支管理
分支在实际中的作用是,再给当前项目开发新功能的时候,可以将新功能未完成的代码库提交到独立的分支,但整体完成后再合并到主分支。从而既保证了原项目能正常运作,又杜绝了新功能丢失进度的风险。
创建与合并分支
创建dev
分支:
$ git checkout -b dev
Switched to a new branch 'dev'
git checkout
命令加上-b
参数表示创建并切换,相当于以下两条命令:
$ git branch dev
$ git checkout dev
用git branch
命令查看当前分支:
$ git branch
* dev
master
git branch
命令会列出所有分支,并在当前分支前标*
号。
现在可以在dev
分支上进行修改,比如在readme.txt
加上一行:
Creating a new branch is quick.
在提交并切换到master
分支后,可以发现master
分支的提交点没有变化。
接下来合并master
分支和dev
分支:
$ git merge dev
Updating b3ce958..f39faf9
Fast-forward
readme.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Fast-forward
信息表示此次合并是”快进模式“,直接把master
指向dev
的提交。
合并完成后可以放心删除dev
分支:
$ git branch -d dev
Deleted branch dev (was f39faf9).
解决冲突
在合并分支是也可能会出现一些问题,比如:
创建一个新的分支featurel
,并将readme.txt
文件的最后一行改为:
Creating a new branch is quick AND simple.
在featurel
分支上提交:
$ git add readme.txt
$ git commit -m "And simple"
[featurel 724fe08] And simple
1 file changed, 1 insertion(+), 1 deletion(-)
切换到master
分支:
$ git checkout 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
分支上把readme.txt
文件的最后一行修改为:
Creating a new branch is quick & simple.
并提交,那么master
分支与featurel
分支都分别有了新的提交,如图:
这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,比如:
$ git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
readme.txt
文件存在冲突,需要手动解决之后才能提交。此时可用git status
查找冲突的文件。
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
# Unmerged paths:
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified: readme.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
此时编辑readme.txt
可以看到:
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1
Git用<<<<<<<
,=======
,>>>>>>>
标记出不同分支的内容。
再次修改如下后保存:
Creating a new branch is quick and simple.
并提交:
$ git add readme.txt
$ git commit -m "conflict fixed"
[master f648aa0] conflict fixed
现在的分支情况就如下图所示:
用带参数的git log也可以看到分支的合并情况:
* f648aa0 conflict fixed
|\
| * 44f163b AND simple
* | 2a2a0d6 & simple
|/
* 2db35f3 brach test
...
最后,删除feature1
分支:
$ git branch -d feature1
Deleted branch feature1 (was 44f163b).
分支管理策略
合并分支时,加上--no-ff
参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward
合并就看不出来曾经做过合并。
操作如下:
$ git checkout -b dev
Switched to a new branch 'dev'
$ git add readme.txt
$ git commit -m "add merge"
[dev 6224937] add merge
1 file changed, 1 insertion(+)
$ git checkout master
Switched to branch 'master'
$ git merge --no-ff -m "merge with no-ff" dev
Merge made by the 'recursive' strategy.
readme.txt | 1 +
1 file changed, 1 insertion(+)
此时用git log
可查看分支历史:
$ git log --graph --pretty=oneline --abbrev-commit
* 7825a50 merge with no-ff
|\
| * 6224937 add merge
|/
* 59bc1cb conflict fixed
...
Bug分支
Git提供了stash
功能可以暂存不方便提交的工作,以便于切换到其他分支时不丢失当前进度。
示例:
$ git stash
Saved working directory and index state WIP on dev: 6224937 add merge
HEAD is now at 6224937 add merge
可用git stash list
查看暂存的工作。
恢复则有两种选择,一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;
另一种方式是用git stash pop,恢复的同时把stash内容也删了。
Future 分支
软件开发中,总有无穷无尽的新的功能要不断添加进来。
添加一个新功能时,肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature
分支,在上面开发,完成后,合并,最后,删除该feature
分支。
现在,终于接到了一个新任务:开发代号为Vulcan的新功能,该功能计划用于下一代星际飞船。
于是准备开发:
$ git checkout -b feature-vulcan
Switched to a new branch 'feature-vulcan'
5分钟后,开发完毕:
$ git add vulcan.py
$ git status
# On branch feature-vulcan
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: vulcan.py
#
$ git commit -m "add feature vulcan"
[feature-vulcan 756d4af] add feature vulcan
1 file changed, 2 insertions(+)
create mode 100644 vulcan.py
切回dev
,准备合并:
$ git checkout dev
一切顺利的话,feature
分支和bug
分支是类似的,合并,然后删除。
但是,就在此时,接到上级命令,因经费不足,新功能必须取消!
虽然白干了,但是这个分支还是必须就地销毁:
$ git branch -d feature-vulcan
error: The branch 'feature-vulcan' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature-vulcan'.
销毁失败。Git友情提醒,feature-vulcan
分支还没有被合并,如果删除,将丢失掉修改,如果要强行删除,需要使用命令git branch -D feature-vulcan
。
现在强行删除:
$ git branch -D feature-vulcan
Deleted branch feature-vulcan (was 756d4af).
删除成功!
多人协作
当从远程仓库克隆时,实际上Git自动把本地的master
分支和远程的master
分支对应起来了,并且,远程仓库的默认名称是origin
。
要查看远程库的信息,用git remote
:
$ git remote
origin
或者,用git remote -v显示更详细的信息:
$ git remote -v
orgin https://github.com/yimingjin1995/learngit.git (fetch)
orgin https://github.com/yimingjin1995/learngit.git (push)
上面显示了可以抓取和推送的origin
的地址。如果没有推送权限,就看不到push的地址。
推送分支
推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支。例如:
$ git push origin dev