Git版本控制器使用总结性梳理

 

Git为什么物?
Git 是什么?你们确定会说不就是版本控制器嘛,是的Git是目前世界上最早进的分布式版本控制系统(没有之一)。
1)那什么是版本控制器?
举个简单的例子,好比咱们用Word写文章,那你必定有这样的经历:好比增长一个段落你得复制一份,你删除一个段落你又得复制一份,防止下次又要修改保留上次你要删除的段落。最后一个接一个的版本,你复制了不少版本,最后可能你本身都不知道修改了哪些?嘿嘿,而后你只能一个一个的找,太麻烦了,如果有东西帮你管理那应该多好。
2)分布式管理
你写的文章或书,你确定会给你朋友或者其余人看,让他们给你建议并作相应的修改,而后他们用邮件或U盘再发给你,你再合并修改一下,真是麻烦,因而你想,若是有一个软件,不但能自动帮我记录每次文件的改动,还可让朋友之间协做编辑,这样就不用本身管理一堆相似的文件了,也不须要把文件传来传去。若是想查看某次改动,只须要在软件看一眼就能够,岂不是很方便?这个软件用起来就应该像这个样子,能记录每次文件的改动:node

版本 用户 说明 修改日期
1 user1 增长一行内容 2014/4/10 10:22
2 user2 修改一行内容 2014/4/10 13:12
3 user3 删除几个字 2014/4/15 20:42
4 user2 增长某个内容 2014/4/20 16:32

Git 的诞生
简单说:Linus开发Linux内核,须要版本控制器,因而开发了Git。下面是开发周期:
1)2005/4/3 开发;
2)2005/4/6 发布;
3)2005/4/7 管理自身;
4)2005/6/16 管理Kernel2.6.12。
大牛是怎么定义的呢?你们能够体会一下。哈哈^_^…… Git 迅速成为最流行的分布式版本控制系统,尤为是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。至于Git与GitHub的关系,会再下面的文章里说明。git

集中管理 VS 分布式管理
Linus一直痛恨的CVS及SVN都是集中式的版本控制系统,而Git是分布式版本控制系统,集中式和分布式版本控制系统有什么区别呢? 下面咱们来看看两张图:
1)集中管理程序员

集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是本身的电脑,因此要先从中央服务器取得最新的版本,而后开始干活,干完活了,再把本身的活推送给中央服务器。中央服务器就比如是一个图书馆,你要改一本书,必须先从图书馆借出来,而后回到家本身改,改完了,再放回图书馆。github

缺点:
集中式版本控制系统最大的毛病就是必须联网才能工做,若是在局域网内还好,带宽够大,速度够快,可若是在互联网上,遇到网速慢的话,可能提交一个10M~20M的文件就须要10分钟甚至更多时间,这还不得把人给急死啊。后端

2)分布式管理centos

那分布式版本控制系统与集中式版本控制系统有何不一样呢?首先,分布式版本控制系统没有“中央服务器”,每一个人的电脑上都是一个完整的版本库,这样,你工做的时候,就不须要联网了,由于版本库就在你本身的电脑上。既然每一个人电脑上都有一个完整的版本库,那多我的如何协做呢?比方说你在本身电脑上改了文件fiel,你的同事也在他的电脑上改了文件file,这时,大家俩之间只需把各自的修改推送给对方,就能够互相看到对方的修改了。数组

和集中式版本控制系统相比,分布式版本控制系统的安全性要高不少,由于每一个人电脑里都有完整的版本库,某一我的的电脑坏掉了没关系,随便从其余人那里复制一个就能够了。而集中式版本控制系统的中央服务器要是出了问题,全部人都无法干活了。
在实际使用分布式版本控制系统的时候,其实不多在两人之间的电脑上推送版本库的修改,由于可能大家俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。所以,分布式版本控制系统一般也有一台充当“中央服务器”的电脑,但这个服务器的做用仅仅是用来方便“交换”你们的修改,没有它你们也同样干活,只是交换修改不方便而已。如上图!缓存

Git特色安全

