人生不易,我有必杀技技术硬通货Mark

Git使用教程

2015-04-08  本文已影响687人  东皇Amrzs

声明:本文不是讲原理的文章.
我能保证你看完会用Git,但不能保证你能知道Git用法的原理.
换句话说就是——我保证教会你怎么开拖拉机,但我不教你怎么造拖拉机
(我只是想用个版本控制工具而已,并没想过要搞懂它,Git最大的特点就是对分支的处理)

一. 在Linux上安装Git(windows下去官网下载Git安装)

首先,你可以试着输⼊git,看看系统有没有安装Git:

$ git
The program 'git' is currently not installed. You can install it
by typing:
$ sudo apt-get install git

如果你碰巧⽤Debian或Ubuntu Linux,通过一条“sudo apt-get install git”就可以直接完成Git的安装,非常简单
如果是其他Linux版本,先从Git官网下载源码,然后解压,依次输入:./config,make,sudo make install这几个命令安装就好了。
安装完成后,还需要最后⼀步设置,在命令⾏输⼊:

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

因为Git是分布式版本控制系统,所以,每个机器都必须⾃报家⻔:你的名字和Email地址。
不必担⼼会有人冒充,真的有冒充的也是有办法可查的。
注意:git config命令的--global参数,⽤了这个参数,表⽰你这台机器上所有的Git仓库都会使⽤这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。

二. 创建版本库

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

$ mkdir learngit
$ cd learngit
$ pwd
/Users/michael/learngit

注意:如果你使用Windows系统,为了避免遇到各种莫名其妙的问题,请确保目录名(包括⽗目录)不包含中文

$ git init
Initialized empty Git repository in /Users/michael/learngit/.git/

瞬间Git就把仓库建好了,⽽且告诉你是⼀个空的仓库(empty Git repository),可以发现当前目录下多了一个.git的⽬录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录⾥面的文件,不然改乱了,就把Git仓库给破坏了。
也不⼀定必须在空⽬录下创建Git仓库,选择一个已经有东西的目录也是可以的。(不过,不建议你使用⾃己正在开发的公司项目来学习Git)

三. 把文件添加到版本库

首先这⾥再明确⼀下,所有的版本控制系统,其实只能跟踪文本文件的改动,⽐如TXT⽂件,网页,所有的程序代码等等,Git也不例外。⽽图⽚、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制⽂件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道(例如Microsoft的Word即是二进制格式,所以没办法跟踪)所以如果要真正使用版本控制系统,就必须要以纯⽂本方式编写⽂件

使用Windows的童鞋要特别注意
千万不要使⽤Windows⾃带的记事本编辑任何⽂本文件。原因是Microsoft记事本保存UTF-8编码的⽂件的时候自作聪明地在每个文件开头添加了0xefbbbf(⼗六进制)的字符,你会遇到很多不可思议的问题,⽐如,网⻚页第⼀⾏可能会显⽰示⼀个“?”,明明正确的程序⼀编译就报语法错误,等等,都是由记事本的弱智⾏为带来的(作者在这里推荐了notepad++,修改默认编码格式为UTF-8 without BOM即可)

现在我们编写⼀个readme.txt文件,内容如下:

Git is a version control system.
Git is free software.
//一定要放到learngit⽬录下(⼦目录也⾏行),因为这是⼀个Git仓库,放到其他地⽅Git再厉害也找不到这个⽂件。

把⼀个⽂件放到Git仓库只需要两步(为了可以一次提交多个文件)

  1. 用命令git add告诉Git,把文件添加到仓库:

$ git add readme.txt//(注意,可反复多次使用添加多个⽂件)
//无任何显示

  1. 用命令git commit告诉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后⾯输入的是本次提交的说明(一定要写),可以输⼊任意内容,当然最好是有意义的,这样你就能从历史记录⾥方便地找到改动记录。

总结一下:一、二部分

  1. 初始化一个Git仓库,使⽤git init命令。
  2. 添加⽂件到Git仓库(两步)(注意:这里实际上是可以简化为一个步骤的:git commit -a -m "注释"将当下所有文件添加到缓存区并且提交)

三.时光机穿梭(返回版本)

1.掌握工作区的状态(git status/diff)

我们继续修改readme.txt文件,改成如下内容:

Git is a distributed version control system.
Git is free software.

$ 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
#
no changes added to commit (use "git add" and/or "git commit -a")

