zoukankan      html  css  js  c++  java
  • GIt学习第二天之版本回退、工作区和暂存区

     搬运自 ‘廖雪峰的官方网站’ 地址:https://www.liaoxuefeng.com/

    1.版本回退

      在Git中,我们用git log命令显示从最近到最远的提交日志,如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline参数:

      

      你看到的一大串类似0530cb8524...的是commit id(版本号),和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样,以你自己的为准。为什么           commit id需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。

      现在准备将text.txt回退到上一个版本,首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交1094adb...(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^

           比较容易数不过来,所以写成HEAD~100

           现在,我们要把当前版本append GPL回退到上一个版本is a test txt,就可以使用git reset命令:

      $ git reset --hard HEAD^
      HEAD is now at e475afc add distributed
    

       --hard参数有啥意义?这个后面再讲,现在你先放心使用。

       看看text.txt的内容是不是版本is a test txt:

       

       可以看到被还原了,但是git log 发现最新的那个版本 append GPL已经看不到了,想要再回去,两种办法

       只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个append GPLcommit id是0530cb8524...,于是就可以指定回到未来的某个版本:

       $ git reset --hard 0530cb8524
       HEAD is now at 0530cb8524 append GPL
    

        版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。

       

    Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向append GPL

    git-head

    改为指向add distributed

    git-head-move

      然后顺便把工作区的文件更新了。所以你让HEAD指向哪个版本号,你就把当前版本定位在哪。

      如果命令窗口关掉了,再想恢复到append GPL,就必须找到append GPL的commit id,Git提供了一个命令git reflog用来记录你的每一次命令:

      

      从输出可知,append GPL的commit id是0530cb8,那么就可以用reset命令进行版本回退了

    2.工作区和暂存区

           工作区(Working Directory)就是你在电脑里能看到的目录,比如我的GitRepository文件夹就是一个工作区:

      

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

      Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

      git-repo

      分支和HEAD的概念我们以后再讲。

      前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:

      第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;

      第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

      因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。

      你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。

      

      俗话说,实践出真知。现在,我们再练习一遍,先对readme.txt做个修改,比如加上一行内容:

      Git is a distributed version control system.
      Git is free software distributed under the GPL.
      Git has a mutable index called stage.
    

      然后,在工作区新增一个LICENSE文本文件(内容随便写)。

      先用git status查看一下状态:

      $ git status
      On branch master
      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:   readme.txt
    
      Untracked files:
        (use "git add <file>..." to include in what will be committed)
    
          LICENSE
    
      no changes added to commit (use "git add" and/or "git commit -a")
    

      Git非常清楚地告诉我们,readme.txt被修改了,而LICENSE还从来没有被添加过,所以它的状态是Untracked

      现在,使用两次命令git add,把readme.txtLICENSE都添加后,用git status再查看一下:

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

      现在,暂存区的状态就变成这样了:

      git-stage

      所以,git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。

      $ git commit -m "understand how stage works"
      [master e43a48b] understand how stage works
       2 files changed, 2 insertions(+)
       create mode 100644 LICENSE
    

      一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:

      $ git status
      On branch master
      nothing to commit, working tree clean
    

      现在版本库变成了这样,暂存区就没有任何内容了:

      git-stage-after-commit

    git diff    #是工作区(work dict)和暂存区(stage)的比较
    
    git diff --cached    #是暂存区(stage)和分支(master)的比较

    git diff HEAD --文件名 #是工作区和分支(master)的比较

    小结

    现在总结一下:

    • HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id

    • 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。

    • 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。

  • 相关阅读:
    LeetCode Missing Number (简单题)
    LeetCode Valid Anagram (简单题)
    LeetCode Single Number III (xor)
    LeetCode Best Time to Buy and Sell Stock II (简单题)
    LeetCode Move Zeroes (简单题)
    LeetCode Add Digits (规律题)
    DependencyProperty深入浅出
    SQL Server存储机制二
    WPF自定义RoutedEvent事件示例代码
    ViewModel命令ICommand对象定义
  • 原文地址:https://www.cnblogs.com/HJkoma/p/10081611.html
Copyright © 2011-2022 走看看