1)分布式
2)存储快照而非差别
3)本地有彻底的版本库,几乎全部操做都在本地
4)有内在的一致性,SHA1
5)优秀的分支管理
6)支持各类协同模式
7)开源,有一些第三方软件可整合使用,几乎全部操做都是

与CVS/SVN,Git 的优点
1)支持离线开发,离线Repository(仓库)
2)强大的分支功能,适合多个独立开发者协做
3)速度块

为何选择Git来控制版本,理由以下:bash

1)快速 
若是你每移动一下鼠标都要等待五秒,是否是很受不了?版本控制也是同样的,每个命令多那么几秒钟,一天下来也会浪费你很多时间。Git的操做很是快速,你能够把时间用在别的更有意义的地方。 
2)离线工做 
在没有网络的状况下如何工做?若是你用SVN或者CVS的话就很麻烦。而Git可让你在本地作全部操做,提交代码,查看历史,合并,建立分支等等。 
3)回退 
人不免犯错。我很喜欢Git的一点就是你能够“undo”几乎全部的命令。你能够用这个功能来修正你刚刚提交的代码中的一个问题或者回滚整个代码提交操做。你甚至能够恢复一个被删除的提交,由于在后端,Git几乎不作任何删除操做。
4)省心 
你有没有丢失过版本库?我有,而那种头疼的感受如今还记忆犹新。而用Git的话,我就没必要担忧这个问题,由于任何一我的机器上的版本都是一个完整的备份。 
5)选择有用的代码提交 
当你把纽带,冰块还有西红柿一块儿扔进搅拌机的时候至少有两个问题。第一,搅拌事后,没有人知道以前扔进去了些什么东西。第二,你不能回退,从新把西红柿拿出来。一样的,当你提交了一堆无关的更改,例如功能A增强,新增功能B,功能C修复,想要理清这一堆代码到底干了什么是很困难的。固然,当发现功能A出问题的时候,你没法单独回滚功能A。Git能够经过建立“颗粒提交”,帮你解决这个问题。“staging area”的概念可让你决定到底那些东西须要提交,或者更新,精确到行。
6)自由选择工做方式 
使用Git,你能够同时和多个远程代码库链接,“rebase”而不是"merge"甚至只链接某个模块。可是你也能够选择一个中央版本库,就像SVN那样。你依然能够利用Git的其余优势。 
7)保持工做独立 
把不一样的问题分开处理将有助于跟踪问题的进度。当你在为功能A工做的时候,其余人不该该被你尚未完成的代码所影响。分支是解决这个问题的办法。虽然其余的版本控制软件业有分支系统,可是Git是第一个把这个系统变得简单而快速的系统。
8)随大流 
虽然只有死于才随着波浪前进,可是不少时候聪明的程序员也是随大流的。愈来愈多的公司,开源项目使用Git,包括Ruby On Rails,jQuery,Perl,Debian,Linux Kernel等等。拥有一个强大的社区是很大的优点,有不少教程、工具。

Git原理

1)四种基本类型
BLOB:  每一个blob表明一个(版本的)文件,blob只包含文件的数据,而忽略文件的其余元数据,如名字、路径、格式等。
TREE:  每一个tree表明了一个目录的信息,包含了此目录下的blobs,子目录(对应于子trees),文件名、路径等元数据。所以,对于有子目录的目录,git至关于存储了嵌套的trees。
COMMIT:每一个commit记录了提交一个更新的全部元数据,如指向的tree,父commit,做者、提交者、提交日期、提交日志等。每次提交都指向一个tree对象,记录了当次提交时的目录信息。一个commit能够有多个(至少一个)父commits。
TAG:   ag用于给某个上述类型的对象指配一个便于开发者记忆的名字, 一般用于某次commit。

2)工做区(Working Dir),提交区/暂存区(stage/index),版本库 

 

Git的安装

