Git系列三:Git 分支管理与版本控制

Git 作为版本控制工具,另一个强大之处就是分支的管理

而分支管理对于团队的合作至关重要,它可以让不同的团队在不同的分支上进行工作,这样团队之间就不会相互干扰;最后将分支进行合并,这样就愉快的完成了团队合作的任务

相比于其他的版本控制工具,Git 的分支模型是“必杀技”,因为 Git 处理分支的方式相当的轻量,创建以及在分支之间的切换都能很快的完成;因此,Git 实际上鼓励在工作流中使用分支;

一、分支简介

Git 保存数据的时候,实际上保存并不是文件的变化或者差异,而是一系列不同时刻的快照(snapshot)。

在进行提交(commit)操作的时候,这个提交会包含一个指向暂存内容快照的指针,同时还包含作者信息、提交时输入的信息以及指向它的父对象的指针(首次提交没有父指针)

  • 实际上,每一次提交,产生的提交对象都会包含指向父对象的指针和指向快照的指针,如下图所示
    在这里插入图片描述

  • 分支的本质:仅仅是指向提交对象的可变指针

    1. 使用 HEAD 这个特殊指针来确定当前处于哪一个分支

    在这里插入图片描述

    1. 当我们分别在两个分支上作出一些修改:

    在这里插入图片描述

二、分支的基本操作

1)新建 & 切换分支 & 删除分支 & 查看分支

假设开始时,分支状态如图所示(当前处于 master 分支):

在这里插入图片描述

  • 新建并切换分支:这样我们就可以在 test 分支上进行修改,而不会影响 master 分支了

    # 新建 test 分支
    git checkout -b test
    
    # 上面的命令是下面两个命令的简写
    git branch test
    git checkout test
    

    在这里插入图片描述

  • 进行一系列的修改之后,分支情况如下:

    在这里插入图片描述

  • 删除分支

    # 删除一个分支
    git branch -d hotfix
    
  • 查看分支(包括远程分支)

    # 只查看本地分支
    git branch 
    
    # 查看包括本地和远程的所有分支
    git branch -a
    
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
# or
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 来实现版本的回退;

  1. 以 HEAD 作为基准回退版本:

    # 当前版本为 HEAD,则上一版本为 HEAD^, 上上版本为 HEAD^^,
    git reset HEAD^
    
  2. 以 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 中的文件都被删除;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值