- $ man git-log
分类: 嵌入式
2011-07-27 11:49:30
本文讲述了如何导入新项目到Git,如何修改项目以及如何将修改通知给其他开发者。
如果主要是想了解如何使用Git来取得一个项目,例如测试项目的最新版本,可以参考的前两章。
这里首先介绍下如何查阅Git文档,下面以命令git log --graph为例:
或者:
利用后者,可以查阅manual pages式的帮助,详情请参见。
在开始使用Git之前,最好设置使用者的名字和电子邮件以方便Git记录日志。设置方法如下:
假如项目文件为project.tar.gz,可以通过如下方法将其导入到Git。
Git会做出以下回应
至此,工作目录已经初始化完成,并且在当前位置创建了一个新目录.git。
接着,利用git add命令将当前目录下所有文件的快照通知Git:
当前目录所有文件的快照被存储在索引文件中。可以利用git commit命令把索引文件的内容永远存储到Git中:
这条命令会提示用户输入注释。至此,项目的第一个版本已经存储到Git中了。
修改一些文件,然后将修改添加到索引文件中:
现在可以提交了。在提交以前,可以通过如下命令检查即将提交的内容与原始内容的差异:
(如果不添加--cached选项, git diff将会显示所有没有添加到索引文件的修改)
也可以通过命令git status来获取当前Git状态:
如果还需要修改其他内容,那赶紧改吧。然后,就可以把所有的修改加到索引文件,并用下面的命令提交:
执行上面的命令,系统会提示输入注释,然后记录一个新版本到版本库。
如果不想在提交之前执行git add命令,可以使用:
这条命令可以自动检查所有修改(不包括新加文件),然后添加到索引文件中并提交。
注意:在提交修改时,最好在注释的开始写上一行简短的修改摘要(少于50个字符),接着一个空行,最后是关于修改的详细描述。Git会把修改注释转换成电子邮件,例如,把注释的第一行作为邮件的标题,其余部分作为邮件的内容。
很多版本控制系统都提供add命令,用于通知版本控制系统跟踪新添加文件的修改。Git的add命令用法更简单,功能更强:git add 不仅用于跟踪新添加文件,还可以用于跟踪最近修改内容的文件。在这两种情况下,Git都会记录修改,并修改索引文件,再下次提交的时候将修改写入版本库。
查看项目的修改历史日志
在任何时候,可以利用如下的命令查看修改历史日志
如果希望查看每一步的完整比较,使用:
更为常用的用法是利用下面的命令查看每一次修改的总结
一个简单的Git版本库可以支持多个分支的开发。使用如下命令创建名为“experimental”的分支:
如果现在执行下面的命令
系统将会列出目前所有的分支:
"experimental"是刚刚创建的分支,"master"是系统自动创建的默认分支。星号代表当前用户正在工作的分支。输入如下命令:
切换为“experimental“分支。然后编辑文件,提交,并返回“master”分支:
检查刚刚的修改在当前分支上并不存在,这是因为刚刚在“experimental”分支上修改,修改后切换回“master”分支。
针对同一文件,在"master"分支做不同的修改:
此时,两个分支出现不一致,不同的分支上有着不同的修改。为了把“experimental”分支上的修改合并到“master”分支,需要执行
如果修改没有冲突,那么合并就做完了。否则,用于表明冲突的标记会被添加到冲突的文件中。
git diff可以用来查看冲突。一旦你修改了文件,解决了冲突
将会提交合并的结果到版本库。最后
将会显示一个友好的图形界面来展示修改历史。
这时,可以执行下面的命令删除“experimental”分支
这个命令可以确保“experimental”分支的全部修改已经合并到当前的分支,否则删除将失败。
如果不想在“crazy-idea”分支上继续开发,可以执行如下命令删除分支
Git的分支操作如此的简单高效,所以,这是我们做试验的好方法。
假设Alice已经开始了一个新项目,项目的Git版本库位于/home/alice/project。Bob想要参与到项目中来,并且,Bob在同一台机器上也有home目录。
Bob开始执行如下命令:
这条命令创建了一个新目录"myrepo",它是Alice的Git版本库的克隆。这个克隆的版本库和原始的项目处于同等地位,一切在克隆版本库上的操作,都会记录在属于克隆版本库自己的项目日志文件中。
然后,Bob做了一些修改并提交到Git版本库
当修改完成后,Bob通知Alice把他的修改从位于同台机器/home/bob/myrepo目录下的Git版本库中合并到本地。Alice执行了下面的命令
这条指令将会把Bob在"master"分支做的修改合并到Alice当前的分支上。如果同时Alice也在修改,那么她需要手动的解决冲突。
"pull"命令实际上执行两个操作:从待合并的分支获取变更,然后把它们合并到当前分支。
注意:一般情况下,Alice希望在执行“pull”命令之前把她的本地修改提交到Git版本库。如果Bob的修改与Alice的修改存在冲突,Alice将要利用她的版本树和索引文件来解决冲突。这时候现有的本地修改将会干扰冲突的解决(Git将会执行获取,但是不会执行合并……Alice将不得不删掉本地的修改,然后重新执行"pull"命令)。
Alice可以在没有合并之前利用“fetch”命令来查看一下Bob的修改;为了决定到底是否需要利用“pull”命令获取Bob的修改,Alice可以使用特殊的符号"FETCH_HEAD"来查看Bob的修改:
即使Alice存在没有提交的本地修改,这条指令也不会影响本地的修改。范围"HEAD..FETCH_HEAD"的含义是:显示从FETCH_HEAD开始可以取得的修改,但是不包含从HEAD开始可以取得的修改。Alice已经知道使她处于当前状态的(HEAD)的所有修改,通过这个命令Alice可以查看Bob所处状态((FETCH_HEAD)的修改。
如果Alice想要以一种图形化的方式查看Bob的修改,她可以使用如下命令:
这种两个点表示范围的用法和我们刚才使用git log时的用法是一致的。
Alice或许想要查看他们两个人的修改。她可以使用三个点的形式:
三个点表示范围的含义是:显示从它们任意一个开始可以取得的修改,但是不包含从它们两个全都包含的修改。
注意:以三个点表示范围的用法既可以和“gitk”一起使用,也可以和"git log"一起使用。
在检查了Bob的修改以后,如果没有什么紧急的修改,Alice或许会继续本地的修改,而不会合并Bob的修改到本地。如果Bob的修改是Alice当前需要的,Alice可能会选择先备份她本地的修改,然后,取得Bob的修改到本地,最后恢复她的备份。
当你工作在一个小的工作组时,通常会不断操作同一版本库。可以通过定义远程版本库缩写使操作更简单:
定义了版本库缩写,Alice可以利用git fetch命令单独执行"pull"操作的第一部分,而不去执行合并操作:
和git fetch普通用法不一样的是,当Alice利用缩写来取得Bob的修改时,取得的修改是存储在远程跟踪分支(remote-tracking branch),上面的例子中存储在bob/master分支。因此,运行如下命令:
显示的是从Bob克隆Alice分支后所有修改的列表。
在检查过所有的修改后,Alice可能会合并所有的修改到本地的"master"分支:
也可以通过从远程跟踪分支(remote-tracking branch)上获取来完成合并,像下面这样:
注意:无论在命令行上添加任何参数,git pull总是合并修改到当前的分支。
稍后,Bob可以用下面的命令更新自己版本库:
注意:Bob不需要指定Alice版本库的路径。当Bob克隆Alice版本库的时候,Git将Alice版本库的位置保存在版本库的配置中,这个配置在执行git pull命令的时候使用:
(Git克隆所创建的全部配置可以通过命令git config -l查询,详情请参见)
Git还保存了Alice版本库master分支的原始拷贝,名字为"origin/master":
如果以后Bob希望在另一台机器上工作,他可以利用ssh协议来执行克隆,获取:
再者,Git还提供原生协议,也可以使用rsync协议或者http协议,详情参见。
Git也可以工作在一种类似于CVS的模式,在这种模式下,不同的用户推送修改到中心版本库,详情参见和。
Git历史日志被表示为一系列相关的提交。在前面的例子中,已经看到git log可以列出这些提交。值得注意的是,每条日志的第一行是提交的名字:
可以利用这个名字来查看每个提交的详细内容。
Git还支持其他的方法查看提交的详细内容。可以使用提交名字的一部分来标识提交:
每个提交一般都有一个父提交,父提交指向项目的前一个状态:
注意:合并提交可能有不止一个父提交:
可以通过下面的命令给提交命名:
可以通过自定义名字“v2.5"查看提交1b2e1d63ff。如果你希望和其他人共享这个自定义名字(例如:指定发行版本号), 你应该创建一个"tag"对象并签名,详情参见。
任何涉及提交内容的命令都可以使用自定义名字。例如:
请注意最后一个命令:除了丢失当前工作目录的所有修改, 当前分支之后的的提交也会被删除。如果那些提交仅仅存在于当前分支,那么它们会彻底丢失。再者,不要在公共可见的分支上使用git reset命令,因为它将强制其他开发者做没有必要的合并,从而导致其他开发者丢失修改。如果你需要回滚你的提交,可以使用git revert。
命令git grep可以用来在项目的任意版本中搜索字符串,因此
上述命令会在v2.5这个提交中搜索"hello"。
如果不指定提交名称,git grep将会搜索当前目录的所有文件。
上述命令是一种比较快捷的方法用来搜索所有Git跟踪的文件。
很多Git命令可以选取一组提交,而且有多种实现方法。下面以git log为例:
在使用git log的时候,可以指定一个范围,而且范围的起始点不必是终止点的祖先。例如,如果分支“stable"和分支"master"在一段时间以前就已经不一致了,那么
将会列出在“master”分支上的提交,而不会列出在“stable”分支上的提交,然而,
将会列出在“stable”分支上的提交,而不会列出在“master”分支上的提交。
命令git log有一个缺点:它必须把提交以列表的形式展现。当历史记录中包含一些分叉的开发,然后又被合并到一起,那么git log所展现的这些提交的顺序则失去了意义。
有很多参与者的项目(例如Linux kernel或者Git本身)都会频繁的做合并,gitk在这方面做的比较好,提供给用户以图形的界面。例如,
上述命令允许你浏览最近两个星期在“drivers”目录下的提交。(注意:可以通过按住Ctrl+或者Ctrl-来调整gitk的字体。)
最后,大多数以文件名作为参数的命令,允许你在文件名前指定版本号:
可以利用git show查看任意文件
本指南对于在项目中使用分布式版本管理应该是足够了。但是,如果想更全面的理解Git,你应该了解下面两个观念:
对象数据库是相当优雅的系统被用来存储项目历史(文件,目录和提交)。
索引文件是目录树状态的缓存,主要用在创建提交, 签出工作目录以及保持合并过程中涉及的各种文件。
本指南的第二部分介绍了对象数据库,索引文件和一些零碎的东西,这样你将了解了Git的绝大多数内容。第二部分参见.
如果你不想立刻学习第二部分,还有一些其他方面的或许你会感兴趣:
, : 这些将Git提交转换成电子邮件的插件,或者反向转换的插件,对于十分倚重电子邮件的项目十分有用,例如Linux kernel项目。
: 当项目出现退步,跟踪bug的一个方式是搜索Git历史日志找到使项目退步的提交。Git bisect可以帮助你执行二进制搜索找到指定的提交。即使针对一个包含很多合并分支,并且复杂的非线性历史记录,Git bisect也能够智能的执行接近于最优的搜索。
:推荐的工作流概述
: CVS用户迁移到Git