您的位置:首页 > 其它

git使用指南

2014-08-14 23:44 267 查看
转载请注明出处:http://www.codelast.com/

以下都是比较基础的操作,高手们请绕道,不必浪费时间来看了。

(A)SVN

(1)查看日志

提交的时候一般会写上注释,如果要查看提交日志,用以下命令:

其中,-l 4表示只查看最近4条日志(也可以没有这样的参数,就表示查看所有日志)。但是你通常会很抓狂地发现,最近的几条日志中,竟然没有你才刚刚提交的那一次的日志!这是怎么回事?日志丢了吗?

其实,是因为你要很用以下命令,更新本地的版本库,才能看到最近提交的日志:

这事如果你没注意到,那么可能会浪费你很多时间。问Google也不好找答案,因为这个问题不太好描述,所以不好搜索答案。

(2)查看指定的版本修改了哪些文件

其中,566是你指定的版本。

(3)查看某个文件在指定的版本修改了什么内容

其中,Test.java是你要检查的文件,566是你指定的版本,最后diff被输出到了codelast.diff文件中。

(4)提交

其中,Your comment 就是你填写的注释,如果你想换行写,也是可以的,只要你不写后面的那个引号,你可以写一行就回车一次,最后写完了,再加上后面的引号,然后再回车,就执行提交动作了。

(5)检出指定版本的版本库

其中,https://xxx 是你的版本库地址,566是你要检出的版本号。版本库将被检出到当前路径下。
文章来源:http://www.codelast.com/

(6)将指定version的trunk上的代码拷贝到tags的指定目录下

如上命令将trunk下的 my-project 项目的 1333 版本拷贝到了tags下的 my-project-r1333 中。

(7)将branches上的指定版本合并(merge)到trunk上

有时候我们会在一个分支(branches)上开发,等开发完成的时候,需要把我们已经提交到branches上的代码合并到trunk上,假设你本地的工作目录是在branches上(刚开发完branches上的一个版本,提交了代码),那么可以像下面这样做:

其中,第一条命令是将本地工作目录切换到trunk上。执行完这条命令后,你本地的工作目录里的文件就会变成与trunk里的文件一致。

第二条命令是将branches上的文件合并到本地。执行完这条命令行,你本地的工作目录里的文件就会变成与branches合并的结果。但是请注意,由于本地的工作目录已经是trunk了(用svn info可查看),所以这一更新,就导致本地有若干文件变成“已修改,但未提交”的状态。因此,你需要把本地因merge被修改过的文件提交一次,就可以使得trunk上的文件变成与branches合并后的版本:

文章来源:http://www.codelast.com/

关于svn merge的更详细说明,可参考此文档

(8)为文件添加上可执行权限

假设你有一个脚本文件checkin到代码库中了,但是你在commit之前,却忘了给它添加可执行权限,那么,当checkout出来这份代码时,就会得到一个没有x权限的脚本,还需要手工再为它添加上x权限,非常麻烦。所以,要为该文件添加上x权限:

然后再 svn ci 提交修改即可(尽管你没有修改文件内容,只是修改了文件的权限,也是会被标记为已修改的,需要将此修改提交到代码库中)。

(9)checkout单个文件到本地

如果用 svn checkout 单个文件的URL 来检出一个文件到本地的话,会得到如下的错误提示:

svn: E200007: URL 'https://xxx' refers to a file, not a directory

那么,如何checkout单个文件呢?答案是用svn export命令即可。

(10)Review Board提交svn的diff文件时,提示“The file 'https://svn.codelast.com/abc.txt' (r1030) could not be found in the repository”错误的解决办法

我遇到的这例错误,是因为我在一个项目中新添加了一个文件abc.txt,于是用 svn add abc.txt 添加它,然后 svn diff > today.diff 生成了项目的diff文件,然后把该diff文件提交到Review Board中,想要生成一个新的review,结果就遇到了上面的错误提示。

这个错误提示乍一看非常搞笑:因为abc.txt是新添加的文件,它当然不会在repository中存在啊!这不是废话么?

同时我注意到,当我执行 svn add abc.txt时,命令行提示:

A (bin) abc.txt

虽然abc.txt是一个纯文本文件,但是svn貌似把它认作了一个binary文件,于是我Google到了这个链接,按照里面的说法,我在 svn add abc.txt
之后进行了如下操作:

然后再生成项目的diff文件,再提交到Review Board上,问题搞定!

(B)Git

(1)提交修改到远程的git repository的基本流程(前提是你当前目录已经处于git版本控制之下)

添加当前目录下所有文件到“即将提交的列表”(当然也可以指定某些指定的文件,将 . 换成指定的文件即可):

将修改提交到本地:

提交到远程的git repository:

(2)删除远程git repository中的文件

假设要删除当前目录下的abc.txt文件(指远程git repository中的),则:

然后提交到本地:

然后提交到远程的repository:

文章来源:http://www.codelast.com/
(3)TortoiseGit提交代码前弹出错误提示“username and email must be set...”的解决办法

