小丁带你走进git的世界二-工作区暂存区分支

一、Git基本工作流程

1.初始化一个仓库

git  init

git  clone

git仓库分为两种情况:

第一种是在现有项目或目录下导入所有文件到 Git 中; 第二种是从一个服务器克隆一个现有的 Git 仓库

git  init  –bare  git 创建一个裸仓库

2.git仓库有三个区域

  • 工作区working directory日常编辑代码的地方
  • 历史仓库history repository是commit指向的一个树形结构
  • 暂存区Staging area相当于是工作区与历史提交中间的缓存,它代表着是你要提交代码的一个工作状态,它维护的是一个虚拟的树形结构

讲述完了git的区域,接下来讲解下git文件的状态,其实git的状态无外乎两种:已跟踪和未跟踪,已跟踪的文件说明的是被纳入版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后,它们的状态可能处于未修改,已修改或已放入暂存区。 工作目录中除已跟踪文件以外的所有其它文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有放入暂存区。 初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态。

讲解下文件变化周期,比如我们在项目中添加了一个文件a,这时候文件a处于的状态则是Untracked未跟踪状态,当我们git add的时候这时候就会将文件放到暂存区中这时候状态变为Stage,当我们commit这个暂存区的文件后这个文件就变成未修改状态,因为没有进行修改过了相对于版本控制中的文件,当我们修改了a文件后这时候从unmodified变成modified(修改状态),这是再git add的时候就会将修改的文件变成stage,放入暂存区用于等待commit。

接下来就详细讲解下这些命令:

往暂存区里面添加东西使用如下git指令

git  add

从暂存区提交到历史记录使用如下指令

git  commit

查看工作区和暂存区之间的区别,来确保提交时我们所需要的呢?

git  status

从暂存区里面删除内容

git  rm

工作区内重命名文件或者移动文件,然后再把他们添加到暂存区

git  mv

确保工作区内里面不需要的文件不被添加进去添加到暂存区和历史。

.gitignore

实例讲解:

新建一个仓库

git  init  git_init

cd  git_init

touch a             //新建a文件

git  add  a   //将a添加到暂存区

git status会显示我们要提交的内容a文件,这时候a两个文件都是Changes to be committed也就是待commit的状态。

$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: a

git  commit  -m  “initial commit”//提交a文件到版本控制中。

touch b新建文件b

git add b //将b放入暂存区中

$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: b

编辑一下a文件,这时候在调用git status

$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: a
new file: bb

这时候a文件是出于修改状态,那么如果我们在进行修改a文件时候,在调用下git status会发生什么奇怪的事呢?let’s  go。

$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: a
new file: bb
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: a

这时候我们会发现两个modified a,这是为什么呢?但是两个文件分别存在暂存区和非暂存区,实际上暂存区内只保存了git add的版本,而最新修改的一份没有提交到暂存区内还在工作区域中,所以我们会看到两个,如果这时候调用git commit的话就只会讲已经在暂存区的文件存入到版本控制中,而最新修改的那一次记录没有被提交。

当然这里还提供了跳过暂存区的方法就是git commit –a –m“注释内容”可以直接跳过暂存区直接提交到记录里面去。

将a移除整个项目

git  rm  a

清楚缓存中的内容,也就是已经暂存的文件

git  rm  a  –cached

给文件重命名将a文件名换成c

git  mv  a  c

二、Git暂存区

假设工作区里面有这么一些文件如下图所示:

在第一次add都还没有进行的时候,暂存区还没有被创建出来,当我们add的时候会创建一个暂存区出来(文件分开add产生两个数据对象),如下图所示:

.git目录下面多了一个index的文件,那么这个index文件就是我们所说的暂存区的文件,那么每一条索引都是hash值表示以及它对应的文件名。每个索引还包含了他的文件模式权限还有status number来表示他的合并状态、时间戳等。每一个索引都是跟对象库的文件是对应的。比如说file.txt这里对应的是标号1,那么file2.txt对应的就是标号2(上图所示标号),这个index里面除了维护了索引之外还维护了提前计算好的tree对象的内容,也就是我们的顶层的目录tree以及folder的tree对象内容,当我们提交的时候他可以迅速的根据我们已经计算好的内容生成一个tree对象,然后添加到历史记录里面。

