专栏首页我是东东强Git工作区、版本库与暂存区

Git工作区、版本库与暂存区

全文概要

Git与其它版本控制系统如SVN的一个最大的不同之处就是发明了暂存区的概念,本文从创建Git版本库开始,依次描述了追踪文件、修改文件、丢弃修改、提交修改等基本Git操作,在此过程中介绍了Git版本控制系统中三个重要概念:工作区、版本库与暂存区。

工作区(Working Directory)


就是你能在电脑中看到的目录,即本地目录,比如我的GitTest就是一个工作区,准确的来说,Git工作区应该指的是执行过git init初始化后的本地目录,下图可以看到现在工作区内只有一个文件:a.txt:

版本库(Repository)


工作区有一个隐藏目录.git,这个不是工作区,而是Git的版本库。

Git版本库里存了很多东西,其中最重要的就是称为”Stage”的暂存区,还有Git为我们自动创建的第一个本地分支Master。

分支与HEAD的概念之后的博文会详细讲解。

暂存区(Stage)


前面说到暂存区实际是Git版本库里面的一个区域,具体的结构参见下图:

下文中会结合一次完整的版本控制操作过程来具体讲解各个区域的作用。

本地版本控制流程实例


实例开始之前在强调一下,使用git命令时,status绝对是一个功能超乎想象重要的参数,让使用者可以获得整个版本文件的实时视图。

流程按照上图中显示的git版本库继续操作,所有操作均在本地分支Master上完成:

工作区中包含未被追踪的文件(Untracked files):a.txt,按提示使用命令:git add <文件名>,就可以将该文件添加至暂存区,并使用命令git status,查看当前版本完整视图:

根据提示使用命令:git rm - -cached <文件名>,可取消缓存在暂存区的文件修改:

发现暂存区的文件被弹出,a.txt重新回到了Untracked files下,再次执行git add将其加入暂存区:

接下来使用命令:git commit -m “message”,将暂存区文件提交,此时终端显示“nothing to commit, working directory clean”(没有可提交的内容,工作区是干净的),这是因为工作区中的文件修改已全部提交至版本库中的本地分支Master上,工作区与Master分支内容完全一致,即没有“脏”内容(类比数据库的“脏读”(Dirty Read),脏读是指一个事务读到了另一个事务还未提交的数据,实际就是存在有未提交的数据)的情况:

下面我们试着在工作区创建一个新文件b.txt,此时显然该文件属于Untracked files

b.txt
这是第一次修改.

同样将其添加到暂存区中:

如果你足够细心,不难发现一些有意思的事情:同样是追踪文件即将文件修改加入暂存区,两次执行git add命令的效果一样,但是Git给出的取消文件暂存命令提示不太一样:

  • a.txt加入暂存区时,Git提示取消暂存的命令为:git rm - -cached <文件名>
  • b.txt加入暂存区时,Git提示取消暂存的命令为:git reset HEAD <文件名>

出现这种差异是因为a.txt属于第一次提交(Initial Commit)的文件内容,对应取消暂存的命令就是:git rm - -cached <文件名>。而如果在初始化版本库(即git init)之后新增的文件,取消暂存的命令则是:git reset HEAD <文件名>

那我们执行取消暂存b.txt的命令:git reset HEAD b.txt,发现b.txt重新回到Untracked files类别下:

再次将b.txt添加到暂存区:

然后我们在最后提交之前再对b.txt进行修改,增加一行内容:

b.txt
这是第一次修改.
这是第二次修改.

发现b.txt同时在暂存区(Changes to be committed)和未暂存区(Changes not staged for commit,为了与暂存区对比,姑且这么称呼,实际上就是工作区,只不过对应文件在上一次被暂存后又再次被修改过,而修改过的文件内容还未被暂存),但是描述有些许不同:

  • 在暂存区中,b.txt前面修饰词为new,表示对于暂存区而言,这是b.txt第一次被加入到暂存区中。
  • 在未暂存区中,b.txt前面修饰词为modified,表示对于为暂存区而言,它已经知道b.txt之前已经被暂存过一次,而在那之后又被修改过。

