git 的使用(3)-基础命令
来源:互联网 发布:软件学徒招聘骗局 编辑:程序博客网 时间:2024/05/09 01:52
前言:
git 基本是在用git 掌握了命令基本上也就会说自己会git了。
推荐下这2本书:特别是第一本,写的特别好,浅显易懂。
http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
http://git.oschina.net/progit/
为什么要使用git, 而不是svn
我们平时的开发过程中,起码在国内,其实大部分还是在用svn的,第一是我们大部分的开发其实都在windows在进行,比较习惯用图形化的东西。第二是windows上的TortoiseSVN图形化软件实在太方便了, 很多人使用SVN就是因为图这个方便,所以就导致了git的不流行。但是这也并不能影响我们不去关注优秀的git。回到正题,我们为什么越来越喜欢用git,而不是svn。
1. svn是集中式的的版本管理,而git是分布式的。
为了理解分布式和集中式我们来看2张图片:
svn 集中式:
git 分布式:
从上2张图我们可以很清楚看到,svn和git的工作原理。
svn就是你每次commit前都必须先将最新的别人的提交给up到本地,然后你再commit,最关键是你提交的时候必须要联网,因为你要集中commit到svn服务器上,这样才能生效。如果是局域网开发,不连外网也没关系,几台机器相连,其实也叫联网。但是如果假设你要把代码待会家里去做开发,或者出差在火车上,在宾馆里,这样就悲剧了啊,因为连不上公司的内部网,就算svn有外部的网可以提交,你能想象每次写好一段代码,就commmit一次,而且svn联网很慢,要是提交个10M的东西,估计你自己都要郁闷死了。有人又说了,我不提交不就可以了吗,我一次性全部写好,回公司再提交,这样也行。但是,如果中间出现问题,停电文件没保存,或者想回到2个小时之前的代码状态,这个时候你就知道每过10分钟commit一次代码的好处了吧。
git 就完全解决了上上诉svn的痛苦的地方。它是分布式的。也就是说我的每一台机器都是一个独立的服务器,我不用去管其他的东西。但是为了集中管理代码呢。我们通过也会选择一台服务器当作源码机器。当然了。这台机器仅仅是为了统一源码管理的左右,没有其他的作用。所以,我们用clone命令将远程的代码克隆到本地后,我们自己的机器就成了一个服务器了。所以我每次写好代码后,执行commit命令,就是我的代码提交到我自己的机器git上,而不是像svn那样提交到远程。这样我可以随时回到我之前的版本上,因为都是在本地,速度很快。当我所有的都ok了之后,那么你就可以push你的代码到源码服务器上了。其他人也可以共享。
罗嗦说了这么多,不知道我有没有讲清楚,总结下,为什么要使用git:
1. git 速度比svn 要快,且是分布式的,所有的操作初了最后一步push都是在自己本地的机子上完成,速度很快。
2. git不联网(内网,外网)也能完成代码提交等所有操作。
3. git所有的操作都是基于快照的,不像svn是基于文件的差异,这也是它快的一个原因,这点后续会讲到。
git的安装
前面2篇,我花了大量时间来讲述在Linux以及windows上的安装,这里就不再累述了,从这里开始,我们假设已经刚刚安装好了git,并且是windows平台上安装的。
安装完成后,我们要做的第一步就是配置用户名和邮箱:
$ git config --global user.name yangyi$ git config --global user.email yangyi@sina.cn
好了。我们查看下配置成功了没。我们可以使用git config -l命令,查看:
$ git config -lcore.symlinks=falsecore.autocrlf=truecolor.diff=autocolor.status=autocolor.branch=autocolor.interactive=truepack.packsizelimit=2ghelp.format=htmlhttp.sslcainfo=/bin/curl-ca-bundle.crtsendemail.smtpserver=/bin/msmtp.exediff.astextplain.textconv=astextplainrebase.autosquash=trueuser.email=yangyi@sina.cnuser.name=iyangyi
我们看到配置成功了。那么为什么要一上来就要配置这个蛋疼的玩意儿呢? 且听我慢慢道来。因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。这样你提交代码的时候就会带上这些信息,其他人看到了也就知道是你提交得了。出了问题,也会发邮件来问候你。
创建版本库
git安装好了。config也配置好了。接下来就是初始化创建版本库了。初始化的意思就是你新建一个目录,并让git在这个目录下生效,初始化的命令是:git init
什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
我们新建一个目录learngit
$ mkdir learngit$ cd learngit$ pwd/d/learngit$ git initInitialized empty Git repository in d:/learngit/.git/
瞬间Git就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository),细心的读者可以发现当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。
把文件添加到版本库
我们刚才已经创建了一个版本库learngit 文件夹,现在呢,我们开始新建一个文件。README.md。很熟悉对不对,一般我们开源的github项目,都会默认生成这样一个文件,用来说明我们的项目的一些东西。
$ touch README.md$ vi README.mdGit is a version control system.Git is free software.
好了。我们往README.md文件里加了2行内容。下面我们如何将这个文件加入到git版本库中呢?首选我们看svn只怎么做的,是先add这个文件,再commit吧。git中也一样,只不过git中的commit只是提交到本地的版本库中,你看不需要联网就能操作,svn没网不行了吧。
第一步:添加到版本库,用git add命令
$ git add README.md
哎,命令执行完,怎么没有任何的输出啊。没有任何显示,这就对了,Unix的哲学是“没有消息就是好消息”,说明添加成功。
第二步,提交到版本库,用git commit -m "some msg"命令
$ git commit -m "write a new readme.md file"[master (root-commit) e2b9781] write a new readme.md file 1 file changed, 2 insertions(+) create mode 100644 README.md
我们看到成功了。返回的信息告诉我们,1个文件修改,2行添加,并且显示了我们刚才的message信息。-m 这个参数是提交的注释说明,简单说明一下我们本次提交的一些信息,便于查看。所以这个参数一定要加,不加会报错。
为什么Git添加文件需要add,commit一共两步呢?因为commit可以一次提交很多文件,所以你可以多次add不同的文件,比如:
$ git add file1.txt$ git add file2.txt$ git add file3.txt$ git commit -m "add 3 files."
查看状态
在git中我们随时随地可以用 git status命令来查看当前分支的状态,比如查看当前分支是否提交,增加了哪些东西还没提交等。由于上一步,我们已经commit过,所以现在现在看一下这个命令:
$ git statusOn branch masternothing to commit, working directory clean
我们可以通过这个命令知道,我们现在在很master分支上(为什么会是master分支,我们后续会讲),没有东西需要提交,而且工作目录是干净的。很清楚明了。
现在我们修改一下README.md文件,修改成为:
Git is a distributed version control system.Git is free software.
$ git statusOn branch masterChanges 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.mdno changes added to commit (use "git add" and/or "git commit -a")git 提示非常友善,让我们清楚的知道,README.md文件已经被修改过了,Changes not staged for commit表示还没被添加到暂缓区(后续会讲到)并提示我们可以用git add命令添加。那我们仅仅知道这个文件被修改了,我们也想知道修改了哪些地方呢?这个时候,我们可以用git diff命令,diff就是difficult的意思,就是差异不同,让我们知道哪些地方存在被修改了,我们试一下这个命令:
$ git diffdiff --git a/README.md b/README.mdindex 46d49bf..9247db6 100644--- a/README.md+++ b/README.md@@ -1,2 +1,2 @@-Git is a version control system.+Git is a distributed version control system. Git is free software.显示的格式是Unix通用的diff格式,可以百度下这种格式的具体用法。我们能清楚的知道了README.md文件被修改了哪些地方,如果有很多文件,会分段显示这种效果。我们知道了哪些地方被修改了,这个时候就可以放心的提交修改了,提交也同样是两部,先提交修改,再提交commit。
提交修改
修改一个文件和新添加一个文件,命令是一样的,都是:git add命令。这时候,我们提交修改:
$ git add readme.txt
同样,也是没输出任何东西,我们就知道修改成功了。那这时候,我们再看看状态是啥样呢? 我们再次使用 git status命令看看:$ git statusOn branch masterChanges to be committed: (use "git reset HEAD <file>..." to unstage) modified: README.md
这个时候提示就不是Changes not staged for commit,而是Changes to be committed,表示已经添加到暂缓区了,正在准备被提交(commit)。那我们再试一下git diff命令呢?还能看到各文件的差异吗?
$ git diff唉。居然是空的,啥都没输出。因为我们已经将代码提交到暂缓区了,已经不能再追溯到差异了。所以我们在修改提交之前,使用这个命令。
好了。已经添加好了,那我们就commit提交吧,还记得什么命令吗?对,是这个:git commit -m "some msg"
$ git commit -m "modify a line"[master 4b86146] modify a line 1 file changed, 1 insertion(+), 1 deletion(-)我们就能清楚的看到,1个文件改变了,新加了一行,删除了一行。正是我们刚才所做的。
提交了后,我们再次看一下,status状态:
$ git statusOn branch masternothing to commit, working directory clean
恩。又回到了刚开始的状态了,没有需要提交的,目录是干净的。版本回退
上面呢,我们搞明白了如何添加新文件到版本库,以及提交修改,查看状态,查看差异,现在呢。我们来看看如何回退,回退是也我们必不可少的常用操作。
我们先尝试着对README.md做几次修改,然后回退到某一次修改上去:
第一次:加上,“it is a good tool”,依次进行add 和commit操作
$ vi README.mdGit is a distributed version control system.Git is free software. it is a good tool$ git add README.md$ git commit -m 'it is a good tool'[master 0e87e34] it is a good tool 1 file changed, 1 insertion(+), 1 deletion(-)
第二次:加上这句"distributed under the GPL."。依次进行add 和commit操作
$ vi README.mdGit is a distributed version control system.Git is free software. it is a good tool. distributed under the GPL.$ git add README.md$ git commit -m 'add GPL'[master c790395] add GPL 1 file changed, 1 insertion(+), 1 deletion(-)
好,修改完毕,现在我们来捋一捋,我们对这个文件做过多少次修改,我算了下,应该是4次,包括刚才的2次,以及新建这个文件算一次,和上一篇我们查看status命令时的“modify a line”。所以,应该是有4次,当然我们是为了把关系给说清楚,并不是说我们真正开发的时候,去手动去数,没意义。
恩。回到主题,我们要想回到哪一步,我们首先要清楚我们做了多少次操作,也就是历史记录,在Git中,我们用git log来查看我们的提交记录。
我现在来试一下:
$ git logcommit c790395ac6e65457f32f06dcc170a5a3597dcaaeAuthor: iyangyi <yangyi@sina.cn>Date: Thu Sep 4 14:37:43 2014 +0800 add GPLcommit 0e87e34eec1fb358d0d38374e69276ae93fb8c96Author: iyangyi <yangyi@sina.cn>Date: Thu Sep 4 14:34:57 2014 +0800 it is a good toolcommit 4b86146be5fc04ea70770181a198debd568772d7Author: iyangyi <yangyi@sina.cn>Date: Wed Sep 3 11:47:19 2014 +0800 modify a linecommit c96a8e5a54d4476c300438b8aa17dfbca4d55214Author: iyangyi <yangyi@sina.cn>Date: Wed Sep 3 11:01:44 2014 +0800 write a new readme.md file果然显示了每一次提交,正是四次。如果嫌输出信息太多,看得眼花缭乱的,可以试试加上 --pretty=oneline参数:
$ git log --pretty=onelinec790395ac6e65457f32f06dcc170a5a3597dcaae add GPL0e87e34eec1fb358d0d38374e69276ae93fb8c96 it is a good tool4b86146be5fc04ea70770181a198debd568772d7 modify a linec96a8e5a54d4476c300438b8aa17dfbca4d55214 write a new readme.md file
这样就看的比较清楚了,我们看到的这一大串类似"c790395.....caae"是commit id,版本号,和SVN不一样,Git的commit id不是1,2,3递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示。为什么commit id需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里,因为都是本地工作,如果大家都用1,2,3作为版本号,一push到代码库,那肯定就冲突了。
ok,到现在我们知道了我们提交的文件的版本号了,那现在我想回到上一步,也就是“it is a good tool” 这一步,我们如何做呢?
当当当当!我们新的命令又来了。就是git reset --hard commit_id(id前7位)这个命令了。或者使用git reset --hard HEAD^快速回到上一次提交。
我们先来说说HEAD吧,在Git中,用HEAD表示当前版本,也就是最新的提交 "add GPL" 的commit id "c790395.....caae", 上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100
再次回到正题,我们要用HEAD^回到上一个版本,也就是“it is a good tool” 这一步:
$ git reset --hard HEAD^HEAD is now at 0e87e34 it is a good tool我们看到提示了,说HEAD已经在it is a good tool上了。不错。很好。当然我们也可以用git reset --hard 0e87e34,也可达到效果
$ git reset --hard 0e87e34HEAD is now at 0e87e34 it is a good tool好了,现在理论上讲,我们想回到之前的哪一步都ok的。用了git reset --hard commit_id
别高兴太早,我们现在再来看一看,之前提到的git log命令,还记得是干嘛用的嘛,就是记录我们所有的提交,我们再次看下:
$ git log --pretty=oneline0e87e34eec1fb358d0d38374e69276ae93fb8c96 it is a good tool4b86146be5fc04ea70770181a198debd568772d7 modify a linec96a8e5a54d4476c300438b8aa17dfbca4d55214 write a new readme.md file看到结果我惊呆了。我擦。我回退把最近一次的"add GPL"给搞掉了啊。悲剧啊。我想回到过去怎么办啊?少年,莫急莫急。我们首先来分析一下为毛一回退,回退到的版本之后的版本都没了:
git 中的回退这么快的原因之一,是因为内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向"append GPL":(下图所示)
改为指向"add distributed":(下图所示)
看图就很清楚了。图是书中的配图,回到我们这里,就是HEAD指针从"add GPL" 移动到了“it is a good tool” ,所以很快。那么这个时候HEAD 就指向“it is a good tool”了,也就是说它现在就是头了。git log命令永远记录的是从HEAD开始往上的提交记录,HEAD都变了,当然最近一次的"add GPL"就没了。
那你又说了。我虽然懂了没有了的原因,但是我还是得回到"add GPL" 这一步,怎么办,亚麻跌,求求你啦~`(*∩_∩*)′。
当当当当当,解决办法再次降临,这个命令就是 git reflog命令,这个命令记录着我们的每一个命令,不管是回退的还是没有回退的。看,是不是很高端,那帅哥,我们赶紧回到被干掉的"add GPL" 这一步吧。
$ git reflog0e87e34 HEAD@{2}: reset: moving to HEAD^c790395 HEAD@{3}: commit: add GPL0e87e34 HEAD@{4}: commit: it is a good tool4b86146 HEAD@{5}: commit: modify a linec96a8e5 HEAD@{6}: commit (initial): write a new readme.md file果然,你看,它记录着我们刚才的每一步操作。我们赶紧找到"add GPL"的commit id 是多少,ok,看到了。是c790395 。好。我们再次可以使用git reset --hard c790395:
$ git reset --hard c790395HEAD is now at c790395 add GPL哈哈,我们看到add GPL注释了。果真回来了。我们再用git log命令看下,有我们的add GPL这个记录了没?
$ git log --pretty=onelinec790395ac6e65457f32f06dcc170a5a3597dcaae add GPL0e87e34eec1fb358d0d38374e69276ae93fb8c96 it is a good tool4b86146be5fc04ea70770181a198debd568772d7 modify a linec96a8e5a54d4476c300438b8aa17dfbca4d55214 write a new readme.md file哈哈哈哈哈哈。该有的。都有啦。
本节总结
由于篇幅太多,来是这样改,很容易把样式给改掉,处女座的我觉得很不美观。我决定另写一篇。这里先总结一下这一篇。(抱歉我直接照搬书的过来了)
1. 初始化一个Git仓库,使用git init命令。
2. 添加文件到Git仓库,分两步:
第一步,使用命令git add ,注意,可反复多次使用,添加多个文件;
第二步,使用命令git commit -m "some message",完成。
3. 要随时掌握工作区的状态,使用git status命令。
4. 如果git status告诉你有文件被修改过,用git diff可以查看修改内容。
5. HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。
6. 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
7. 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
第一步,使用命令git add ,注意,可反复多次使用,添加多个文件;
第二步,使用命令git commit -m "some message",完成。
3. 要随时掌握工作区的状态,使用git status命令。
4. 如果git status告诉你有文件被修改过,用git diff可以查看修改内容。
5. HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。
6. 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
7. 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
0 0
- git 的使用(3)-基础命令
- git 基础使用命令
- git基础使用命令
- git基础命令使用
- git的基础命令
- git基础使用命令记录
- git的使用 git命令
- Git基础命令的使用——详细教程2
- GIT常用的基础命令
- git基础类的命令
- git的一些基础命令
- Git操作的基础命令
- git命令的使用
- git命令的使用
- git命令的使用
- Git的命令使用
- git的使用命令
- git命令的使用
- [算法导论] 递归式求解的三种方法
- 即时改变badgeValue的值(使用KVO)
- eclipse字体颜色的设置方法
- 【POJ】1797 Heavy Transportation 二分+最短路
- iOS程序发布测试生成AD_HOC时需要的证书
- git 的使用(3)-基础命令
- Oracle Database 学习
- Android Service与Activity之间通信的几种方式
- Nginx负载均衡配置实例详解
- 龙组第5周总结
- ios中使view向左移动,且右边不动
- jquery笔记大全
- Openssl证书操作
- chmod 命令的一些常识