git status命令可以让我们时刻掌握仓库当前的状态,上⾯的命令告诉我们,readme.txt被修改过了,但还没有准备提交修改。

如果能看看具体修改了什么内容,⾃然是很好的:

$ git diff readme.txt
diff --git a/readme.txt b/readme.txt
index 46d49bf..9247db6 100644
--- a/readme.txt
+++ b/readme.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”单词。
知道了对readme.txt作了什么修改后,再把它提交到仓库就放⼼多了,提交修改和提交新文件是⼀样的两步.

$ git add readme.txt

同样没有任何输出。再执⾏第⼆步git commit之前,我们再运⾏git status看看当前仓库的状态:

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

git status告诉我们,将要被提交的修改包括readme.txt,下一步,就可以放⼼地提交了:

$ git commit -m "add distributed"
[master ea34578] add distributed
1 file changed, 1 insertion(+), 1 deletion(-)

提交后,我们再⽤用git status命令看看仓库的当前状态:

$ git status
# On branch master
nothing to commit (working directory clean)

Git告诉我们当前没有需要提交的修改,⽽且,工作目录是干净(working directory clean)的。
小结

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

2.版本回退

再练习⼀次修改和提交,修改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恢复,然后继续⼯作,⽽不是把几个月的工作成果全部丢失。
现在回顾⼀下readme.txt文件⼀共有几个版本被提交到Git仓库里了:

当然了,实际⼯作中,我们脑⼦里怎么不可能记得⼀个几千行的⽂件每次都改了什么内容,不然要版本控制系统干什么。版本控制系统肯定有某个命令可以告诉我们历史记录,在Git中,我们⽤git log命令查看:

$ 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

git log命令显⽰示从最近到最远的提交日志,我们可以看到3次提交,最近的一次是“append GPL”,上⼀次是“add distributed”,最早的一次是“wrote a readmefile”。 如果嫌输出信息太多,看得眼花缭乱的,可以试试加上
--pretty=oneline参数

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

友情提⽰:这一大串类似“ 3628164...882e1e0”的是commit id(版本号,每台终端都不一样)以你⾃己的为准。为每提交一个新版本,实际上Git就会把它们自动串成一条时间线。如果使⽤用可视化⼯工具查看Git历史,就可以更清楚地看到提交历史的时间线:

此处的图片以后再补充此处的图片以后再补充
好了,现在我们启动时光穿梭机,准备把readme.txt回退到上⼀一个版本,也就是“add distributed”的那个版本,怎么做呢?
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交“ 3628164...882e1e0”(注意我的提交ID和你的肯定不⼀一样),上一个版本就是HEAD,上上一个版本就是HEAD,当然往上100个版本写100个比较容易数不过来,所以写成HEAD~100。

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

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

--hard参数有啥意义这个后面再讲,现在你先放心使⽤
看看readme.txt的内容是不是版本“add distributed”:

$ cat readme.txt
Git is a distributed version control system.
Git is free software.

果然。
还可以继续回退到上一个版本“wrote a readme file”,不过且慢,然我们⽤git log再看看现在版本库的状态:

$ git log
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

最新的那个版本“append GPL”已经看不到了!好⽐你从21世纪坐时光穿梭机来到了19世纪,想再回去已经回不去了,肿么办?
办法其实还是有的,只要上⾯面的命令⾏行窗⼝口还没有被关掉,你就可以顺着往上找啊找啊,找到那个“append GPL”的commit id是“3628164...”,于是就可以指定回到未来的某个版本:

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

版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。
再⼩心翼翼地看看readme.txt的内容:

$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.

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


图片明天再补充图片明天再补充

现在,你回退到了某个版本,关掉了电脑,第⼆二天早上就后悔了,想恢复到新版本怎么办?找不到新版本的commit id怎么办?

在Git中,总是有后悔药可以吃的。当你⽤$ git reset --hard HEAD^回退到“add distributed”版本时,再想恢复到“append GPL”,就必须找到“append GPL”的commit id。Git提供了⼀一个命令git reflog⽤用来记录你的每一次命令:

$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”的commit id是3628164,现在,你又可以乘坐时光机回到未来了。
小结:
1.HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id
2. 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本
3. 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本

这些内容也均来自现在自学的廖雪峰笔记,贴出来可以让自己知道,我不是一个人在努力着,我,有大家的陪伴!
4/8/2015

上一篇 下一篇

猜你喜欢

热点阅读