当我们修改了file2.txt的时候,这时候git add到暂存区时,发现对象库里面新创了一个对象,那么暂存区的这条索引就被指向新对象的索引替换掉。这时候git暂存区又从新计算了下顶层目录tree对象的一个内容。当我们提交的时候我们直接使用已经计算好的内容创建好一个新的tree对象,生成一个commit对象将master分支上面的HEAD指针指向当前commit对象上去。如下图所示:

这里的标号8指向的就是新生成的commit对象。

三、Git本地分支与合并

1.创建分支git branch

2.给固定的commit做标记 git  tag

3.分支之间进行切换 git  checkout

4.切换分支之前保存本地修改 git  stash

5.合并分支 git  merge

例子创建一个分支名字叫test并切换到当前的分支上去。

这时候分支的名称不再是master而是改变成为test分支。编辑下a文件用test分支进行提交

切换到master分支上面我们看一下a的内容

并没有test分支在a中添加的内容这时候我们切换分支时会使用我们分支上最新的一个提交来还原我们的暂存区和工作区内容,那么可以让我们在不同的分支之间独立的做自己的工作。

git  log  –oneline  –decorate  –graph  –all

我们可以看到提交的记录或提交这些提交的引用

给第一个提交加一个名称tag

git  tag  “v0”  f6699b3

在查看下git  log  –oneline  –decorate  –graph  –all

多了一个tag:v0使用git show v0查看下内容,这是打的tag是一个轻量级的只是一个固定的引用。

而使用git tag –a的方式进行添加时会是一个tag对象,他有tag的属性,包括提交人时间等信息。

Tag指向了一个提交commit

Tag也可以使用checkout进行操作

但是它当前的没有指向一个分支而是指向了一个commit,这时候就会出现一个问题就是我们切换分支的时候这一部分内容就有可能被遗弃掉,也就是说head引用直接指向了一个commit而不是一个分支名,checkout提供了针对当前commit新建一个分支的方法并切换到当前分支。

git  checkout  -b  “ttt_v0”

接下来切换master分支

这时候会用的git  stash进行保存工作区,因为我们切换checkout的时候会覆盖掉当前的内容所以我们先将其保存起来。如果想要保存暂存区就可以使用-a来保存。

Git  stash  save  -a   “stash1”

这时候我们来查看下缓存区状态git  status的时候是很干净的如下图:

下面我们切换到master分之下,在切换会ttt_v0下时我们要还原stash里面的内容

会有一个stash的缓存内容存在,下面我们来恢复stash里面的内容,并将缓存区内容还原。

git  stash   pop  –index  stash@{0}   这里的标记红色的表示stash里面的第0个stash

我们会发现之前修改的a文件已经在暂存区内贮备提交了

使用git  stash  apply  –index  stash@{0}这种方式时git stash list里面的内容是不会被清理掉的这里–index是恢复暂存区内容

使用git  stash  drop  stash@{0}清除掉,如果不加stash@{0}引用的话他默认会清楚stash栈最上面的一个。

清楚多个stash的时候使用git  stash  clear

四、查看与对比历史记录

1.git show

2.git log

3.git diff

输入git  log  –oneline  –decorate  –graph  –all查看完整的历史示意图。

git  log  -p常用的选项是 -p,用来显示每次提交的内容差异, 你也可以加上 -2 来仅显示最近两次提交:

我们可以根据查看git  show  f6699b3的信息

最新的一次提交可以用git  show  master 或者git  show  HEAD,也可以使用git  show  master^表示master分支的第一次提交master^2表示第二次提交

通常我们会用git diff来回答两个问题:第一个就是当前做了什么还没有提交暂存区?第二个问题就是当前那些文件已经暂存了等待提交?

git  diff 这个命令是查看当前工作区与暂存区快照的差异,也就是那些还没有暂存起来。