不一样的系统不一样的安装命令,centos系统下直接yum就能够。
[root@master-node ~]# yum install -y git
安装完成后,还须要最后一步设置,在命令行输入:
[root@master-node ~]#git config --global user.email "you@example.com"
[root@master-node ~]#git config --global user.name "Your Name"
由于Git是分布式版本控制系统,因此,每一个机器都必须自报家门:你的名字和Email地址。你也许会担忧,若是有人故意冒充别人怎么办?这个没必要担忧,首先咱们相信你们都是善良无知的群众,其次,真的有冒充的也是有办法可查的。
注意:
git config命令的--global参数,用了这个参数,表示你这台机器上全部的Git仓库都会使用这个配置,固然也能够对某个仓库指定不一样的用户名和Email地址。

Git经常使用的命令(即git + 下面的参数组成的命令):

add           添加文件内容至索引
bisect       经过二分查找定位引入 bug 的变动
branch     列出、建立或删除分支
checkout  检出一个分支或路径到工做区
clone       克隆一个版本库到一个新目录
commit    记录变动到版本库
diff          显示提交之间、提交和工做区之间等的差别
fetch       从另一个版本库下载对象和引用
grep        输出和模式匹配的行
init         建立一个空的 Git 版本库或从新初始化一个已存在的版本库
log         显示提交日志
merge    合并两个或更多开发历史
mv        移动或重命名一个文件、目录或符号连接
pull       获取并合并另外的版本库或一个本地分支
push     更新远程引用和相关的对象
rebase  本地提交转移至更新后的上游分支中
reset    重置当前HEAD到指定状态
rm       从工做区和索引中删除文件
show    显示各类类型的对象
status  显示工做区状态
tag      建立、列出、删除或校验一个GPG签名的 tag 对象

建立版本库

什么是版本库呢?版本库又名仓库,英文名repository,你能够简单理解成一个目录,这个目录里面的全部文件均可以被Git管理起来,每一个文件的修改、删除,Git都能跟踪,以便任什么时候刻均可以追踪历史,或者在未来某个时刻能够“还原”。
因此,建立一个版本库很是简单,首先,选择一个合适的地方,建立一个空目录:

第一步:建立一个仓库的目录
[root@master-node /]# mkdir git_test
[root@master-node /]# cd git_test/
[root@master-node git_test]# pwd
/git_test

第二步:经过git init 命令把这个目录变成git能够管理的仓库
[root@master-node git_test]# git init
初始化空的 Git 版本库于 /git_test/.git/
[root@master-node git_test]# ls -al
总用量 12
drwxr-xr-x 3 root root 4096 5月 10 13:53 .
drwxr-xr-x. 19 root root 4096 5月 10 13:50 ..
drwxr-xr-x 7 root root 4096 5月 10 13:53 .git
瞬间Git就把仓库建好了,并且告诉你是一个空的仓库(empty Git repository),细心的读者能够发现当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,否则改乱了,就把Git仓库给破坏了。也不必定必须在空目录下建立Git仓库,选择一个已经有东西的目录也是能够的。

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

如今咱们编写一个readme.txt文件,内容以下
[root@master-node git_test]# cat readme.txt
Git is veryt good tool
auth :cgt
必定要放到git_test目录下面,子目录也能够,放到其余地方git找不到文件。

把一个文件放到Git仓库只须要两步。
1)用命令git add告诉git,把文件添加到仓库
[root@master-node git_test]# git add readme.txt
执行上面的命令,没有任何的显示就对了。Linux的哲学思想:没有消息就是最好的消息,说明添加成功。
2)用命令git commit告诉git,把文件提交到仓库
[root@master-node git_test]# git commit -m "cgt write a readme file"
[master(根提交) 87818f5] cgt write 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不一样的文件,好比:
[root@master-node git_test]# touch file1 file2 file3
[root@master-node git_test]# ls
file1 file2 file3 readme.txt
[root@master-node git_test]# git add file1 file2 file3
[root@master-node git_test]# git commit -m "add 3 files"
[master 827526e] add 3 files
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 file1
create mode 100644 file2
create mode 100644 file3

再次插足一下,说明一下git的工做流:

