分支

    因为在上文中已经说到,Git保存文件的最基本的对象是对象,Git本质上只是一棵巨大的文件树,树的每一个节点就是blob对象,而分支只是树的一个分叉。说白了,分支就是一个有名字的引用,它包含一个提交对象的的40位校验和,所以创建分支就是向一个文件写入 41 个字节(外加一个换行符)那么简单,所以自然就快了,而且与项目的复杂程度无关。

    Git的默认分支是master,存储在.git\refs\heads\master文件中,假设你在master分支运行git branch dev创建了一个名字为dev的分支,那么git所做的实际操作是:

    • 将HEAD指向的当前分支(当前为master)的40位SHA-1 校验和外加一个换行符写入dev文件。
    • 结束。
    • 修改.git文件下的HEAD文件为ref: refs/heads/<分支名称>
    • 结束。
      记住,HEAD文件指向当前分支的最后一次提交,同时,它也是以当前分支再次创建一个分支时,将要写入的内容。

    分支合并

    再来说一说合并,首先是Fast-forward,换句话说,如果顺着一个分支走下去可以到达另一个分支的话,那么 Git 在合并两者时,只会简单地把指针右移,因为这种单线的历史分支不存在任何需要解决的分歧,所以这种合并过程可以称为快进(Fast forward)。比如:file注意箭头方向,因为每一次提交都有一个指向上一次提交的指针,所以箭头方向向左,更为合理

    当在master分支合并dev分支时,因为他们在一条线上,这种单线的历史分支不存在任何需要解决的分歧,所以只需要master分支指向dev分支即可,所以非常快。

    分支的变基rebase

    把一个分支中的修改整合到另一个分支的办法有两种:mergerebase。首先mergerebase最终的结果是一样的,但 rebase能产生一个更为整洁的提交历史。仍然以上图为例,如果简单的merge,会生成一个提交对象v8,现在我们尝试使用变基合并分支,切换到:

    1. $ git checkout master
    2. $ git merge dev

    file现在的v5'对应的快照,其实和普通的三方合并,即上个例子中的 v8 对应的快照内容一模一样。虽然最后整合得到的结果没有任何区别,但变基能产生一个更为整洁的提交历史。如果视察一个变基过的分支的历史记录,看起来会更清楚:仿佛所有修改都是在一根线上先后进行的,尽管实际上它们原本是同时并行发生的。