Git Commit(提交)的时候,如果Tortoise弹出一个错误对话框,提示你必须先设置用户名和Email,那么你理所当然地按它的指引点击“Yes”去设置,奇葩的是,在我的Win7上,TortoiseGit settings→Git页面中的“Name”和“Email”竟然无法输入文字(仿佛输入框是只读的一样)!就算我找到了这篇教程,也无济于事。

后来我又找到了这篇教程,尝试用命令行去设置,果然OK了:

执行这两条命令之后,再回到TortoiseGit的settings→Git页面,就看到Name和Email已经设置好了。

(4)解决每次 git pull 的时候都提示输入密码的烦人问题

执行以下命令:

其中,timeout值表示缓存密码多少时间(单位是毫秒还是秒,我不记得了),把它设置为一个非常大的值即可,然后你再git pull的时候,按提示输入密码之后,下一次就不会再提示输入密码了(在timeout时间之内)。
文章来源:http://www.codelast.com/
(5)Windows下的TortoiseGit每次push的时候都提示要输入密码的问题

可以通过修改TortoiseGit的配置来解决:

在设置界面中,“Git”设置子项中,点击“编辑本地.git/config”,会打开一个文本文件,在最后加上如下内容并保存:

然后再push一次并输入密码,TortoiseGit就可以记住你的密码啦。

1. GIT和SVN之间的五个基本区别

1)GIT是分布式的,SVN不是:

这是GIT和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别。如果你能理解这个概念,那么你就已经上手一半了。需要做一点声明,GIT并不是目前第一个或唯一的分布式版本控制系统。还有一些系统,例如Bitkeeper, Mercurial等,也是运行在分布式模式上的。但GIT在这方面做的更好,而且有更多强大的功能特征。

GIT跟SVN一样有自己的集中式版本库或服务器。但,GIT更倾向于被使用于分布式模式,也就是每个开发人员从中心版本库/服务器上chect out代码后会在自己的机器上克隆一个自己的版本库。可以这样说,如果你被困在一个不能连接网络的地方时,你仍然能够提交文件,查看历史版本记录,创建项目分支等。

2)GIT把内容按元数据方式存储,而SVN是按文件:

所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn,.cvs等的文件夹里。如果你把.git目录的体积大小跟.svn比较,你会发现它们差距很大。因为,.git目录是处于你的机器上的一个克隆版的版本库,它拥有中心版本库上所有的东西,例如标签,分支,版本记录等。

3)GIT分支和SVN的分支不同:

分支在SVN中一点不特别,就是版本库中的另外的一个目录。如果你想知道是否合并了一个分支,你需要手工运行像这样的命令svn propget svn:mergeinfo,来确认代码是否被合并。

然而,处理GIT的分支却是相当的简单和有趣。你可以从同一个工作目录下快速的在几个分支间切换。你很容易发现未被合并的分支,你能简单而快捷的合并这些文件。

4)GIT没有一个全局的版本号,而SVN有:

目前为止这是跟SVN相比GIT缺少的最大的一个特征。

5)GIT的内容完整性要优于SVN:

GIT的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。

2、SVN和GIT基本操作对比

1)仓库创建初始化

在SVN中,仓库本身的管理和日常应用,使用的是两套不同的命令。仓库的创建和备份维护等使用的命令是 svnadmin, 使用svnadmin create来创建一个新的仓库

在git中,创建一个新的仓库,可以在一个空目录下,使用git init来实现,它将创建一个.git目录用来维护仓库数据。

在SVN中,创建仓库的地方并不是你日常使用的仓库的地方,你需要在别的地方checkout出特定的仓库路径作为你的日常工作的目录。在git中,仓库所在的目录也就是你的日常工作目录,没有服务器端和客户端之分。(严格的说 .git目录才是仓库,.git目录外的地方是你的工作目录,对于bare project来说,只有git目录下的内容,工作目录离得内容还是要checkout出来的)

2)Checkout仓库

在SVN中,使用SVN checkout(co)来checkout本地或远程仓库的代码

而对于git来说,尽管也有checkout命令,但是由于你需要在本地拥有仓库,所以通常从服务器上checkout代码的第一步是使用git clone来获取一个仓库的拷贝,默认的git clone操作同时还会checkout一份远程仓库上当前active的分支

在SVN中,其仓库的管理形式决定了你可以只checkout仓库中特定路径/分支下的子目录,而不是整个仓库,而git只能checkout整个分支。

3)将文件纳入版本管理

在SVN中,使用SVN add,这样在以后的commit过程中,每次在提交数据之前,svn都会自动根据这些add过的对象的修改情况,构建一个commit tree。

在git中,因为存在index的概念,要将一个文件纳入版本管理的范畴,首先是要用git-update-index –-add将文件纳入index的监控范围,只有更新到index中的内容才会在commit的时候被提交。另外,文件本身的改动并不会自动更新到index中,每次的任何修改都必须重新更新到index中去才会被提交。 当然,通常会用git add这样的封装脚本来调用git-update-index