你的本地仓库由 git 维护的三棵"树"组成。第一个是你的 工做目录,它持有实际文件;第二个是 暂存区(staging),它像个缓存区域,临时保存你的改动;最后是 HEAD,它指向你最后一次提交的结果。
你能够提出更改(把它们添加到暂存区),使用以下命令:
git add <filename>
git add *
这是 git 基本工做流程的第一步;使用以下命令以实际提交改动:
git commit -m "代码提交信息"
如今,你的改动已经提交到了 HEAD,可是还没到你的远端仓库。

回滚-让去哪就去哪

前面已经建立了一个readme.txt文件,如今咱们对他进行一些改动操做。
[root@master-node git_test]# cat readme.txt
Git is veryt good tool
auth :cgt
date:2016-5-10
执行git status 
[root@master-node git_test]# git status
# 位于分支 master
# 还没有暂存以备提交的变动:
# (使用 "git add <file>..." 更新要提交的内容)
# (使用 "git checkout -- <file>..." 丢弃工做区的改动)
#
# 修改: readme.txt
#
修改还没有加入提交(使用 "git add" 和/或 "git commit -a")
git status命令可让咱们时刻掌握仓库当前的状态,上面的命令告诉咱们,readme.txt被修改过了,但尚未准备提交的修改。
虽然Git告诉咱们readme.txt被修改了,但若是能看看具体修改了什么内容,天然是很好的。好比你次日上班时,已经记不清上次怎么修改的readme.txt,因此,须要用git diff这个命令看看,而后add以后在看一下status,是显示要commit的文件,如今再回想一下那个工做流图
[root@master-node git_test]# git diff
diff --git a/readme.txt b/readme.txt
index b7cffdb..43b7253 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,3 @@
Git is veryt good tool
auth :cgt
+date:2016-5-10
[root@master-node git_test]# git add readme.txt
[root@master-node git_test]# git status
# 位于分支 master
# 要提交的变动:
# (使用 "git reset HEAD <file>..." 撤出暂存区)
#
# 修改: readme.txt
接下来进行commit操做
[root@master-node git_test]# git commit -m "add date"
[master de00305] add date
1 file changed, 1 insertion(+)
提交以后,在查看status
[root@master-node git_test]# git status
# 位于分支 master
无文件要提交,干净的工做区

版本的回退

如今,你已经学会了修改文件,而后把修改提交到Git版本库,如今,再练习一次,修改readme.txt文件以下:
[root@master-node git_test]# cat readme.txt
Git is veryt good tool
auth :cgt
date:2016-5-10
version:1
[root@master-node git_test]# git add readme.txt
[root@master-node git_test]# git commit -m "version"
[master 8b7d4ee] version
1 file changed, 1 insertion(+)

目前咱们已经提交了三次,暂时你还能记住,可是在实际工做中咱们是记不住的,否则要版本控制系统干什么。版本控制系统确定有某个命令能够告诉咱们历史记录,在Git中,咱们用git log命令查看:
[root@master-node git_test]# git log
commit 8b7d4eebe4e03809162f8193d6b2338926896ab4
Author: caoxiaojian <1099415469@qq.com>
Date: Tue May 10 14:59:16 2016 +0800
version
commit de003058c91312f695b57f42724f826f6ef42f17
Author: caoxiaojian <1099415469@qq.com>
Date: Tue May 10 14:52:10 2016 +0800
add date
commit 827526ee243c93bfaf8f4f2f9dc22d31325cb47a
Author: caoxiaojian <1099415469@qq.com>
Date: Tue May 10 14:23:08 2016 +0800
add 3 files
commit 87818f5454a2bc41cfbeca4b923a510d11fe72ac
Author: caoxiaojian <1099415469@qq.com>
Date: Tue May 10 14:19:08 2016 +0800
cgt write a readme file
git log 显示从最近到最远的提交日志,咱们能够看到四次提交,最近的一次是version,上一次是date,最先的一次是cgt write a readme file 。

