git现在已经是一个程序员必须掌握的一个技能呢,最近在跟着公司项目走,公司的项目管理就是使用git,为了不在工作中因为git操作不熟练影响工作效率,以及出于一个合格的程序员对新技术的热情,所以就抽空对git进行了学习。学习的主要途径也是来源廖雪峰老师的博客,这里也给和廖雪峰老师一样具有开源精神的大师们点赞,下面就大体梳理一下学习到的知识体系。
git的基本概念
版本库
版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
我个人的理解就是git通过技术,使得一个本地目录可以对文件进行追踪管理。git将一个本地文件目录变成仓库也很简单,通过一个简单的命令
git init
只需要一行命令你的本地目录就变成一个可以追踪文件修改、删除的版本库了,重要的标志就是你输入命令的目录下多了一个隐藏文件夹.****git,千万不要随意去修改这个文件下的内容,不然可能会造成git版本库出现问题。
工作区与暂存区
工作区可以理解为本地的工作区域(就是本地的文件夹),暂存区可以理解为你推送内容到分支前的临时缓存地带(git通过分支记录你的每次修改),分支与暂存区等这些重要内容统统记录在.****git文件夹内部。大体工作方式如图1所示,git默认自动会给生成一个master分支,分支可以自己创建、切换、删除。
git最常用的重要操作
我们使用git最常用的操作就是推送文件,git推送文件到分支需要两步,第一步为:
git add 推送的文件名(可以一次性指定多个)
该命令就是叫指定的文件推送到上边说的暂存区
git add .
使用上边指令就是推送文件夹下的所有内容
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支,因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
git commit -m '本次修改的说明信息'
使用git commit命令是将暂存区的修改提交到分支上,如果不使用git add命令是不能够提交修改的。
git常用查看版本库信息的命令
当我们使用git工作的时候我们肯定会经常需要掌握版本库当前的状况,方便我们后续工作。
git status
git status命令可以让我们时刻掌握仓库当前的状态。
假设现在我们修改了readme.txt文件内容:
Gitisa distributed version control system.Gitisfree software.
上面的命令输出如下信息
On branch master
Changes not staged for commit:
(use "git add ..." toupdatewhat will be committed)
(use"git checkout -- ..."todiscard changesinworking directory)
modified: readme.txtnochanges addedtocommit
(use"git add"and/or"git commit -a")
上面信息告诉我们,readme.txt被修改过了,但还没有提交修改,连提交和撤销修改的方法都教给我们了,是不是非常贴心。
虽然Git告诉我们readme.txt被修改了,但如果能看看具体修改了什么内容,自然是很好的。比如你休假两周从国外回来,第一天上班时,已经记不清上次怎么修改的readme.txt,所以,需要用git diff这个命令看看:
$ 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 命令会比较你的工作区与当前分支上的内容列出之间的区别
知道了对readme.txt作了什么修改后,再把它提交到仓库就放心多了,提交修改和提交新文件是一样的两步,第一步是git add:
$ git add readme.txt
在执行第二步git commit之前,我们再运行git status看看当前仓库的状态:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified: readme.txt
git status这个时候的报告信息就不一样了,告诉我们现在可以提交修改以及修改的内容,最贴心的还告诉我们回置暂存空间的命令(git reset)
版本回退
日志查看
当我们提交内容到分支的次数多了以后我们可能需要追踪我们的提交历史方便我们分析我们的版本变更历史。
日志查看命令为git log。
git log
下边为使用日志查看命令后输出的信息
$ git log
commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master)
Author: Michael Liao
Date: Fri May 18 21:06:15 2018 +0800
append GPL
commit e475afc93c209a690c39c13a46716e8fa000c366
Author: Michael Liao
Date: Fri May 18 21:03:36 2018 +0800
add distributed
commit eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0
Author: Michael Liao
Date: Fri May 18 20:59:18 2018 +0800
wrote a readme file
git log命令显示从最近到最远的提交日志,我们可以看到3次提交,最近的一次是append GPL,上一次是add distributed,最早的一次是wrote a readme file。
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline参数:
$ git log --pretty=oneline
1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master) append GPL
e475afc93c209a690c39c13a46716e8fa000c366 add distributed
eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0 wrote a readme file
上边一大串类似1094adb...的是commit id(版本号),和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样,以你自己的为准。为什么commit id需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。
如果我们希望把readme.txt回退到上一个版本,也就是add distributed的那个版本,怎么做呢?
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交1094adb...(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD,上上一个版本就是HEAD,当然往上100个版本写100个比较容易数不过来,所以写成HEAD~100。
回退版本
现在,我们要把当前版本append GPL回退到上一个版本add distributed,就可以使用git reset命令:
$ git reset --hard HEAD^
HEAD is now at e475afc add distributed
提示信息也已经告诉我们现在我们就回到了上一个版本了,这里要说一下的是:当我们使用版本回退功能回到之前的版本,那那个版本之后的版本信息我们就会丢失,现在我们使用git log命令看当前版本信息:
$ git log
commit e475afc93c209a690c39c13a46716e8fa000c366 (HEAD -> master)
Author: Michael Liao
Date: Fri May 18 21:03:36 2018 +0800
add distributed
commit eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0
Author: Michael Liao
Date: Fri May 18 20:59:18 2018 +0800
wrote a readme file
修改回退版本
最新的那个版本append GPL已经看不到了!好比你从21世纪坐时光穿梭机来到了19世纪,想再回去已经回不去了,肿么办?
办法其实还是有的,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个append GPL的commit id是1094adb...,于是就可以指定回到未来的某个版本:
$ git reset --hard 1094a
HEAD is now at 83b0afe append GPL
版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。
现在,你回退到了某个版本,关掉了电脑,第二天早上就后悔了,想恢复到新版本怎么办?找不到新版本的commit id怎么办?
在Git中,总是有后悔药可以吃的。当你用$ git reset --hard HEAD^回退到add distributed版本时,再想恢复到append GPL,就必须找到append GPL的commit id。Git提供了一个命令git reflog用来记录你的每一次命令:
$ git reflog
e475afc HEAD@{1}: reset: moving to HEAD^
1094adb (HEAD -> master) HEAD@{2}: commit: append GPL
e475afc HEAD@{3}: commit: add distributed
eaadf4e HEAD@{4}: commit (initial): wrote a readme file
从输出可知,append GPL的commit id是1094adb,现在,你又可以愉快的玩耍了。
撤销修改
很多时候我们修改了某些文件我们后悔了,我们希望撤销掉修改,这种时候分两种情况。
没有放到暂存区
这种情况非常简单,使用如下命令
git checkout -- 文件名
git checkout 后边的--很重要,因为git checkout还有切换分支的作用,如果没有-- checkout无法完成撤销修改的功能。
已经放到暂存区
这个时候麻烦一点需要多一个步骤,用来情况暂存区
git reset HEAD 文件名
git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示当前最新的版本。
这个时候暂存区就是干净的了,接着使用git checkout清理掉工作区文件的修改即可。
ok这个时候一切都可以重新开始了!!!
继续加油工作吧。
删除文件
git中将删除文件视为对工作区的一种修改,删除文件的命令为:
$ rm 文件名
这个时候,Git知道你删除了文件,因此,工作区和版本库就不一致了,git status命令会立刻告诉你哪些文件被删除了:
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
deleted: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
这个时候如果你确实要删除文件只要commit提交修改到分支就可以了。
$ git commit -m "remove test.txt"
[master d46f35e] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
如果后悔了不想删除文件了就用到刚刚说过的命令取消工作区的修改就好了,如下:
$ git checkout -- test.txt
参考链接
https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000