git checkout
Git 我们想要切换到新的分支上
如果你想创建一个新的分支同时切换到新创建的分支的话,可以通过 git checkout -b
来实现。
如何将两个分支合并到一起。就是说我们新建一个分支,在其上开发某个新功能,开发完成后再合并回主线。
第一种合并分支的方法是 git merge
。在 Git 中合并两个分支时会产生一个特殊的提交记录,它有两个父节点。翻译成自然语言相当于:“我要把这两个父节点本身及它们所有的祖先都包含进来。”
我们准备了两个分支,每个分支上各有一个独有的提交。这意味着没有一个分支包含了我们修改的所有内容。咱们通过合并这两个分支来解决这个问题。
我们要把 bugFix
合并到 master
里
git merge bugFix
看见了吗?首先,master
现在指向了一个拥有两个父节点的提交记录。假如从 master
开始沿着箭头向上看,在到达起点的路上会经过所有的提交记录。这意味着 master
包含了对代码库的所有修改。
还有,看见各个提交记录的颜色变化了吗?为了帮助学习理解,我引入了颜色搭配。每个分支都有不同的颜色,而每个提交记录的颜色是所有包含该提交记录的分支的颜色混合之后的颜色。
所以,master
分支的颜色被混入到所有的提交记录,但 bugFix
没有。下面咱们让它也改变一下颜色。
咱们再把 master
分支合并到 bugFix
:
git checkout bugFix ; git merge master
因为 master
继承自 bugFix
,Git 什么都不用做,只是简单地把 bugFix
移动到 master
所指向的那个提交记录。
现在所有提交记录的颜色都一样了,这表明每一个分支都包含了代码库的所有修改!大功告成!
第二种合并分支的方法是 git rebase
。Rebase 实际上就是取出一系列的提交记录,“复制”它们,然后在另外一个地方逐个的放下去。
Rebase 的优势就是可以创造更线性的提交历史,这听上去有些难以理解。如果只允许使用 Rebase 的话,代码库的提交历史将会变得异常清晰。
还是准备了两个分支;注意当前所在的分支是 bugFix(星号标识的是当前分支)
我们想要把 bugFix 分支里的工作直接移到 master 分支上。移动以后会使得两个分支的功能看起来像是按顺序开发,但实际上它们是并行开发的。咱们这次用 git rebase
实现此目标
git rebase master
怎么样?!现在 bugFix 分支上的工作在 master 的最顶端,同时我们也得到了一个更线性的提交序列。
注意,提交记录 C3 依然存在(树上那个半透明的节点),而 C3' 是我们 Rebase 到 master 分支上的 C3 的副本。
现在唯一的问题就是 master 还没有更新,下面咱们就来更新它吧……
现在我们切换到了 master
上。
把它 rebase 到 bugFix
分支上……
git rebase bugFix
了!由于 bugFix
继承自 master
,所以 Git 只是简单的把 master
分支的引用向前移动了一下而已。
我们首先看一下 “HEAD”。 HEAD 是一个对当前检出记录的符号引用 —— 也就是指向你正在其基础上进行工作的提交记录。
HEAD 总是指向当前分支上最近一次提交记录。大多数修改提交树的 Git 命令都是从改变 HEAD 的指向开始的。
HEAD 通常情况下是指向分支名的(如 bugFix)。在你提交时,改变了 bugFix 的状态,这一变化通过 HEAD 变得可见。
下面咱们通过实际操作看一下。我们将会观察提交前后 HEAD 的位置。
分离的 HEAD 就是让其指向了某个具体的提交记录而不是分支名。在命令执行之前的状态如下所示:
HEAD -> master -> C1 (HEAD 指向 master, master 指向 C1)
git checkout c1 就变成了
在 Git 里撤销变更的方法很多。和提交一样,撤销变更由底层部分(暂存区的独立文件或者片段)和上层部分(变更到底是通过哪种方式被撤销的)组成。我们这个应用主要关注的是后者。
主要有两种方法用来撤销变更 —— 一是 git reset
,还有就是 git revert
。接下来咱们逐个进行讲解。
git reset
通过把分支记录回退几个提交记录来实现撤销改动。你可以将这想象成“改写历史”。git reset
向上移动分支,原来指向的提交记录就跟从来没有提交过一样。
git reset HEAD~1;
Git 把 master 分支移回到 C1
;现在我们的本地代码库根本就不知道有 C2
这个提交了
虽然在你的本地分支中使用 git reset
很方便,但是这种“改写历史”的方法对大家一起使用的远程分支是无效的哦!
为了撤销更改并分享给别人,我们需要使用 git revert
。来看演示:
git revert HEAD
奇怪!在我们要撤销的提交记录后面居然多了一个新提交!这是因为新提交记录 C2'
引入了更改 —— 这些更改刚好是用来撤销 C2
这个提交的。也就是说 C2'
的状态与 C1
是相同的。
revert 之后就可以把你的更改推送到远程仓库与别人分享啦。
如果你想将一些提交复制到当前所在的位置(HEAD
)下面的话, Cherry-pick 是最直接的方式了
咱们还是通过例子来看一下!
这里有一个仓库, 我们想将 side
分支上的工作复制到 master
分支,你立刻想到了之前学过的 rebase
了吧?但是咱们还是看看 cherry-pick
有什么本领吧。
git cherry-pick c2 c4
这就是了!我们只需要提交记录 C2
和 C4
,所以 Git 就将被它们抓过来放到当前分支下了。 就是这么简单!
将上面这张图变为下面这张图
$ git rebase master bugFix
$ git rebase bugFix side
$ git rebase side another
$ git rebase another master