若是嫌输出的信息太多,可使用--pretty=oneline
[root@master-node git_test]# git log --pretty=oneline
8b7d4eebe4e03809162f8193d6b2338926896ab4 version
de003058c91312f695b57f42724f826f6ef42f17 add date
827526ee243c93bfaf8f4f2f9dc22d31325cb47a add 3 files
87818f5454a2bc41cfbeca4b923a510d11fe72ac cgt write a readme file

须要友情提示的是,你看到的一大串8b7d4eebe4e03809162f8193d6b2338926896ab4相似的是commit id(版本号),和SVN不同,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个很是大的数字,用十六进制表示,并且你看到的commit id和个人确定不同,以你本身的为准。为何commit id须要用这么一大串数字表示呢?由于Git是分布式的版本控制系统,后面咱们还要研究多人在同一个版本库里工做,若是你们都用1,2,3……做为版本号,那确定就冲突了。

如今开始回滚,
准备把readme.txt回退到上一个版本,也就是“date”的那个版本,怎么作呢?
首先,Git必须知道当前版本是哪一个版本,在Git中,用HEAD表示当前版本,也就是最新的提交3628164...882e1e0(注意个人提交ID和你的确定不同),上一个版本就是HEAD^,上上一个版本就是HEAD^^,固然往上100个版本写100个^比较容易数不过来,因此写成HEAD~100。
回滚,咱们可使用git reset这个命令

[root@master-node git_test]# git reset --hard HEAD^
HEAD 如今位于 de00305 add date
[root@master-node git_test]# cat readme.txt
Git is veryt good tool
auth :cgt
date:2016-5-10
能够看出,他没有version那行,说明回滚成功。

再来看git log 
[root@master-node git_test]# git log
commit de003058c91312f695b57f42724f826f6ef42f17
Author: caoxiaojian <1099415469@qq.com>
Date: Tue May 10 14:52:10 2016 +0800
add date
commit 827526ee243c93bfaf8f4f2f9dc22d31325cb47a
Author: caoxiaojian <1099415469@qq.com>
Date: Tue May 10 14:23:08 2016 +0800
add 3 files
commit 87818f5454a2bc41cfbeca4b923a510d11fe72ac
Author: caoxiaojian <1099415469@qq.com>
Date: Tue May 10 14:19:08 2016 +0800
cgt write a readme file
没有了以前的version,那我要怎么才能恢复呢,回你的终端上,看看version的commit id,咱们找到了:
8b7d4eebe4e03809162f8193d6b2338926896ab4 version,执行恢复。恢复的时候ID不须要写所有的。
[root@master-node git_test]# git reset --hard 8b7d4eebe4
HEAD 如今位于 8b7d4ee version
[root@master-node git_test]# cat readme.txt
Git is veryt good tool
auth :cgt
date:2016-5-10
version:1

回滚原理解析:
Git的版本回退速度很是快,由于Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从当前的version,指到date

回滚后

而后顺便把工做区的文件更新了。因此你让HEAD指向哪一个版本号,你就把当前版本定位在哪。
到了这里确定有童鞋要问,那我要是不知道我前面的ID了,我去哪里回滚,我是否是该收拾工位回滚到家中了,git早就替你想好了,可使用git reflog,把以前的ID都显示出来
[root@master-node git_test]# git reflog
8b7d4ee HEAD@{0}: reset: moving to 8b7d4eebe4
de00305 HEAD@{1}: reset: moving to HEAD^
8b7d4ee HEAD@{2}: commit: version
de00305 HEAD@{3}: commit: add date
827526e HEAD@{4}: commit: add 3 files
87818f5 HEAD@{5}: commit (initial): cgt write a readme file

工做区和暂存区
不知道你是否是理解了我以前说的那个工做流,我们这里再来啰嗦一遍。
Git和其余版本控制系统如svn不一样之处是有暂存区的概念

先弄清楚这几个名次
工做区:
就是在你的电脑里能看到的目录,好比我们建立的git_test

版本库:
工做区中有一个隐藏目录.git(以前已经给童鞋们提到过这个文件),它不算工做区,而是git的版本库。

