我们一定在某个分支上工作——master分支,这是git特性决定的。关于这一点,我们可以在gitdemo目录下执行git branch命令来查看,会得到这样的结果:
* master
这个命令列出现存本地分支,并以星号(*)高亮当前所在的分支。
git branch -r列出远程分支
git branch -a列出远程分支和本地分支
我们需要在分支上工作
几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。
通常,master分支作为稳定分支,和线上发布版同步,不适合频繁更改。我们会建立多个开发分支,在开发分支上开发、测试,直到认为新功能或旧功能改造完全完成,再往主分支上合并。整个过程就像一条河流,有多个支流,每个支流都各自向前推进,某些地方他么又并入主干,然后在下面的某个地方有分叉开来,但最终汇入大海。
创建一个开发分支
git branch testing # 新建分支
执行这个命令仍在 master 分支上。 因为 git branch 命令仅仅创建 一个新分支,并不会自动切换到新分支中去。
切换分支
$ git checkout testing # 切换分支
$ git branch # 查看分支
* testing
master
$ ll #查看目录结构
查看目录结构我们发现和切换前一模一样,这是因为新建分支并不是建立一个完全无关的空目录,事实上只是在此处开叉了
git checkout -,快速切换回上个分支。练习执行两次又会回到当前分支。
git checkout -b testing可新建并立即切换分支。
分支的机制
git的分支,本质上仅仅是指向提交对象的可变指针。
创建分支,git只是为你创建了一个可以移动的新的指针,指针的名字就是分支的名字,你可以这样认为分支就是指针。创建一个testing分支,这会在当前所在的提交对象上创建一个指针(名字叫testing)。
它有一个名为HEAD的特殊指针。在 Git 中,它是一个指针,指向当前所在的本地分支。
在新分支上工作并提交
我们已经成功切换到testing分支,现在我们可以在testing分支上做一些自己的开发任务,而不用担心影响主分支。
每个分支都可以独立地向前推进,如下:
HEAD和分支随着提交操作自动向前移动
不同分支间不断地来回切换和工作,在时机成熟时将它们合并起来。
分支合并
现在我们在主分支,我们认为testing上的改变很重要,现在希望master上拥有这些变化,这么做
$ git branch # 确认当前分支
$ git merge testing # 将testing的修改合并到当前master分支
---
Merge made by the 'recursive' strategy.
lesson2/test.rb | 1 +
1 file changed, 1 insertion(+)
create mode 100644 lesson2/test.rb
合并会产生新的提交,因此,git弹出文本编辑器要求你记录下这次合并的日志。
删除分支
$ git branch -d testing # 删除分支
解决分支合并冲突
在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git就没法干净的合并它们。
git checkout -b dev #新建并切换分支
vi test1.rb #编辑test1.rb,在第二行输入"dev中新增一行"
git add .
git commit -m "dev change test1"
git checkout master
vi test1.rb #编辑test1.rb,在第二行输入"master新增一行"
git add .
git commit -m "master change test1"
现在来合并
git merge dev
—
Auto-merging lesson2/test1.rb
CONFLICT (content): Merge conflict in lesson2/test1.rb
Automatic merge failed; fix conflicts and then commit the result.
此时 Git 做了合并,但是没有自动地创建一个新的合并提交。 Git 会暂停下来,等待你去解决合并产生的冲突。明显,lesson2/test1.rb 是有冲突的文件,自动合并失败,需要我们手工解决冲突然后再提交
合并冲突后的任意时刻使用 git status 命令来查看那些因包含合并冲突而处于未合并(unmerged)状态的文件。
Git 会在有冲突的文件中加入标准的冲突解决标记,这样你可以打开这些包含冲突的文件然后手动解决冲突。 出现冲突的文件会包含一些特殊区段,看起来像下面这个样子:
复制
testsomething
<<<<<<< HEAD
master新增一行
=======
dev中新增一行
>>>>>>> dev
=======将内容分为两部分,<<<<<<< HEAD和分割线中间的部分表示HEAD所指的版本(也就是你的 master 分支所在的位置,因为你在运行 merge 命令的时候已经检出到了这个分支),而分割线和>>>>>>> dev中间的部分是dev分支的版本。
为了解决冲突,你必须选择使用由 ======= 分割的两部分中的一个,或者你也可以自行合并这些内容。
在你解决了所有文件里的冲突之后,对每个文件使用 git add 命令来将其标记为冲突已解决,然后提交