前言
上一节带大家入了个门,了解了什么是Git,并且掌握了Git的文件管理中的添加文件和版本回退的基本用法,但是可能有很多朋友对我上节提到的工作区和暂存区以及分支区的概念还很模糊,因此,本节咱们着重来研究什么是工作区,什么是缓存区,什么又是分支区以及文件管理中的文件的撤销修改和删除文件的操作啦!
工作区和暂存区
Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。故名思意,暂存区也就是暂时存放代码或者文件的位置,一般来说,咱们的代码不会长留在此。为了让大家能够清晰的明白工作区、缓存区、分支区的意思以及它们的 “职能” ,我会以图解的方式一一阐述。
工作区(Working Directory)
所谓工作区就是你在电脑里能看到的目录,比如我的mypro文件夹就是一个工作区
版本库(Repository)
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(在Eclipse中称之为index)的暂存区,还有Git为我们自动创建的第一个分支区master,以及指向master的一个指针叫HEAD。
上一节我们提到过,把文件往Git版本库里添加的时候,是分两步执行的:
第一步:用 git add
把文件添加进去,实际上就是把文件修改添加到暂存区
第二步:用 git commit
提交更改,实际上就是把暂存区的所有内容提交到当前分支
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,·git commit·就是往master分支上提交更改。
你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
比如说现在我们创建了一个readme.txt
文件,那么当我们执行git add readme.txt
指令的时候,我们工作区的文件就被提交到了stage里面,此时分支里面还是空的。需要注意的是工作区的文件提交到stage中,原本工作区的文件不会消失!
而当我们执行完git commit -m ”common“
之后,statge的文件就会被转移到master分支区域中,stage里面的内容则会被清空
这也就是为什么我们在第一篇博文讲到Git中的文件从暂存区被commit
之后,Git会提示我们说nothing to commit, working tree clean
,原因就是stage中已经没有内容了,并且源文件,也就是工作区中的文件在commit
之后,也没有再次被修改!
Git文件的修改撤销
在理解了Git的工作区和暂存区以及Master分支区域的概念之后,咱们来介绍文件管理中文件的修改撤销。
还是借用上节的栗子,比方说我这边修改一下文件tuofeilun.txt
,在《陀飞轮》中加上《退后》的歌词,很显然这是错的…
修改只在工作区
现在我还没有add到暂存区,但是又不想点进去删除,该怎么操作?
Marco@Marco-Laptop MINGW64 /d/git/mypro (master)
$ git checkout -- tuofeilun.txt #撤销未add到暂存区的操作
此时我们再看,是不是撤回到了之前的内容?
修改被添加到暂存区
那比方说我们之前的修改操作已经执行,并且文件被add到暂存区,该怎么办?
依次执行$ git reset tuofeilun.txt
和git checkout -- tuofeilun.txt
就可以啦!
Marco@Marco-Laptop MINGW64 /d/git/mypro (master)
$ git reset tuofeilun.txt #撤销add到暂存区的操作
Unstaged changes after reset:
M tuofeilun.txt
Marco@Marco-Laptop MINGW64 /d/git/mypro (master)
$ git checkout -- tuofeilun.txt #回退文件中被修改的内容
修改被提交到本地分支
那如果之前的修改操作已经执行,并且修改被提交到本地分支,我后悔了,该怎办?
直接$ git reset --hard HEAD^
,一招制敌!
Marco@Marco-Laptop MINGW64 /d/git/mypro (master)
$ git reset --hard HEAD^ #回退到上一个版本
HEAD is now at b9cf206 合并之后再提交
修改被提交到本地分支并同步到远程库存
这个时候,你就先烧个香,拜个佛好了…
哈哈哈,开玩笑的,正确的做法是在本地工作区中将内容先改回来,再提交,并同步到中央仓库。
但是!会有历史记录存在,如果你里面有不能让老板看到的东西,呵呵… 就祈祷老板不要检查历史记录吧…
Git删除文件
同样的,主要还是分三种情况,文件只存在于工作区、文件存到暂存区、文件已经提交
文件只存在于工作区
第一个很简单,直接一波$ rm -rf test.txt
带走敌方文件
文件存到暂存区
这种情况也需要先reset撤回操作,再remove文件
如果不reset,直接remove文件的话,那么之前被add的文件依然会停留在暂存区
Marco@Marco-Laptop MINGW64 /d/git/mypro (master)
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: test.txt #文件依然停留在暂存区
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: test.txt
文件已经提交
此时需要先执行$ git rm -rf test.txt
,然后再执行$ git commit -m "delete and commit"
提交删除操作。
git checkout
实质上是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
git rm
命令用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,但是会丢失最近一次提交后你修改的内容。