git的版本库里面存放了不少的东西,其中最重要的就是称为stage(index)的暂存区,还有git为咱们自动建立的第一个分支master,以及指向master的一个指针叫head。

当咱们在工做区建立了文件后,执行add后,再来看这个图

当你执行commit后,暂存区的内容就没有

管理修改

为何Git比其余版本控制系统设计得优秀,由于Git跟踪并管理的是修改,而非文件。
你会问,什么是修改?好比你新增了一行,这就是一个修改,删除了一行,也是一个修改,更改了某些字符,也是一个修改,删了一些又加了一些,也是一个修改,甚至建立一个新文件,也算一个修改。
为何说Git管理的是修改,而不是文件呢?咱们仍是作实验。第一步,对readme.txt作一个修改,第二步,添加到暂存区。第三步,查看状态
[root@master-node git_test]# cat readme.txt
Git is veryt good tool
auth :cgt
date:2016-5-10
version:1
modify----------1
[root@master-node git_test]# git add readme.txt
[root@master-node git_test]# git status
# 位于分支 master
# 要提交的变动:
# (使用 "git reset HEAD <file>..." 撤出暂存区)
#
# 修改: readme.txt
#
第四步,再次编辑readme.txt,而后直接commit,再次查看status

[root@master-node git_test]# cat readme.txt
Git is veryt good tool
auth :cgt
date:2016-5-10
version:1
modify----------1
modify----------2
[root@master-node git_test]# git commit -m "modify"
[master 766baac] modify
1 file changed, 1 insertion(+)
[root@master-node git_test]# git status
# 位于分支 master
# 还没有暂存以备提交的变动:
# (使用 "git add <file>..." 更新要提交的内容)
# (使用 "git checkout -- <file>..." 丢弃工做区的改动)
#
# 修改: readme.txt
#
修改还没有加入提交(使用 "git add" 和/或 "git commit -a")
发现第二次的修改没有commit,那是由于你没有add

提交后,用git diff HEAD -- readme.txt命令能够查看工做区和版本库里面最新版本的区别:

[root@master-node git_test]# git diff HEAD -- readme.txt
diff --git a/readme.txt b/readme.txt
index 4416460..07c12e7 100644
--- a/readme.txt
+++ b/readme.txt
@@ -3,3 +3,4 @@ auth :cgt
date:2016-5-10
version:1
modify----------1
+modify----------2

撤销修改

编辑了readme,
[root@master-node git_test]# cat readme.txt
Git is veryt good tool
auth :cgt
date:2016-5-10
version:1
modify----------1
modify----------2
caoxiaojian is xiaojianjian
已经编辑完成,突然发现了问题,最后一行,道出了笔者的心声。既然已经发现错误,那就很容易纠正它,你能够删除掉最后一行,手动把文件恢复到上一个版本的状态,若是用git status查看一下,

[root@master-node git_test]# git status
# 位于分支 master
# 还没有暂存以备提交的变动:
# (使用 "git add <file>..." 更新要提交的内容)
# (使用 "git checkout -- <file>..." 丢弃工做区的改动)
#
# 修改: readme.txt
#
修改还没有加入提交(使用 "git add" 和/或 "git commit -a")
你能够发现上面提示你使用 "git checkout -- <file>..." 丢弃工做区的改动,那咱们执行下

[root@master-node git_test]# git checkout -- readme.txt
[root@master-node git_test]# cat readme.txt
Git is veryt good tool
auth :cgt
date:2016-5-10
version:1
modify----------1
已经回来了。