4)检查当前状态

SVN Status 可以显示当前working tree的文件修改状态

在git中 git status 命令显示当前index的状态和working tree的状态。

5)提交文件

Git commit操作在git命令中属于相对简单的,需要注意的一点就是上面提到的,只有index中的内容才会比提交。

6)删除文件

在使用Svn rm删除一个目录的时候,因为每个目录下都存在.svn目录,记录了这个目录于服务器端仓库相关的信息,所以在commit之前,目录里的其它文件会被删除,但是目录及其子目录并不会被真正删除,只有commit以后,目录才会被删除。

在git中,同样,使用git rm 删除文件。但是git对目录的处理有些奇怪,如果某个目录下的所有文件都被删除以后,该目录就会被自动删除,也就是说你无法保留一个空的目录。你也无法添加一个空目录到仓库里。也就是说git 自动忽略空目录,不知道这样做的目的是什么?

7)查看log

svn log命令基本上就是用来查看版本提交时的所填写的log信息

git log可以做的事情会多很多,毕竟git log是对底层核心命令的再包装,通过它,不仅可以查看log信息,还可以输出特定版本的具体变更内容等等信息。

8)版本回溯

在SVN中,不提供任何从仓库中删除对象的机制,任何的修改都会导致版本的递增,所以,如果想丢弃一个修改,你需要做的事是反向diff你的修改,再提交一个新的版本。

在git中提供了重置committed tree对象索引的机制,所以,你可以通过例如git-reset这样的操作将当前分支的版本恢复到以前的某个状态。经常看见的例子就是回溯一个版本,然后修改内容,再次提交。不过这样做搞不好很容易出问题。包括在git-push之类的操作时会被reject,需要强行push之类的。

如果只是想放弃一个修改,git的文档推荐使用git-revert操作,这个操作基本上和SVN的思路是一样的了,就是提交一个新的版本将需要revert的版本的内容再反向修改回去,版本会递增,不影响之前提交的内容。

9)放弃当前修改

在SVN中,使用SVN revert对目录或文件操作都可以将当前工作树上特定路径的修改恢复到服务器上的版本,放弃当前的修改。

Git中,对特定文件使用不带其它参数的git checkout命令可以将文件恢复到index中的状态,如果你想恢复的特定的版本,那么类似: git checkout HEAD file这样的操作,将文件恢复到HEAD tree即最近一次提交的状态。

不过git checkout有个问题,不知道是否是故意这样设计的,就是即使用git rm删除的内容,如果没有提交,git checkout以后也会恢复,包括它在index中的状态。这点有些不理解。 理论上index上已经记录这个删除操作,不应该恢复才对。

Git中还有一种办法,可以快速彻底的放弃自从上次commit以来的所有变更,git reset –hard HEAD

10)代码合并

git merge能够自动记住以前merge过的位置和状态,这个比较容易理解,因为通过每个分支的head commit可以跟踪它的对象索引关系。另外,因为其对象管理机制的原因,只能以commit为单位,merge整个分支的所有修改。不能有选择的merge部分路径下的修改。Merge的时候要求index和HEAD是一致的,如果merge成功,内容会直接commit,而工作树上的修改仍会保持。(如果失败,会在工作树上将需要merge的内容和你已有的修改合并,大概不是你所希望的,所以最好不要这样做)

merge特定分支的特定版本之前的所有修改,可以通过merge那个版本对应的rev来实现,merge某一段版本区间的修改,考虑到commit需要完整的代码树关系,估计靠git merge来做是没有办法了,需要自己diff / patch代码来实现

SVN的Merge操作不会记住它的merge历史,换句话说,你可以多次merge同一份代码,但是他的好处是你可以自由的选择merge哪一部分、哪一段版本之间的代码,应该说他基本等同于是diff和patch的组合。不过因为SVN没有index的概念,所以merge的操作会和当前working tree上的修改合并在一起。

关于历史信息方面,因为svn的merge实际是patch文件内容本身,所以,不同分支上的历史信息不会在merge以后的主干上体现出来,而git的merge,如果没有冲突的话,实际是merge commit树的继承关系,所以,所有的历史信息在merge以后的commit中都能够被索引到。

11)获取单纯的代码

在svn中,如果不需要任何历史信息,只想要某个版本纯粹的代码(经常会有这种需求,这样做本地数据比较小) 那么,使用svn export命令即可以实现。

在git中,似乎没有这样的命令,不过,由于git的本地仓库信息完全维护在project根目录的.git目录下,(不像svn一样,每个子目录下都有单独的.svn目录)。所以,只要clone,checkout然后删除.git目录就可以了。

另外两篇csdn的文章
http://blog.csdn.net/yihui8/article/details/6445847 http://blog.csdn.net/crylearner/article/details/7685182
以上内容通过百度之后收集的,多谢大侠们分享,本人是由于公司内网原因才盗用宝贵资源,希望谅解。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  git svn