这是git操作最大的一块儿,来吧,继续学习。
直至现在为止,我们的项目版本库一直都是只有一个分支 master。在 git 版本库中创建分支的成本几乎为零,所以,不必吝啬多创建几个分支。下面列举一些常见的分支策略,仅供大家参考:
-
创建一个属于自己的个人工作分支,以避免对主分支 master 造成太多的干扰,也方便与他人交流协作。
-
当进行高风险的工作时,创建一个试验性的分支,扔掉一个烂摊子总比收拾一个烂摊子好得多。
-
合并别人的工作的时候,最好是创建一个临时的分支,关于如何用临时分支合并别人的工作的技巧,将会在后面讲述。
创建分支
下面的命令将创建我自己的工作分支,名叫 robin,并且将以后的工作转移到这个分支上开展。
$ git branch robin$ git checkout robin
更简单和常用的方法是直接通过 checkout 命令来一次性创建并转移到新建分支上,命令如下:
$ git checkout -b robin [start_point]
其中 start_point 是一个可选参数,指定新建分支 robin 是基于哪个节点,默认为当前所在分支的节点。
删除分支
要删除版本库中的某个分支,使用 git branch -d 命令就可以了,例如:
$ git branch -d branch-name
但是需要注意的是,如果删除的分支还没有被 merge 到其他分支,删除这样的分支会导致这个分支上所做的改动丢失,因此 git branch -d 命令会失败,提示你这样做会丢失信息。如果你的确想删除这样的分支,不怕信息丢失,那么可以使用 git branch -D 命令,这个命令不会去判断分支的merge状态,例如:
$ git branch -D branch-name
通常建议使用 -d 参数来删除分支,以防无意的信息丢失。
查看分支运行下面的命令可以得到你当前工作目录的分支列表:
$ git branch
在你正在工作的分支的名字前面,会有 * 号标示,比如:
$ git branch
bugfix
* master
说明有两个本地分支 bugfix 和 master, 其中当前的工作分支为 master。
查看项目的发展变化和比较差异。
介绍几个查看项目的版本库的发展变化以及比较差异的很有用的命令:
git show-branchgit diffgit whatchanged
我们现在为 robin, master 两个分支都增加一些内容。
$ git checkout robin$ echo "Work, work, workd" >> hello$ git commit -m "Some workd" -i hello
$ git checkout master$ echo "Play, play, play" >> hello$ echo "Lots of fun" >> example
$ git commit -m "Some fun" -i hello example
git show-branch 命令可以使我们看到版本库中每个分支的世系发展状态,并且可以看到每次提交的内容是否已进入每个分支。
$ git show-branch
这个命令让我们看到版本库的发展记录。
* [master] Some fun! [robin] some work--
* [master] Some fun+ [robin] some work
*+ [master^] a new day for git
譬如我们要查看世系标号为 master^ 和 robin 的版本的差异情况,我们可以使用这样的命令:
$ git diff master^ robin
我们可以看到这两个版本的差异:
diff --git a/hello b/helloindex 263414f…cc44c73 100644— a/hello+++ b/hello@@ -1,2 +1,3 @@Hello WorldIt’s a new day for git+Work, work, workNote
关于 GIT 版本世系编号的定义,请参看 git help rev-parse 。
我们现在再用 git whatchanged 命令来看看 master 分支是怎么发展的。
$ git checkout master
$ git whatchangeddiff-tree 1d2fa05… (from 3ecebc0…)Author: Vortune.RobinDate: Tue Mar 21 02:24:31 2006 +0800Some fun:100644 100644 f24c74a… 7f8b141… M example:100644 100644 263414f… 06fa6a2… M hellodiff-tree 3ecebc0… (from 895f09a…)Author: Vortune.RobinDate: Tue Mar 21 02:17:23 2006 +0800a new day for git:100644 100644 557db03… 263414f… M hello
从上面的内容中我们可以看到,在 robin 分支中的日志为 “Some work” 的内容, 并没有在 master 分支中出现。
合并分支
合并两个分支:
$git merge
既然我们为项目创建了不同的分支,那么我们就要经常地将自己或者是别人在一个分支上的工作合并到其他的分支上去。现在我们看看怎么将 robin 分支上的工作合并到 master 分支中。现在转移我们当前的工作分支到 master,并且将 robin 分支上的工作合并进来。
$ git checkout master$ git merge -m "Merge from robin" robin
上面的命令会将 robin 分支的改动 merge 到 master,并生成一个新的 commit 节点,这个 commit 的注释信息为 “Merge from robin”
(kwydwuf注: $ git merge “Merge work in robin” HEAD robin 是老版本的用法,应该废弃 )
合并两个分支,还有一个更简便的方式,下面的命令和上面的命令是等价的 (kwydwuf注:git pull 的本意是用来 merge 远端版本库中的某个分支,用在此处没有任何简便之处,可以废弃)。
$ git checkout master$ git pull . robin
但是,此时 git 会出现合并冲突提示:
Trying really trivial in-index merge…fatal: Merge requires file-level mergingNope.Merging HEAD with d2659fcf690ec693c04c82b03202fc5530d50960Merging:1d2fa05b13b63e39f621d8ee911817df0662d9b7 Some fund2659fcf690ec693c04c82b03202fc5530d50960 some workfound 1 common ancestor(s):3ecebc0cb4894a33208dfa7c7c6fc8b5f9da0eda a new day for gitAuto-merging helloCONFLICT (content): Merge conflict in helloAutomatic merge failed; fix up by hand
git 的提示指出,在合并作用于文件 hello 的 ‘Some fun’ 和 ‘some work’ 这两个对象时有冲突,具体通俗点说,就是在 master, robin 这两个分支中的 hello 文件的某些相同的行中的内容不一样。我们需要手动解决这些冲突,现在先让我们看看现在的 hello 文件中的内容。
$ cat hello
此时的 hello 文件应是这样的,用过其他的版本控制系统的朋友应该很容易看出这个典型的冲突表示格式:
Hello WorldIt’s a new day for git<<<<<<< HEAD/helloPlay, play, play=======Work, work, work>>>>>>> d2659fcf690ec693c04c82b03202fc5530d50960/hello
我们用编辑器将 hello 文件改为:
Hello WorldIt’s a new day for gitPlay, play, playWork, work, work
现在可以将手动解决了冲突的文件提交了。
$ git commit -i hello
以上是典型的两路合并(2-way merge)算法,绝大多数情况下已经够用。但是还有更复杂的三路合并和多内容树合并的情况。详情可参看: git help read-tree, git help merge 等文档。
逆转恢复
逆转与恢复:
<