分布式版本控制(Git,Bazaar和Mercurial)的三巨头各自对待分支的方式完全不同。例如,在Bazaar,分支机构是独立的回购(实际上是父回购的不同副本);在您的文件系统上,不同的分支存在于不同的目录中。另一方面,在Git中,您可以在同一个repo中存在多个分支(因此在文件系统的同一目录中)。 Mercurial支持 两种行为,后者用 命名分支。
这些不同的分支模型有哪些优缺点?在我看来,Bazaar的一个分支,一个回购的方法使分支比Git的方法更痛苦(例如在Bazaar中使用分支,我必须先创建分支,然后cd出我当前的工作副本,然后检查出来新的分支,就像我在SVN中那样)。
Bazaar不要求您以您描述的方式工作。我其实写的 一篇博文 关于它两天前。您只需使用一个工作树即可完成工作,在各个分支之间切换并创建新分支而无需离开工作树。有用的命令是: checkout
, switch
, branch --switch
。看看 工作流程 Bazaar的文档,您将看到您可以以任何您想要的方式配置它。
除了Git之外,我对VCS中的分支模型了解不多。我会说在任何DVCS中你都可以通过克隆来实现分支(你通过克隆来创建分支)。事实上,Mercurial所谓的“命名分支”(据我所知) 提交标签 仅被解释为分支,有时需要本地编号的修订以解决歧义。我认为,Mercurial“书签”与Git分支非常相似。有两个DVCS 非常 不同的分支概念是 单调 和 的darcs。我认为Subversion使用的“通过复制分支”,项目名称和分支名称之间的分离是由 惯例,是个错误的想法。
在Git版本中,形成了提交的有向无环图(DAG)。这是指示,因为提交有父母。这是一个非常重要的问题:提交的DAG中的边缘是从提交到其父级(或者,在合并提交的情况下,其父级中的两个或更多)。提交图是非循环的,这意味着没有链(没有路径)以相同的对象开始和结束。
Git词汇表 将“分支”定义为 积极的发展路线。这个想法是在Git中实现分支的背后。
分支上的最新提交称为 小费 那个分支。分支的尖端由a引用 分行负责人,这只是此提交的符号名称。在它的“松散”形式中,这样的分支头(例如对于名为“master”的分支)只是一个文件 refs/heads/
git仓库里面的目录(里面 .git
dir),其中包含对分支的当前提示的引用:其提交的SHA-1标识符(作为十六进制字符串)。
当您在Git中创建新提交时,当前签出分支的提示会向前移动。换句话说,新提交是在当前分支的顶端创建的,并且分支头进入新提交(有点类似于指向堆栈顶部的指针可能如何前进)。
单个git存储库可以跟踪任意数量的分支,但是您的工作树(如果有的话)只与其中一个(“当前”或“已检出”分支)相关联。当前分支由HEAD指针给出。 HEAD是(通常)指向当前检出分支(指向分支头名称)的指针,就像分支头是指向分支提示的指针一样。
例如,如果当前签出的分支是'master',那么 .git/HEAD
file(表示HEAD)将包含单个LF终止行 ref: refs/heads/master
(象征性的参考 refs/heads/master
),和 .git/refs/heads/master
('master'分支的头部)将包含例如LF终止线 0b127cb8ab975e43398a2b449563ccb78c437255
,whihc是'master'分支的尖端的SHA-1标识符(即如果当前分支没有“打包”:那么你必须看看 .git/packed-refs
)。
Git中的一些命令,例如“git commit”或“git reset”操作/更改分支头;其他如“git checkout”操纵/改变HEAD(对当前分支的符号引用)。
“git log 科
“命令显示从分支提示可以访问的所有提交,这意味着该父提交的分支,父,父(或父)的提示等。它显示提交的DAG的一部分。
在Git中删除分支意味着只需删除分支头。这可能意味着某些提交变为“不可见”,无法访问的freom引用(分支和标记),这意味着在某些时候这些提交可能会从存储库中收集垃圾并将其删除。但是,如果您可以使用“git branch -d <branchname>”删除分支,那么这意味着不会丢失任何提交;您可以使用“git branch -D <branchname>”强制删除分支。重命名分支只是重命名分支头,分支头的符号引用(符号名称);分支名称不会保存在提交对象中的任何位置。
Git也有概念 reflogs,这是分支尖指向(和何时)的本地历史。例如,如果使用“git commit --amend”修改提交,则分支提示将被修改的提交替换,并且HEAD ^将在修改之前和之后成为提交的父级,而在修改之前将在reflog中输入版本。在修改之后。如果使用“git reset”重绕历史记录,则reflog将包含重新排列前旧分支提示的信息。
简而言之,reflog为git命令提供了额外的安全性和轻松恢复。