图中显示的是暂存区和工作区的区别在于a文件被修改了添加了next edit file。请注意,git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。 所以有时候你一下子暂存了所有更新过的文件后,运行 git diff 后却什么也没有,就是这个原因。

回顾:

所谓的分支就是一个commit记录的引用如下图所示:

在这些分支上工作会产生各自的历史记录(commit记录)所谓的分支切换就是指的Head指针的切换以及暂存区和工作区的一个还原,比如说我们现在当前Head指向的位置处再建两个分支之后他们所指向的commit都是同一个如下图所示:

分支切换后如下图所示:

而tag指向了一个固定的commit记录,如下图所示:

分为两种一种是轻量级的一种是标签对象,主要区别就是轻量级的tag只是一个固定的连接,但是标签对象就是创建标签的时候会产生一个标签对象,这个标签对象存储在.git/object目录里面,tag对象里面包括对数据对象的指向,以及创建时间数据对象类型和创建人等信息。

举个例子来说明一下分支切换以及合并:

开始的状态是这样的,我们提交了三次commit后的示意图如下:

当我们使用了git  branch test的时候,将会在当前位置处新建一个分支,分支的名称叫test,但是分支并没有切换依然是master分支(Head的指向)如下图所示:

我们在master分支上面工作会产生master分支上面的commit记录如下图所示:

这个时候我们是用git  checkout  test的时候HEAD指针就会指向test,并且还原暂存区和工作区内容。如下图所示:

继续在test分支上面进行工作,会产生test对应分支上面的commit记录

我们来说一下合并,合并分为两种一种是fast-farword  merge也就是说test所指向的commit记录他其实是master所指向的commit所衍生出来的如下图所示:

蓝色部分是master分支,红色部分是master分支所衍生出来的分支。这时候我们在master分支上面进行合并git  merge  test不会产生新的commit记录出来,master分支指向test分支所指向的commit记录上去,然后把工作区和暂存区还原成了test的暂存区和工作区内容。如下图所示:

另外一种就是non-fast-farword  merge也就是我们的三方合并。

我们可以看到master指向的commit和test只想的commit有一个共同的父节点就是70e4d8这个节点。Master指向的commit和test指向的commit并没有一个衍生的关系,这时候我们在master分支上面git merge test,会生成一个新的commit来承载两个分支的历史内容

五、结束语

这篇文章非一天写完的我也是在学习的过程中总结,以及参考大婶们写的文章加自己的理解写成的,如果这里有些错的或者有雷同的请各位大神指点一二。小丁谢过,写一篇文章确实不容易,能支持的就支持下不能支持的就当没看过这篇文章就好了。写篇文章容易么?写完了还被移除首页,已经发了两篇了第一篇只是开始被移除了首页~看看这个给不给我移除首页吧~

小丁带你走进git的世界二-工作区暂存区分支的更多相关文章

  1. 小丁带你走进git的世界三-撤销修改

    一.撤销指令 git checkout还原工作区的功能 git reset  还原暂存区的功能 git clean  还没有被添加进暂存区的文件也就是git还没有跟踪的文件可以使用这个命令清除他们 g ...

  2. 小丁带你走进git的世界三-撤销修改(转)

    一.撤销指令 git checkout还原工作区的功能 git reset  还原暂存区的功能 git clean  还没有被添加进暂存区的文件也就是git还没有跟踪的文件可以使用这个命令清除他们 g ...

  3. 小丁带你走进git的世界四-重写历史记录

    一.git对象文件创建 开篇先补充一个知识点,就是比如我建立一个文件之后,使用git add就会生成一个git对象,但是git对象生成后可以在.git/objects里面对应,首先我们来初始化一个仓库 ...

  4. 小丁带你走进git世界一-git简单配置

    小丁带你走进git世界一-git简单配置 1.github的简单配置 配置提交代码的信息,例如是谁提交的代码之类的. git config  –global user.name BattleHeaer ...

  5. 小丁带你走进git世界五-远程仓库

    一.文件,指令讲解 首先讲一下远程仓库和本地仓库在文件上面的区别,首先我们来看下对比图(当然这里说的区别是在于.git文件下面的文件内容,至于里面内容我们不会关注)這裡我们进行了相同的操作就是本地仓库 ...

  6. Git入门 时光穿梭鸡 版本回退 工作区 暂存区

    分布式集中式 CVS及SVN都是集中式的版本控制系统 , 而Git是分布式版本控制系统 集中式版本控制系统,版本库是集中存放在中央服务器的, 而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得 ...

  7. 版本控制Git(1)——理解暂存区

    一.svn和Git的比较 我们都知道传统的源代码管理都是以服务器为中心的,每个开发者都直接连在中间服务器上, 本地修改,然后commit到svn服务器上.这种做法看似完美,但是有致命的缺陷. 1. 开 ...

  8. Git学习(三)——暂存区、远程仓库、增删改管理

    一.工作区和暂存区 工作区(Working Directory) 就是在你的电脑里能看到的目录 版本库(Repository) 工作区中的一个隐藏目录.git,这个不算工作区,而是Git版本库.Git ...

  9. Git学习02 --暂存区,撤销修改,删除文件

    工作区和暂存区概念: 工作区(Working Directory)就是你在电脑里能看到的目录. 版本库(Repository) 工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库. Gi ...

