Git 作为版本控制工具,另一个强大之处就是分支的管理;
而分支管理对于团队的合作至关重要,它可以让不同的团队在不同的分支上进行工作,这样团队之间就不会相互干扰;最后将分支进行合并,这样就愉快的完成了团队合作的任务
相比于其他的版本控制工具,Git 的分支模型是“必杀技”,因为 Git 处理分支的方式相当的轻量,创建以及在分支之间的切换都能很快的完成;因此,Git 实际上鼓励在工作流中使用分支;
一、分支简介
Git 保存数据的时候,实际上保存并不是文件的变化或者差异,而是一系列不同时刻的快照(snapshot)。
在进行提交(commit)操作的时候,这个提交会包含一个指向暂存内容快照的指针,同时还包含作者信息、提交时输入的信息以及指向它的父对象的指针(首次提交没有父指针)
二、分支的基本操作
1)新建 & 切换分支 & 删除分支 & 查看分支
假设开始时,分支状态如图所示(当前处于 master 分支):
2)合并分支
合并分支有两种情况:Fast-forward (--ff) 和 No-fast-forward (--no-ff) ;
-
fast-forward (–ff):当顺着一个分支走下去能够达到另外一个分支,那么 Git 在合并的时候,只会简单地将指针向前移动;这个类型的合并不会产生新的提交 -
no-fast-forward (–no-ff):通常情况下,很少会出现上面的合并情况,因为我们多数情况下会在多个分支上同时进行修改,这里就是我们将要介绍的合并 no-fast-forward,这种情况将会创建新的提交(commit) 因为这时候在两个分支上分别进行了改动,两个分支分别做了哪些改动需要一个参考,这里就涉及到了三方合并,这里推荐腾讯官方文章 -
冲突合并
当两个分支在同一文件的同一行做了修改,在进行合并的时候就会产生冲突,因为即便有三方合并的比较,Git 还是不能确定哪一个版本是你想要保留的,这时候就需要我们手动进行选择
假设我们分别在 README.md 文件中进行了修改,则合并的过程如下图所示(注意到,这里我们解决冲突使用的是 vim,之后我们还需要添加到暂存区,然后添加到 Git 版本库):
3)变基操作
变基操作和合并分支都是将两个分支进行合并,但是变基操作通常很少用到,因为这样的操作会导致整个项目的历史的改变,尤其是大型的项目中比较少使用;
但是,变基操作有自己的使用场景:通常在 feature 分支上对文件进行了修改,同时 master 分支也进行了更新,这时候就可以进行变基操作来更新 feature 分支
4)Reverting
这个操作实际上是删除之前的修改,但是与我们在之前讲过的不太一样的地方是,我们并不是简单地回退到历史提交,而是创建新的提交回到历史状态
5)Cherry-pick
当另外一个分支的提交是我们当前分支想要的提交的时候,我们可以使用这个命令将另外一个分支的提交复制过来,这样在当前分支上,我们会创建新的提交
三、贮藏与清理
通常,当我们对一个分支进行了修改之后,如果我们想要切换分支,就必须让这个分支重新变的干净,所谓的干净就是没有未提交的文件;
那么,这时候就有两种方法,一种是直接提交,另一种就是贮藏;当我们不想提交的时候,贮藏是一个非常好的选择
贮藏(stash)会处理工作目录的脏的状态——即跟踪文件的修改与暂存的改动——然后将未完成的修改保存到一个栈上, 而你可以在任何时候重新应用这些改动(甚至在不同的分支上)
1)贮藏
将修改推送到栈上,就可以得到一个干净的分支
git stash
git stash push
2)查看贮藏
git stash list
3) 应用贮藏
git stash apply
git stash apply stash@{2}
git stash pop
- 应用贮藏不一定还是应用在原来的分支,可以是其他的分支;当然也不一定是干净的分支才能应用
4) 删除贮藏
删除指定的贮藏
git stash drop stash@{0}
四、版本回退
既然是版本控制工具,Git 的主要功能当然是控制版本,便于我们对于各个历史版本的管理;Git 可以清楚地记录我们提交的每一个历史版本,当我们想要回退到某一个历史版本的时候是非常方便的;
- 为了最简化,这里假设只有一个分支,所以不涉及分支的合并的问题;
1)查看历史版本
- 首先我们要查看历史版本,这样我们才能知道要回退到哪一个历史版本:
git log
- 当我们不是处于当前分支的最后一次提交的时候,会发现一些最新的提交并没有显示,别慌,使用下面的命令:
git reflog
2) 回退到指定的历史版本
从上面的 log 中我们可以查看每一次提交的 commit id,我们就是要使用这个 ID 来实现版本的回退;
-
以 HEAD 作为基准回退版本:
git reset HEAD^
-
以 commit id 来指定回退的版本 git reset commit_id_of_specific_version
这里需要注意的是 reset 后面可以加可选参数:
git reset --soft commit_id_of_specific_version
git reset --mixed commit_id_of_specific_version
git reset --hard commit_id_of_specific_version
-
soft reset : 版本回退,但是工作区和暂存区的内容都没有改变 -
hard reset:版本回退,暂存区和工作区的内容都清除(注意保存有用的修改) -
另外一个需要注意的是: 即便使用 --hard 可选参数 git reset 只能删除已经追踪的文件,不能删除未追踪的文件,比如新添加的但是还没有加入到暂存区的文件就是没有被追踪的,是不能删除的;这个时候就需要使用 git clean 来删除没有跟踪的文件,但是使用这个命令的时候要小心,不要随意添加参数,导致 .gitignore 中的文件都被删除;
|