命令git checkout -- readme.txt意思就是,把readme.txt文件在工做区的修改所有撤销,这里有两种状况:
一种是readme.txt自修改后尚未被放到暂存区,如今,撤销修改就回到和版本库如出一辙的状态;
一种是readme.txt已经添加到暂存区后,又做了修改,如今,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
git checkout -- file命令中的--很重要,没有--,就变成了“切换到另外一个分支”的命令,咱们在后面的分支管理中会再次遇到git checkout命令。
刚刚我们没有将修改提交到暂存区,那假如你提交到了呢??????你说咋整呢?????是否是吓尿了????
[root@master-node git_test]# cat readme.txt
Git is veryt good tool
auth :cgt
date:2016-5-10
version:1
modify----------1
caoxiaojian is xiaojianjian
[root@master-node git_test]# git add readme.txt
[root@master-node git_test]# git status
# 位于分支 master
# 要提交的变动:
# (使用 "git reset HEAD <file>..." 撤出暂存区)
# 修改: readme.txt
你要是聪明的话,你应该已经知道要怎么作了。。。。对是的,就是你想的那样。

[root@master-node git_test]# git reset HEAD readme.txt
重置后撤出暂存区的变动:
M readme.txt
[root@master-node git_test]# git status
# 位于分支 master
# 还没有暂存以备提交的变动:
# (使用 "git add <file>..." 更新要提交的内容)
# (使用 "git checkout -- <file>..." 丢弃工做区的改动)
#
# 修改: readme.txt
#
修改还没有加入提交(使用 "git add" 和/或 "git commit -a")
已经退出了暂存区。你可能要问,那要是已经commit了呢??你小子胆子还真不小啊,教你一招,以前不是讲过回滚嘛,直接回滚。不过这个也是有条件的,就是你尚未把本身的本地版本库推送到远程。Git是一个分布式版本控制,他还有远程版本库,一旦你提交到远程版本库,那你就能够git go home

删除文件

