Sky's blog

.git学习-边学边记录

Word count: 3,515 / Reading time: 13 min
2017/07/12 Share

前言

因为最近做题目总是遇到.git泄露,不学习一下还真没法做,加上项目频繁增多,学习.git这么方便的东西迫在眉睫,何况我的博客也是用了.git呢(滑稽脸),所以今天开始学习一下.git大法
大部分文字均来源于廖雪峰的.git教程:
http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

准备工作

安装.git

因为我是windows,所以只学了windows版本,等换了mac再看os吧= =还有坑爹的Linux,日后部署服务器再学吧~~hhhhhh
在Windows上安装Git:
Windows下要使用很多Linux/Unix的工具时,需要Cygwin这样的模拟环境,Git也一样。Cygwin的安装和配置都比较复杂,不过,有高人已经把模拟环境和Git都打包好了,名叫msysgit,只需要下载一个单独的exe安装程序,其他什么也不用装,绝对好用。

msysgit是Windows版的Git,从
https://git-for-windows.github.io下载(网速慢的同学请移步国内镜像),然后按默认选项安装即可。

安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明Git安装成功!

安装完成后,还需要最后一步设置,在命令行输入:

1
2
$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。

创建版本库

版本库又名仓库,英文名repository,可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

第一步:
创建一个版本库,选择一个合适的地方,创建一个空目录:

1
2
3
$ mkdir learngit
$ cd learngit
$ pwd

注:pwd命令用于显示当前目录。
(如果你使用Windows系统,为了避免遇到各种莫名其妙的问题,请确保目录名(包括父目录)不包含中文。)

第二步:
通过git init命令把这个目录变成Git可以管理的仓库

然后Git就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository)
但是可以发现当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。(目测这就是.git泄露的由来)
(如果你没有看到.git目录,那是因为这个目录默认是隐藏的,用ls -ah命令就可以看见。)

常用指令与操作

把文件添加到版本库

首先这里再明确一下,所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。

不幸的是,Microsoft的Word格式是二进制格式,因此,版本控制系统是没法跟踪Word文件的改动的,前面我们举的例子只是为了演示,如果要真正使用版本控制系统,就要以纯文本方式编写文件。

因为文本是有编码的,比如中文有常用的GBK编码,日文有Shift_JIS编码,如果没有历史遗留问题,强烈建议使用标准的UTF-8编码,所有语言使用同一种编码,既没有冲突,又被所有平台所支持。

Windows特别注意:
千万不要使用Windows自带的记事本编辑任何文本文件。原因是Microsoft开发记事本的团队使用了一个非常弱智的行为来保存UTF-8编码的文件,他们自作聪明地在每个文件开头添加了0xefbbbf(十六进制)的字符,你会遇到很多不可思议的问题,比如,网页第一行可能会显示一个“?”,明明正确的程序一编译就报语法错误,等等,都是由记事本的弱智行为带来的。建议你下载Notepad++代替记事本,不但功能强大,而且免费!记得把Notepad++的默认编码设置为UTF-8 without BOM即可

言归正传,现在编写一个readme.txt文件,内容如下:

1
2
Git is a version control system.
Git is free software.

一定要放到learngit目录下(子目录也行),因为这是一个Git仓库,放到其他地方Git再厉害也找不到这个文件。
把一个文件放到Git仓库只需要两步:

第一步,用命令git add告诉Git,把文件添加到仓库:
$ git add readme.txt
执行上面的命令,没有任何显示,这就对了

第二步,用命令git commit告诉Git,把文件提交到仓库:
$ git commit -m "wrote a readme file"

简单解释一下git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
git commit命令执行成功后会告诉你,
1个文件被改动(我们新添加的readme.txt文件),插入了两行内容(readme.txt有两行内容)。

为什么Git添加文件需要addcommit一共两步呢?因为commit可以一次提交很多文件,所以你可以多次add不同的文件,比如

1
2
3
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."

所以
初始化一个Git仓库,使用git init命令。

对于仓库添加文件,一共就两步:
第一步,使用命令git add <file>,注意,可反复多次使用,添加多个文件;

第二步,使用命令git commit,完成。

查看文件状态与改变

运用git status指令:
可以让我们时刻掌握仓库当前的状态,让我们知道哪些文件被修改过了,哪些文件还没有准备提交的修改。

运用git diff指令:
可以让我们知道修改过的文件具体修改了什么内容
git diff顾名思义就是查看difference,显示的格式正是Unix通用的diff格式)

