git简介
是目前世界上先进的分布式版本控制系统(没有之⼀)。 不但能自动帮我记录每次文件的改动,还可以让同事协作编辑,这样就不用自己管理一堆类似的文件了,也不需要把文件传来传去。Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux 系统的源码已经由Git管理了!Git迅速成为流⾏行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。
集中式vs分布式
CVS及SVN都是集中式的版本控制系统,而Git是分布式版本控制系统。
先说集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得新的版本,然后开始干 活,干完活了,再把自⼰ 的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。
集中式版本控制系统⼤大的⽑毛病就是必须联网才能工作,如果在局域网内还好,带宽够大, 速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的⽂文件就需要5分钟, 这还不得把⼈人给憋死啊。
那分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本 没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这 样,你工作的时候,就 不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有⼀一个完整的版本 库,那多个人如何协作呢?比方说你在自己电脑上改 了文件A,你的同事也在他的电脑上改 了文件A,这时,你们俩之间只需把各⾃自的修改推送给对方,就可以互相看到对方的修改 了。
和集中式版本控制系统相比,分布式版本控制系统的安全性要⾼高很多,因为每个⼈人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而 集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。
在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改, 因为可能你们俩不在⼀一个局域网内,两台电脑互相访问不了,也 能今天你的同事病了, 他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电 脑,但这个服务器的作用仅仅是用来方便“交换” 大家的修改,没有它大家也⼀样干活, 只是交换修改不方便而已。
当然,Git的优势不单是不必联网这么简单,后面我们还会看到Git极其强大的分支管理,把 SVN等远远抛在了后⾯面。
Ubuntu 版
安装
首先,你可以试着输入git,看看系统有没有安装Git:
$ git
The program 'git' is currently not installed. You can install it by typing:```
$ sudo apt-get install git
可以如下代码安装git
$ sudo apt-get install git
验证是否安装成功
$ git
若执行git命令如图所示,则证明已安装成功
安装完成后,还需要后一步设置,在命令行输入:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。
创建仓库
创建一个版本库非常简单,首先,选择一个合适的地⽅方,创建一个空目录:
$ mkdir git
$ cd git
$ pwd
/home/gaoyang/git
第二步,通过git init命令把这个目录变成Git可以管理的仓库:
$ git commit -m "wrote a readme file"
[master (root-commit) cb926e7] wrote a readme file 1 file changed, 2 insertions(+) create mode 100644 readme.txt
简单解释一下git commit命令,-m后⾯面输入的是本次提交的说明,可以输入任意内容,当然好是有意义的,这样你就能从历史记录里方便地找到改动记录。
嫌麻烦不想输入-m "xxx"行不行?确实有办法可以这么干,但是强烈不建议你这么干,因为输入说明对自己对别人阅读都很重要。实在不想输入说明的童鞋请自行Google,我不告诉 你这个参数。
git commit命令执行成功后会告诉你,1个文件被改动(我们新添加的readme.txt文件),插入了两行内容(readme.txt有两行内容)。
为什么Git添加⽂文件需要add,commit⼀一共两步呢?因为commit可以⼀一次提交很多⽂文件, 所以你可以多次add不同的⽂文件,比如:
$ git add file1.txt
$ git add file2.txt
$ git add file3.txt
$ git commit -m "add 3 files."
小结
初始化一个Git仓库,使用git init命令。
添加⽂文件到Git仓库,分两步:
• 第一步,使用命令git add ,注意,可反复多次使用,添加多个文件;
• 第二步,使用命令git commit,完成。
时光机穿梭
运⾏行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: redame.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
"../Git\346\225\231\347\250\213.pdf"
no changes added to commit (use "git add" and/or "git commit -a")
git status命令可以让我们时刻掌握仓库当前的状态,上面的命令告诉我们,readme.txt被 修改过了,但还没有准备提交的修改。
虽然Git告诉我们redame.txt被修改了,但如果能看看具体修改了什么内容,自然是很好的。比如你休假两周从国外回来,第一天上班时,已经记不清上次怎么修改的 redame.txt,所以,需要用git diff这个命令看看:
$ git diff redame.txt
diff --git a/learn/redame.txt b/learn/redame.txt
index 46d49bf..9247db6 100644
--- a/learn/redame.txt
+++ b/learn/redame.txt
@@ -1,2 +1,2 @@
-Git is a version control system.
+Git is a distributed version control system.
Git is free software.
git diff顾名思义就是查看difference,⽰示的格式正是Unix通用的diff格式,可以从上面的命令输出看到,我们在第一行添加了一个“distributed”单词。
知道了对redame.txt作了什么修改后,再把它提交到仓库就放⼼心多了,提交修改和提交新文件是一样的两步,第一步是git add:
git add redame.txt
同样没有任何输出。在执行第二步git commit之前,我们再运行git status看看当前仓库的状 态:
git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
learnNot.txt
nothing added to commit but untracked files present (use "git add" to track)
应该是之前已经提交过redame.txt了,并且我重新向git中添加了learnNot.txt文档。所以查看当前状态是这样的情况。我们继续提交learnNot.txt文档,所用到的命令是一样的。提交learnNot.txt文档:
git commit -m 'hello'
On branch master
Untracked files:
learnNot.txt
nothing added to commit but untracked files present
查看当前状态:
git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
learnNot.txt
nothing added to commit but untracked files present (use "git add" to track)
恩,虽然英语不太好,但还是勉强读懂了。貌似是之前add的是redame.txt,然而commit的是learnNot.txt。故导致提交失败,尝试重新add,再commit:
git add learnNot.txt
gaoyang@ubuntu:~/git/learn$ git commit -m 'hello'
[master 5cbe811] hello
1 file changed, 2 insertions(+)
create mode 100644 learn/learnNot.txt
gaoyang@ubuntu:~/git/learn$ git status
On branch master
nothing to commit, working directory clean
说明此前假设成立,确为add文档为已经提交过且未发生变化的文档,而提交的时候仓库中存在已经发生变化而未被添加的文档。
小结
要随时掌握工作区的状态,使用git status命令。
如果git status告诉你有文件被修改过,用git diff可以查看修改内容。
版本回退
现在,你已经知道了如何修改文件,然后把修改提交到Git版本库,现在,再练习一次,修改 redame.txt文件如下:
Git is a distributed version control system.
Git is free software distributed under the GPL.
然后尝试提交:
git add redame.txt
gaoyang@ubuntu:~/git/learn$ git commit -m 'append GPL'
[master a51f10d] append GPL
1 file changed, 2 insertions(+), 2 deletions(-)
像这样,你不断对文件进行修改,然后不断提交修改到版本库里,就好比玩RPG游戏时,每 通过一关就会自动把游戏状态存盘,如果某一关没过去,你还可以选择读取前一关的状 态。有些时候,在打Boss之前,你会手动存盘,以便万一打Boss失败了,可以从近的地方重新开 始。Git也是⼀一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快 照”,这个快照在Git中被称为commit。一旦你把文件改乱了,或者误删了文件,还可以从近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失。 现在,我们回顾一下redame.txt文件一共有几个版本被提交到Git仓库里了:
版本1:
wrote a readme file
Git is a version control system. Git is free software.
版本2:
first commit
Git is a distributed version control system.
Git is free software.
版本3:
append GPL
Git is a distributed version control system.
Git is free software distributed under the GPL.
当然了,在实际工作中,我们脑子里怎么可能记得⼀一个几千行的文件每次都改了什么内容, 不然要版本控制系统干什么。版本控制系统肯定有某个命令可以告诉我们历史记录,在Git 中,我们用git log命令查看:
git log
commit a51f10d41c94ae59d7a9a4ec436803c2a63a5627
Author: G.Hope <1638327522@qq.com>
Date: Sat Jul 21 00:38:39 2018 -0700
append GPL
commit 5cbe811db86d59ccb1234f287dff57b91dd0c6d3
Author: G.Hope <1638327522@qq.com>
Date: Sat Jul 21 00:30:18 2018 -0700
hello
commit 326774bc7579e8a3eb31465b215b23b1ffc3730f
Author: G.Hope <1638327522@qq.com>
Date: Tue Jul 17 17:39:18 2018 -0700
first commit
commit c3e0fbf35bddbf07c2152f6fb4f959c0cdcd5f1c
Author: G.Hope <1638327522@qq.com>
Date: Mon Jul 16 17:50:17 2018 -0700
wrote a redame file
其中按照时间由近到远的顺序从上到下依次排列,其中第二个版本,也就是我写文档打算提交的那个文档是前天问老师git diff命令提示出来的信息怎么解读的时候老师就帮我提交了那个文档。顺带这又想起了我的Ubuntu中并没有输入法。。。等会也把它解决了吧!见另一篇笔记。
当然,如果嫌输出信息太多,看得眼花缭乱的,可以试试加上 --pretty=oneline参数:
git log --pretty=oneline
a51f10d41c94ae59d7a9a4ec436803c2a63a5627 append GPL
5cbe811db86d59ccb1234f287dff57b91dd0c6d3 hello
326774bc7579e8a3eb31465b215b23b1ffc3730f first commit
c3e0fbf35bddbf07c2152f6fb4f959c0cdcd5f1c wrote a redame file
需要友情提示的是,你看到的一大串类似“ 3628164...882e1e0”的是commit id(版本号),和SVN不⼀一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常⼤大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样, 以你自己的为准。为什么commit id需要⽤用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后⾯面我们还要研究多⼈人在同一个版本库⾥里⼯工作,如果⼤大家都用1,2,3……作 为版本 号,那肯定就冲突了。
每提交一个新版本,实际上Git就会把它们自动串成一条时间线。如果使用可视化工具查看 Git历史,就可以更清楚地看到提交历史的时间线:
好了,现在我们启动时光穿梭机,准备把redame.txt回退到上一个版本,也就是“first commit”的那个版本,怎么做呢?
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表⽰示当前版本,也就是新的提交“ 3628164...882e1e0”(注意我的提交ID和你的肯定不一样),上一个版本就是 HEAD,上上一个版本就是HEAD^,当然往上100 个版本写100个^比较容易数不过来, 所以写成HEAD~100。
现在,我们要把当前版本“append GPL”回退到上⼀一个版本“fiest commit”,就可 以使用git reset命令:
git reset --hard HEAD ^
fatal: Cannot do hard reset with paths.
gaoyang@ubuntu:~/git/learn$ git reset --hard HEAD^
HEAD is now at 5cbe811 hello
gaoyang@ubuntu:~/git/learn$ git reset --hard HEAD^
HEAD is now at 326774b first commit
需要说明的是HEAD^之间不能有空格,类似于HEAD ^就会报找不到路径的错误。而且版本回退回退到的是hello版本,他们并不是同一个文件,却也返回了。我觉得这应该就是分支所发挥的作用吧!后面会学到的,总之现在已经回退到了‘first commit'版本,--hard参数有啥意义?这个后面再讲,现在你先放心使用。 看看redame.txt的内容是不是版本“first commit”:
cat redame.txt
Git is a distributed version control system.
Git is free software.
果然。还可以继续回退到上一个版本“wrote a readme file”,不过且慢,然我们用git log再看看现在版本库的状态:
git log
commit 326774bc7579e8a3eb31465b215b23b1ffc3730f
Author: G.Hope <1638327522@qq.com>
Date: Tue Jul 17 17:39:18 2018 -0700
first commit
commit c3e0fbf35bddbf07c2152f6fb4f959c0cdcd5f1c
Author: G.Hope <1638327522@qq.com>
Date: Mon Jul 16 17:50:17 2018 -0700
wrote a redame file
在Git中,总是有后悔药可以吃的。当你用$ git reset --hard HEAD^回退到“first commit”版本时,再想恢复到“append GPL”,就必须找到“append GPL”的 commit id。Git提供了一个命令git reflog用来记录你的每一次命令:
git reflog
326774b HEAD@{0}: reset: moving to HEAD^
5cbe811 HEAD@{1}: reset: moving to HEAD^
a51f10d HEAD@{2}: commit: append GPL
5cbe811 HEAD@{3}: commit: hello
326774b HEAD@{4}: commit: first commit
c3e0fbf HEAD@{5}: commit (initial): wrote a redame file
指定回到未来的某个 版本:
git reset --hard a51f10d
HEAD is now at a51f10d append GPL
现在总结一下:
*HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命 令git reset --hard commit_id。
*穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
*要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
Windows 版
安装
Windows下要使⽤用很多Linux/Unix的工具时,需要Cygwin这样的模拟环境,Git也一样。 Cygwin的安装和配置都比较复杂, 就不建议你折腾了。
不过,有高人已经把模拟环境和 Git都打包好了,名叫msysgit,只需要下载一个单独的exe安装程序,其他什么也不用装,绝对好用。 msysgit是Windows版的Git,从http://msysgit.github.io/下载,然后按默认选项安装即可。
安装完成后,在开始菜单⾥里找到“Git”->“Git Bash”,蹦出⼀一个类似命令⾏行窗⼝口的东西,就说明Git安装成功!
安装完成后,还需要后一步设置,在命令行输入:
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。
创建仓库
找到合适的位置(个人认为这是超级麻烦的一步,因为默认进去我的目录在/c/Users/Machenike下,想去到F盘创建git库,就先使用cd ..命令回退到根目录下,在进入F盘创建git)
pwd 查看当前所在路径
ls 查看当前目录下文件
cd .. 回退到上一级目录
cd ./XXX 进入当前目录下文件
mkdir 创建文件夹
因为我已经建立过git,就不再演示如何创建文件夹的操作了,同Linux操作差不多的。
如上,我们已经为库的建立找到了位置。创建一个空目录,通过git init命令把这个目录变成Git可以管理的仓库:
mkdir learn
cd learn/
pwd
/f/git/learn
git init
Initialized empty Git repository in F:/git/learn/.git/
在learn中编写一个用来测试的文档,练习git的基本使用。我创建的是text.txt,文本内容是一首有些小错误的诗:
前无古人,后无来者。
念天地之悠悠,独怆然而涕下。
然后使用git add text.txt将测试文本添加入git中,执行上面的命令,没有任何显示,这就对了,Unix的哲学是“没有消息就是好消息”,说明 添加成功。 第二步,用命令git commit告诉Git,把文件提交到仓库:
git add text.txt
git commit -m "登幽州台歌"
1 file changed, 2 insertions(+)
create mode 100644 text.txt
On branch master
nothing to commit, working tree clean
时光穿梭
修改测试文件,将古诗修改正确。修改内容如下:
前不见古人,后不见来者。
念天地之悠悠,独怆然而涕下。
运⾏行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 -- <
git status命令可以让我们时刻掌握仓库当前的状态,上面的命令告诉我们,text.txt被 修改过了,但还没有准备提交的修改。
虽然Git告诉我们readme.txt被修改了,但如果能看看具体修改了什么内容,自然是很好 的。比如你休假两周从国外回来,第一天上班时,已经记不清上次怎么修改的 readme.txt,所以,需要⽤用git diff这个命令看看:
git diff text.txt
diff --git a/text.txt b/text.txt
index 1703de1..8749e44 100644
--- a/text.txt
+++ b/text.txt
@@ -1,2 +1,2 @@
-ǰ<CE><C5><C8>ˣ<AC><BA><F3><CE><DE><C0><B4><D5>ߡ<A3>
+ǰ<B2><BB><BC><FB><B9><C5><C8>ˣ<AC><BA><FB><C0><B4><D5>ߡ<A3>
<C4><EE><CC><EC><B5><D8>֮<D3><C6><D3>ƣ<AC><B6><C0><E2><EB>Ȼ<B6><F8><CC><E9><CF>¡ <A3>
\ No newline at end of file
根据Ubuntu和Windows两次对于diff命令的使用,我觉得红色部分应该是之前的版本,绿色是修改之后的版本。windows中因为中文原因所以显示结果就看起来很奇怪,不过这不重要了。只需要知道红色代表之前版本,绿色代表当前版本就好了。
知道了对text.txt作了什么修改后,再把它提交到仓库就放心多了,提交修改和提交新 文件是一样的两步,第一步是git add:
git add text.txt
同样没有任何输出。在执⾏行第二步git commit之前,我们再运行git status看看当前仓库的状 态:
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: text.txt
git status告诉我们,将要被提交的修改包括text.txt,下一步,就可以放心地提交了:
git commit -m "write right"
[master 559f1b0] write right
1 file changed, 1 insertion(+), 1 deletion(-)
提交后,我们再⽤用git status命令看看仓库的当前状态:
git status
On branch master
nothing to commit, working tree clean
Git告诉我们当前没有需要提交的修改,而且,工作目录是干净(working directory clean)的。
小结:
要随时掌握工作区的状态,使用git status命令。
如果git status告诉你有文件被修改过,用git diff可以查看修改内容。
版本回退
现在,已经学会了修改文件,然后把修改提交到Git版本库,现在,再练习一次,修改 text.txt文件如下:
登幽州台歌
前不见古人,后不见来者。
念天地之悠悠,独怆然而涕下。
然后尝试提交:
git add text.txt
git commit -m "write complete"
[master e2f20fe] write complete
1 file changed, 1 insertion(+)
像这样,你不断对文件进行修改,然后不断提交修改到版本库里,就好比玩RPG游戏时,每通过一关就会⾃自动把游戏状态存盘,如果某一关没过去,你还可以选择读取前一关的状 态。有些时候,在打Boss之前,你会手动存盘,以便万一打Boss失败了,可以从近的地⽅方 重新开 始。Git也是一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快 照”,这个快照在Git中被称为commit。一旦你把文件改乱了,或者误 删了文件,还可以 从近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失。
现在,我们回顾一下readme.txt文件一共有几个版本被提交到Git仓库里了:
版本1:
wrote a text file Git is a version control system.
Git is free software.
版本2:
write right Git is a text version control system.
Git is free software.
版本3:
write complete Git is a text version control system.
Git is free software .
当然了,在实际工作中,我们脑子里怎么可能记得一个几千行的文件每次都改了什么内容, 不然要版本控制系统干什么。版本控制系统肯定有某个命令可以告诉我们历史记录,在Git 中,我们用git log命令查看:
git log
commit e2f20fe939de1e410806da1085d58ae64a47fd0f (HEAD -> master)
Author: G.Hope <1638327522@qq.com>
Date: Thu Jul 19 09:25:53 2018 +0800
write complete
commit 559f1b01e06218dd9a10cdae96c84e917bd4bb33
Author: G.Hope <1638327522@qq.com>
Date: Thu Jul 19 09:06:28 2018 +0800
write right
commit 7b70286e53d99055b1f31e20d6fd814d793f89ee
Author: G.Hope <1638327522@qq.com>
Date: Wed Jul 18 20:49:08 2018 +0800
登幽州台歌
git log命令显示从近到远的提交日志,我们可以看到3次提交,近的一次是“write complete”,上一次是“write right”,早的一次是“登幽州台歌”。 如果嫌输出信息太多,看得眼花缭乱的,可以试试加上 --pretty=oneline参数:
git log --pretty=oneline
e2f20fe939de1e410806da1085d58ae64a47fd0f (HEAD -> master) write complete
559f1b01e06218dd9a10cdae96c84e917bd4bb33 write right
7b70286e53d99055b1f31e20d6fd814d793f89ee 登幽州台歌
需要友情提示的是,你看到的一大串类似“e2f20fe939de1e410806da1085d58ae64a47fd0f ”的是commit id(版本号),和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算 出来的一个非常大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样, 以你自己的为准。为什么commit id需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。每提交一个新版本,实际上Git就会把它们⾃自动串成一条时间线。如果使用可视化工具查看Git历史,就可以更清楚地看到提交历史的时间线:
好了,现在我们启动时光穿梭机,准备把text.txt回退到上一个版本,也就是“write right”的那个版本,怎么做呢?
首先,Git必须知道当前版本是哪个版本,在Git中,⽤用HEAD表⽰示当前版本,也就是新的提交“e2f20fe939de1e410806da1085d58ae64a47fd0f ”(注意我的提交ID和你的肯定不一样),上一个版本就是 HEAD,上上一个版本就是HEAD^,当然往上100 个版本写100个^比较容易数不过来, 所以写成HEAD~100。 现在,我们要把当前版本“write complete”回退到上一个版本“write right”,就可以使用git reset命令:
git reset --hard HEAD^
HEAD is now at 559f1b0 write right
--hard参数有啥意义?这个后⾯面再讲,现在你先放⼼心使⽤用。 看看text.txt的内容是不是版本“write right”:
cat text.txt
ǰ▒▒▒▒▒▒▒ˣ▒▒▒▒▒▒ߡ▒
▒▒▒▒▒֮▒▒▒ƣ▒▒▒▒▒Ȼ▒▒▒▒▒¡▒
...,乱码,我猜测十有八九是中文的原因。所以以后的项目中要切记,如非必要,避免任何中文出现。不过问题不大,用git log再看看现在版本库的状态:
git log
commit 559f1b01e06218dd9a10cdae96c84e917bd4bb33 (HEAD -> master)
Author: G.Hope <1638327522@qq.com>
Date: Thu Jul 19 09:06:28 2018 +0800
write right
commit 7b70286e53d99055b1f31e20d6fd814d793f89ee
Author: G.Hope <1638327522@qq.com>
Date: Wed Jul 18 20:49:08 2018 +0800
登幽州台歌
新的那个版本“write complexe”已经看不到了!好比你从21世纪坐时光穿梭机来到了19 世纪,想再回去已经回不去了,肿么办?
办法其实还是有的,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找 到那个“write complexe”的commit id是“e2f20fe939de1e410806da1085d58ae64a47fd0f”,于是就可以指定回到未来的某个版本:
git reset --hard e2f20fe93
HEAD is now at e2f20fe write complete
查看版本,恩,又是日常乱码,不过可以通过log(日志)查看是否成功
cat text.txt
▒▒▒▒▒▒̨▒▒
ǰ▒▒▒▒▒▒▒ˣ▒▒▒▒▒▒ߡ▒
▒▒▒▒▒֮▒▒▒ƣ▒▒▒▒▒Ȼ▒▒▒▒▒¡▒
当前日志:
git log
commit e2f20fe939de1e410806da1085d58ae64a47fd0f (HEAD -> master)
Author: G.Hope <1638327522@qq.com>
Date: Thu Jul 19 09:25:53 2018 +0800
write complete
commit 559f1b01e06218dd9a10cdae96c84e917bd4bb33
Author: G.Hope <1638327522@qq.com>
Date: Thu Jul 19 09:06:28 2018 +0800
write right
commit 7b70286e53d99055b1f31e20d6fd814d793f89ee
Author: G.Hope <1638327522@qq.com>
Date: Wed Jul 18 20:49:08 2018 +0800
登幽州台歌
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向“write complete ”,改为指向“write right”。
然后顺便把工作区的文件更新了。所以你让HEAD指向哪个版本号,你就把当前版本定位在哪。
现在,你回退到了某个版本,关掉了电脑,第二天早上就后悔了,想恢复到新版本怎么办? 找不到新版本的commit id怎么办? 在Git中,总是有后悔药可以吃的。当你用$ git reset --hard HEAD^回退到“write right”版本时,再想恢复到“write complete”,就必须找到“write complete”的 commit id。
Git提供了一个命令git reflog用来记录你的每一次命令:
git reflog
e2f20fe (HEAD -> master) HEAD@{0}: reset: moving to e2f20fe93
559f1b0 HEAD@{1}: reset: moving to HEAD^
e2f20fe (HEAD -> master) HEAD@{2}: commit: write complete
559f1b0 HEAD@{3}: commit: write right
7b70286 HEAD@{4}: commit (initial): 登幽州台歌
小结
现在总结一下:
• HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使⽤用命 令git reset --hard commit_id。
• 穿梭前,⽤用git log可以查看提交历史,以便确定要回退到哪个版本。
• 要重返未来,⽤用git reflog查看命令历史,以便确定要回到未来的哪个版本。