对于状态下的b.txt文件,Git都给出了明确的提示,我们挨个尝试一遍。

直接取消上一次暂存:

再次暂存b.txt

再次修改b.txt,增加一个文本行:

b.txt
这是第一次修改.
这是第二次修改.
这是第三次修改.

执行命令:git checkout - - <文件名>,该命令效果应该是丢弃本地修改:

cat命令查看b.txt内容发现上次对b.txt的修改(新增一个文本行)果然被丢弃。

再次修改b.txt内容,增加一个空行和一个文本行:

b.txt
这是第一次修改.
这是第二次修改.

这是第四次修改.

这一次我们直接将修改后的b.txt添加至暂存区:

提交暂存区到本地分支Master:

以上,我们就完成了一次本地分支的版本控制。

小结


  1. 工作区:本地目录,包含所有被Git追踪的文件的实时内容;
  2. 版本库:工作区中的.git文件夹,实际包含暂存区和当前分支指针HEAD,通过命令:git init可以初始化创建版本库;
  3. 暂存区:暂存被追踪的文件修改,为正式提交到本地分支提供内容。
  • 工作区文件修改后通过命令:git add <文件名>,将文件添加至暂存区
  • 暂存区通过命令:git rm –cached <文件名>(针对在初始化版本库之前就已经在工作区中的文件),或git reset HEAD <文件名>(针对在初始化版本库之后才新增的文件),将暂存文件弹回到工作区
  • 若要在工作区丢弃文件自上一次暂存以来的全部修改,可执行命令:git checkout – <文件名>

参考资料


[1] 廖雪峰Git教程

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 素数筛选算法

    最近学习了一种筛素数的方法,能够以时间复杂度O(n),即线性时间完成。一开始不能理解其中的一句话,搜索了很久,大部分结果都是一群人在网上卖萌。好好思索了一番,按...

    我是东东东
  • 网络测量之NetSight(NSDI-2014)

    NSDI 2014年中,由斯坦福大学”SDN之父”,Nick Mckeown教授带领的实验室发表了题为《I Know What Yout Packet Did ...

    我是东东东
  • 常见算法之排序

    各类排序算法,不仅是算法基本功,也是面试中永恒的考题,关于每种算法思想、实现(递归与非递归)以及时空复杂度分析是必须牢牢把握的送分题。本文先将排序算法按不同标准...

    我是东东东
  • Android中Java和JavaScript交互

    Android提供了一个很强大的WebView控件用来处理Web网页,而在网页中,JavaScript又是一个很举足轻重的脚本。本文将介绍如何实现Java代码和...

    技术小黑屋
  • leetcode-139-单词拆分(递归超时,动归解决)

    给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。

    chenjx85
  • tomcat weblogic 对比

    J2ee开发主要是浏览器和服务器进行交互的一种结构.逻辑都是在后台进行处理,然后再把结果传输回给浏览器。可以看出服务器在这种架构是非常重要的。   这几天接触...

    MickyInvQ
  • 裁员、卖厂,全球第三大晶圆代工厂格罗方德或难逃被收购命运

    最近,《电子时报》(DigiTimes)报道称,全球第三大代工厂格罗方德在此前的裁员风波之后可能将面临被出售的命运。虽然目前它仍然是全球第三大代工厂,市场份额占...

    镁客网
  • IT男的真实人生:总被误认为是修电脑的

    在互联网和信息化高唱主旋律的时代,IT行业成为当之无愧的朝阳产业,这个行业的从业者可谓时代宠儿。他们智商高、年纪轻,在技术的海洋里自由驰骋,却与社会保持着一定的...

    哲洛不闹
  • php字符串基本操作

    字符串查找strstr(查找目标字符串,查找关键词),stristr(查找目标字符串,查找关键词)

    十月梦想
  • 研究监控系统之prometheus

    以前用过nagios和zabbix,nagios用起来太过原始,配置文件维护得很累,监控的图表也比较难看;zabbix的主要开发语言是C和PHP,要暴露一些自定...

    jeremyxu

扫码关注云+社区

领取腾讯云代金券