可以说,任何一个真实的项目的源代码管理,都会用到“分支”这个概念。我们可以把分支理解成是并行的时间线,在这些时间线上,有它们各自的行为,彼此不互相影响。为了演示这个概念,我新建了一个Vapor项目git-learning,完成后,Vapor会自动为我们创建一个git repository。

在图中可以看到,git
在创建仓库的时候,就默认创建了一个分支,叫做master
。通常,这个分支上的代码都是经过严格测试,准备对外发布的。我们很少直接在这个分支上开发新功能以及修改Bug。
为什么需要一个分支呢?
为什么呢?
来看个例子。假设只有一个master分支,在routes.swift中,我们用demo来模拟一个正在开发中的功能:
public func routes(_ router: Router) throws {
router.get("hello") { req in
return "Hello, world!"
}
router.post("deom") { req in
return "Some complicated features"
}
}
完成后,我们就执行git add .
和git commit -m "Finish the demo"
把它提交到了master上。并且,谁也没有发现上面代码中的这个typo。
然后,我们很快就开始投入新的工作了,再添加一个新的路由:
public func routes(_ router: Router) throws {
// Basic "Hello, world!" example
router.get("hello") { req in
return "Hello, world!"
}
router.post("deom") { req in
return "Some complicated features."
}
router.get("about") { req in
return "About us"
}
}
这时,有人反馈说demo这个API遇到无法访问啊,需要立即修复,该怎么办呢?如果about还没有完成,显然我们不应该提交和它相关的任何代码。但我们修复了bug之后执行git add
的时候,这些代码是肯定会包含进来的,这样就很尴尬了。除非我们把手头正在开发的代码全部剪切出来存在别的地方,但这只是一个理论上可行的方案罢了,对于一个真实的项目来说,你不可能会做这样的事情。
而这,就是需要分支的理由。我们需要一个并行于master分支的新分支。所有的开发工作都在这个新分支上进行。
使用分支来解Bug和开发需求
对于我们上面说到的这种情况,先执行下git status
就会看到下面的提示:

我们可以执行:
git checkout -- Sources/App/routes.swift
撤销掉master分支上,在最后一次提交之后的所有修改。当然,这也是没办法的事情,谁让我们之前做错了事情呢 :)
创建分支
接下来,为了创建一个分支来开发我们的about API,我们可以执行:
git branch feature-about
git checkout feature-about
其中:
-
git branch
用于创建一个新的分支。分支的名称,通常都应该反应这个分支的用途。例如,我们在开发功能,因此叫做feature-about。如果是修改Bug,则应该是类似bug-id,如果是Github上的issue,则应该是issue-id等; -
git checkout feature-about
则是从master分支切换到feature-about分支。这时,从Shell提示符就会看到我们已经切换了当前分支:

实际上,之前创建并切换分支我们也可以执行
git checkout -b feature-about
。
在这个分支里的所有操作,就不会影响master了。现在,我们把之前的about代码再添加进来:
public func routes(_ router: Router) throws {
/// ...
router.get("about") { req in
return "About us"
}
}
然后执行:
git add .
git commit -m "Finish about api"
about的实现就被提交到了feature-about这个分支上。执行git log
,就会看到下面这样的结果:

也就是说,在feature-about这条时间线上,比master领先了一个提交。接下来,执行git checkout master
,回到master分支,我们该处理之前的BUG了。理论上说,我们也应该创建一个分支来修改BUG。不过,对于typo这种无害的BUG,这里简单起见,我们就在master上修改就好了。还是之前那句话,规则固然应该遵守,但也不是绝对不能打破,重要的是,你要知道自己在干什么就好了。
完成修改之后,执行下面的命令更新master分支:
git add .
git commit -m "Fix typo"
现在,执行一下git log
看下提交日志,就会发现,这里只有关于demo的记录,而没有任何about功能的信息:

这正是我们期望的结果,现在master和feature-about是两个平行的时间线。
合并分支
现在,假设feature-about上的代码已经通过测试准备发布了,我们自然要把它合并进master分支上。为此:
- 我们要先确保自己在master分支上,这一步这很重要;
- 其次,执行
git merge feature-about
。这时,git
就会打开默认编辑器,让我们对这次合并做一个说明。默认的说明就是Merge branch branch_name。通常,我们也不会修改它,直接保存退出,合并就完成了;

这时,重新执行下git log
,就会发现之前这两条时间线上的行为,以发生时间为序合并在了一起:

删除分支
现在,feature-about分支也就没有存在的意义了。我们可以执行git branch -d feature-about
把它删掉就好了。
网友评论