读完本章你就能上手使用 Git 了。本章将介绍几个最基本的,也是最经常使用的 Git 命令,之后绝大多数时间里用到的也就是这几个命令。读完本章,你就能初始化一个新的代码仓库,作一些适当配置;开始或中止跟踪某些文件;暂存或提交某些更 新。咱们还会展现如何让 Git 忽略某些文件,或是名称符合特定模式的文件;如何既快且容易地撤消犯下的小错误;如何浏览项目的更新历史,查看某两次更新之间的差别;以及如何从远程仓库 拉数据下来或者推数据上去。html
有两种取得 Git 项目仓库的方法。第一种是在现存的目录下,经过导入全部文件来建立新的 Git 仓库。第二种是从已有的 Git 仓库克隆出一个新的镜像仓库来。git
要对现有的某个项目开始用 Git 管理,只需到此项目所在的目录,执行:github
$ git init
初始化后,在当前目录下会出现一个名为 .git 的目录,全部 Git 须要的数据和资源都存放在这个目录中。不过目前,仅仅是按照既有的结构框架初始化好了里边全部的文件和目录,但咱们尚未开始跟踪管理项目中的任何一个文件。正则表达式
若是当前目录下有几个文件想要归入版本控制,须要先用 git add 命令告诉 Git 开始对这些文件进行跟踪,而后提交:shell
$ git add README $ git commit -m 'initial project version'
稍后咱们再逐一解释每条命令的意思。不过如今,你已经获得了一个实际维护着若干文件的 Git 仓库。编程
若是想对某个开源项目出一份力,能够先把该项目的 Git 仓库复制一份出来,这就须要用到 git clone 命令。若是你熟悉其余的 VCS 好比 Subversion,你可能已经注意到这里使用的是 clone 而不是 checkout。这是个很是重要的差异,Git 收取的是项目历史的全部数据(每个文件的每个版本),服务器上有的数据克隆以后本地也都有了。实际上,即使服务器的磁盘发生故障,用任何一个克隆出来 的客户端均可以重建服务器上的仓库,回到当初克隆时的状态(虽然可能会丢失某些服务器端的挂钩设置,但全部版本的数据仍旧还在.vim
克隆仓库的命令格式为
git clone [url]
。好比,要克隆 Ruby 语言的 Git 代码仓库 Grit,能够用下面的命令:api
$ git clone git://github.com/schacon/grit.git
这会在当前目录下建立一个名为“grit”的目录,其中包含一个 .git 的目录,用于保存下载下来的全部版本记录,而后从中取出最新版本的文件拷贝。若是进入这个新建的grit 目录,你会看到项目中的全部文件已经在里边了,准备好后续的开发和使用。若是但愿在克隆的时候,本身定义要新建的项目目录名称,能够在上面的命令末尾指定新的名字:bash
$ git clone git://github.com/schacon/grit.git mygrit
惟一的差异就是,如今新建的目录成了 mygrit,其余的都和上边的同样。服务器
Git 支持许多数据传输协议。以前的例子使用的是
git://
协议,不过你也能够用http(s)://
或者user@server:/path.git
表示的 SSH 传输协议。
如今咱们手上已经有了一个真实项目的 Git 仓库,并从这个仓库中取出了全部文件的工做拷贝。接下来,对这些文件做些修改,在完成了一个阶段的目标以后,提交本次更新到仓库。
请记住,工做目录下面的全部文件都不外乎这两种状态:已跟踪或未跟踪。已跟踪的文件是指原本就被归入版本控制管理的文件,在上次快照中有它们的记 录,工做一段时间后,它们的状态多是未更新,已修改或者已放入暂存区。而全部其余文件都属于未跟踪文件。它们既没有上次更新时的快照,也不在当前的暂存区域。初次克隆某个仓库时,工做目录中的全部文件都属于已跟踪文件,且状态为未修改。
在编辑过某些文件以后,Git 将这些文件标为已修改。咱们逐步把这些修改过的文件放到暂存区域,直到最后一次性提交全部这些暂存起来的文件,如此重复。
要肯定哪些文件当前处于什么状态,能够用 git status 命令。若是在克隆仓库以后当即执行此命令,会看到相似这样的输出:
$ git status # On branch master nothing to commit (working directory clean)
这说明你如今的工做目录至关干净。换句话说,当前没有任何跟踪着的文件,也没有任何文件在上次提交后更改过。此外,上面的信息还代表,当前目录下没 有出现任何处于未跟踪的新文件,不然 Git 会在这里列出来。最后,该命令还显示了当前所在的分支是 master,这是默认的分支名称,实际是能够修改的,如今先不用考虑。
如今让咱们用 vim 编辑一个新文件 README,保存退出后运行
git status
会看到该文件出如今未跟踪文件列表中:
就是在“Untracked files”这行下面。Git 不会自动将之归入跟踪范围,除非你明明白白地告诉它“我须要跟踪该文件”,于是不用担忧把临时文件什么的也纳入版本管理。不过如今的例子中,咱们确实想要跟踪管理 README 这个文件。
使用命令
git add
开始跟踪一个新文件。因此,要跟踪 README 文件,运行:
$ git add README.md
此时再运行
git status
命令,会看到 README 文件已被跟踪,并处于暂存状态:
只要在 “Changes to be committed” 这行下面的,就说明是已暂存状态。若是此时提交,那么该文件此时此刻的版本将被留存在历史记录中。你可能会想起以前咱们使用
git init
后就运行了git add
命令,开始跟踪当前目录下的文件。在git add
后面能够指明要跟踪的文件或目录路径。若是是目录的话,就说明要递归跟踪该目录下的全部文件。(译注:其实git add
的潜台词就是把目标文件快照放入暂存区域,也就是 add file into staged area,同时不曾跟踪过的文件标记为须要跟踪。这样就好理解后续add
操做的实际意义了。)
如今咱们修改下以前已跟踪过的文件 main.js 而后再次运行 status 命令,会看到这样的状态报告:
文件 main.js 出如今 “Changes not staged for commit” 这行下面,说明已跟踪文件的内容发生了变化,但尚未放到暂存区。要暂存此次更新,须要运行
git add
命令(这是个多功能命令,根据目标文件的状态不一样,此命令的效果也不一样:能够用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等)。如今让咱们运行git add
将 main.js 放到暂存区,而后再看看git status
的输出:
如今两个文件都已暂存,下次提交时就会一并记录到仓库。假设此时,你想要在 main.js 里再加条注释,从新编辑存盘后,准备好提交。不过且慢,再运行
git status
看看:
怎么回事?main.js 文件出现了两次!一次算未暂存,一次算已暂存,这怎么可能呢?好吧,实际上 Git 只不过暂存了你运行
git add
命令时的版本,若是如今提交,那么提交的是添加注释前的版本,而非当前工做目录中的版本。因此,运行了git add
以后又做了修订的文件,须要从新运行git add
把最新版本从新暂存起来:
通常咱们总会有些文件无需归入 Git 的管理,也不但愿它们总出如今未跟踪文件列表。一般都是些自动生成的文件,好比日志文件,或者编译过程当中建立的临时文件等。咱们能够建立一个名为
.gitignore
的文件,列出要忽略的文件模式。来看一个实际的例子:
Git忽略以 .suo或 .sln结尾的文件。通常这类对象文件和存档文件都是编译过程当中出现的,咱们用不着跟踪它们的版本。
此外,你可能还须要忽略 log,tmp 或者 pid 目录,以及自动生成的文档等等。要养成一开始就设置好 .gitignore 文件的习惯,以避免未来误提交这类无用的文件。文件 .gitignore 的格式规范以下:
所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。星号(*)匹配零个或多个任意字符;[abc] 匹配任何一个列在方括号中的字符
咱们再看一个 .gitignore 文件的例子:
# 此为注释 – 将被 Git 忽略 *.a # 忽略全部 .a 结尾的文件 !lib.a # 但 lib.a 除外 /TODO # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO build/ # 忽略 build/ 目录下的全部文件 doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
实际上
git status
的显示比较简单,仅仅是列出了修改过的文件,若是要查看具体修改了什么地方,能够用git diff
命令。稍后咱们会详细介绍git diff
,不过如今,它已经能回答咱们的两个问题了:当前作的哪些更新尚未暂存?有哪些更新已经暂存起来准备好了下次提交?git diff
会使用文件补丁的格式显示具体添加和删除的行。假如再次修改 README 文件后暂存,而后编辑 main.js 文件后先别暂存,运行
status
命令,会看到:
要查看还没有暂存的文件更新了哪些部分,不加参数直接输入
git diff
:
此命令比较的是工做目录中当前文件和暂存区域快照之间的差别,也就是修改以后尚未暂存起来的变化内容。
若要看已经暂存起来的文件和上次提交时的快照之间的差别,能够用
git diff --cached
命令。(Git 1.6.1 及更高版本还容许使用git diff --staged
,效果是相同的,但更好记些。)来看看实际的效果:
请注意,单单
git diff
不过是显示尚未暂存起来的改动,而不是此次工做和上次提交之间的差别。因此有时候你一会儿暂存了全部更新过的文件后,运行git diff
后却什么也没有,就是这个缘由。像以前说的,暂存 mian.js 后再编辑,运行
git status
会看到暂存先后的两个版本:
如今运行
git diff
看暂存先后的变化:
而后用
git diff --cached
查看已经暂存起来的变化:
如今的暂存区域已经准备稳当能够提交了。在此以前,请必定要确认还有什么修改过的或新建的文件尚未
git add
过,不然提交的时候不会记录这些还没暂存起来的变化。因此,每次准备提交前,先用git status
看下,是否是都已暂存起来了,而后再运行提交命令git commit
:
$ git commit
这种方式会启动文本编辑器以便输入本次提交的说明。(默认会启用 shell 的环境变量 $EDITOR 所指定的软件,通常都是 vim 或 emacs。固然也可使用
git config --global core.editor
命令设定你喜欢的编辑软件。)编辑器会显示相似下面的文本信息(本例选用 Vim 的屏显方式展现):
][18]
能够看到,默认的提交消息包含最后一次运行
git status
的输出,放在注释行里,另外开头还有一空行,供你输入提交说明。你彻底能够去掉这些注释行,不过留着也不要紧,多少能帮你回想起此次更新的内容有哪些。(若是以为这还不够,能够用-v
选项将修改差别的每一行都包含到注释中来。)退出编辑器时,Git 会丢掉注释行,将说明内容和本次更新提交到仓库。另外也能够用
-m
参数后跟提交说明的方式,在一行命令中提交更新:
$ git commit -m '注释信息'
好,如今你已经建立了第一个提交!能够看到,提交后它会告诉你,当前是在哪一个分支(master)提交的,本次提交的完整 SHA-1 校验和是什么(le88712),以及在本次提交中,有多少文件修订过,多少行添改和删改过。
记住,提交时记录的是放在暂存区域的快照,任何还未暂存的仍然保持已修改状态,能够在下次提交时归入版本管理。每一次运行提交操做,都是对你项目做一次快照,之后能够回到这个状态,或者进行比较。
尽管使用暂存区域的方式能够精心准备要提交的细节,但有时候这么作略显繁琐。Git 提供了一个跳过使用暂存区域的方式,只要在提交的时候,给
git commit
加上-a
选项,Git 就会自动把全部已经跟踪过的文件暂存起来一并提交,从而跳过git add
步骤:
看到了吗?提交以前再也不须要
git add
文件 main.js 了。
要从 Git 中移除某个文件,就必需要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),而后提交。能够用
git rm
命令完成此项工做,并连带从工做目录中删除指定的文件,这样之后就不会出如今未跟踪文件清单中了。若是只是简单地从工做目录中手工删除文件,运行
git status
时就会在 “Changes not staged for commit:” 部分(也就是_未暂存_清单)看到:
而后再运行
git rm
记录这次移除文件的操做:
最后提交的时候,该文件就再也不归入版本管理了。若是删除以前修改过而且已经放到暂存区域的话,则必需要用强制删除选项
-f
(译注:即 force 的首字母),以防误删除文件后丢失修改的内容。
另一种状况是,咱们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然但愿保留在当前工做目录中。换句话说,仅是从跟踪清单中删除。好比一些大型日志文件或者一堆
.a
编译文件,不当心归入仓库后,要移除跟踪但不删除文件,以便稍后在.gitignore
文件中补上,用--cached
选项便可:(也就是从将已经跟踪的文件去除跟踪,即删除暂存区的文件,可是在工做区,该文件仍是存在的)
$ git rm --cached readme.txt
后面能够列出文件或者目录的名字,也可使用 glob 模式。比方说:
$ git rm log/\*.log
注意到星号 * 以前的反斜杠 ,由于 Git 有它本身的文件模式扩展匹配方式,因此咱们不用 shell 来帮忙展开(译注:实际上不加反斜杠也能够运行,只不过按照 shell 扩展的话,仅仅删除指定目录下的文件而不会递归匹配。上面的例子原本就指定了目录,因此效果等同,但下面的例子就会用递归方式匹配,因此必须加反斜 杠。)。此命令删除全部log/ 目录下扩展名为
.log
的文件。相似的好比:
$ git rm \*~
会递归删除当前目录及其子目录中全部 ~ 结尾的文件。
不像其余的 VCS 系统,Git 并不跟踪文件移动操做。若是在 Git 中重命名了某个文件,仓库中存储的元数据并不会体现出这是一次更名操做。不过 Git 很是聪明,它会推断出究竟发生了什么,至于具体是如何作到的,咱们稍后再谈。
既然如此,当你看到 Git 的 mv 命令时必定会困惑不已。要在 Git 中对文件更名,能够这么作:
$ git mv file_from file_to
它会恰如预期般正常工做。实际上,即使此时查看状态信息,也会明白无误地看到关于重命名操做的说明:
其实,运行 git mv 就至关于运行了下面三条命令:
$ mv add.js add2.js $ git rm add.js $ git add add2.js
如此分开操做,Git 也会意识到这是一次更名,因此无论何种方式都同样。固然,直接用
git mv
轻便得多,不过有时候用其余工具批处理更名的话,要记得在提交前删除老的文件名,再添加新的文件名。
在提交了若干更新以后,又或者克隆了某个项目,想回顾下提交历史,可使用 git log
命令查看。
接下来的例子会用我专门用于演示的 gitCommandsUser 项目,运行下面的命令获取该项目源代码:
$ git clone https://github.com/MarlonYJG/gitCommandsUser.git
而后在此项目中运行 git log,应该会看到下面的输出:
默认不用任何参数的话,
git log
会按提交时间列出全部的更新,最近的更新排在最上面。看到了吗,每次更新都有一个 SHA-1 校验和、做者的名字和电子邮件地址、提交时间,最后缩进一个段落显示提交说明。
git log
有许多选项能够帮助你搜寻感兴趣的提交,接下来咱们介绍些最经常使用的。咱们经常使用
-p
选项展开显示每次提交的内容差别,用-2
则仅显示最近的两次更新:
在作代码审查,或者要快速浏览其余协做者提交的更新都做了哪些改动时,就能够用这个选项。此外,还有许多摘要选项能够用,好比
--stat
,仅显示简要的增改行数统计:
每一个提交都列出了修改过的文件,以及其中添加和移除的行数,并在最后列出全部增减行数小计。还有个经常使用的
--pretty
选项,能够指定使用彻底不一样于默认格式的方式展现提交历史。好比用oneline
将每一个提交放在一行显示,这在提交数很大时很是有用。另外还有short
,full
和fuller
能够用,展现的信息或多或少有些不一样,请本身动手实践一下看看效果如何。
但最有意思的是
format
,能够定制要显示的记录格式,这样的输出便于后期编程提取分析,像这样:
经常使用的格式占位符写法及其表明的意义。
选项 说明 %H 提交对象(commit)的完整哈希字串 %h 提交对象的简短哈希字串 %T 树对象(tree)的完整哈希字串 %t 树对象的简短哈希字串 %P 父对象(parent)的完整哈希字串 %p 父对象的简短哈希字串 %an 做者(author)的名字 %ae 做者的电子邮件地址 %ad 做者修订日期(能够用 -date= 选项定制格式) %ar 做者修订日期,按多久之前的方式显示 %cn 提交者(committer)的名字 %ce 提交者的电子邮件地址 %cd 提交日期 %cr 提交日期,按多久之前的方式显示 %s 提交说明
你必定奇怪_做者(author)_和_提交者(committer)_之间究竟有何差异,其实做者指的是实际做出修改的人,提交者指的是最后将此 工做成果提交到仓库的人。因此,当你为某个项目发布补丁,而后某个核心成员将你的补丁并入项目时,你就是做者,而那个核心成员就是提交者。
用
oneline
或format
时结合--graph
选项,能够看到开头多出一些 ASCII 字符串表示的简单图形,形象地展现了每一个提交所在的分支及其分化衍合状况。
以上只是简单介绍了一些
git log
命令支持的选项。一些其余经常使用的选项及其释义。
选项 说明 -p 按补丁格式显示每一个更新之间的差别。 --stat 显示每次更新的文件修改统计信息。 --shortstat 只显示 --stat 中最后的行数修改添加移除统计。 --name-only 仅在提交信息后显示已修改的文件清单。 --name-status 显示新增、修改、删除的文件清单。 --abbrev-commit 仅显示 SHA-1 的前几个字符,而非全部的 40 个字符。 --relative-date 使用较短的相对时间显示(好比,“2 weeks ago”)。 --graph 显示 ASCII 图形表示的分支合并历史。 --pretty 使用其余格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。
除了定制输出格式的选项以外,
git log
还有许多很是实用的限制输出长度的选项,也就是只输出部分提交信息。以前咱们已经看到过-2
了,它只显示最近的两条提交,实际上,这是 - 选项的写法,其中的n
能够是任何天然数,表示仅显示最近的若干条提交。不过实践中咱们是不太用这个选项的,Git 在输出全部提交时会自动调用分页程序(less),要看更早的更新只需翻到下页便可。另外还有按照时间做限制的选项,好比
--since
和--until
。下面的命令列出全部最近两周内的提交:
$ git log --since=2.weeks
你能够给出各类时间格式,好比说具体的某一天(“2008-01-15”),或者是多久之前(“2 years 1 day 3 minutes ago”)。
还能够给出若干搜索条件,列出符合的提交。用
--author
选项显示指定做者的提交,用--grep
选项搜索提交说明中的关键字。(请注意,若是要获得同时知足这两个选项搜索条件的提交,就必须用--all-match
选项。)若是只关心某些文件或者目录的历史提交,能够在
git log
选项的最后指定它们的路径。由于是放在最后位置上的选项,因此用两个短划线(--
)隔开以前的选项和后面限定的路径名。其余经常使用的相似选项。
选项 说明 -(n) 仅显示最近的 n 条提交 --since, --after 仅显示指定时间以后的提交。 --until, --before 仅显示指定时间以前的提交。 --author 仅显示指定做者相关的提交。 --committer 仅显示指定提交者相关的提交。
任什么时候候,你都有可能须要撤消刚才所作的某些操做。接下来,咱们会介绍一些基本的撤消操做相关的命令。请注意,有些操做并不老是能够撤消的,因此请务必谨慎当心,一旦失误,就有可能丢失部分工做成果。
有时候咱们提交完了才发现漏掉了几个文件没有加,或者提交信息写错了。想要撤消刚才的提交操做,可使用
--amend
选项从新提交:
$ git commit --amend
此命令将使用当前的暂存区域快照提交。若是刚才提交完没有做任何改动,直接运行此命令的话,至关于有机会从新编辑提交说明,但将要提交的文件快照和以前的同样。
启动文本编辑器后,会看到上次提交时的说明,编辑它确认没问题后保存退出,就会使用新的提交说明覆盖刚才失误的提交。
若是刚才提交时忘了暂存某些修改,能够先补上暂存操做,而后再运行
--amend
提交:
$ git commit -m 'commit' $ git add test_name.js $ git commit --amend
上面的三条命令最终只是产生一个提交,第二个提交命令修正了第一个的提交内容。
接下来将演示如何取消暂存区域中的文件,以及如何取消工做目录中已修改的文件。不用担忧,查看文件状态的时候就提示了该如何撤消,因此不须要死记硬背。
来看下面的例子,有两个修改过的文件,咱们想要分开提交,但不当心用
git add .
全加到了暂存区域。该如何撤消暂存其中的一个文件呢?其实,git status
的命令输出已经告诉了咱们该怎么作:
就在 “Changes to be committed” 下面,括号中有提示,可使用
git reset HEAD ...
的方式取消暂存。好吧,咱们来试试取消暂存add2.js 文件:
如今 add2.js 文件又回到了以前已修改未暂存的状态。
若是以为刚才对 add2.js 的修改彻底没有必要,该如何取消修改,回到以前的状态(也就是修改以前的版本)呢?
git status
一样提示了具体的撤消方法,接着上面的例子,如今未暂存区域看起来像这样:
在第二个括号中,咱们看到了抛弃文件修改的命令(至少在 Git 1.6.1 以及更高版本中会这样提示,若是你还在用老版本,咱们强烈建议你升级,以获取最佳的用户体验),让咱们试试看:
能够看到,该文件已经恢复到修改前的版本。你可能已经意识到了,这条命令有些危险,全部对文件的修改都没有了,由于咱们刚刚把以前版本的文件复制过 来重写了此文件。因此在用这条命令前,请务必肯定真的再也不须要保留刚才的修改。
若是只是想回退版本,同时保留刚才的修改以便未来继续工做,请看后续的文档
记住,任何已经提交到 Git 的均可以被恢复。即使在已经删除的分支中的提交,或者用
--amend
从新改写的提交,均可以被恢复.因此,你可能失去的数据,仅限于没有提交过的,对 Git 来讲它们就像从未存在过同样。
要参与任何一个 Git 项目的协做,必需要了解该如何管理远程仓库。远程仓库是指托管在网络上的项目仓库,可能会有好多个,其中有些你只能读,另外有些能够写。同他人协做开发某 个项目时,须要管理这些远程仓库,以便推送或拉取数据,分享各自的工做进展。管理远程仓库的工做,包括添加远程库,移除废弃的远程库,管理各式远程库分 支,定义是否跟踪这些分支,等等。
要查看当前配置有哪些远程仓库,能够用
git remote
命令,它会列出每一个远程库的简短名字。在克隆完某个项目后,至少能够看到一个名为 origin 的远程库,Git 默认使用这个名字来标识你所克隆的原始仓库.也能够加上
-v
选项(译注:此为--verbose
的简写,取首字母),显示对应的克隆地址:
若是有多个远程仓库,此命令将所有列出。
这样一来,我就能够很是轻松地从这些用户的仓库中,拉取他们的提交到本地。
要添加一个新的远程仓库,能够指定一个简单的名字,以便未来引用,运行
git remote add [shortname] [url]
:
如今能够用字串 dev 指代对应的仓库地址了。
$ git fetch dev
fetch:表明本地仓库
$ git push dev
push:表明远程仓库
正如以前所看到的,能够用下面的命令从远程仓库抓取数据到本地:
$ git fetch [remote-name]
此命令会到远程仓库中拉取全部你本地仓库中尚未的数据。运行完成后,你就能够在本地访问该远程仓库中的全部分支,将其中某个分支合并到本地,或者只是取出某个分支,一探究竟。
若是是克隆了一个仓库,此命令会自动将远程仓库归于 origin 名下。因此,
git fetch origin
会抓取从你上次克隆以来别人上传到此远程仓库中的全部更新(或是上次 fetch 以来别人提交的更新)。有一点很重要,须要记住,fetch
命令只是将远端的数据拉到本地仓库,并不自动合并到当前工做分支,只有当你确实准备好了,才能手工合并。若是设置了某个分支用于跟踪某个远端仓库的分支,可使用
git pull
命令自动抓取数据下来,而后将远端分支自动合并到本地仓库中当前分支。在平常工做中咱们常常这么用,既快且好。实际上,默认状况下git clone
命令本质上就是自动建立了本地的 master 分支用于跟踪远程仓库中的 master 分支(假设远程仓库确实有 master 分支)。因此通常咱们运行git pull
,目的都是要从原始克隆的远端仓库中抓取数据后,合并到工做目录中的当前分支。
项目进行到一个阶段,要同别人分享目前的成果,能够将本地仓库中的数据推送到远程仓库。实现这个任务的命令很简单:
git push [remote-name] [branch-name]
。若是要把本地的 master 分支推送到origin
服务器上(再次说明下,克隆操做会自动使用默认的 master 和 origin 名字),能够运行下面的命令:
$ git push origin master
只有在所克隆的服务器上有写权限,或者同一时刻没有其余人在推数据,这条命令才会如期完成任务。若是在你推数据前,已经有其余人推送了若干更新,那 你的推送操做就会被驳回。你必须先把他们的更新抓取到本地,合并到本身的项目中,而后才能够再次推送。
咱们能够经过命令
git remote show [remote-name]
查看某个远程仓库的详细信息,好比要看所克隆的 origin 仓库,能够运行:
除了对应的克隆地址外,它还给出了许多额外的信息。它友善地告诉你若是是在 master 分支,就能够用
git pull
命令抓取数据合并到本地。另外还列出了全部处于跟踪状态中的远端分支。上面的例子很是简单,而随着使用 Git 的深刻,
git remote show
给出的信息可能会像这样:
$ git remote show origin * remote origin URL: git@github.com:defunkt/github.git Remote branch merged with 'git pull' while on branch issues issues Remote branch merged with 'git pull' while on branch master master New remote branches (next fetch will store in remotes/origin) caching Stale tracking branches (use 'git remote prune') libwalker walker2 Tracked remote branches acl apiv2 dashboard2 issues master postgres Local branch pushed with 'git push' master:master
它告诉咱们,运行
git push
时缺省推送的分支是什么(译注:最后两行)。它还显示了有哪些远端分支尚未同步到本地(译注:第六行的caching 分支),哪些已同步到本地的远端分支在远端服务器上已被删除(译注:Stale tracking branches 下面的两个分支),以及运行git pull
时将自动合并哪些分支(译注:前四行中列出的 issues 和 master 分支)。
在新版 Git 中能够用
git remote rename
命令修改某个远程仓库在本地的简短名称,好比想把 dev 改为dev2,能够这么运行:
注意,对远程仓库的重命名,也会使对应的分支名称发生变化,原来的
dev/master
分支如今成了dev2/master
。碰到远端仓库服务器迁移,或者原来的克隆镜像再也不使用,又或者某个参与者再也不贡献代码,那么须要移除对应的远端仓库,能够运行
git remote rm
命令:
同大多数 VCS 同样,Git 也能够对某一时间点上的版本打上标签。人们在发布某个软件版本(好比 v1.0 等等)的时候,常常这么作。(如何列出全部可用的标签,如何新建标签,以及各类不一样类型标签之间的差异。)
列出现有标签的命令很是简单,直接运行 git tag 便可:
$ git tag
显示的标签按字母顺序排列,因此标签的前后并不表示重要程度的轻重。
咱们能够用特定的搜索模式列出符合条件的标签。在 Git 自身项目仓库中,有着超过 240 个标签,若是你只对 1.4.2 系列的版本感兴趣,能够运行下面的命令:
$ git tag -l 'v1.4.2.*' v1.4.2.1 v1.4.2.2 v1.4.2.3 v1.4.2.4
Git 使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。轻量级标签就像是个不会变化的分支,实际上它就是个指向特 定提交对象的引用。而含附注标签,其实是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标 签自己也容许使用 GNU Privacy Guard (GPG) 来签署或验证。通常咱们都建议使用含附注型的标签,以便保留相关信息;固然,若是只是临时性加注标签,或者不须要旁注额外信息,用轻量级标签也没问题。
建立一个含附注类型的标签很是简单,用
-a
(译注:取 annotated 的首字母)指定标签名字便可:
而
-m
选项则指定了对应的标签说明,Git 会将此说明一同保存在标签对象中。若是没有给出该选项,Git 会启动文本编辑软件供你输入标签说明。可使用 git show 命令查看相应标签的版本信息,并连同显示打标签时的提交对象。
咱们能够看到在提交对象信息上面,列出了此标签的提交者和提交时间,以及相应的标签说明。
若是你有本身的私钥,还能够用 GPG 来签署标签,只须要把以前的
-a
改成-s
(译注: 取 signed 的首字母)便可:
$ git tag -s v1.5 -m 'my signed 1.5 tag' $ git show v1.5
轻量级标签实际上就是一个保存着对应提交对象的校验和信息的文件。要建立这样的标签,一个
-a
,-s
或-m
选项都不用,直接给出标签名字便可:
$ git tag v1.4-lw $ git tag $ git show v1.4-lw
可使用
git tag -v [tag-name]
(译注:取 verify 的首字母)的方式验证已经签署的标签。此命令会调用 GPG 来验证签名,因此你须要有签署者的公钥,存放在 keyring 中,才能验证:
$ git tag -v v1.4.2.1
你甚至能够在后期对早先的某次提交加注标签。好比在下面展现的提交历史中:
$ git log --pretty=oneline 15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment' a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support 0d52aaab4479697da7686c15f77a3d64d9165190 one more thing 6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment' 0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function 4682c3261057305bdd616e23b64b0857d832627b added a todo file 166ae0c4d3f420721acbb115cc33848dfcc2121a started write support 9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile 964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo 8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme
咱们忘了在提交 “updated rakefile” 后为此项目打上版本号 v1.2,不要紧,如今也能作。只要在打标签的时候跟上对应提交对象的校验和(或前几位字符)便可:
$ git tag -a v1.2 9fceb02
能够看到咱们已经补上了标签:
$ git tag $ git show v1.2
默认状况下,git push 并不会把标签传送到远端服务器上,只有经过显式命令才能分享标签到远端仓库。其命令格式如同推送分支,运行
git push origin [tagname]
便可:
若是要一次推送全部本地新增的标签上去,可使用 --tags 选项:
$ git push origin --tags
如今,其余人克隆共享仓库或拉取数据同步后,也会看到这些标签。
不少使用 Git 的开发者可能根本就没用过这些技巧
若是你用的是 Bash shell,能够试试看 Git 提供的自动完成脚本。下载 Git 的源代码,进入 contrib/completion 目录,会看到一个git-completion.bash 文件。将此文件复制到你本身的用户主目录中(译注:按照下面的示例,还应更名加上点:cp git-completion.bash ~/.git-completion.bash),并把下面一行内容添加到你的.bashrc 文件中:
source ~/.git-completion.bash
也能够为系统上全部用户都设置默认使用此脚本。Mac 上将此脚本复制到 /opt/local/etc/bash_completion.d 目录中,Linux 上则复制到/etc/bash_completion.d/ 目录中。这两处目录中的脚本,都会在 Bash 启动时自动加载。
若是在 Windows 上安装了 msysGit,默认使用的 Git Bash 就已经配好了这个自动完成脚本,能够直接使用。
在输入 Git 命令的时候能够敲两次跳格键(Tab),就会看到列出全部匹配的可用命令建议:
键入 git co 而后连按两次 Tab 键,会看到两个相关的建议(命令)
commit
和config
。继而输入m
会自动完成git commit
命令的输入。命令的选项也能够用这种方式自动完成,其实这种状况更实用些。好比运行
git log
的时候忘了相关选项的名字,能够输入开头的几个字母,而后敲 Tab 键看看有哪些匹配的:
$ git log --s --shortstat --since= --src-prefix= --stat --summary
这个技巧不错吧,能够节省不少输入和查阅文档的时间。
期待各位大佬的批评指正,有错误之处还请谅解!!若是以为有用,你懂得(记得收藏)