读《Git权威指南》ing...

2018-08-03  本文已影响6人  阿洋12138

Git权威指南

Git初始化

创建版本库以及第一次提交

本章主要学习:git initgit addgit commit

git --version //获取git当前版本

设置Git的环境变量,这是一次性的设置。即这些设置会在全局文件(用户主目录下的.gitconfig)或系统文件(/etc/gitconfig)中做永久的记录。

  1. 终端中输入:git init 会在当前目录下初始化git仓库,即:创建了隐藏目录/{path}/.git
    .git版本库目录所在的目录,称为工作区。

  2. 假如在这个目录创建文件hello.txt,那么现在在git的工作区出现了这个文件,但是文件还没有添加进入工作区。终端中输入:git add hello.txt将这个文件进行标记(后面会提到,即:放入暂存区),继续输入git commit -m "说明描述",将文件添加进本地的版本库中。

    • git add hello.txt这个只是标记一个文件如果文件非常多如果这样一个一个的添加未免有些麻烦,可以使用git add .来进行批量操作。

Git暂存区

当我们在工作去修改了文件之后,我们是不能直接将工作区的文件直接提交到本地的版本库中的,在git中有一个被称之为暂存区的文件,这相当于是工作区与本地版本库中的中间状态(这里称之为状态其实也不合适,但是我也找不到用什么词好)。当我们在工作区的文件进行了修改之后,将修改的文件add进暂存区,然后执行commit,这样就会将工作区的变动存入版本库中。

  1. 工作区中修改了文件object.h

    • 执行git status -s精简的状态输出
    $ git status -s
     M object.h
    
  2. 执行命令git add object.h,到这一步修改的文件只被提交到在暂存区。

    • 这时执行git diff会发现没有输出,因为这是对比的暂存区和版本库中文件的差异。
    • 执行git diff HEAD,将当前工作区和HEAD(当前版本库的头指针)进行比较,会发现有差异。这个差异才是正常的,因为尚未真正提交么。
    • 执行git status -s精简的状态输出与执行git add之前的精简状态输出相比,有细微的差别
    $ git status -s
    M  object.h
    
    1. 虽然都是 M(Modified)标识,但是位置不一样。在执行git add命令之前,这个M位于第二列(第一列是一个空格),在执行完git add之后,字符M位于第一列(第二列是空白)。 
    2. 位于第一列的字符M的含义是:版本库中的文件和处于中间状态——提交任务(提交暂存区,即stage)中的文件相比有改动。
    3. 位于第二列的字符M的含义是:工作区当前的文件和处于中间状态——提交任务(提交暂存区,即stage)中的文件相比也有改动。
    
  3. 此时继续修改本地文件object.h

    • 执行git status -s精简的状态输出,下面表示:不但版本库中最新提交的文件和处于中间状态 —— 提交任务(提交暂存区, stage)中的文件相比有改动,而且工作区当前的文件和处于中间状态 —— 提交任务(提交暂存区, stage)中的文件相比也有改动。
    $ git status -s
    MM welcome.txt
    
    • 不带任何选项和参数调用git diff显示工作区最新改动,即工作区和提交任务(提交暂存区,stage)中相比的差异。
    • 将工作区和HEAD(当前工作分支)相比(git diff HEAD),会看到更多的差异。
    • 通过参数--cached或者--staged参数调用git diff命令,看到的是提交暂存区(提交任务,stage)和版本库中文件的差异。
  4. 现在执行git commit -m "备注"

    • 执行git status -s精简的状态输出。此时第一列的M没有了,表示暂存区-版本库之间的变动没有了,因为暂存区中的内容被提交到了版本库。但是第二个M还在,表示工作区的内容和暂存区之间还存在差异,需要将工作区的改动add进入暂存区。
    $ git status -s
     M welcome.txt
    
image.png

在这个图中,可以看到部分Git命令是如何影响工作区和暂存区(stage,亦称index)的。下面就对这些命令进行简要的说明,而要彻底揭开这些命令的面纱要在接下来的几个章节。

  • 图中左侧为工作区,右侧为版本库。在版本库中标记为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重置

重置命令(git reset)是Git最常用的命令之一,也是最危险,最容易误用的命令。来看看git reset命令的用法。

用法一: git reset [-q] [<commit>] [--] <paths>...
用法二: git reset [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]

HEAD^代表HEAD的父提交

$ git reset --hard HEAD^

这条命令就相当于将master重置到上一个老的提交上

  1. 终端中执行touch new-commit.txt命令,会在工作区创建一个名为new-commit的文件
  2. 此时,工作区将会保存之前存在的文件和刚才创建的文件。继续执行git reset --hard HEAD^。由于之前创建的文件没有保存到仓库中,所以执行这条命令后HEAd所指向的master分支会重置到前一次提交并且工作区的文件也一起被重置了。

Ps. 实际上使用这个命令的时候,有的时候文件的内容是会回到前一个版本,但是新增的文件不会删除,但是还有的时候新增的文件也会删除。我也不知道为什么,还请知道�的大神指点一波,还是说是我自己弄错了?。。。哈哈哈哈

image.png

命令格式: git reset [–soft | –mixed | –hard ] [<commit>]



Git检出

重置命令(reset)一般用于重置暂存区(除非使用--hard参数,否则不重置工作区)

检出命令(checkout)主要是覆盖工作区(如果<commit>不省略,也会替换暂存区中相应的文件)

检出命令(git checkout)是Git最常用的命令之一,同样也很危险,因为这条命令会重写工作区。

用法一: git checkout [-q] [<commit>] [--] <paths>...
用法二: git checkout [<branch>]
用法三: git checkout [-m] [[-b|--orphan] <new_branch>] [<start_point>]

用法一的<commit>是可选项,如果省略则相当于从暂存区(index)进行检出。

image.png

Git恢复进度

使用git stash

命令git stash可以用于保存和恢复工作进度
命令git stash可以将当前的工作状态保存到git栈,在需要的时候再恢复

上一篇 下一篇

猜你喜欢

热点阅读