在上一篇章中,我们介绍了版本控制工具的变更,以及相应的优点、缺点,相信看到这里,你已经知道了Git这款分布式版本控制系统的魅力,想进一步学习、利用这款最好的版本控制系统,那么在这一章,我们一起来学习git。
在这一章,你会掌握git的基本命令,初步入门git。
我假设你在电脑上已经将Git安装好了,就算没有,我相信你会搞定它的,如果遇到什么困难,可以去附录查看,我会详细的告诉你安装方式。
好的,接下来正式开始学习。
使用如下操作查看你的电脑上安装的Git版本:
$ git –version
git version 1.9.1
可以看到在这台电脑上已经成功安装了git,并且版本是1.9.1。
在正式使用Git前,需要设置一下Git的配置变量,配置会永久保存在Git的全局文件(/homr/.gitconfig)或者系统文件(/etc/gitconfig)中。
- 配置Git当前的用户名和邮件地址,这将在你提交版本库时用到。
$ git config –global user.name “li xinxing”
$ git config –global user.email lixinxing@tujing.site
- 配置一些Git别名,提高Git使用效率。
# sudo git config –system alias.st status
# sudo git config –system alias.ci commit
# sudo git config –system alias.co checkout
# sudo git config –system alias.br branch
- 在Git命令输出中开启颜色显示
$ git config –global color.ui true
Git的所有操作,都是又Git 一个命令完成的,下面演示如何创建Git版本库。
$ mkdir test
$ cd test
$ git init
初始化空的 Git 版本库于 /home/lixinxing/test/.git/
除在目录下使用 git init命令创建版本库外,还可以在 git init 命令后面直接输入目录名称,自动完成目录的初始化。
$ git init /home/lixinxing/test2
初始化空的 Git 版本库于 /home/lixinxing/test2/.git/
查看git目录下所有文件:
$ ls -aF
./ ../ .git/
可以看到在git库下多了一个隐藏目录 .git ,这个隐藏的.git目录就是Git版本库(又叫仓库,repository)。
.git 版本库所在目录为 /home/lixinxing/test,它被称为工作区。
下面提交代码到版本库
在工作区中新建文件welcome.txt,内容就是一行“hello world!”。
$ echo “Hello World!” > welcome.txt
将welcome.txt添加到版本库:
$ git add welcome.txt
这里添加文件只是将添加到版本库的暂存区,要将其添加到版本库中,还需在执行一次提交命令:git commit。
需要注意的是,执行提交命令时需要加参数 –m 给出提交说明,不然git会自动打开编辑器,要求输入提交说明。
~/test$ git commit -m “initialized”
[master (根提交) b11d1c2] initialized
1 file changed, 1 insertion(+)
create mode 100644 welcome.txt
在提交成功后,我们可以通过git status命令显示工作区文件状态
$ git status
位于分支 master
无文件要提交,干净的工作区
这样就提示在工作区的文件已经全部提交成功。
提交后,可以通过git log命令查看提交日志(附加的 –stat参数可以看到每次提交的文件变更统计)。
$ git log
commit b11d1c220a8e2bc21fc5a8bccd08650411e0bfc1
Author: li xinxing <lixinxing@tujing.site>
Date: Mon Feb 16 11:33:03 2015 +0800
initialized
$ git log –stat
commit b11d1c220a8e2bc21fc5a8bccd08650411e0bfc1
Author: li xinxing <lixinxing@tujing.site>
Date: Mon Feb 16 11:33:03 2015 +0800
initialized
welcome.txt | 1 +
1 file changed, 1 insertion(+)
我们可以看到welcome.txt文件已经提交到版本库中,如果我们修改welcome.txt文件,那么,怎样才能看到修改后的文件与版本库中的不同呐,我们可以通过非常强大的git diff命令来查看不同。
首先修改welcome.txt文件,在其后面追加一行。
$ echo “Nice to meet you.” >> welcome.txt
现在将修改后的文件添加到暂存区。
$ git add welcome.txt
接着继续修改welcome.txt文件,在其后面追加一行。
$ echo “Bye-Bye.” >> welcome.txt
现在,Git工作区、暂存区、版本库中的welcome.txt文件都不一样了,我们可以通过git diff查看差异。
- 不带任何参数的git diff命令显示工作区中的改动,即工作区中文件与提交任务(提交暂存区,stage)相比的差异。
$ git diff
diff –git a/welcome.txt b/welcome.txt
index 82d2e42..dbad484 100644
— a/welcome.txt
+++ b/welcome.txt
@@ -1,2 +1,3 @@
Hello World!
Nice to meet you.
+Bye-Bye.
- 将工作区与HEAD(当前分支)相比,会有更多的差异。
$ git diff HEAD
diff –git a/welcome.txt b/welcome.txt
index 980a0d5..dbad484 100644
— a/welcome.txt
+++ b/welcome.txt
@@ -1 +1,3 @@
Hello World!
+Nice to meet you.
+Bye-Bye.
- 通过参数 –cached或—staged调用git diff 命令,显示提交暂存区(staged)与版本库中文件的差异。
$ git diff –staged
diff –git a/welcome.txt b/welcome.txt
index 980a0d5..82d2e42 100644
— a/welcome.txt
+++ b/welcome.txt
@@ -1 +1,2 @@
Hello World!
+Nice to meet you.
当有新的提交发生时,文件.git/refs/heads/master内容就会发生改变,指向新的提交。
Git提供了git reset 命令,可以将“游标”.git/refs/heads/master指向任意一个存在的提交ID。下面示例人为的更改游标。
我们首先在工作区创建一个新文件,姑且为new-commit.txt,然后提交到版本库中。
$ touch new-commit.txt
$ git add new-commit.txt
$ git ci -m “add new-commit.txt”
[master 1924a0c] add new-commit.txt
2 files changed, 1 insertion(+)
create mode 100644 new-commit.txt
此时,工作区下有两个文件:
$ ls
new-commit.txt welcome.txt
这时查看版本库引用空间下的master文件内容
$ cat .git/refs/heads/master
1924a0c69cc38e3ee2b45cfd41bdbdce3870f08f
可以看到,master文件指向了新的提交1924a0c。
使用git log 查看提交日志,可以看到刚刚完成的提交:
$ git log –graph –oneline
* 1924a0c add new-commit.txt
* b11d1c2 initialized
我们使用git reset 命令更改提交
$ git reset –hard HEAD^
HEAD 现在位于 b11d1c2 initialized
提示:
在命令中使用了– -hard 参数,这会破坏工作区中未提交的改动,使用前要慎重!
命令中使用的HEAD^代表版本库中的上一次提交。
符号^可以用于指代父提交。例如:
- HEAD^代表版本库中最近一次提交的父提交。
- HEAD^^代表HEAD^的父提交。
对于一个提交的多个父提交,可以在符号^后面用数字表示是第几个父提交。例如:
- 1924a0c^2表示提交1924a0c的多个父提交中的第二个父提交。
- HEAD^1相当于HEAD^.
- HEAD^^2表示HEAD^(HEAD父提交)的多个父提交中的第二个父提交。
在$ git reset –hard HEAD^命令后我们查看工作区文件:
$ ls
welcome.txt
可以看到new-commit.txt文件丢失了,查看引用文件内容:
$ cat .git/refs/heads/master
b11d1c220a8e2bc21fc5a8bccd08650411e0bfc1
可以看到master分支的引用文件的指向更改为前一次提交的ID了。
我们可以通过git reflog 命令操作分支master应用文件,使用show 子命令显示此文件的内容。
$ git reflog show master |head -5
b11d1c2 master@{0}: reset: moving to HEAD^
1924a0c master@{1}: commit: add new-commit.txt
b11d1c2 master@{2}: commit (initial): initialized
git reflog 的输出将最新的更改放在了最前面显示,而且只显示每次更改的最终哈希值。最重要是git reflog 命令的输出中还提供了一个方便易表达的表达式:<refname>@{n},这个表达式的含义是引用<refname>之前第{n}此改变时的SHA1哈希值。
我们要想取消改变,重新找回new-commit.txt文件,可以使用命令
$ git reset –hard master@{1}
HEAD 现在位于 1924a0c add new-commit.txt
可以看到new-commit.txt也回来了,提交历史也回来了。
$ ls
new-commit.txt welcome.txt
$ git log –oneline
1924a0c add new-commit.txt
b11d1c2 initialized
我们来看看git reset 的几种常用命令。
- 命令 : git reset
仅用HEAD指向的目录树重置暂存区,工作区不会受到影响。即将之前用git add 命令添加到暂存区的内容撤出暂存区,引用也没有改变。
- 命令 : git reset HEAD
同上。
- 命令 : git reset – – filename
仅将文件filename撤出暂存区,其他文件未收到影响。
- 命令 : git reset HEAD — filename
同上
- 命令 : git reset – – soft HEAD^
工作区和暂存区不更改,但是引用向前回退一次。对最新提交的提交说明或提交的更改不满意时,撤销最新的提交以便重新提交。
- 命令 : git reset HEAD^
工作区不改变,但是暂存区会会退到上一次之前,引用也会回退一次。
- 命令 : git reset – – hard HEAD^
彻底撤销最近的提交,引用会回退到前一次,而且工作区和暂存区的内容都会回退到上一次提交时的状态。自上次提交以来的更改全部丢失。