随机推荐

  1. C语言 · 最大值与最小值计算

    输入11个整数,计算它们的最大值和最小值. 样例输入 0 1 2 3 4 5 6 7 8 9 10 样例输出 10 0   #include<stdio.h> int main(){ ]; ...

  2. 标准产品+定制开发:专注打造企业OA、智慧政务云平台——山东森普软件,交付率最高的技术型软件公司

    一.公司简介山东森普信息技术有限公司(以下简称森普软件)是一家专门致力于移动互联网产品.企业管理软件定制开发的技术型企业.公司总部设在全国五大软件园之一的济南齐鲁软件园.森普SimPro是由Simpl ...

  3. 开源一个跨平台运行的服务插件 - TaskCore.MainForm

    本次将要很大家分享的是一个跨平台运行的服务插件 - TaskCore.MainForm,此框架是使用.netcore来写的,现在netcore已经支持很多系统平台运行了,所以将以前的Task.Main ...

  4. C#为IE编写BHO插件心得

    啥是BHO,其实大家都用过,没听过只是没在意而已,来张图你就知道是什么了 是不是很熟悉,就是这么个玩意~~ 先说说我要用来干嘛~我们有个库,里面数据很全面,但是某个部门需要在第三方的B/S系统录入某些 ...

  5. OpenLiveWriter代码插件

    1.OpenLiveWriter安装 Windows Live Writer在2012年就停止了更新,Open Live Writer(以下简称OLW)是由Windows Live WriterWri ...

  6. VS项目中使用Nuget还原包后编译生产还一直报错?

    Nuget官网下载Nuget项目包的命令地址:https://www.nuget.org/packages 今天就遇到一个比较奇葩的问题,折腾了很久终于搞定了: 问题是这样的:我的解决方案原本是好好的 ...

  7. mysql删除重复记录语句的方法

    例如: id name value 1 a pp 2 a pp 3 b iii 4 b pp 5 b pp 6 c pp 7 c pp 8 c iii id是主键 要求得到这样的结果 id name ...

  8. linux系统内存爆满的解决办法!~

    1.首先用free工具检查一下内存的使用情况: 这个是我的linux时时数据 Mem: 4046824 763620 3283204 9004 10284 61560  -/+buffers/cach ...

  9. 萌新笔记——vim命令“=”、“d”、“y”的用法(结合光标移动命令,一些场合会非常方便)

    vim有许多命令,网上搜有一堆贴子.文章列举出各种功能的命令. 对于"="."d"."y",我在无意中发现了它们所具有的相同的一些用法,先举 ...

  10. Centos、Ubuntu 安装 Mono、Jexus

    Mono是.NET的跨平台实现 在众多关于语言的争论中,.NET一直被以不能跨平台而诟病,Mono改变了这一现状. 有人当心Mono会涉及版权啥的问题.高深的偶不懂,不过我觉得Unity3D都能用,为 ...