先建立文件,后add,在commit,而后删除工做区的文件
[root@master-node git_test]# cat test.txt
qwertyuiop[
adfghjjljh
fdgscvxz
[root@master-node git_test]# git add test.txt
[root@master-node git_test]# git commit -m "del test"
[master 63d3bf7] del test
1 file changed, 3 insertions(+)
create mode 100644 test.txt
[root@master-node git_test]# rm -rf test.txt
[root@master-node git_test]# git status
# 位于分支 master
# 还没有暂存以备提交的变动:
# (使用 "git add/rm <file>..." 更新要提交的内容)
# (使用 "git checkout -- <file>..." 丢弃工做区的改动)
#
# 修改: readme.txt
# 删除: test.txt
#
修改还没有加入提交(使用 "git add" 和/或 "git commit -a")
如今你有两个选择,一是确实要从版本库中删除该文件,那就用命令git rm删掉,而且git commit:
[root@master-node git_test]# git rm test.txt
rm 'test.txt'
[root@master-node git_test]# git commit -m "remove test.txt"
[master 5f04ee2] remove test.txt
1 file changed, 3 deletions(-)
delete mode 100644 test.txt
如今文件就从版本库中完全的删除了。

命令git rm用于删除一个文件。若是一个文件已经被提交到版本库,那么你永远不用担忧误删,可是要当心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。

另外一种状况是删错了,由于版本库里还有呢,因此能够很轻松地把误删的文件恢复到最新版本:

使用

git checkout -- test.txt
git checkout实际上是用版本库里的版本替换工做区的版本,不管工做区是修改仍是删除,均可以“一键还原”。

远程仓库

可使用github给咱们提供的服务,做为咱们的一个远程仓库。可是须要作一下的设置。
因为你的本地Git仓库和GitHub仓库之间的传输是经过SSH加密的,因此咱们首先生成秘钥。

第1步:建立SSH Key。
在用户主目录下,看看有没有.ssh目录,若是有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,若是已经有了,可直接跳到下一步。若是没有,打开Shell(Windows下打开Git Bash),建立SSH Key:
ssh-keygen -t rsa -C "youremail@example.com"
你须要把邮件地址换成你本身的邮件地址,而后一路回车,使用默认值便可,因为这个Key也不是用于军事目的,因此也无需设置密码。
若是一切顺利的话,能够在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,能够放心地告诉任何人。

第2步:添加公钥到你的
登录GitHub,打开“Account settings”,“SSH Keys”页面,而后将你的key添加上。
为何GitHub须要SSH Key呢?由于GitHub须要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,因此,GitHub只要知道了你的公钥,就能够确认只有你本身才能推送。

添加远程库
你本来在本地已经建立了一个Git仓库,如今又想在github上也建立一个仓库,让这两个仓库能够远程同步。这样github的仓库既能够做为备份,又可让其余人经过该仓库来协做。

第一步:建立一个新的仓库repository
右上角有个➕,而后如今new repository

而后进入建立页面

仓库内容的提交

接下来我们看如何使用
本地没有仓库的状况下,要先建立仓库。
[root@master-node ~]# mkdir /test
[root@master-node ~]# cd /test
使用git init 建立定义仓库
[root@master-node ~]# git init
Initialized empty Git repository in C:/Program Files/Git/test/.git/
[root@master-node ~]# ls -al
total 8
drwxr-xr-x 1 cgt 197121 0 五月 16 06:11 ./
drwxr-xr-x 1 cgt 197121 0 五月 16 06:11 ../
drwxr-xr-x 1 cgt 197121 0 五月 16 06:11 .git/

在仓库中建立一个文件,而后add commit
[root@master-node ~]# echo "# test " >> README.md
[root@master-node ~]# git add README.md
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory.

[root@master-node ~]# git commit -m "first commit"
[master (root-commit) 7eeb945] first commit
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory.
1 file changed, 1 insertion(+)
create mode 100644 README.md
至此,提交到本地的head中。也就是本地仓库中,而后从本地仓库向远程仓库提交。

使用remote关联一个远程库,add是定义一个远程的名称,默认通常使用origin,后面跟的是远程仓库的名称
[root@master-node ~]# git remote add origin git@github.com:caoxiaojian/test.git
把本地库的内容推送到远程,其实是将本地的当前分支master,推送到远程
[root@master-node ~]# git push -u origin master
Warning: Permanently added the RSA host key for IP address '192.30.252.128' to the list of known hosts.
Counting objects: 3, done.
Writing objects: 100% (3/3), 210 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:caoxiaojian/test.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
因为远程库是空的,咱们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在之后的推送或者拉取时就能够简化命令。

再次修改README.md
[root@master-node ~]# echo "# this is my test file " >> README.md
[root@master-node ~]# git add README.md
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory.
[root@master-node ~]# git commit -m "2 commit"
[master warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory.
80bc0e7] 2 commit
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory.
1 file changed, 1 insertion(+)
[root@master-node ~]# git push origin master
Warning: Permanently added the RSA host key for IP address '192.30.252.120' to the list of known hosts.
Counting objects: 3, done.
Writing objects: 100% (3/3), 257 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:caoxiaojian/test.git
7eeb945..80bc0e7 master -> master
到github下面对应的仓库里查看

 

 

 

 

每次本地提交后,只要有必要,就可使用命令git push origin master推送最新修改

克隆远程库
在刚建立的仓库中建立新文件

建立文件

 建立完成后能够看见你的新文件

由于以前已经建立了test这个本地仓库,因此先删除,而后再clone
[root@master-node ~]# rm -rf /test/
[root@master-node ~]# git clone git@github.com:caoxiaojian/test.git
Cloning into 'test'...
Warning: Permanently added the RSA host key for IP address '192.30.252.121' to the list of known hosts.
remote: Counting objects: 9, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 9 (delta 0), reused 6 (delta 0), pack-reused 0
Receiving objects: 100% (9/9), done.
Checking connectivity... done.
[root@master-node ~]# cd /test/
test (master)
[root@master-node ~]# ls
new_file README.md
test (master)
[root@master-node ~]# cat new_file
make a new file for clone test

分支管理分支在实际中有什么用呢?假设你准备开发一个新功能,可是须要两周才能完成,第一周你写了50%的代码,若是马上提交,因为代码还没写完,不完整的代码库会致使别人不能干活了。若是等代码所有写完再一次提交,又存在丢失天天进度的巨大风险。如今有了分支,就不用怕了。你建立了一个属于你本身的分支,别人看不到,还继续在原来的分支上正常工做,而你在本身的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工做。

相关文章
相关标签/搜索