使用分支
BY 童仲毅(geeeeeeeeek@github)
这是一篇在原文(BY atlassian)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名(CC BY 2.5 AU)协议共享。
这份教程是 Git 分支的综合介绍。首先,我们简单讲解如何创建分支,就像请求一份新的项目历史一样。然后,我们会看到 git checkout 是如何切换分支的。最后,学习一下 git merge 是如何整合独立分支的历史。
我们已经知道,Git 分支和 SVN 分支不同。SVN 分支只被用来记录偶尔大规模的开发效果,而 Git 分支是你日常工作流中不可缺失的一部分。
git branch
分支代表了一条独立的开发流水线。分支是我们在第二篇中讨论过的「编辑/缓存/提交」流程的抽象。你可以把它看作请求全新「工作目录、缓存区、项目历史」的一种方式。新的提交被存放在当前分支的历史中,导致了项目历史被 fork 了一份。
git branch
命令允许你创建、列出、重命名和删除分支。它不允许你切换分支或是将被 fork 的历史放回去。因此,git branch
和 git checkout
、git merge
这两个命令通常紧密地结合在一起使用。
用法
git branch
列出仓库中所有分支。
git branch <branch>
创建一个名为 <branch>
的分支。不会 自动切换到那个分支去。
git branch -d <branch>
删除指定分支。这是一个安全的操作,Git 会阻止你删除包含未合并更改的分支。
git branch -D <branch>
强制删除指定分支,即使包含未合并更改。如果你希望永远删除某条开发线的所有提交,你应该用这个命令。
git branch -m <branch>
将当前分支命名为 <branch>
。
讨论
在 Git 中,分支是你日常开发流程中的一部分。当你想要添加一个新的功能或是修复一个 bug 时——不管 bug 是大是小——你都应该新建一个分支来封装你的修改。这确保了不稳定的代码永远不会被提交到主代码库中,它同时给了你机会,在并入主分支前清理你 feature 分支的历史。
比如,上图将一个拥有两条独立开发线的仓库可视化,其中一条是一个不起眼的功能,另一条是长期运行的功能。使用分支开发时,不仅可以同时在两条线上工作,还可以保持主要的 master branch
不混入奇怪的代码。
分支的顶端
Git 分支背后的实现远比 SVN 的模型要轻量。与其在目录之间复制文件,Git 将分支存为指向提交的引用。换句话说,分支代表了一系列提交的 顶端 ——而不是提交的 容器 。分支历史通过提交之间的关系来推断。
这使得 Git 的合并模型变成了动态的。SVN 中的合并是基于文件的,而Git 让你在更抽象的提交层面操作。事实上,你可以看到项目历史中的合并其实是将两个独立的提交历史连接起来。
栗子
创建分支
分支只是指向提交的 指针 ,理解这一点很重要。当你创建一个分支是,Git 只需要创建一个新的指针——仓库不会受到任何影响。因此,如果你最开始有这样一个仓库:
接下来你用下面的命令创建了一个分支:
git branch crazy-experiment
仓库历史保持不变。你得到的是一个指向当前提交的新的指针:
注意,这只会 创建 一个新的分支。要开始在上面添加提交,你需要用 git checkout
来选中这个分支,然后使用标准的 git add
和 git commit
命令。
删除分支
一旦你完成了分支上的工作,准备将它并入主代码库,你可以自由地删除这个分支,而不丢失项目历史:
git branch -d crazy-experiment
然后,如果分支还没有合并,下面的命令会产生一个错误信息:
error: The branch 'crazy-experiment' is not fully merged.
If you are sure you want to delete it, run 'git branch -D crazy-experiment'.
Git 保护你不会丢失这些提交的引用,或者说丢失访问整条开发线的入口。如果你 真的 想要删除这个分支(比如说这是一个失败的实验),你可以用大写的 -D
标记:
git branch -D crazy-experiment
它会删除这个分支,无视它的状态和警告,因此需谨慎使用。
git checkout
git checkout
命令允许你切换用 git branch
创建的分支。查看一个分支会更新工作目录中的文件,以符合分支中的版本,它还告诉 Git 记录那个分支上的新提交。将它看作一个选中你正在进行的开发的一种方式。
在上一篇中,我们看到了如何用 git checkout
来查看旧的提交。「查看分支」和「将工作目录更新到选中的版本/修改」很类似;但是,新的更改 会 保存在项目历史中——这不是一个只读的操作。
用法
git checkout <existing-branch>
查看特定分支,分支应该已经通过 git branch
创建。这使得 <existing-branch>
成为当前的分支,并更新工作目录的版本。
git checkout -b <new-branch>
创建并查看 <new-branch>
,-b
选项是一个方便的标记,告诉Git在运行 git checkout <new-branch>
之前运行 git branch <new-branch>
。
git checkout -b <new-branch> <existing-branch>
和上一条相同,但将 <existing-branch>
作为新分支的基,而不是当前分支。
讨论
git checkout
和 git branch
是一对好基友。当你想要创建一个新功能时,你用 git branch
创建分支,然后用 git checkout
查看。你可以在一个仓库中用 git checkout
切换分支,同时开发几个功能。
每个功能专门一个分支对于传统 SVN 工作流来说是一个巨大的转变。这使得尝试新的实验超乎想象的简单,不用担心毁坏已有的功能,并且可以同时开发几个不相关的功能。另外,分支可以促进了不同的协作工作流。