本篇正式开始介绍Git的基础操做与原理,看完本篇,你应该知道如何使用Git进行一次基础的版本控制,包括:Git仓库的生成和获取,添加和忽略版本控制对象;暂存,查看,缓存,变动;查看和查找提交历史;格式化历史记录输出;删除和移动Git仓库内对象。javascript
使用Git的第一步是要获取一个Git仓库,咱们使用Git的操做对象都是存放在Git仓库里,获取Git仓库的方式有两种:java
若咱们须要使用一个项目或目录生成一个Git仓库,只须要经过命令行进入该目录,执行以下Git指令:webpack
git init复制代码
此操做将在此目录生成一个.git子目录,该目录包含整个仓库结构,即仓库的全部文件;同时会检出(checkout)一个默认工做分支,一般名为master。git
此时,咱们只是初始化生成了一个Git仓库,还未添加须要进行版本控制的对象--文件或目录。github
不少时候,咱们须要从远程服务器获取一个已存在的Git仓库,咱们只须要使用以下指令:web
git clone https://github.com/codingplayboy/javascript_notes复制代码
git clone
后面跟着的url就是已存在的Git仓库地址,咱们须要知道的是Git克隆是对服务器上仓库的一次近乎完整的数据拷贝,当前仓库项目的全部文件及其各版本历史都会被获取。缓存
执行如上指令后,会在当前目录建立一个javascript_notes目录并在javascript_notes中初始化一个.git子目录,拉取仓库的全部数据,而后根据仓库(或项目)的最新版本检出(check out)一个工做分支,一般该分支默认名称为master。服务器
咱们克隆一个Git仓库时,其默认名仍是仓库名,可是也支持咱们自定义本地别名:url
git clone https://github.com/codingplayboy/javascript_notes js_notes复制代码
执行如上指令,会克隆一个仓库,并导入到当前目录下的js_notes目录。spa
Git仓库Url支持的协议有不少,最多见的是https:// 和git@;还有使用SSH传输协议的,
形如git://或者user@server:path/xxx/repository.git。
在上节,咱们已经知道如何获取一个Git仓库,可是到目前为止也仅仅是存在一个仓库,咱们进行版本控制的对象(文件或目录)并无添加进仓库。
相关指令:git status
当咱们获取一个仓库,如克隆一个远端仓库后,在仓库目录执行上面指令,如图所示:
on branch master
告诉咱们当前咱们处在名为master的分支;up-to-date with 'origin/master'
,说明目前分支与远程仓库的master分支保持同步最新版本;working directory clean
,说明目前仓库中没有新加或修改过的对象(文件或目录)。在当前工做目录的文件或目录,可能出于两种状态:
已标记(tracked)
所谓已标记文件或目录,即那些在Git最新快照里存在的对象,多是未修改(unmodified),已修改(modified)或暂存(staged)的文件或目录。
未标记(untracked)
未标记对象,即除去已标记对象外,全部对象,好比在工做目录下可是未包含在最新快照里而且不在暂存区(staging area)。
能够想象一下,当第一次克隆一个远程仓库后,仓库下的全部文件都应该是处于已标记(tracked)可是未修改的状态。
添加版本控制对象的指令是git add
,好比,咱们可使用以下指令添加一个README.txt文件,固然咱们首先须要在仓库目录下,建立该文件(任意方式建立),查看状态:
如上图,显示README.txt文件为Untracked file,而且提示:use git add
to track;
而后使用git add
指令后:
git add README.txt复制代码
再次执行git status
指令:
如上,出现:Changes to be committed,说明该文件已被标记(tracked)且被暂存,咱们能够进行提交了。
固然该指令还能够对目录使用:
git add test/复制代码
如上指令,将添加该test目录及其内全部文件或子目录。
最后,也许咱们但愿一次添加全部变动,而不是一个一个添加,以下指令,能够实现:
git add .复制代码
咱们还须要关注git add
指令,不仅是能添加版本控制对象,还有如下功能:
git add指令,更贴切的做用应该是添加新内容(文件/目录/变动)到下一次提交,即将新内容加入最新快照,等待提交;
关于后两点功能,后文有详细介绍。
有时候,咱们并不但愿对仓库内全部对象(文件或目录)进行管理,
某些开发依赖或本地调试使用文件和目录,咱们不须要在团队间共享,这些文件应该被Git忽略,咱们只须要建立一个.gitignore文件,在此文件中列出但愿被忽略的文件或目录,如:
.gitignore文件语法主要以下:
在添加README.txt文件后,咱们能够对其进行修改,如在该文件加入一行文字http://blog.codingplayboy.com
,而后执行git status指令
,结果以下:
发现,除了以前新添加文件的记录,又多了一条记录:Changes not staged for commit
,代表已标记对象发生变动可是未被暂存,其下面第一第二行是辅助信息,第三行告诉咱们,README.txt已经修改(modified);
随后咱们可使用git add
指令暂存这次变动,此时,再执行git status
指令,能够看到:
全部变动都已暂存,等待下一次提交。
上文已经指出,使用git status
能够查看当前工做目录完整的状态,同时,git还支持使用参数指明查看简短状态信息:
git status -s
or
git status --short复制代码
以下,其信息比git status
简洁明了:
前文的git status
能够查看当前工做目录的状态信息,包括当前分支,变动文件等,但都属于文件层次的信息;
有时咱们但愿知道:
git status
显然是不能告诉咱们,由于这是属于git diff
的使命,如,在README.txt文件中内容添加‘/’:
,如上图,git diff
以行为单位,告诉咱们全部变动文件哪些行发生变动(增长或删除)。
git diff
比较当前工做目录和暂存区的内容,而后展现哪些文件内容发生变动而且还没有暂存;
同时,其支持额外参数--staged
(或--cached),该参数指定时,将输出上次提交内容与暂存区内容比较后的的变动,
简言之,git diff
输出未暂存的变动,git diff --staged
输出已暂存待提交的变动。
在使用git add .
暂存变动后,使用git diff
指令是没用的,而使用git diff --staged
指令,输出以下:
全部的变动,最终都须要提交,才能在本地持久化报存,在将全部变动暂存(git add)后,咱们就能够进行提交了,相关指令就是:
git commit复制代码
在输入如上指令后,将进入Git commit信息编辑状态:
咱们能够编辑本次提交的备注信息,其中的默认备注信息都以#开头,代表提交时会被忽略。
git commit指令告诉Git持久化记录(提交)咱们暂存区(staging area)中的快照,任何未被暂存的变动,不会被添加进暂存区的快照,仍然保留在当前工做目录,咱们能够随后提交。
除了使用默认的git commit指令,咱们还能够添加-v
参数,在提交信息中显示变动内容,以下:
如上图,和以前的比较,除了基本的提示,还有文件变动内容提示,能够避免某些误提交。
固然,Git还支持咱们使用-m
参数,指明咱们在使用git commit
指令时直接填写提交备注信息:
咱们知道对于发生变动的对象,咱们须要先使用git add
,暂存变动,再使用git commit
提交变动;
可是还有一种能够不使用git add
指令的方式,能够提交变动,就是给git commit
指令添加-a
参数:
git commit -a复制代码
可是须要注意的是,该参数,只能直接提交工做目录中已标记的对象(文件或目录)的变动,对于未标记,如新添加的对象,是无效的。
本节要介绍的是如何查看以前的提交历史及信息,你应该知道的git log
指令,
默认地,不带参数时,执行git log
指令,输出的是当前仓库按逆序排序(最近提交在最前)的提交记录:
如上图,每一个提交记录包含其SHA-1校验和,提交者用户名,提交日期,提交备注信息。
git log
指令支持指定许多参数,以过滤输出不一样提交记录,下文展开介绍。
Git支持咱们指定数量参数,限定该次查看提交记录数量,如git log -2
,以后输出最近的两条提交记录。
Git支持咱们格式化输出的提交记录信息,使用--pretty参数,其值主要有如下几个:
git log --pretty=format:"%h - %an, %ar : %s"复制代码
git log --stat
输出以下:
除了输出基础提交信息,后面还输出了本次提交的简要变动信息:变动了多少文件,及每一个文件变动的行数,并在最后输出总结数据。
相对于git log --stat
输出简要提交变动信息,咱们能够指定-p参数:git log -p
,输出提交变动的详细内容,如:
参数 | 说明 |
---|---|
-p | 显示详细提交变动 |
--stat | 显示简要提交变动 |
--shortstat | 在--stat参数输出基础上只输出修改,新增或删除的行 |
--name-only | 显示提交时发生变动的文件名 |
--name-status | 显示提交时发生变动的文件名,并显示变动类型(删除,新增,或修改) |
--abbrev-commit | 只显示提交记录SHA-1校验和的前几个字符 |
--relative-date | 显示简要提交日期(如, “2 weeks ago”) |
--graph | 显示分支提交历史的ASCII图 |
--pretty | 支持预约义输出格式,详细说明见上文 |
Git支持咱们在输出历史记录时,添加多种过滤条件,最简单的好比-<num>
参数条件,指定输出最近的若干条提交记录,还有诸如提交时间,提交做者等条件。
--since/--after: git log --since=2.weeks
输出两周内的提交记录,参数值还能够形如"2016-01-15","2 years 1 day 10 minutes ago"
--until/--before: git log --until=2016-01-15
--grep: git log --grep=README
能够指定关键字,只有提交信息中存在关键字才会输出
--author: 过滤输出指定提交做者的记录
-S: git -log -Swebpack
输出提交内容(代码或文件或目录)包含指定字符串的记录
不少时候,咱们也会须要从Git仓库中删除某些对象,rm
就是删除文件或目录的指令,可是须要特别强调的是,该指令只是将某对象从当前工做目录删除,如:
使用rm
后,当前状态是"Changes not staged for commit:"这次变动未被暂存和提交。
若你须要将某对象从已标记文件或暂存区删除,则须要使用git rm
指令,以下:
使用git rm
后,变动会被暂存。
当咱们发生某次变动,且将其添加到暂存区(index索引),咱们只使用git rm
指令是不行的:
咱们必须加上-f
参数,指明强制删除。
有时候,咱们在某次变动添加了某文件(甚至可能已经添加到暂存区),可是暂时不须要提交,又不想直接删除它,即只在工做目录存在,而不将其放入暂存区,只须要添加--cached
参数,如修改README.txt同时,新增了test.txt文件,而且暂存了变动,以后提交时咱们不但愿这次提交test.txt,但又不但愿删除它,则在提交前使用git rm --cached test.txt
:
一般,咱们也许须要移动或重命名某文件或目录,Git有mv
指令,还要一个更方便的指令git mv
,如:
git mv a.txt b.txt复制代码
另外一方面,重命名或移动某文件或目录,这两个操做对于Git来讲是没有太大区别的,好比上面的重命名文件操做等效于:
mv a.txt b.txt
git rm a.txt
git add b.txt复制代码
咱们能够看到git mv
指令是在mv
指令操做的基础上暂存这次操做的变动,而mv
只是一个重命名或移动指令,不涉及版本控制流程。
到此,Git的基本使用,已经介绍完成,不过,本篇讲解的基础操做,都是在计算机本地进行的版本控制,并无同步到服务器,那么下一篇的主题就出来了:Git如何与远程服务器进行协同工做。