每次提交,Git 把它们串成⼀条时间线,这条时间线就是⼀个分支。git 初始化时默认创建了一个分支,即 master 分支。HEAD 严格来说不是指向提交,而是指向 master,master 才是指向提交的,所以,HEAD 指向的就是当前分支。一开始的时候,master 分支是一条线,Git 用 master 指向最新的提交,再用 HEAD 指向 master,就能确定当前分支,以及当前分支的提交点。
例如创建新的分支 dev,Git 新建了一个指针叫 dev,指向 master 相同的提交,再把 HEAD 指向 dev,就表示当前分支在 dev 上,创建分支命令:
$ git checkout -b dev
Switched to a new branch 'dev'
git checkout 命令加上 -b 参数表示创建并切换,相当于以下两条命令:
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
然后,用git branch命令查看当前分支:
$ git branch
* dev
master
git branch 命令会列出所有分支,当前分支前面会标一个 * 号。
如果切换分支:
$ git checkout master
Switched to branch 'master'
dev 上的工作完成了,就可以把 dev 合并到 master 上。最简单的方法,就是直接把 master 指向 dev 的当前提交,就完成了合并。dev 分支的工作成果合并到master分支上:
$ git merge dev
Updating d17efd8..fec145a
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
通常,合并分支时,如果可能,Git会用“Fast forward”模式,但这种模式下,删除分支后,会丢掉分支信息。如果要强制禁用“Fast forward”模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
$ git merge --no-ff -m "merge with no-ff" dev
Merge made by the 'recursive' strategy.
readme.txt | 1 +
1 file changed, 1 insertion(+)
--no-ff
参数,表示禁用“Fast forward”,因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
所以Git合并分支很快!就改变指针,工作区内容也不变!合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,就剩master分支。
$ git branch -d dev
Deleted branch dev (was fec145a).
$ git branch
* master
git branch -a
$ git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
$ 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")
查看文件内容:
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 用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,修改冲突后再次提交。
$ git log --graph --pretty=oneline --abbrev-commit
* 59bc1cb conflict fixed
|\
| * 75a857c AND simple
* | 400b400 & simple
|/
* fec145a branch test
...
用git log --graph
命令可以看到分支合并图。
在实际开发中,应该按照几个基本原则进行分支管理:首先,一个项目分支分为三类:一个master分支,一个次于master分支的次分支,和个人分支(每个人都有一个分支);其次,master 分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;干活都在次分支上,也就是说,分支是不稳定的,到某个时候,比如1.0版本发布时,再把分支合并到master上,在master分支发布1.0版本;最后,每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。所以,团队合作的分支看起来就像这样:
软件开发中,有了bug就需要修复,在Git中,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
但是很多时候,目前的工作没法提交,可以使用 stash 功能。
其实在开发新功能的时候,和修复 bug 的概念一样,都是建议重新建立一个分支功能分支,然后合并,删除分支,如果要丢弃一个没有被合并过的分支,可以通过vgit branch -D name
强行删除。
在使用git checkout , git status,或git diff files时会出现奇怪的标志。如M,T,D,A,R,U等等。
$ git checkout master
M cpp-iniparser
文件cpp-iniparser前面有个M。git的这些奇怪标志是什么意思呢。
A: 增加的文件。
C: 文件的一个新拷贝。
D: 删除的一个文件。
M: 文件的内容或者mode被修改了。
R: 文件名被修改了。
T: 文件的类型被修改了。
U: 文件没有被合并。(你需要完成合并才能进行提交)
X: 未知状态。(很可能是遇到git的bug了,你可以向git提交bug report)
在git diff-files的手册man git diff-files中可以查到这些标志的说明。
这些状态标志在git的源代码的diff.h文件中被定义。
git 切换分支时会把未 add 或未 commit 的内容带过去,因为未add的内容不属于任何一个分支, 未commit的内容也不属于任何一个分支。 也就是说,对于所有分支而言, 工作区和暂存区是公共的。
要想在分支间切换, 又不想又上述影响, 怎么办呢?git stash
搞起。要注意,在当前分支git stash的内容, 在其他分支也可以git stash pop出来,为什么? 因为:工作区和暂存区是公共的。
另外一种方法就是用 git add
和 git commit
提交修改,只要用 git status
检查工作区和暂存区是干净的就可以了。
git clone git@X.X.5X.X:share/test.git
Zh@Zh-PC MINGW64 /d/Git/test (master)
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/dev
remotes/origin/feature
remotes/origin/master
git clone默认会把远程仓库整个给clone下来,但只会在本地默认创建一个master分支。
$ git checkout -b feature origin/feature
,现在 $ git branch
,会出现:
* feature
masterl
$ git checkout -t origin/feature
假设分支名称为oldName
,想要修改为newName
;
因篇幅问题不能全部显示,请点此查看更多更全内容