A用户的id_rsa.pub绝对路径?

文章总数93 篇
评论留言95 条
分类目录32 个
文章标签115 个
友情链接0 个
网站运行17766 天
浏览总量19485 次
最后更新日
记住我的登录信息
点击“立即注册”转到用户注册页面。
输入用户名或电子邮箱地址,您会收到一封新密码链接的电子邮件。
用户名或电子邮件地址22034 条评论分享收藏感谢收起jingyan.baidu.com/article/f71d6ab641d117.htmlxampp下载:弄好了,我就开始下各种主题和插件,一直折腾到我觉得满意后,我决定开始玩真的,建站!1.买域名本来我的选择只有万网或者新网,但是后来听说国内的域名注册一点都不自由,说封就封,而且基本上没有转让域名的可能性。所以我果断出国啦,网友推荐我用狗爹godaddy,我去看了一下价格觉得还不错,而且目前已中文化,点击进入:另外建议百度一下优惠码再购买,可以省一些钱。2.买空间我本来想买阿里云空间的,但是看了看价格,还是算了。所以就想买个最便宜的美国虚拟主机,由于英语不行,去外国网站买虚拟空间后台管理肯定生不如死,所以我就找在中国有代理美国空间的空间商,知乎上都推荐老鹰主机,或者老薛主机,我对比了一下,还是老薛主机便宜,于是就买了最便宜的50元美国空间,付款的时候问了客服有没有优惠码,最后一共花了35元。点击进入:3.安装wordpress老薛主机的后台是cPane的,我完全没见过,于是参考了这篇教程,cPanel安装WordPress中文教程但是在网页上直接上传实在太慢,我采用FlashFXP工具上传,不过要先去cPanel-ftp账户那里设置一下账号密码,IP就是空间的共享IP。4.域名绑定空间这个我不知道啥原理,但是DNSPOD上面有教程:点击查看:要注意的是A记录要设置俩个,一个是www,一个是@。这样www开头的域名才能打开。大概就是这样了,欢迎转载,但是请注明转载自我的博客哦!好好琢磨:赞同 31747 条评论分享收藏感谢收起首先要设置你git的用户名和邮箱,这个很重要,设置用户名:git config --global user.name "your_account_name"设置邮箱:git config --global user.email "your_email_full_name"这个用户名和邮箱是你注册Git时候所使用的用户名和邮箱。1.登录Github官网毫无疑问肯定是点击“Start a project”按钮啦。2.创建远程库。进入到项目编辑页面在这里,一定要选择Public哦,如果你想选择私人的,是要另外升级你的账户,是要软妹币的哦。Description栏目里面可以输入你对该项目的描述。“Initialize this respository with a README”这个按钮勾选了的话,会生成一个README.md文件用于描述这个项目。建议不要勾选,否则后面有一些麻烦。最后点击“Create respository”按钮就能创建一个新的空的版本库啦啦啦3.创建ssh密钥。github采用的ssh加密,至于原理是什么自行百度。你首先要看看你自己是否有密钥,在bash窗口中输入命令:cd
~/.ssh 一般你第一次使用都是没有这个文件夹的啦,有的话你得进去看看呀,使用命令:ls -a 如果有如下两个文件:id_rsa,id_rsa.pub这两个文件,要进入id_rsa.pub文件进去看看末尾是不是你登录Github官网的账号,如果不是,请删除这两个文件,然后在命令行中使用命令:ssh-keygen -t rsa -C “your_account_name” git会要求你输入密码,不用管,直接按空格就行。这样会重新生成这两个文件。如果没有.ssh文件夹,你直接输入命令:ssh-keygen -t rsa -C “your_account_name”就会在指定的位置生成啦。4.在官网输入公钥,也就是id_rsa.pub文件中的内容。进入官网后点你的头像下的设置 然后再选中SSH and GPG keys这一栏,再点击“New SSH key”新建ssh密钥按钮主题“Title”栏目随便输入,不输入也行,必须在key 这一栏中输入刚刚生成的id_rsa.pub文件中的内容,复制粘贴即可。然后再点击“Add SSH key”按钮即可添加。5.添加密钥到ssh。在bash窗口中输入命令:ssh-add 文件全名
这里的文件全名是包含绝对路径的文件名哦,将上面生成的两个密钥文件id_rsa , 以及id_rsa.pub文件 使用该命令添加到密钥。我只添加了公钥id_rsa.pub,私钥id_rsa我没有添加。然后使用命令:ssh -T 试试是否连接成功,出现以下画面那么congratulation。6.将本地仓库同步到远程仓库。推荐的做法是:你也甭在本地建仓了,直接在你想要放置项目的位置使用命令:
git clone https://github.com/yourname/yourproject 这个做法简单,粗暴,直接从远程仓库clone一个项目下来,自己在本地写自己的项目,然后推送到远程,省去n多麻烦。首先在你的本地创建一个仓库,使用远程仓库名作为文件夹名,然后进入该文件夹,在该文件夹下使用命令:git init 就能创建一个本地的git库。
其次要关联远程仓库,使用命令:git remote add origin :yourname/your_project.git 一定要使用自己的用户名和用户自己在远程建立的仓库名称。这样就将你的本地库关联到了远程仓库了。接下来就是将本地库的内容推送到远程库。到这一步按理来说应该推送本地库的内容了,但是因为在第2步创建远程仓库的时候,点击了创建readme文件所以,所以远程仓库有readme文件,本地没有,所以要先从远程仓库拉去下来。使用命令:git pull origin master 会将远程库有的内容同步到本地库。这个时候再使用命令:git push -u origin master 就能将本地库的内容推送到远程仓库。加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。下一次直接使用 git pull 或者git push.如果你在第二部没有勾选创建readme文件,那么好办了,你只需要关联远程仓库后,直接使用命令:git push -u origin master 就能把你本地仓库的内容推送到远程仓库了。
GIT是一个分布式版本控制系统,这不同于CVS,SVN等集中式版本控制系统,同一个Git仓库,可以分布到不同的机器上,且每台机器上版本库是一样的没有主次之分。所以一般来讲需要至少两太电脑才能实验远程库...
git链接远程库及使用命令推拉文件
一.链接远程库
使用运行启动PowerShell
使用命令进入你的库中(就是git init创建的库 ,其中有.git文件)
...
查看远程库$ git remote -vorigin https://github.com/autoliuweijie/MachineLearning.git (fetch)
origin https...
Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。
gitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名gitHub。
开发项目的时候会遇到本地有一个现成的项目,我需要关联到GitHub上某一个远程仓库,这个时候我们应该如何操作呢?
首先我们在GitHub上创建一个新的仓库
新建远程仓库
特别注意,当我们勾选Ini...
因为我个人喜好用GitHub作为我的远程托管库,但是和实验室的小伙伴们做项目(可公开的那种,如一起参加某比赛)的时候大家又用的是码云。由此我想两个远程端同时同步我的代码。。。、
之前写了一个git仓库与项目文件分离的博客,现在补充一下本地git仓库对应多个远程库的介绍,前一篇博客写到将服务端项目文件与git仓库分离开来,那么我们需要对新项目进行测试的时候肯定不能再现有项目上进...
最近刚开始学git,感谢原作者,这个用作自己的学习笔记!
转载的文章地址 http://www.jianshu.com/p/04e9a885c5c8...
工作区(Working Directory)
就是你在电脑里能看到的目录,如下图的learngit文件夹就是一个工作区:
版本库(Repository)
工作区有一个隐藏目录.git...
照着 pro git book来架了个私有git 远程库,做个记录。
验证选用ssh,RSA加密方式。
首先 在远程服务器架设库:yum install git-core建好后,就是建一个远程裸库...
没有更多推荐了,Git&教程&-&Git&基本用法
&收藏该经验
Git&是当前最流行的版本控制程序之一,文本包含了&Git&的一些基本用法&创建&git&仓库&初始化&git&仓库&
mkdir&project&&#&创建项目目录&
cd&project&&#&进入到项目目录&
git&init&&#&初始化&git&仓库。此命令会在当前目录新建一个&.git&目录,用于存储&git&仓库的相关信息&
初始化提交&
touch&README&
git&add&.&&#&将当前目录添加到&git&仓库中,&使用&git&add&-A&则是添加所有改动的文档&
git&commit&&-m&&&Initial&commit&&
git&remote&add&origin&&git&@github.com:lugir&/repo.git&&#&设置仓库&
修补提交(修补最近一次的提交而不创建新的提交)&
git&commit&&--amend&&-m&&&commit&message.&&
提交冲突时可以合并后再推送&
git&pull&&#&获取远程版本库提交与本地提交进行合并&
git&push&&#&提交&
使用别人的仓库&
git&clone&http:&//path&/to&/git.git&&#&clone&的内容会放在当前目录下的新目录&
将代码从本地回传到仓库&
git&push&&-u&origin&master&
使用&git&status&查看文件状态&
git&status&
查看提交日志&
git&log&&#&查看提交信息&
git&log&&--pretty=oneline&&#&以整洁的单行形式显示提交信息&
git&branch&&#&查看分支&
git&branch&&<span style="color:#.x-&<span style="color:#.x&&#&添加分支&6.x-1.x&
git&branch&checkout&master&&#&切换到主分支&
git&branch&&-d&&<span style="color:#.x-&<span style="color:#.x&&#&删除分支&6.x-1.x&
git&push&origin&:branchname&&#&删除远端分支&
git&tag&&#&查看分支&
git&tag&&<span style="color:#.x-&<span style="color:#.0&&#&添加标签&6.x-1.0&
git&show&&<span style="color:#.x-&<span style="color:#.0&&#&查看标签&6.x-1.0&的信息&
git&tag&&-a&&<span style="color:#.x-&<span style="color:#.0&965e066&&#&为之前提交的信息记录&965e066&加上标签&
git&push&&--tags&&#&提交时带上标签信息&
git&push&origin&:&/refs&/tags&/tagname&&#&删除远端标签&
从&git&仓库中导出项目&
git&archive&&--format&&tar&&--output&&/path&/to&/file.tar&master&&#&将&master&以&tar&&#26684;式打包到指定文件&
使用&Git&的一些基本守则:&当要commit/提交patch时:&
·&使用&git&diff&--check&检查行尾有没有多余的空白
·&每个&commit&只改一件事情。如果一个文档有多个变更,使用&git&add&--patch&只选择文档中的部分变更进入&stage
·&写清楚&commit&message
Git详解之一&Git起步&
&收藏该经验
本章介绍开始使用&Git&前的相关知识。我们会先了解一些版本控制工具的历史背景,然后试着让&Git&在你的系统上跑起来,直到最后配置好,可以正常开始开发工作。读完本章,你就会明白为什么&Git&会如此流行,为什么你应该立即开始使用它。
1.1&关于版本控制
什么是版本控制?我真的需要吗?版本控制是一种记录若干文件内容变化,以便将来查阅特定版本修订情况的系统。在本书所展示的例子中,我们仅对保存着软件源代码的文本文件作版本控制管理,但实际上,你可以对任何类型的文件进行版本控制。
如果你是位图形或网页设计师,可能会需要保存某一幅图片或页面布局文件的所有修订版本(这或许是你非常渴望拥有的功能)。采用版本控制系统&(VCS)是个明智的选择。有了它你就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态。你可以比较文件的变化细节,查出最&后是谁修改了哪个地方,从而导致出现怪异问题,又是谁在何时报告了某个功能缺陷等等。使用版本控制系统通常还意味着,就算你乱来一气把整个项目中的文件改&的改删的删,你也照样可以轻松恢复到原先的样子。但额外增加的工作量却微乎其微。
本地版本控制系统
许多人习惯用复制整个项目目录的方式来保存不同的版本,或许还会改名加上备份时间以示区别。这么做唯一的好处就是简单。不过坏处也不少:有时候会混淆所在的工作目录,一旦弄错文件丢了数据就没法撤销恢复。
为了解决这个问题,人们很久以前就开发了许多种本地版本控制系统,大多都是采用某种简单的数据库来记录文件的历次更新差异(见图&1-1)。
图&本地版本控制系统&
其中最流行的一种叫做&rcs,现今许多计算机系统上都还看得到它的踪影。甚至在流行的&Mac&OS&X&系统上安装了开发者工具包之后,也可以使用&rcs&命令。它的工作原理基本上就是保存并管理文件补丁(patch)。文件补丁是一种特定&#26684;式的文本文件,记录着对应文件修订前后的内容变化。所以,根据每次&修订后的补丁,rcs&可以通过不断打补丁,计算出各个版本的文件内容。
集中化的版本控制系统
接下来人们又遇到一个问题,如何让在不同系统上的开发者协同工作?于是,集中化的版本控制系统(&Centralized&Version&Control&Systems,简称&CVCS&)应运而生。这类系统,诸如&CVS,Subversion&以及&Perforce&等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。多年以来,这&已成为版本控制系统的标准做法(见图&1-2)。
图&集中化的版本控制系统&
这种做法带来了许多好处,特别是相较于老式的本地&VCS&来说。现在,每个人都可以在一定程度上看到项目中的其他人正在做些什么。而管理员也可以轻松掌控每个开发者的权限,并且管理一个&CVCS&要远比在各个客户端上维护本地数据库来得轻松容易。
事分两面,有好有坏。这么做最显而易见的缺点是中央服务器的单点故障。如果宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。要&是中央服务器的磁盘发生故障,碰巧没做备份,或者备份不够及时,就还是会有丢失数据的风险。最坏的情况是彻底丢失整个项目的所有历史更改记录,而被客户端&提取出来的某些快照数据除外,但这样的话依然是个问题,你不能保证所有的数据都已经有人事先完整提取出来过。本地版本控制系统也存在类&#20284;问题,只要整个项&目的历史记录被保存在单一位置,就有丢失所有历史更新记录的风险。
分布式版本控制系统
于是分布式版本控制系统(&Distributed&Version&Control&System,简称&DVCS&)面世了。在这类系统中,像&Git,Mercurial,Bazaar&以及&Darcs&等,客户端并不只提取最新版本的文件快照,而是把原始的代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜&像出来的本地仓库恢复。因为每一次的提取操作,实际上都是一次对代码仓库的完整备份(见图&1-3)。
图&分布式版本控制系统&
更进一步,许多这类系统都可以指定和若干不同的远端代码仓库进行交互。籍此,你就可以在同一个项目中,分别和不同工作小组的人相互协作。你可以根据需要设定不同的协作流程,比如层次模型式的工作流,而这在以前的集中式系统中是无法实现的。
1.2&Git&简史
同生活中的许多伟大事件一样,Git&诞生于一个极富纷争大举创新的年代。Linux&内核开源项目有着为数众广的参与者。绝大多数的&Linux&内核维护工作都花在了提交补丁和保存归档的繁琐事务上(年间)。到&2002&年,整个项目组开始启用分布式版本控制系统&BitKeeper&来管理和维护代码。
到了&2005&年,开发&BitKeeper&的商业公司同&Linux&内核开源社区的合作关系结束,他们收回了免费使用&BitKeeper&的权力。这就迫使&Linux&开源社区(特别是&Linux&的缔造者&Linus&Torvalds&)不得不吸取教训,只有开发一套属于自己的版本控制系统才不至于重蹈覆辙。他们对新的系统制订了若干目标:
*&速度&*&简单的设计&*&对非线性开发模式的强力支持(允许上千个并行开发的分支)&*&完全分布式&*&有能力高效管理类&#20284;&Linux&内核一样的超大规模项目(速度和数据量)
自诞生于&2005&年以来,Git&日臻成熟完善,在高度易用的同时,仍然保留着初期设定的目标。它的速度飞快,极其适合管理大项目,它还有着令人难以置信的非线性分支管理系统(见第三章),可以应付各种复杂的项目开发需求。
1.3&Git&基础
那么,简单地说,Git&究竟是怎样的一个系统呢?请注意,接下来的内容非常重要,若是理解了&Git&的思想和基本工作原理,用起来就会知其所以然,游刃有余。在开始学习&Git&的时候,请不要尝试把各种概念和其他版本控制系统(诸如&Subversion&和&Perforce&等)相比拟,否则容易混淆每个操作的实际意义。Git&在保存和处理各种信息的时候,虽然操作起来的命令形式非常相近,但它与其他版本控制系统的做法颇为不同。理解这些差异将有助于你准确地使用&Git&提供的各种工具。
直接记录快照,而非差异比较
Git&和其他版本控制系统的主要差别在于,Git&只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。这类系统&(CVS,Subversion,Perforce,Bazaar&等等)每次记录有哪些文件作了更新,以及都更新了哪些行的什么内容,请看图&1-4。
图&其他系统在每个版本中记录着各个文件的具体差异&
Git&并不保存这些前后变化的差异数据。实际上,Git&更像是把变化的文件作快照后,记录在一个微型的文件系统中。每次提交更新时,它会纵览一遍所有文件的指纹信息并对文件作一快照,然后保存一个指向这次快照&的索引。为提高性能,若文件没有变化,Git&不会再次保存,而只对上次保存的快照作一链接。Git&的工作方式就像图&1-5&所示。
图&保存每次更新时的文件快照&
这是&Git&同其他系统的重要区别。它完全颠覆了传统版本控制的套路,并对各个环节的实现方式作了新的设计。Git&更像是个小型的文件系统,但它同时还提供了许多以此为基础的超强工具,而不只是一个简单的&VCS。稍后在第三章讨论&Git&分支管理的时候,我们会再看看这样的设计究竟会带来哪些好处。
近乎所有操作都是本地执行
在&Git&中的绝大多数操作都只需要访问本地文件和资源,不用连网。但如果用&CVCS&的话,差不多所有操作都需要连接网络。因为&Git&在本地磁盘上就保存着所有当前项目的历史更新,所以处理起来速度飞快。
举个例子,如果要浏览项目的历史更新摘要,Git&不用跑到外面的服务器上去取数据回来,而直接从本地数据库读取后展示给你看。所以任何时候你都可以马上翻阅,无需等待。如果想要看当前版本的文件和一个月&前的版本之间有何差异,Git&会取出一个月前的快照和当前文件作一次差异运算,而不用请求远程服务器来做这件事,或是把老版本的文件拉到本地来作比较。
用&CVCS&的话,没有网络或者断开&VPN&你就无法做任何事情。但用&Git&的话,就算你在飞机或者火车上,都可以非常愉快地频繁提交更新,等到了有网络的时候再上传到远程仓库。同样,在回家的路上,不用连接&VPN&你也可以继续工作。换作其他版本控制系统,这么做几乎不可能,抑或非常麻烦。比如&Perforce,如果不连到服务器,几乎什么都做不了(译注:默认无法发出命令p4&edit&file&开始编辑文件,因为&Perforce&需要联网通知系统声明该文件正在被谁修订。但实际上手工修改文件权限可以绕过这个限制,只是完成后还是无法提交更新。);如果是&Subversion&或&CVS,虽然可以编辑文件,但无法提交更新,因为数据库在网络上。看上去好像这些都不是什么大问题,但实际体验过之后,你就会惊喜地发现,这其实是会带来&很大不同的。
时刻保持数据完整性
在保存到&Git&之前,所有数据都要进行内容的校验和(checksum)计算,并将此结果作为数据的唯一标识和索引。换句话说,不可能在你修改了文件或目录之后,Git&一无所知。这项特性作为&Git&的设计哲学,建在整体架构的最底层。所以如果文件在传输时变得不完整,或者磁盘损坏导致文件数据缺失,Git&都能立即察觉。
Git&使用&SHA-1&算法计算数据的校验和,通过对文件的内容或目录的结构计算出一个&SHA-1&哈希&#20540;,作为指纹字符串。该字串由&40&个十六进制字符(0-9&及&a-f)组成,看起来就像是:
24b9daaa493b52fb00373
Git&的工作完全依赖于这类指纹字串,所以你会经常看到这样的哈希&#20540;。实际上,所有保存在&Git&数据库中的东西都是用此哈希&#20540;来作索引的,而不是靠文件名。
多数操作仅添加数据
常用的&Git&操作大多仅仅是把数据添加到数据库。因为任何一种不可逆的操作,比如删除数据,都会使回退或重现历史版本变得困难重重。在别的&VCS&中,若还未提交更新,就有可能丢失或者混淆一些修改的内容,但在&Git&里,一旦提交快照之后就完全不用担心丢失数据,特别是养成定期推送到其他仓库的习惯的话。
这种高可靠性令我们的开发工作安心不少,尽管去做各种试验性的尝试好了,再怎样也不会弄丢数据。至于&Git&内部究竟是如何保存和恢复数据的,我们会在第九章讨论&Git&内部原理时再作详述。
文件的三种状态
好,现在请注意,接下来要讲的概念非常重要。对于任何一个文件,在&Git&内都只有三种状态:已提交(committed),已修改(modified)和已暂存(staged)。已提交表示该文件已经被安全地保存在本地数据库&中了;已修改表示修改了某个文件,但还没有提交保存;已暂存表示把已修改的文件放在下次提交时要保存的清单中。
由此我们看到&Git&管理项目时,文件流转的三个工作区域:Git&的工作目录,暂存区域,以及本地仓库。
图&工作目录,暂存区域,以及本地仓库&
每个项目都有一个&Git&目录(译注:如果&git&clone&出来的话,就是其中&.git&的目录;如果git&clone&--bare&的话,新建的目录本身就是&Git&目录。),它是&Git&用来保存元数据和对象数据库的地方。该目录非常重要,每次克隆镜像仓库的时候,实际拷贝的就是这个目录里面的数据。
从项目中取出某个版本的所有文件和目录,用以开始后续工作的叫做工作目录。这些文件实际上都是从&Git&目录中的压缩对象数据库中提取出来的,接下来就可以在工作目录中对这些文件进行编辑。
所谓的暂存区域只不过是个简单的文件,一般都放在&Git&目录中。有时候人们会把这个文件叫做索引文件,不过标准说法还是叫暂存区域。
基本的&Git&工作流程如下:
1.&在工作目录中修改某些文件。&2.&对修改后的文件进行快照,然后保存到暂存区域。&3.&提交更新,将保存在暂存区域的文件快照永久转储到&Git&目录中。
所以,我们可以从文件所处的位置来判断状态:如果是&Git&目录中保存着的特定版本文件,就属于已提交状态;如果作了修改并已放入暂存区域,就属于已暂存状态;如果自上次取出后,作了修改但还没有放到暂存区域,就&是已修改状态。到第二章的时候,我们会进一步了解其中细节,并学会如何根据文件状态实施后续操作,以及怎样跳过暂存直接提交。
1.4&安装&Git
是时候动手尝试下&Git&了,不过得先安装好它。有许多种安装方式,主要分为两种,一种是通过编译源代码来安装;另一种是使用为特定平台预编译好的安装包。
从源代码安装
若是条件允许,从源代码安装有很多好处,至少可以安装最新的版本。Git&的每个版本都在不断尝试改进用户体验,所以能通过源代码自己编译安装最新版本就再好不过了。有些&Linux&版本自带的安装包更新起来并不及时,所以除非你在用最新的&distro&或者&backports,那么从源代码安装其实该算是最佳选择。
Git&的工作需要调用&curl,zlib,openssl,expat,libiconv&等库的代码,所以需要先安装这些依赖工具。在有&yum&的系统上(比如&Fedora)或者有&apt-get&的系统上(比如&Debian&体系),可以用下面的命令安装:
$&yum&install&curl-devel&expat-devel&gettext-devel&\
&&openssl-devel&zlib-devel
$&apt-get&install&libcurl4-gnutls-dev&libexpat1-dev&gettext&\
&&libz-dev&libssl-dev
之后,从下面的&Git&官方站点下载最新版本源代码:
http://git-scm.com/download
然后编译并安装:
$&tar&-zxf&git-1.7.2.2.tar.gz
$&cd&git-1.7.2.2
$&make&prefix=/usr/local&all
$&sudo&make&prefix=/usr/local&install
现在已经可以用&git&命令了,用&git&把&Git&项目仓库克隆到本地,以便日后随时更新:
$&git&clone&git://git.kernel.org/pub/scm/git/git.git
在&Linux&上安装
如果要在&Linux&上安装预编译好的&Git&二进制安装包,可以直接用系统提供的包管理工具。在&Fedora&上用&yum&安装:
$&yum&install&git-core
在&Ubuntu&这类&Debian&体系的系统上,可以用&apt-get&安装:
$&apt-get&install&git-core
在&Mac&上安装
在&Mac&上安装&Git&有两种方式。最容易的当属使用图形化的&Git&安装工具,界面如图&1-7,下载地址在:
http://code.google.com/p/git-osx-installer
图&安装工具&
另一种是通过&MacPorts&(http://www.macports.org)&安装。如果已经装好了&MacPorts,用下面的命令安装&Git:
$&sudo&port&install&git-core&&#43;svn&&#43;doc&&#43;bash_completion&&#43;gitweb
这&种方式就不需要再自己安装依赖库了,Macports&会帮你搞定这些麻烦事。一般上面列出的安装选项已经够用,要是你想用&Git&连接&Subversion&的代码仓库,还可以加上&&#43;svn&选项,具体将在第八章作介绍。(译注:还有一种是使用&homebrew(https://github.com/mxcl/homebrew):brew&install&git。)
在&Windows&上安装
在&Windows&上安装&Git&同样轻松,有个叫做&msysGit&的项目提供了安装包,可以到&Google&Code&的页面上下载&exe&安装文件并运行:
http://code.google.com/p/msysgit
完成安装之后,就可以使用命令行的&git&工具(已经自带了&ssh&客户端)了,另外还有一个图形界面的&Git&项目管理工具。
1.5&初次运行&Git&前的配置
一般在新的系统上,我们都需要先配置下自己的&Git&工作环境。配置工作只需一次,以后升级时还会沿用现在的配置。当然,如果需要,你随时可以用相同的命令修改已有的配置。
Git&提供了一个叫做&git&config&的工具(译注:实际是&git-config&命令,只不过可以通过&git&加一个名字来呼叫此命令。),专门用来配置或读取相应的工作环境变量。而正是由这些环境变量,决定了&Git&在各个环节的具体工作方式和行为。这些变量可以存放在以下三个不同的地方:
·&/etc/gitconfig&文件:系统中对所有用户都普遍适用的配置。若使用&git&config&时用--system&选项,读写的就是这个文件。
·&~/.gitconfig&文件:用户目录下的配置文件只适用于该用户。若使用&git&config&时用--global&选项,读写的就是这个文件。
·&当前项目的&目录中的配置文件(也就是工作目录中的&.git/config&文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以.git/config&里的配置会覆盖/etc/gitconfig&中的同名变量。
在&Windows&系统上,Git&会找寻用户主目录下的&.gitconfig&文件。主目录即&$HOME&变量指定的目录,一般都是C:\Documents&and&Settings\$USER。此外,Git&还会尝试找寻/etc/gitconfig&文件,只不过看当初&Git&装在什么目录,就以此作为根目录来定位。
第一个要配置的是你个人的用户名称和电子邮件地址。这两条配置很重要,每次&Git&提交时都会引用这两条信息,说明是谁提交了更新,所以会随更新内容一起被永久纳入历史记录:
$&git&config&--global&user.name&&John&Doe&
$&git&config&--global&user.email&
如果用了&--global&选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。如果要在某个特定的项目中使用其他名字或者电邮,只要去掉--global&选项重新配置即可,新的设定保存在当前项目的.git/config&文件里。
文本编辑器
接下来要设置的是默认使用的文本编辑器。Git&需要你输入一些额外消息的时候,会自动调用一个外部文本编辑器给你用。默认会使用操作系统指定的默认编辑器,一般可能会是&Vi&或者&Vim。如果你有其他偏好,比如&Emacs&的话,可以重新设置:
$&git&config&--global&core.editor&emacs
差异分析工具
还有一个比较常用的是,在解决合并冲突时使用哪种差异分析工具。比如要改用&vimdiff&的话:
$&git&config&--global&merge.tool&vimdiff
Git&可以理解&kdiff3,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,和&opendiff&等合并工具的输出信息。当然,你也可以指定使用自己开发的工具,具体怎么做可以参阅第七章。
查看配置信息
要检查已有的配置信息,可以使用&git&config&--list&命令:
$&git&config&--list
user.name=Scott&Chacon
user.email=
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
有时候会看到重复的变量名,那就说明它们来自不同的配置文件(比如&/etc/gitconfig&和&~/.gitconfig),不过最终&Git&实际采用的是最后一个。
也可以直接查阅某个环境变量的设定,只要把特定的名字跟在后面即可,像这样:
$&git&config&user.name
Scott&Chacon
1.6&获取帮助
想了解&Git&的各式工具该怎么用,可以阅读它们的使用帮助,方法有三:
$&git&help&&$&git&&--help
$&man&git-
比如,要学习&config&命令可以怎么用,运行:
$&git&help&config
我们随时都可以浏览这些帮助信息而无需连网。不过,要是你觉得还不够,可以到&Frenode&IRC&服务器(irc.freenode.net)上的&#git&或&#github&频道寻求他人帮助。这两个频道上总有着上百号人,大多都有着丰富的&git&知识,并且乐于助人。
至此,你该对&Git&有了点基本认识,包括它和以前你使用的&CVCS&之间的差别。现在,在你的系统上应该已经装好了&Git,设置了自己的名字和电邮。接下来让我们继续学习&Git&的基础知识。
Git详解之二&Git基础&
&收藏该经验
读完本章你就能上手使用&Git&了。本章将介绍几个最基本的,也是最常用的&Git&命令,以后绝大多数时间里用到的也就是这几个命令。读完本章,你就能初始化一个新的代码仓库,做一些适当配置;开始或停止跟踪某些文件;暂存或提交某些更&新。我们还会展示如何让&Git&忽略某些文件,或是名称符合特定模式的文件;如何既快且容易地撤消犯下的小错误;如何浏览项目的更新历史,查看某两次更新之间的差异;以及如何从远程仓库&拉数据下来或者推数据上去。
2.1&&取得项目的&Git&仓库
有两种取得&Git&项目仓库的方法。第一种是在现存的目录下,通过导入所有文件来创建新的&Git&仓库。第二种是从已有的&Git&仓库克隆出一个新的镜像仓库来。
在工作目录中初始化新仓库
要对现有的某个项目开始用&Git&管理,只需到此项目所在的目录,执行:
$&git&init
初始化后,在当前目录下会出现一个名为&.git&的目录,所有&Git&需要的数据和资源都存放在这个目录中。不过目前,仅仅是按照既有的结构框架初始化好了里边所有的文件和目录,但我们还没有开始跟踪管理项目中的任何一个文件。(在第九章我们会详细说明刚才创建的.git&目录中究竟有哪些文件,以及都起些什么作用。)
如果当前目录下有几个文件想要纳入版本控制,需要先用&git&add&命令告诉&Git&开始对这些文件进行跟踪,然后提交:
$&git&add&*.c
$&git&add&README
$&git&commit&-m&'initial&project&version'
稍后我们再逐一解释每条命令的意思。不过现在,你已经得到了一个实际维护着若干文件的&Git&仓库。
从现有仓库克隆
如果想对某个开源项目出一份力,可以先把该项目的&Git&仓库复制一份出来,这就需要用到&git&clone&命令。如果你熟悉其他的&VCS&比如&Subversion,你可能已经注意到这里使用的是&clone&而不是&checkout。这是个非常重要的差别,Git&收取的是项目历史的所有数据(每一个文件的每一个版本),服务器上有的数据克隆之后本地也都有了。实际上,即便服务器的磁盘发生故障,用任何一个克隆出来&的客户端都可以重建服务器上的仓库,回到当初克隆时的状态(虽然可能会丢失某些服务器端的挂钩设置,但所有版本的数据仍旧还在,有关细节请参考第四章)。
克隆仓库的命令&#26684;式为&git&clone&[url]。比如,要克隆&Ruby&语言的&Git&代码仓库&Grit,可以用下面的命令:
$&git&clone&git://github.com/schacon/grit.git
这会在当前目录下创建一个名为“grit”的目录,其中包含一个&.git&的目录,用于保存下载下来的所有版本记录,然后从中取出最新版本的文件拷贝。如果进入这个新建的grit&目录,你会看到项目中的所有文件已经在里边了,准备好后续的开发和使用。如果希望在克隆的时候,自己定义要新建的项目目录名称,可以在上面的命令末尾指定新的名字:
$&git&clone&git://github.com/schacon/grit.git&mygrit
唯一的差别就是,现在新建的目录成了&mygrit,其他的都和上边的一样。
Git&支持许多数据传输协议。之前的例子使用的是&git://&协议,不过你也可以用&http(s)://&或者user@server:/path.git&表示的&SSH&传输协议。我们会在第四章详细介绍所有这些协议在服务器端该如何配置使用,以及各种方式之间的利弊。
2.2&&记录每次更新到仓库
现在我们手上已经有了一个真实项目的&Git&仓库,并从这个仓库中取出了所有文件的工作拷贝。接下来,对这些文件作些修改,在完成了一个阶段的目标之后,提交本次更新到仓库。
请记住,工作目录下面的所有文件都不外乎这两种状态:已跟踪或未跟踪。已跟踪的文件是指本来就被纳入版本控制管理的文件,在上次快照中有它们的记&录,工作一段时间后,它们的状态可能是未更新,已修改或者已放入暂存区。而所有其他文件都属于未跟踪文件。它们既没有上次更新时的快照,也不在当前的暂存&区域。初次克隆某个仓库时,工作目录中的所有文件都属于已跟踪文件,且状态为未修改。
在编辑过某些文件之后,Git&将这些文件标为已修改。我们逐步把这些修改过的文件放到暂存区域,直到最后一次性提交所有这些暂存起来的文件,如此重复。所以使用&Git&时的文件状态变化周期如图&2-1&所示。
图&文件的状态变化周期&
检查当前文件状态
要确定哪些文件当前处于什么状态,可以用&git&status&命令。如果在克隆仓库之后立即执行此命令,会看到类&#20284;这样的输出:
$&git&status
#&On&branch&master
nothing&to&commit&(working&directory&clean)
这说明你现在的工作目录相&当干净。换句话说,当前没有任何跟踪着的文件,也没有任何文件在上次提交后更改过。此外,上面的信息还表明,当前目录下没&有出现任何处于未跟踪的新文件,否则&Git&会在这里列出来。最后,该命令还显示了当前所在的分支是&master,这是默认的分支名称,实际是可以修改的,现在先不用考虑。下一章我们就会详细讨论分支和引用。
现在让我们用&vim&编辑一个新文件&README,保存退出后运行&git&status&会看到该文件出现在未跟踪文件列表中:
$&vim&README
$&git&status
#&On&branch&master
#&Untracked&files:
#&&&(use&&git&add&...&&to&include&in&what&will&be&committed)
nothing&added&to&commit&but&untracked&files&present&(use&&git&add&&to&track)
就是在“Untracked&files”这行下面。Git&不会自动将之纳入跟踪范围,除非你明明白白地告诉它“我需要跟踪该文件”,因而不用担心把临时文件什么的也归入版本管理。不过现在的例子中,我们确实想要跟踪管理&README&这个文件。
跟踪新文件
使用命令&git&add&开始跟踪一个新文件。所以,要跟踪&README&文件,运行:
$&git&add&README
此时再运行&git&status&命令,会看到&README&文件已被跟踪,并处于暂存状态:
$&git&status
#&On&branch&master
#&Changes&to&be&committed:
#&&&(use&&git&reset&HEAD&...&&to&unstage)
# new&file:&&&README
只要在&“Changes&to&be&committed”&这行下面的,就说明是已暂存状态。如果此时提交,那么该文件此时此刻的版本将被留存在历史记录中。你可能会想起之前我们使用git&init&后就运行了&git&add&命令,开始跟踪当前目录下的文件。在&git&add&后面可以指明要跟踪的文件或目录路径。如果是目录的话,就说明要递归跟踪该目录下的所有文件。(译注:其实git&add&的潜台词就是把目标文件快照放入暂存区域,也就是&add&file&into&staged&area,同时未曾跟踪过的文件标记为需要跟踪。这样就好理解后续&add&操作的实际意义了。)
暂存已修改文件
现在我们修改下之前已跟踪过的文件&benchmarks.rb,然后再次运行&status&命令,会看到这样的状态报告:
$&git&status
#&On&branch&master
#&Changes&to&be&committed:
#&&&(use&&git&reset&HEAD&...&&to&unstage)
# new&file:&&&README
#&Changed&but&not&updated:
#&&&(use&&git&add&...&&to&update&what&will&be&committed)
# modified:&&&benchmarks.rb
文件&benchmarks.rb&出现在&“Changed&but&not&updated”&这行下面,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。要暂存这次更新,需要运行git&add&命令(这是个多功能命令,根据目标文件的状态不同,此命令的效果也不同:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等)。现在让我们运行git&add&将&benchmarks.rb&放到暂存区,然后再看看&git&status&的输出:
$&git&add&benchmarks.rb
$&git&status
#&On&branch&master
#&Changes&to&be&committed:
#&&&(use&&git&reset&HEAD&...&&to&unstage)
# new&file:&&&README
# modified:&&&benchmarks.rb
现在两个文件都已暂存,下次提交时就会一并记录到仓库。假设此时,你想要在&benchmarks.rb&里再加条注释,重新编辑存盘后,准备好提交。不过且慢,再运行git&status&看看:
$&vim&benchmarks.rb&
$&git&status
#&On&branch&master
#&Changes&to&be&committed:
#&&&(use&&git&reset&HEAD&...&&to&unstage)
# new&file:&&&README
# modified:&&&benchmarks.rb
#&Changed&but&not&updated:
#&&&(use&&git&add&...&&to&update&what&will&be&committed)
# modified:&&&benchmarks.rb
怎么回事?benchmarks.rb&文件出现了两次!一次算未暂存,一次算已暂存,这怎么可能呢?好吧,实际上&Git&只不过暂存了你运行&git&add&命令时的版本,如果现在提交,那么提交的是添加注释前的版本,而非当前工作目录中的版本。所以,运行了git&add&之后又作了修订的文件,需要重新运行&git&add&把最新版本重新暂存起来:
$&git&add&benchmarks.rb
$&git&status
#&On&branch&master
#&Changes&to&be&committed:
#&&&(use&&git&reset&HEAD&...&&to&unstage)
# new&file:&&&README
# modified:&&&benchmarks.rb
忽略某些文件
一般我们总会有些文件无需纳入&Git&的管理,也不希望它们总出现在未跟踪文件列表。通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。我们可以创建一个名为&.gitignore&的文件,列出要忽略的文件模式。来看一个实际的例子:
$&cat&.gitignore
第一行告诉&Git&忽略所有以&.o&或&.a&结尾的文件。一般这类对象文件和存档文件都是编译过程中出现的,我们用不着跟踪它们的版本。第二行告诉&Git&忽略所有以波浪符(~)结尾的文件,许多文本编辑软件(比如&Emacs)都用这样的文件名保存副本。此外,你可能还需要忽略&log,tmp&或者&pid&目录,以及自动生成的文档等等。要养成一开始就设置好&.gitignore&文件的习惯,以免将来误提交这类无用的文件。
文件&.gitignore&的&#26684;式规范如下:
·&所有空行或者以注释符号&#&开头的行都会被&忽略。
·&可以使用标准的&模式匹配。&匹配模式最后跟反斜杠(/)说明要忽略的是目录。&要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
所谓的&glob&模式是指&shell&所使用的简化了的正则表达式。星号(*)匹配零个或多个任意字符;[abc]&匹配任何一个列在方括号中的字符(这个例子要么匹配一个&a,要么匹配一个&b,要么匹配一个&c);问号(?)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如[0-9]&表示匹配所有&0&到&9&的数字)。
我们再看一个&.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&会使用文件补丁的&#26684;式显示具体添加和删除的行。
假如再次修改&README&文件后暂存,然后编辑&benchmarks.rb&文件后先别暂存,运行&status&命令,会看到:
$&git&status
#&On&branch&master
#&Changes&to&be&committed:
#&&&(use&&git&reset&HEAD&...&&to&unstage)
# new&file:&&&README
#&Changed&but&not&updated:
#&&&(use&&git&add&...&&to&update&what&will&be&committed)
# modified:&&&benchmarks.rb
要查看尚未暂存的文件更新了哪些部分,不加参数直接输入&git&diff:
$&git&diff
diff&--git&a/benchmarks.rb&b/benchmarks.rb
index&3cb747f..da
---&a/benchmarks.rb
&#43;&#43;&#43;&b/benchmarks.rb
@@&-36,6&&#43;36,10&@@&def&main
&&&&&&&&&&&@commit.parents[0].parents[0].parents[0]
&&&&&&&&&end
&#43;&&&&&&&&run_code(x,&'commits&1')&do
&#43;&&&&&&&&&&git.commits.size
&#43;&&&&&&&&end
&&&&&&&&&run_code(x,&'commits&2')&do
&&&&&&&&&&&log&=&git.commits('master',&15)
&&&&&&&&&&&log.size
此命令比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容。
若要看已经暂存起来的文件和上次提交时的快照之间的差异,可以用&git&diff&--cached&命令。(Git&1.6.1&及更高版本还允许使用git&diff&--staged,效果是相同的,但更好记些。)来看看实际的效果:
$&git&diff&--cached
diff&--git&a/README&b/README
new&file&mode&100644
index&902a1
---&/dev/null
&#43;&#43;&#43;&b/README2
@@&-0,0&&#43;1,5&@@
&#43;&by&Tom&Preston-Werner,&Chris&Wanstrath
&#43;&http://github.com/mojombo/grit
&#43;Grit&is&a&Ruby&library&for&extracting&information&from&a&Git&repository
请注意,单单&git&diff&不过是显示还没有暂存起来的改动,而不是这次工作和上次提交之间的差异。所以有时候你一下子暂存了所有更新过的文件后,运行git&diff&后却什么也没有,就是这个原因。
像之前说的,暂存&benchmarks.rb&后再编辑,运行&git&status&会看到暂存前后的两个版本:
$&git&add&benchmarks.rb
$&echo&'#&test&line'&&&&benchmarks.rb
$&git&status
#&On&branch&master
#&Changes&to&be&committed:
# modified:&&&benchmarks.rb
#&Changed&but&not&updated:
# modified:&&&benchmarks.rb
现在运行&git&diff&看暂存前后的变化:
$&git&diff
diff&--git&a/benchmarks.rb&b/benchmarks.rb
index&e445e28..86b2f7c&100644
---&a/benchmarks.rb
&#43;&#43;&#43;&b/benchmarks.rb
@@&-127,3&&#43;127,4&@@&end
&##pp&Grit::GitRuby.cache_client.stats
&#43;#&test&line
然后用&git&diff&--cached&查看已经暂存起来的变化:
$&git&diff&--cached
diff&--git&a/benchmarks.rb&b/benchmarks.rb
index&3cb747f..e445e28&100644
---&a/benchmarks.rb
&#43;&#43;&#43;&b/benchmarks.rb
@@&-36,6&&#43;36,10&@@&def&main
&&&&&&&&&&@commit.parents[0].parents[0].parents[0]
&&&&&&&&end
&#43;&&&&&&&&run_code(x,&'commits&1')&do
&#43;&&&&&&&&&&git.commits.size
&#43;&&&&&&&&end
&&&&&&&&run_code(x,&'commits&2')&do
&&&&&&&&&&log&=&git.commits('master',&15)
&&&&&&&&&&log.size
现在的暂存区域已经准备妥当可以提交了。在此之前,请一定要确认还有什么修改过的或新建的文件还没有&git&add&过,否则提交的时候不会记录这些还没暂存起来的变化。所以,每次准备提交前,先用git&status&看下,是不是都已暂存起来了,然后再运行提交命令&git&commit:
$&git&commit
这种方式会启动文本编辑器以便输入本次提交的说明。(默认会启用&shell&的环境变量&$EDITOR&所指定的软件,一般都是&vim&或&emacs。当然也可以按照第一章介绍的方式,使用git&config&--global&core.editor&命令设定你喜欢的编辑软件。)
编辑器会显示类&#20284;下面的文本信息(本例选用&Vim&的屏显方式展示):
#&Please&enter&the&commit&message&for&your&changes.&Lines&starting
#&with&'#'&will&be&ignored,&and&an&empty&message&aborts&the&commit.
#&On&branch&master
#&Changes&to&be&committed:
#&&&(use&&git&reset&HEAD&...&&to&unstage)
#&&&&&&&new&file:&&&README
#&&&&&&&modified:&&&benchmarks.rb
&.git/COMMIT_EDITMSG&&10L,&283C
可以看到,默认的提交消息包含最后一次运行&git&status&的输出,放在注释行里,另外开头还有一空行,供你输入提交说明。你完全可以去掉这些注释行,不过留着也没关系,多少能帮你回想起这次更新的内容有哪些。(如果觉得这还不够,可以用-v&选项将修改差异的每一行都包含到注释中来。)退出编辑器时,Git&会丢掉注释行,将说明内容和本次更新提交到仓库。
另外也可以用&-m&参数后跟提交说明的方式,在一行命令中提交更新:
$&git&commit&-m&&Story&182:&Fix&benchmarks&for&speed&
[master]:&created&463dc4f:&&Fix&benchmarks&for&speed&
&2&files&changed,&3&insertions(&#43;),&0&deletions(-)
&create&mode&100644&README
好,现在你已经创建了第一个提交!可以看到,提交后它会告诉你,当前是在哪个分支(master)提交的,本次提交的完整&SHA-1&校验和是什么(463dc4f),以及在本次提交中,有多少文件修订过,多少行添改和删改过。
记住,提交时记录的是放在暂存区域的快照,任何还未暂存的仍然保持已修改状态,可以在下次提交时纳入版本管理。每一次运行提交操作,都是对你项目作一次快照,以后可以回到这个状态,或者进行比较。
跳过使用暂存区域
尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做略显繁琐。Git&提供了一个跳过使用暂存区域的方式,只要在提交的时候,给&git&commit&加上-a&选项,Git&就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过&git&add&步骤:
$&git&status
#&On&branch&master
#&Changed&but&not&updated:
# modified:&&&benchmarks.rb
$&git&commit&-a&-m&'added&new&benchmarks'
[master&83e38c7]&added&new&benchmarks
&1&files&changed,&5&insertions(&#43;),&0&deletions(-)
看到了吗?提交之前不再需要&git&add&文件&benchmarks.rb&了。
要从&Git&中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。可以用&git&rm&命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。
如果只是简单地从工作目录中手工删除文件,运行&git&status&时就会在&“Changed&but&not&updated”&部分(也就是_未暂存_清单)看到:
$&rm&grit.gemspec
$&git&status
#&On&branch&master
#&Changed&but&not&updated:
#&&&(use&&git&add/rm&...&&to&update&what&will&be&committed)
#&&&&&&&deleted:&&&&grit.gemspec
然后再运行&git&rm&记录此次移除文件的操作:
$&git&rm&grit.gemspec
rm&'grit.gemspec'
$&git&status
#&On&branch&master
#&Changes&to&be&committed:
#&&&(use&&git&reset&HEAD&...&&to&unstage)
#&&&&&&&deleted:&&&&grit.gemspec
最后提交的时候,该文件就不再纳入版本管理了。如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项&-f(译注:即&force&的首字母),以防误删除文件后丢失修改的内容。
另外一种情况是,我们想把文件从&Git&仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。换句话说,仅是从跟踪清单中删除。比如一些大型日志文件或者一堆.a&编译文件,不小心纳入仓库后,要移除跟踪但不删除文件,以便稍后在&.gitignore&文件中补上,用&--cached&选项即可:
$&git&rm&--cached&readme.txt
后面可以列出文件或者目录的名字,也可以使用&glob&模式。比方说:
$&git&rm&log/\*.log
注意到星号&*&之前的反斜杠&\,&因为&Git&有它自己的文件模式扩展匹配方式,所以我们不用&shell&来帮忙展开(译注:实际上不加反斜杠也可以运行,只不过按照&shell&扩展的话,仅仅删除指定目录下的文件而不会递归匹配。上面的例子本来就指定了目录,所以效果等同,但下面的例子就会用递归方式匹配,所以必须加反斜&杠。)。此命令删除所有log/&目录下扩展名为&.log&的文件。类&#20284;的比如:
$&git&rm&\*~
会递归删除当前目录及其子目录中所有&~&结尾的文件。
不像其他的&VCS&系统,Git&并不跟踪文件移动操作。如果在&Git&中重命名了某个文件,仓库中存储的元数据并不会体现出这是一次改名操作。不过&Git&非常聪明,它会推断出究竟发生了什么,至于具体是如何做到的,我们稍后再谈。
既然如此,当你看到&Git&的&mv&命令时一定会困惑不已。要在&Git&中对文件改名,可以这么做:
$&git&mv&file_from&file_to
它会恰如预期般正常工作。实际上,即便此时查看状态信息,也会明白无误地看到关于重命名操作的说明:
$&git&mv&README.txt&README
$&git&status
#&On&branch&master
#&Your&branch&is&ahead&of&'origin/master'&by&1&commit.
#&Changes&to&be&committed:
#&&&(use&&git&reset&HEAD&...&&to&unstage)
#&&&&&&&renamed:&&&&README.txt&-&&README
其实,运行&git&mv&就相当于运行了下面三条命令:
$&mv&README.txt&README
$&git&rm&README.txt
$&git&add&README
如此分开操作,Git&也会意识到这是一次改名,所以不管何种方式都一样。当然,直接用&git&mv&轻便得多,不过有时候用其他工具批处理改名的话,要记得在提交前删除老的文件名,再添加新的文件名。
2.3&&查看提交历史
在提交了若干更新之后,又或者克隆了某个项目,想回顾下提交历史,可以使用&git&log&命令查看。
接下来的例子会用我专门用于演示的&simplegit&项目,运行下面的命令获取该项目源代码:
git&clone&git://github.com/schacon/simplegit-progit.git
然后在此项目中运行&git&log,应该会看到下面的输出:
commit&ca82a6dff817ec66f90a
Author:&Scott&Chacon&
Date:&&&Mon&Mar&17&21:52:11&
&&&&changed&the&version&number
commit&085bb3bcb608e1e2f8ecbe
Author:&Scott&Chacon&
Date:&&&Sat&Mar&15&16:40:33&
&&&&removed&unnecessary&test&code
commit&a11bef06a3f63abf99ad00de2209e6
Author:&Scott&Chacon&
Date:&&&Sat&Mar&15&10:31:28&
&&&&first&commit
默认不用任何参数的话,git&log&会按提交时间列出所有的更新,最近的更新排在最上面。看到了吗,每次更新都有一个&SHA-1&校验和、作者的名字和电子邮件地址、提交时间,最后缩进一个段落显示提交说明。
git&log&有许多选项可以帮助你搜寻感兴趣的提交,接下来我们介绍些最常用的。
我们常用&-p&选项展开显示每次提交的内容差异,用&-2&则仅显示最近的两次更新:
$&git&log&-p&-2
commit&ca82a6dff817ec66f90a
Author:&Scott&Chacon&
Date:&&&Mon&Mar&17&21:52:11&
&&&&changed&the&version&number
diff&--git&a/Rakefile&b/Rakefile
index&a874b73..8f
---&a/Rakefile
&#43;&#43;&#43;&b/Rakefile
@@&-5,7&&#43;5,7&@@&require&'rake/gempackagetask'
&spec&=&Gem::Specification.new&do&|s|
-&&&&s.version&&&=&&&&0.1.0&
&#43;&&&&s.version&&&=&&&&0.1.1&
&&&&&s.author&&&&=&&&&Scott&Chacon&
commit&085bb3bcb608e1e2f8ecbe
Author:&Scott&Chacon&
Date:&&&Sat&Mar&15&16:40:33&
&&&&removed&unnecessary&test&code
diff&--git&a/lib/simplegit.rb&b/lib/simplegit.rb
index&a0a60ae..47c
---&a/lib/simplegit.rb
&#43;&#43;&#43;&b/lib/simplegit.rb
@@&-18,8&&#43;18,3&@@&class&SimpleGit
-if&$0&==&__FILE__
-&&git&=&SimpleGit.new
-&&puts&git.show
\&No&newline&at&end&of&file
在做代码审查,或者要快速浏览其他协作者提交的更新都作了哪些改动时,就可以用这个选项。此外,还有许多摘要选项可以用,比如&--stat,仅显示简要的增改行数统计:
$&git&log&--stat&
commit&ca82a6dff817ec66f90a
Author:&Scott&Chacon&
Date:&&&Mon&Mar&17&21:52:11&
&&&&changed&the&version&number
&Rakefile&|&&&&2&&#43;-
&1&files&changed,&1&insertions(&#43;),&1&deletions(-)
commit&085bb3bcb608e1e2f8ecbe
Author:&Scott&Chacon&
Date:&&&Sat&Mar&15&16:40:33&
&&&&removed&unnecessary&test&code
&lib/simplegit.rb&|&&&&5&-----
&1&files&changed,&0&insertions(&#43;),&5&deletions(-)
commit&a11bef06a3f63abf99ad00de2209e6
Author:&Scott&Chacon&
Date:&&&Sat&Mar&15&10:31:28&
&&&&first&commit
&README&&&&&&&&&&&|&&&&6&&#43;&#43;&#43;&#43;&#43;&#43;
&Rakefile&&&&&&&&&|&&&23&&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;
&lib/simplegit.rb&|&&&25&&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;
&3&files&changed,&54&insertions(&#43;),&0&deletions(-)
每个提交都列出了修改过的文件,以及其中添加和移除的行数,并在最后列出所有增减行数小计。还有个常用的&--pretty&选项,可以指定使用完全不同于默认&#26684;式的方式展示提交历史。比如用oneline&将每个提交放在一行显示,这在提交数很大时非常有用。另外还有&short,full&和fuller&可以用,展示的信息或多或少有些不同,请自己动手实践一下看看效果如何。
$&git&log&--pretty=oneline
ca82a6dff817ec66f90a&changed&the&version&number
085bb3bcb608e1e2f8ecbe&removed&unnecessary&test&code
a11bef06a3f63abf99ad00de2209e6&first&commit
但最有意思的是&format,可以定制要显示的记录&#26684;式,这样的输出便于后期编程提取分析,像这样:
$&git&log&--pretty=format:&%h&-&%an,&%ar&:&%s&
ca82a6d&-&Scott&Chacon,&11&months&ago&:&changed&the&version&number
085bb3b&-&Scott&Chacon,&11&months&ago&:&removed&unnecessary&test&code
a11bef0&-&Scott&Chacon,&11&months&ago&:&first&commit
表&2-1&列出了常用的&#26684;式占位符写法及其代表的意义。
选项 &说明
%H 提交对象(commit)的完整哈希字串
%h 提交对象的简短哈希字串
%T 树对象(tree)的完整哈希字串
%t 树对象的简短哈希字串
%P 父对象(parent)的完整哈希字串
%p 父对象的简短哈希字串
%an 作者(author)的名字
%ae 作者的电子邮件地址
%ad 作者修订日期(可以用&-date=&选项定制&#26684;式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者(committer)的名字
%ce 提交者的电子邮件地址
%cd 提交日期
%cr 提交日期,按多久以前的方式显示
%s 提交说明
你一定奇怪_作者(author)_和_提交者(committer)_之间究竟有何差别,其实作者指&的是实际作出修改的人,提交者指的是最后将此&工作成果提交到仓库的人。所以,当你为某个项目发布补丁,然后某个核心成员将你的补丁并入项目时,你就是作者,而那个核心成员就是提交者。我们会在第五章&再详细介绍两者之间的细微差别。
用&oneline&或&format&时结合&--graph&选项,可以看到开头多出一些&ASCII&字符串表示的简单图形,形象地展示了每个提交所在的分支及其分化衍合情况。在我们之前提到的&Grit&项目仓库中可以看到:
$&git&log&--pretty=format:&%h&%s&&--graph
*&2d3acf9&ignore&errors&from&SIGCHLD&on&trap
*&&5e3ee11&Merge&branch&'master'&of&git://github.com/dustin/grit
|&*&420eac9&Added&a&method&for&getting&the&current&branch.
*&|&30e367c&timeout&code&and&tests
*&|&5a09431&add&timeout&protection&to&grit
*&|&e1193f8&support&for&heads&with&slashes&in&them
*&d6016bc&require&time&for&xmlschema
*&&11d191e&Merge&branch&'defunkt'&into&local
以上只是简单介绍了一些&git&log&命令支持的选项。表&2-2&还列出了一些其他常用的选项及其释义。
-p&按补丁&#26684;式显示每个更新之间的差异。
--stat&显示每次更新的文件修改统计信息。
--shortstat&只显示&--stat&中最后的行数修改添加移除统计。
--name-only&仅在提交信息后显示已修改的文件清单。
--name-status&显示新增、修改、删除的文件清单。
--abbrev-commit&仅显示&SHA-1&的前几个字符,而非所有的&40&个字符。
--relative-date&使用较短的相对时间显示(比如,“2&weeks&ago”)。
--graph&显示&ASCII&图形表示的分支合并历史。
--pretty&使用其他&#26684;式显示历史提交信息。可用的选项包括&oneline,short,full,fuller&和&format(后跟指定&#26684;式)。
限制输出长度
除了定制输出&#26684;式的选项之外,git&log&还有许多非常实用的限制输出长度的选项,也就是只输出部分提交信息。之前我们已经看到过&-2&了,它只显示最近的两条提交,实际上,这是&-&选项的写法,其中的&n&可以是任何自然数,表示仅显示最近的若干条提交。不过实践中我们是不太用这个选项的,Git&在输出所有提交时会自动调用分页程序(less),要看更早的更新只需翻到下页即可。
另外还有按照时间作限制的选项,比如&--since&和&--until。下面的命令列出所有最近两周内的提交:
$&git&log&--since=2.weeks
你可以给出各种时间&#26684;式,比如说具体的某一天(“”),或者是多久以前(“2&years&1&day&3&minutes&ago”)。
还可以给出若干搜索条件,列出符合的提交。用&--author&选项显示指定作者的提交,用&--grep&选项搜索提交说明中的关键字。(请注意,如果要得到同时满足这两个选项搜索条件的提交,就必须用--all-match&选项。)
如果只关心某些文件或者目录的历史提交,可以在&git&log&选项的最后指定它们的路径。因为是放在最后位置上的选项,所以用两个短划线(--)隔开之前的选项和后面限定的路径名。
表&2-3&还列出了其他常用的类&#20284;选项。
-(n) 仅显示最近的&n&条提交
--since,&--after&仅显示指定时间之后的提交。
--until,&--before&仅显示指定时间之前的提交。
--author&仅显示指定作者相关的提交。
--committer&仅显示指定提交者相关的提交。
来看一个实际的例子,如果要查看&Git&仓库中,2008&年&10&月期间,Junio&Hamano&提交的但未合并的测试脚本(位于项目的&t/&目录下的文件),可以用下面的查询命令:
$&git&log&--pretty=&%h&-&%s&&--author=gitster&--since=&&&\
&&&--before=&&&--no-merges&--&t/
5610e3b&-&Fix&testcase&failure&when&extended&attribute
acd3b9e&-&Enhance&hold_lock_file_for_{update,append}()
f563754&-&demonstrate&breakage&of&detached&checkout&wi
d1a43f2&-&reset&--hard/read-tree&--reset&-u:&remove&un
51a94af&-&Fix&&checkout&--track&-b&newbranch&&on&detac
b0ad11e&-&pull:&allow&&git&pull&origin&$something:$cur
Git&项目有&20,000&多条提交,但我们给出搜索选项后,仅列出了其中满足条件的&6&条。
使用图形化工具查阅提交历史
有时候图形化工具更容易展示历史提交的变化,随&Git&一同发布的&gitk&就是这样一种工具。它是用&Tcl/Tk&写成的,基本上相当于&git&log&命令的可视化版本,凡是git&log&可以用的选项也都能用在&gitk&上。在项目工作目录中输入&gitk&命令后,就会启动图&2-2&所示的界面。
图&的图形界面&
上半个窗口显示的是历次提交的分支祖先图谱,下半个窗口显示当前点选的提交对应的具体差异。
2.4&&撤消操作
任何时候,你都有可能需要撤消刚才所做的某些操作。接下来,我们会介绍一些基本的撤消操作相关的命令。请注意,有些操作并不总是可以撤消的,所以请务必谨慎小心,一旦失误,就有可能丢失部分工作成果。
修改最后一次提交
有时候我们提交完了才发现漏掉了几个文件没有加,或者提交信息写错了。想要撤消刚才的提交操作,可以使用&--amend&选项重新提交:
$&git&commit&--amend
此命令将使用当前的暂存区域快照提交。如果刚才提交完没有作任何改动,直接运行此命令的话,相当于有机会重新编辑提交说明,但将要提交的文件快照和之前的一样。
启动文本编辑器后,会看到上次提交时的说明,编辑它确认没问题后保存退出,就会使用新的提交说明覆盖刚才失误的提交。
如果刚才提交时忘了暂存某些修改,可以先补上暂存操作,然后再运行&--amend&提交:
$&git&commit&-m&'initial&commit'
$&git&add&forgotten_file
$&git&commit&--amend
上面的三条命令最终只是产生一个提交,第二个提交命令修正了第一个的提交内容。
取消已经暂存的文件
接下来的两个小节将演示如何取消暂存区域中的文件,以及如何取消工作目录中已修改的文件。不用担心,查看文件状态的时候就提示了该如何撤消,所以不需要死记硬背。来看下面的例子,有两个修改过的文件,我们想要分开提交,但不小心用git&add&.&全加到了暂存区域。该如何撤消暂存其中的一个文件呢?其实,git&status&的命令输出已经告诉了我们该怎么做:
$&git&add&.
$&git&status
#&On&branch&master
#&Changes&to&be&committed:
#&&&(use&&git&reset&HEAD&...&&to&unstage)
#&&&&&&&modified:&&&README.txt
#&&&&&&&modified:&&&benchmarks.rb
就在&“Changes&to&be&committed”&下面,括号中有提示,可以使用&git&reset&HEAD&...&的方式取消暂存。好吧,我们来试试取消暂存&benchmarks.rb&文件:
$&git&reset&HEAD&benchmarks.rb
benchmarks.rb:&locally&modified
$&git&status
#&On&branch&master
#&Changes&to&be&committed:
#&&&(use&&git&reset&HEAD&...&&to&unstage)
#&&&&&&&modified:&&&README.txt
#&Changed&but&not&updated:
#&&&(use&&git&add&...&&to&update&what&will&be&committed)
#&&&(use&&git&checkout&--&...&&to&discard&changes&in&working&directory)
#&&&&&&&modified:&&&benchmarks.rb
这条命令看起来有些古怪,先别管,能用就行。现在&benchmarks.rb&文件又回到了之前已修改未暂存的状态。
取消对文件的修改
如果觉得刚才对&benchmarks.rb&的修改完全没有必要,该如何取消修改,回到之前的状态(也就是修改之前的版本)呢?git&status&同样提示了具体的撤消方法,接着上面的例子,现在未暂存区域看起来像这样:
#&Changed&but&not&updated:
#&&&(use&&git&add&...&&to&update&what&will&be&committed)
#&&&(use&&git&checkout&--&...&&to&discard&changes&in&working&directory)
#&&&&&&&modified:&&&benchmarks.rb
在第二个括号中,我们看到了抛弃文件修改的命令(至少在&Git&1.6.1&以及更高版本中会这样提示,如果你还在用老版本,我们强烈建议你升级,以获取最佳的用户体验),让我们试试看:
$&git&checkout&--&benchmarks.rb
$&git&status
#&On&branch&master
#&Changes&to&be&committed:
#&&&(use&&git&reset&HEAD&...&&to&unstage)
#&&&&&&&modified:&&&README.txt
可以看到,该文件已经恢复到修改前的版本。你可能已经意识到了,这条命令有些危险,所有对文件的修改&都没有了,因为我们刚刚把之前版本的文件复制过&来重写了此文件。所以在用这条命令前,请务必确定真的不再需要保留刚才的修改。如果只是想回退版本,同时保留刚才的修改以便将来继续工作,可以用下章介绍&的&stashing&和分支来处理,应该会更好些。
记住,任何已经提交到&Git&的都可以被恢复。即便在已经删除的分支中的提交,或者用&--amend&重新改写的提交,都可以被恢复(关于数据恢复的内容见第九章)。所以,你可能失去的数据,仅限于没有提交过的,对&Git&来说它们就像从未存在过一样。
2.5&&远程仓库的使用
要参与任何一个&Git&项目的协作,必须要了解该如何管理远程仓库。远程仓库是指托管在网络上的项目仓库,可能会有好多个,其中有些你只能读,另外有些可以写。同他人协作开发某&个项目时,需要管理这些远程仓库,以便推送或拉取数据,分享各自的工作进展。管理远程仓库的工作,包括添加远程库,移除废弃的远程库,管理各式远程库分&支,定义是否跟踪这些分支,等等。本节我们将详细讨论远程库的管理和使用。
查看当前的远程库
要查看当前配置有哪些远程仓库,可以用&git&remote&命令,它会列出每个远程库的简短名字。在克隆完某个项目后,至少可以看到一个名为&origin&的远程库,Git&默认使用这个名字来标识你所克隆的原始仓库:
$&git&clone&git://github.com/schacon/ticgit.git
Initialized&empty&Git&repository&in&/private/tmp/ticgit/.git/
remote:&Counting&objects:&595,&done.
remote:&Compressing&objects:&100%&(269/269),&done.
remote:&Total&595&(delta&255),&reused&589&(delta&253)
Receiving&objects:&100%&(595/595),&73.31&KiB&|&1&KiB/s,&done.
Resolving&deltas:&100%&(255/255),&done.
$&cd&ticgit
$&git&remote
也可以加上&-v&选项(译注:此为&--verbose&的简写,取首字母),显示对应的克隆地址:
$&git&remote&-v
origin git://github.com/schacon/ticgit.git
如果有多个远程仓库,此命令将全部列出。比如在我的&Grit&项目中,可以看到:
$&git&remote&-v
bakkdoor&&git://github.com/bakkdoor/grit.git
cho45&&&&&git://github.com/cho45/grit.git
defunkt&&&git://github.com/defunkt/grit.git
koke&&&&&&git://github.com/koke/grit.git
origin&&&&:mojombo/grit.git
这样一来,我就可以非常轻松地从这些用户的仓库中,拉取他们的提交到本地。请注意,上面列出的地址只有&origin&用的是&SSH&URL&链接,所以也只有这个仓库我能推送数据上去(我们会在第四章解释原因)。
添加远程仓库
要添加一个新的远程仓库,可以指定一个简单的名字,以便将来引用,运行&git&remote&add&[shortname]&[url]:
$&git&remote
$&git&remote&add&pb&git://github.com/paulboone/ticgit.git
$&git&remote&-v
origin git://github.com/schacon/ticgit.git
pb git://github.com/paulboone/ticgit.git
现在可以用字串&pb&指代对应的仓库地址了。比如说,要抓取所有&Paul&有的,但本地仓库没有的信息,可以运行&git&fetch&pb:
$&git&fetch&pb
remote:&Counting&objects:&58,&done.
remote:&Compressing&objects:&100%&(41/41),&done.
remote:&Total&44&(delta&24),&reused&1&(delta&0)
Unpacking&objects:&100%&(44/44),&done.
From&git://github.com/paulboone/ticgit
&*&[new&branch]&&&&&&master&&&&&-&&pb/master
&*&[new&branch]&&&&&&ticgit&&&&&-&&pb/ticgit
现在,Paul&的主干分支(master)已经完全可以在本地访问了,对应的名字是&pb/master,你可以将它合并到自己的某个分支,或者切换到这个分支,看看有些什么有趣的更新。
从远程仓库抓取数据
正如之前所看到的,可以用下面的命令从远程仓库抓取数据到本地:
$&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&仓库,可以运行:
$&git&remote&show&origin
*&remote&origin
&&URL:&git://github.com/schacon/ticgit.git
&&Remote&branch&merged&with&'git&pull'&while&on&branch&master
&&&&master
&&Tracked&remote&branches
&&&&master
&&&&ticgit
除了对应的克隆地址外,它还给出了许多额外的信息。它友善地告诉你如果是在&master&分支,就可以用&git&pull&命令抓取数据合并到本地。另外还列出了所有处于跟踪状态中的远端分支。
上面的例子非常简单,而随着使用&Git&的深入,git&remote&show&给出的信息可能会像这样:
$&git&remote&show&origin
*&remote&origin
&&URL:&: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
&&&&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&命令修改某个远程仓库在本地的简短名称,比如想把&pb&改成paul,可以这么运行:
$&git&remote&rename&pb&paul
$&git&remote
注意,对远程仓库的重命名,也会使对应的分支名称发生变化,原来的&pb/master&分支现在成了&paul/master。
碰到远端仓库服务器迁移,或者原来的克隆镜像不再使用,又或者某个参与者不再贡献代码,那么需要移除对应的远端仓库,可以运行&git&remote&rm&命令:
$&git&remote&rm&paul
$&git&remote
2.6&&打标签
同大多数&VCS&一样,Git&也可以对某一时间点上的版本打上标签。人们在发布某个软件版本(比如&v1.0&等等)的时候,经常这么做。本节我们一起来学习如何列出所有可用的标签,如何新建标签,以及各种不同类型标签之间的差别。
列显已有的标签
列出现有标签的命令非常简单,直接运行&git&tag&即可:
显示的标签按字母顺序排列,所以标签的先后并不表示重要程度的轻重。
我们可以用特定的搜索模式列出符合条件的标签。在&Git&自身项目仓库中,有着超过&240&个标签,如果你只对&1.4.2&系列的版本感兴趣,可以运行下面的命令:
$&git&tag&-l&'v1.4.2.*'
Git&使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。轻量级标签就像是个不会变化的分支,实际上它就是个指向特&定提交对象的引用。而含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标&签本身也允许使用&GNU&Privacy&Guard&(GPG)&来签署或验证。一般我们都建议使用含附注型的标签,以便保留相关信息;当然,如果只是临时性加注标签,或者不需要旁注额外信息,用轻量级标签也没问题。
含附注的标签
创建一个含附注类型的标签非常简单,用&-a&(译注:取&annotated&的首字母)指定标签名字即可:
$&git&tag&-a&v1.4&-m&'my&version&1.4'
而&-m&选项则指定了对应的标签说明,Git&会将此说明一同保存在标签对象中。如果没有给出该选项,Git&会启动文本编辑软件供你输入标签说明。
可以使用&git&show&命令查看相应标签的版本信息,并连同显示打标签时的提交对象。
$&git&show&v1.4
Tagger:&Scott&Chacon&
Date:&&&Mon&Feb&9&14:45:11&
my&version&1.4
commit&b64cf874c7bd83b3ff6
Merge:&4a447f7...&a6b4c97...
Author:&Scott&Chacon&
Date:&&&Sun&Feb&8&19:02:46&
&&&&Merge&branch&'experiment'
我们可以看到在提交对象信息上面,列出了此标签的提交者和提交时间,以及相应的标签说明。
如果你有自己的私钥,还可以用&GPG&来签署标签,只需要把之前的&-a&改为&-s&(译注:&取&signed&的首字母)即可:
$&git&tag&-s&v1.5&-m&'my&signed&1.5&tag'
You&need&a&passphrase&to&unlock&the&secret&key&for
user:&&Scott&Chacon&&
1024-bit&DSA&key,&ID&F721C45A,&created&
现在再运行&git&show&会看到对应的&GPG&签名也附在其内:
$&git&show&v1.5
Tagger:&Scott&Chacon&
Date:&&&Mon&Feb&9&15:22:20&
my&signed&1.5&tag
-----BEGIN&PGP&SIGNATURE-----
Version:&GnuPG&v1.4.8&(Darwin)
iEYEABECAAYFAkmQurIACgkQON3DxfchxFr5cACeIMN&#43;ZxLKggJQf0QYiQBwgySN
Ki0An2JeAVUCAiJ7Ox6ZEtK&#43;NvZAj82/
-----END&PGP&SIGNATURE-----
commit&b64cf874c7bd83b3ff6
Merge:&4a447f7...&a6b4c97...
Author:&Scott&Chacon&
Date:&&&Sun&Feb&8&19:02:46&
&&&&Merge&branch&'experiment'
稍后我们再学习如何验证已经签署的标签。
轻量级标签
轻量级标签实际上就是一个保存着对应提交对象的校验和信息的文件。要创建这样的标签,一个&-a,-s&或&-m&选项都不用,直接给出标签名字即可:
$&git&tag&v1.4-lw
现在运行&git&show&查看此标签信息,就只有相应的提交对象摘要:
$&git&show&v1.4-lw
commit&b64cf874c7bd83b3ff6
Merge:&4a447f7...&a6b4c97...
Author:&Scott&Chacon&
Date:&&&Sun&Feb&8&19:02:46&
&&&&Merge&branch&'experiment'
可以使用&git&tag&-v&[tag-name]&(译注:取&verify&的首字母)的方式验证已经签署的标签。此命令会调用&GPG&来验证签名,所以你需要有签署者的公钥,存放在&keyring&中,才能验证:
$&git&tag&-v&v1.4.2.1
object&883653babd8ee7ea23e6a5c392bbeb61
type&commit
tag&v1.4.2.1
tagger&Junio&C&Hamano&&&-0700
GIT&1.4.2.1
Minor&fixes&since&1.4.2,&including&git-mv&and&git-http&with&alternates.
gpg:&Signature&made&Wed&Sep&13&02:08:25&2006&PDT&using&DSA&key&ID&F3119B9A
gpg:&Good&signature&from&&Junio&C&Hamano&&
gpg:&&&&&&&&&&&&&&&&&aka&&[jpeg&image&of&size&1513]&
Primary&key&fingerprint:&&&C9A7&&4A7D&C0C6&D9A4&F311&9B9A
若是没有签署者的公钥,会报告类&#20284;下面这样的错误:
gpg:&Signature&made&Wed&Sep&13&02:08:25&2006&PDT&using&DSA&key&ID&F3119B9A
gpg:&Can't&check&signature:&public&key&not&found
error:&could&not&verify&the&tag&'v1.4.2.1'
后期加注标签
你甚至可以在后期对早先的某次提交加注标签。比如在下面展示的提交历史中:
$&git&log&--pretty=oneline
b64cf874c7bd83b3ff6&Merge&branch&'experiment'
a6b4c9096da251c98a07c7723e65&beginning&write&support
0d52aaab86c15f77a3d64d9165190&one&more&thing
6d52a271edadd79daabbc4d9b6008e&Merge&branch&'experiment'
0bcc7b8c3d5e1dddfed66ff742fcbc&added&a&commit&function
305bdd616e23b64bb&added&a&todo&file
166ae0c4d3f420721acbb115cc33848dfcc2121a&started&write&support
9fceb02d0ae598e95dc970bd61af8&updated&rakefile
964f16d36dfccde844893cac5b347e7b3d44abbc&commit&the&todo
8a5cbc430f1a9c3d00faaeffd08a&updated&readme
我们忘了在提交&“updated&rakefile”&后为此项目打上版本号&v1.2,没关系,现在也能做。只要在打标签的时候跟上对应提交对象的校验和(或前几位字符)即可:
$&git&tag&-a&v1.2&9fceb02
可以看到我们已经补上了标签:
$&git&show&v1.2
Tagger:&Scott&Chacon&
Date:&&&Mon&Feb&9&15:32:16&
version&1.2
commit&9fceb02d0ae598e95dc970bd61af8
Author:&Magnus&Chacon&
Date:&&&Sun&Apr&27&20:43:35&
&&&&updated&rakefile
默认情况下,git&push&并不会把标签传送到远端服务器上,只有通过显式命令才能分享标签到远端仓库。其命令&#26684;式如同推送分支,运行git&push&origin&[tagname]&即可:
$&git&push&origin&v1.5
Counting&objects:&50,&done.
Compressing&objects:&100%&(38/38),&done.
Writing&objects:&100%&(44/44),&4.56&KiB,&done.
Total&44&(delta&18),&reused&8&(delta&1)
To&:schacon/simplegit.git
*&[new&tag]&&&&&&&&&v1.5&-&&v1.5
如果要一次推送所有本地新增的标签上去,可以使用&--tags&选项:
$&git&push&origin&--tags
Counting&objects:&50,&done.
Compressing&objects:&100%&(38/38),&done.
Writing&objects:&100%&(44/44),&4.56&KiB,&done.
Total&44&(delta&18),&reused&8&(delta&1)
To&:schacon/simplegit.git
&*&[new&tag]&&&&&&&&&v0.1&-&&v0.1
&*&[new&tag]&&&&&&&&&v1.2&-&&v1.2
&*&[new&tag]&&&&&&&&&v1.4&-&&v1.4
&*&[new&tag]&&&&&&&&&v1.4-lw&-&&v1.4-lw
&*&[new&tag]&&&&&&&&&v1.5&-&&v1.5
现在,其他人克隆共享仓库或拉取数据同步后,也会看到这些标签。
2.7&&技巧和窍门
在结束本章之前,我还想和大家分享一些&Git&使用的技巧和窍门。很多使用&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&命令的时候可以敲两次跳&#26684;键(Tab),就会看到列出所有匹配的可用命令建议:
$&git&co&commit&config
此例中,键入&git&co&然后连按两次&Tab&键,会看到两个相关的建议(命令)&commit&和&config。继而输入&m&会自动完成git&commit&命令的输入。
命令的选项也可以用这种方式自动完成,其实这种情况更实用些。比如运行&git&log&的时候忘了相关选项的名字,可以输入开头的几个字母,然后敲&Tab&键看看有哪些匹配的:
$&git&log&--s&--shortstat&&--since=&&--src-prefix=&&--stat&&&--summary
这个技巧不错吧,可以节省很多输入和查阅文档的时间。
Git&命令别名
Git&并不会推断你输入的几个字符将会是哪条命令,不过如果想偷懒,少敲几个命令的字符,可以用&git&config&为命令设置别名。来看看下面的例子:
$&git&config&--global&alias.co&checkout
$&git&config&--global&alias.br&branch
$&git&config&--global&alias.ci&commit
$&git&config&--global&alias.st&status
现在,如果要输入&git&commit&只需键入&git&ci&即可。而随着&Git&使用的深入,会有很多经常要用到的命令,遇到这种情况,不妨建个别名提高效率。
使用这种技术还可以创造出新的命令,比方说取消暂存文件时的输入比较繁琐,可以自己设置一下:
$&git&config&--global&alias.unstage&'reset&HEAD&--'
这样一来,下面的两条命令完全等同:
$&git&unstage&fileA
$&git&reset&HEAD&fileA
显然,使用别名的方式看起来更清楚。另外,我们还经常设置&last&命令:
$&git&config&--global&alias.last&'log&-1&HEAD'
然后要看最后一次的提交信息,就变得简单多了:
$&git&last
commit&66938dae3329c7aebe598caf90d04646
Author:&Josh&Goebel&
Date:&&&Tue&Aug&26&19:48:51&2008&&#43;0800
&&&&test&for&current&head
&&&&Signed-off-by:&Scott&Chacon&
可以看出,实际上&Git&只是简单地在命令中替换了你设置的别名。不过有时候我们希望运行某个外部命令,而非&Git&的附属工具,这个好办,只需要在命令前加上&!&就行。如果你自己写了些处理&Git&仓库信息的脚本的话,就可以用这种技术包装起来。作为演示,我们可以设置用&git&visual&启动gitk:
$&git&config&--global&alias.visual&&!gitk&
到目前为止,你已经学会了最基本的&Git&操作:创建和克隆仓库,做出更新,暂存并提交这些更新,以及查看所有历史更新记录。接下来,我们将学习&Git&的必杀技特性:分支模型。
Git详解之三&Git分支&
&收藏该经验
几乎每一种版本控制系统都以某种形式支持分支。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。在很多版本控制系统中,这是个昂贵的过程,常常需要创建一个源代码目录的完整副本,对大型项目来说会花费很长时间。
有人把&Git&的分支模型称为“必

我要回帖

更多关于 rsasecureid安卓 的文章

 

随机推荐