版本回退

运用git log指令:
可以告诉我们文件提交的历史记录,显示从最近到最远的提交日志
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ git log
commit 3628164fb26d48395383f8f31179f24e0882e1e0
Author: Michael Liao <askxuefeng@gmail.com>
Date: Tue Aug 20 15:11:49 2013 +0800

append GPL

commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
Author: Michael Liao <askxuefeng@gmail.com>
Date: Tue Aug 20 14:53:12 2013 +0800

add distributed

commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <askxuefeng@gmail.com>
Date: Mon Aug 19 17:51:55 2013 +0800

wrote a readme file

我们可以看到3次提交,最近的一次是append GPL,上一次是add distributed,最早的一次是wrote a readme file

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

1
2
3
4
$ git log --pretty=oneline
3628164fb26d48395383f8f31179f24e0882e1e0 append GPL
ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed
cb926e7ea50ad11b8f9e909c05226233bf755030 wrote a readme file

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

如果我们准备把文件回退到上一个版本,也就是“add distributed”的那个版本,怎么做呢?

首先,Git必须知道当前版本是哪个版本:
在Git中,用HEAD表示当前版本,也就是最新的提交3628164…882e1e0
上一个版本就是HEAD^,
上上一个版本就是HEAD^^,
当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。

现在,我们要把当前版本“append GPL”回退到上一个版本“add distributed”,就可以使用git reset命令:

1
2
$ git reset --hard HEAD^
HEAD is now at ea34578 add distribute

则回退成功。

如果想再返回到原来的最新版本,即版本号为3628164…882e1e0的那个文件,应该怎么办呢?
办法其实还是有的,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个append GPL
commit id是3628164…,于是就可以指定回到未来的某个版本:

1
2
$ git reset --hard 3628164
HEAD is now at 3628164 append GPL

但如果上面的命令窗口关闭了怎么办?即版本号找不到了:
那么则需要运用git reflog指令:

1
2
3
4
5
$ git reflog
ea34578 HEAD@{0}: reset: moving to HEAD^
3628164 HEAD@{1}: commit: append GPL
ea34578 HEAD@{2}: commit: add distributed
cb926e7 HEAD@{3}: commit (initial): wrote a readme file

很明显的看到了append GPL的版本号
注:
版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针
当你回退版本的时候,Git仅仅是把HEAD从指向append GPL:

改为指向dd distributed

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

工作区和暂存区

工作区(Working Directory):就是你在电脑里能看到的目录
版本库(Repository):工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库
Git的版本库里存了很多东西其中:
最重要的就是称为stage(或者叫index)的暂存区,
还有Git为我们自动创建的第一个分支master,
以及指向master的一个指针叫HEAD。

前面把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,
所以,现在,git commit就是往master分支上提交更改。
可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。

流程如下:


撤销修改

运用git checkout -- file指令:
可以丢弃工作区的修改(比如文件中某段多加了一行不需要的东西,该指令可以帮助返回上一个状态)
例如:

1
$ git checkout -- readme.txt

命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

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

如果在使用了git add指令后还想回退:
可以运用git reset HEAD file指令:
把暂存区的修改撤销掉(unstage),重新放回工作区:
例如:

1
2
3
$ git reset HEAD readme.txt
Unstaged changes after reset:
M readme.txt

git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。
注:
如果你使用了git commit指令后还想回退,那么就可以运行版本回退指令了

删除文件

如果你在你的电脑上把文件删除了,那么git就会知道你删除了哪些文件,因此,工作区和版本库就不一致了
使用git status命令会立刻告诉你哪些文件被删除了

现在你有两个选择:
一是确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit

1
2
3
4
5
6
$ git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt"
[master d17efd8] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt

此时版本库里的文件就被删除了。

另一种情况是删错了,因为版本库里还有,所以可以很轻松地把误删的文件恢复到最新版本:

1
$ git checkout -- test.txt

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

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

远程仓库(尚未学习)

LOADING……

CATALOG
  1. 1. 前言
  2. 2. 准备工作
    1. 2.1. 安装.git
    2. 2.2. 创建版本库
  3. 3. 常用指令与操作
    1. 3.1. 把文件添加到版本库
    2. 3.2. 查看文件状态与改变
    3. 3.3. 版本回退
    4. 3.4. 工作区和暂存区
    5. 3.5. 撤销修改
    6. 3.6. 删除文件
  4. 4. 远程仓库(尚未学习)
    1. 4.1. LOADING……