Git 进阶--时光穿梭机

主要内容

  • 版本回退
  • 工作区和暂存区
  • 管理修改
  • 撤销修改
  • 删除文件

一、两条基本查看命名

查看状态命令:git status

查看修改内容命令:git diff

实例

思路:修改readme.txt文本内容 -> 查看状态:git status-> 查看具体内容:git diff-> 了解修改内容后提交:git -add-> 再查看仓库的当前状态

git diff顾名思义就是查看different,显示的格式正是Unix通用的diff格式。

小结

  • 要随时掌握工作区的状态,使用git status命令。
  • 如果git status告诉你有文件被修改过,用git diff可以查看内容。

二、版本回退

历史版本还原命令:git reset --hard commit_id

查看提交历史命令:git log

恢复先前版本命令:git reflog+git reset

实例

对先前的myrepo/readme.txt进行修改,然后把修改提交到Git版本库。

修改readme.txt文件如下:

Git is a distributed version control system.
Git is free software distributed under the GPL.

然后尝试提交:

$ git add readme.txt
$ git commit -m "append GPL"
[master 3628164] append GPL
1 file changed, 1 insertion(+), 1 deletion(-)

不断地对文件进行修改,然后不断提交到修改到版本库里,就好比玩游戏里的存档,如果某一关没过去,可以选择读取前一关的状态。

有些时候,在Boss之前,你会手动存盘,以便万一打Boss失败了,可以从最近的地方重新开始。Git也是一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失。

在Git中,我们可以用git log命令来查看readme.txt文件一共有几个版本被提交到Git仓库里:

$ git log

Git 进阶--时光穿梭机

如果觉得输入信息太多,看的眼花缭乱,可以试试加上--pretty=oneline参数:

$ git log --pretty=oneline

Git 进阶--时光穿梭机

注意:前面看到的一大串类似于“1396b...74ele5”的是commit id(版本号),和SVN不一样,Git的commit id不是1,2,3...递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样,以你自己的为准。

为什么commit id需要用这么一大串数字表示呢?因为Git是分布式的版本系统,后面还有多人在同一个版本库里工作,如果大家都用1,2,3...作为版本号,那肯定就冲突了。

每提交一个新版本,实际上Git就把它们自动串成一条时间线。

好了,现在我们来启动时光机!把readme.txt回退到上一个版本,也就是“add distributed”的版本。

首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交“59877e...cfe6”,上一个版本是HEAD^,上上一个版本就是HEAD^^,当然往上写100个版本写100个^比较容易数不过来,所以写成HEAD~100

现在,我们把当前版本“append GPL”回退到上一个版本“add distributed”:

$ git reset --hard HEAD^
HEAD is now at 1396b06 append GPL

Git 进阶--时光穿梭机

查看readme.txt的内容是不是版本“add distribute”:

$ cat readme.txt

Git 进阶--时光穿梭机

是的。

还可以继续回退到上一个版本“wrote a readme file”,但需先用git log查看现在版本库的状态。

你会发现最新的那个版本“append GPL”已经看不到了。好比你从21世纪坐时光穿梭机来到了19世纪,想回去已经回不到了,肿么办?

解决办法:只要上面的命令窗口还没有被关掉,可以顺着网上找,找到那个版本的 commit id 然后输入版本号的前几位数字,Git就会自动去找,再git reset一下就回来。

Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向append GPL,改为指向add distributed,然后顺便把工作区的文件更新了。所以你让HEAD指向哪个版本号,你就把当前版本定位在哪。

Git 进阶--时光穿梭机

Git 进阶--时光穿梭机

另外,Git还提供了一个命令git reflog用来记录你的每一条命令。可以从显示信息里面找到忘记了的想回退的新版本的commit id

Git 进阶--时光穿梭机

小结

  • HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。
  • 穿梭前,用git log可以查看提交历史,以便确定回退到哪个版本。
  • 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。

三、工作区和暂存区

Git和其它版本控制系统如SVN的一个不同之处就是有暂存区的概念。

工作区(Working Directory

工作区就是你在电脑里能看到的目录,比如myrepo文件夹就是一个工作区。

版本库(Repository

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

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

Git 进阶--时光穿梭机

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

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

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

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

Git 进阶--时光穿梭机

Git 进阶--时光穿梭机

小结

暂存区是Git非常重要的概念,弄明白了暂存区,就弄明白了Git的很多操作到底干了什么。

四、管理修改

下面我们来讨论的是,为什么Git比其它版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件。

实例

思路:第一次修改 ->git add-> 第二次修改 ->git commit

说明:Git管理的是修改,当你用git add命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,git commit只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。

提示:用git diff HEAD --readme.txt命令可以查看工作区和版本库里面最新版本的区别。

小结

从以上实例可以知道Git是如何跟踪修改的,每次修改,如果不add到暂存区,那就不会加入到commit中。

五、撤销修改

丢弃工作区修改的命令:git checkout --file

命令git checkout --readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

  • 一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
  • 一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加暂存区后的状态。

总之,就是让这个文件回到最近一次git commitgit add时的状态。

注意:git checkout --file命令中的--很重要,没有--,就变成了“创建一个新分支”的命令,在后面的分支管理中会再次遇到git checkout命令。

撤销暂存区修改的命令(unstage):git reset HEAD file

Git 进阶--时光穿梭机

git reset命令既可以回退版本,也可以把暂存区的修改会退到工作区。当我们用HEAD时,表示最新的版本。

小结

  • 场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout --file
  • 场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。
  • 场景3:已经提交了不适合的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库

六、删除文件

删除命令:git rm

实例

在Git中,删除也是一个修改操作。首先,我们先添加一个新文件test.txt到Git并且提交:

Git 进阶--时光穿梭机

一般情况下,你通常直接在文件管理器中把没用的文件删了,或者用rm命令删了:

$ rm test.txt

这个时候,Git知道你删除了文件,因此,工作区和版本库就不一致了,git status命令会立刻告诉你哪些文件被删除了。

现在你有两个选择:

  • 一是确实要从版本库中删除该文件,那就用命令git rm删掉,并且commit。
  • 另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:

$ git checkout -- test.txt

git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

总结

命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容

分类:管理 时间:2015-05-02 人气:168
本文关键词: 管理工具
分享到:

相关文章

iOS 开发

Android 开发

Python 开发

JAVA 开发

开发语言

PHP 开发

Ruby 开发

搜索

前端开发

数据库

开发工具

开放平台

Javascript 开发

.NET 开发

云计算

服务器

Copyright (C) codeweblog.com, All Rights Reserved.

CodeWeblog.com 版权所有 闽ICP备15018612号

processed in 0.032 (s). 12 q(s)