文档章节

Git的工作区、暂存区和版本库之间的关系及其互操作

JAVA_NINA
 JAVA_NINA
发布于 2016/10/21 14:26
字数 1213
阅读 47
收藏 0

工作区,暂存区和版本库之间的关系

工作区:我们会想当然的认为,当前仓库所在目录就是我们的工作区,其实这是不完全正确的。在当前仓库中,新增,更改,删除文件这些动作,都发生在工作区里面。

 

暂存区:英文叫stage, 或index。在版本库.git)目录下,有一个index文件。它实际上就是一个包含文件索引的目录树,像是一个虚拟的工作区。在这个虚拟工作区的目录树中,记录了文件名、文件的状态信息(时间戳、文件长度等),文件的内容并不存储其中,而是保存在Git对象库(.git/objects)中,文件索引建立了文件和对象库中对象实体之间的对应。如果当前仓库,有文件更新,并且使用git

 add 命令,那么这些更新就会出现在暂存区中。

 

版本库:当前仓库下,如果没有任何的提交,那么版本库就是对应上次提交后的内容。下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系。

 

 

图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage, index),标记为 "master" 的是 master 分支所代表的目录树。

 

  图中我们可以看出此时 "HEAD" 实际是指向 master 分支的一个“游标”。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。

 

  图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了创建的各种对象及内容。

 

  当对工作区修改(或新增)的文件执行 "git add" 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。

 

  当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。

 

  当执行 "git reset HEAD" 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。

 

  当执行 "git rm --cached <file>" 命令时,会直接从暂存区删除文件,工作区则不做出改变。

 

  当执行 "git checkout ." 或者 "git checkout -- <file>" 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。

 

  当执行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

 

使用git diff查看各个区之间的差异

git diff 和 git diff --cached容易混淆

 

  git diff 比较的是工作区和暂存区的差别

 

  git diff --cached 比较的是暂存区和版本库的差别

 

  git diff HEAD 可以查看工作区和版本库的差别

 

  每次commit后,git diff --cached没有内容,是因为暂存区的内容已经更新到版本库中,因此暂存区和版本库中的内容无差别

git reset和git revert的区别

reset是重置,默认是git reset --mixed <commit> 可以让版本库重置到某个commit状态,该commit之后的commit不会保留,并重置暂存区,但是不改变工作区。即这个时候,上次提交的内容在工作区中还会存在。

  如果使用git reset --hard <commit> 将版本库,暂存区和工作区的内容全部重置为某个commit的状态。之前的commit不会保留。

  revert比reset更加温柔一点,回滚到某次commit且该commit之后的提交记录都会保留,并且会在此基础上新建一个提交。对于已经push到服务器上的内容作回滚,推荐使用revert。

 

 

下面是一个实际问题:


git checkout -- <path> doesn't do a hard reset; it replaces the working tree contents with the staged contents. git checkout HEAD -- <path> does a hard reset for a path, replacing both the index and the working tree with the version from the HEAD commit. 

 

一些总结:

A "hard reset" for a path is just done with git checkout HEAD -- <path>.
A soft reset for a path doesn't make sense.
A mixed reset for a path is what git reset -- <path> does.

本文转载自:http://san-yun.iteye.com/blog/2061647

共有 人打赏支持
JAVA_NINA
粉丝 26
博文 219
码字总数 33012
作品 0
唐山
程序员
私信 提问
《Git权威指南》读书笔记 第五章 Git暂存区

5.1 修改不能直接提交 首先修改welcome.txt文件,在这个文件后面追加一行: 使用git diff命令查看修改后的文件与暂存区(并不是版本库,后面会有相关讨论)中的文件的差异: 差异的输出格式:...

一万
2016/07/16
35
2
git的学习——工作区,暂存区,版本库以及版本回退

由于工作中只会利用IDE界面化的提交代码方式,经常被项目上的同事所鄙视,特此学习总结一下git. git作为一个分布式的多人共同开发代码的工具,真的很好用,git的工作流程一般为如下几个步骤:...

啊哈关关
2018/07/07
0
0
git命令行详解

下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系: 1、创建本地库 git init $git initInitialized empty Git repository in /Users/guhao/workplace/.git/ 2、现在本地仓库是空...

VincentGu
2017/05/20
0
0
Git 的暂存区(staging area)理解

通常在很多传统集中式版本控制系统中,只有两个空间用来管理你的数据,一个是你的working copy(工作区),另一个便是 datastore(版本库),然而在Git中,引入了staging area(index)这一概...

麦壳原野
2014/04/02
0
0
超详实Git简明教程与命令大全

Git (wiki: en chs )是一个免费开源的分布式版本控制系统,由linux内核作者linus Torvalds开发,大型开源项目linux kernel、Android、chromium、mono、dotnet、UE4等都使用Git管理项目 著名...

腾讯IVWEB团队
2018/10/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

数据库技术-Mysql主从复制与数据备份

数据库技术-Mysql 主从复制的原理: MySQL中数据复制的基础是二进制日志文件(binary log file)。一台MySQL数据库一旦启用二进制日志后,其作为master,它的数据库中所有操作都会以“事件”...

须臾之余
昨天
12
0
Git远程仓库——GitHub的使用(一)

Git远程仓库——GitHub的使用(一) 一 、 Git远程仓库 由于你的本地仓库和GitHub仓库之间的传输是通过SSH加密的,所以需要一下设置: 步骤一、 创建SSH key 在用户主目录下,看看有没有.ss...

lwenhao
昨天
2
0
SpringBoot 整合

springBoot 整合模板引擎 SpringBoot 整合Mybatis SpringBoot 整合redis SpringBoot 整合定时任务 SpringBoot 整合拦截器...

细节探索者
昨天
0
0
第二个JAVA应用

第二个JAVA应用 方法一:配置文件: # cd /usr/local/tomcat/conf/# vim server.xml</Host> <Host name="www.wangzb.cc" appBase="/data/wwwroot/www.wangzb.cc" //引用所......

wzb88
昨天
0
0
2019年阿里Java面试必问:JVM与性能优化+Redis+设计模式+分布式

前言 一年之计在于春 金三银四已经要到来,2019的新的开始,作为一个开发人员,你是否面上了自己理想的公司,薪资达到心中理想的高度? 面试:如果不准备充分的面试,完全是浪费时间,更是对...

火力全開
昨天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部