分支( branches ) 是指在开发主线中分离出来,作进一步开发而不影响到原来主线。html
Git 存储的不是一系列的更改集( changeset ),而是一系列快照。当你执行一次 commit 时, Git 存储一个 commit 对象,它包含一个指针指向你当前须要提交的内容的快照。git
Git 中的 master 分支的功能,和其余分支同样。master 在 git 项目中常见到,是由于 git init 命令运行时默认建立一个分支,并命名为 master。github
建立一个新的分支,就是建立一个新的指针,用来在快照间移动。Git 经过 HEAD 指针,指向当前工做的本地分支。shell
$ git branch testing
使用 git checkcout 命令,能够切换分支。vim
$ git checkout testing
修改文件并 commit 代码后,会移动分支的指针测试
$ vim test.rb $ git commit -a -m 'update test.rb'
经过 checkout 能够切换回去 master 分支。下面的命令作了两件事,一是把 HEAD 指针指向了 master 分支,二是当前工做目录的文件恢复到了 master 所指向的快照版本。也就是说 87ab2 提交的变更,在切换到 master 分支时被移除。网站
$ git checkout master
再作一些变动和 commit 。注意,此时历史记录开始出现分叉。spa
$ vim test.rb $ git commit -a -m 'make other changes'
Git 中的分支,其实是一个简单的包含 40 个字符的文件,这 40 个字符是一次提交所产生的 SHA-1 checksum。因此,在 Git 中建立和销毁一个分支的成本很是低。这个和其余大多数版本管理系统比起来,Git 无需拷贝整个项目的文件,是一个巨大的不一样点。3d
基本的分支与合并指针
下面的例子是一个比较常见的场景,应用了分支与合并的功能。
这时,接收到另外一个紧急的问题,须要马上修复( hotfix )
4. 切换到生产环境分支
5. 建立一个新的分支 ( hotfix ),用于修复线上问题
6. 测试事后,把修复分支合并到主分支上,并推送到生产环境
7. 切换到原来的需求分支,继续工做
最开始的状态以下
经过 branch / checkout / commit 等操做,作到上面的第 5 步, 状态以下
接下来,先合并 hotfix 分支,而后部署到线上环境。
$ git checkout master $ git merge hotfix Updating f42c576..3a0874c Fast-forward index.html | 2 ++ 1 file changed, 2 insertions(+)
上面的提示中,有 Fast-forward 字眼,代表 hotfix 分支指向的 c4 提交,是 master 分支指向的 c3 提交的祖先,所以,直接把 master 移动到 c4 便可。合并后效果关系以下
因为 hotfix 已经合并到 master 分支,此时 master 和 hotfix 指向同一个地方,后续不在须要用到 hotfix 分支,因此能够删除。
$ git branch -d hotfix
下来了能够切换到 iss53 分支继续工做,继续修改,而后提交。当修改完毕后,关系大体以下
$ git checkout iss53 Switched to branch "iss53" $ vim index.html $ git commit -a -m 'finished the new footer [issue 53]' [iss53 ad82d7a] finished the new footer [issue 53] 1 file changed, 1 insertion(+)
接下来开始合并。
$ git checkout master Switched to branch 'master' $ git merge iss53 Merge made by the 'recursive' strategy. index.html | 1 + 1 file changed, 1 insertion(+)
这里合并无了 Fast-forward 字眼,由于不是简单的移动分支指针。Git 采用三路合并( three-way merge ) 方式进行合并,建立了一个 commit ( c6 ),用于包含合并后的结果。三路合并方式,是指经过两个分支的最新提交( c4 和 c5 ),以及他们的共同祖先 c2,来进行分支合并。c6 是一个合并提交记录,特别之处是有两个祖先。
此时,你已不在须要 iss53 分支,能够删除它.
$ git branch -d iss53
基本合并冲突处理
若是两个分支修改同一个文件的同一个部分,例如同一行代码,Git 不知道如何合并,认为这是一个冲突。例如你在 iss53 和 hotfix 分支都修改了 index.html 文件的同一个部分,合并 iss53 到已包含 hotfix 的 master 分支时,效果以下
$ git merge iss53 Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result.
此时,自动合并暂停,须要手动合并。 git status 显示冲突了的文件
$ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") Unmerged paths: (use "git add <file>..." to mark resolution) both modified: index.html no changes added to commit (use "git add" and/or "git commit -a")
Git 在冲突的文件中添加标准的冲突解决标识。
<<<<<<< HEAD:index.html <div id="footer">contact : email.support@github.com</div> ======= <div id="footer"> please contact us at support@github.com </div> >>>>>>> iss53:index.html
这个代表,HEAD 版本的代码是 ======= 以上部分,iss53 的版本是 ======= 如下部分。
开打 index.html 文件,修改为本身想要的版本,并剔除 <<<<<<< ======= >>>>>>> 标识,而后用 git add 标识冲突已接近,而后git commit 提交解决冲突后的版本。
参考资料