svn,git的对照以及常用命令上篇

svn,git的对比以及常用命令上篇

之前定制Rom,需要下载android源码,修改系统应用。android源码管理使用repo+git,下载速度快的吓人。(直接下载的话,被墙了当然慢,请忽略这个因素)。感觉git更适合大型项目管理。项目经验不是非常多,个人无论大小项目,自己选择的话还是喜欢用git。

个人总结的git优点

1、分支管理非常方便

2、回退,查看历史更加方便,支持命令更多

3、速度更快

4、可以离线提交到本地库,可以离线查看log

5....

下面参照大牛的介绍,来具体看一下git和svn的不同

参考http://*.com/questions/871/why-is-git-better-than-subversion

http://*.com/questions/964331/git-file-integrity

GIT是分布式的,SVN不是

这是GIT和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别。GIT并不是目前第一个或唯一的分布式版本控制系统。还有一些系统,例如Bitkeeper , Mercurial 等,也是运行在分布式模式上的。但GIT在这方面做的更好,而且有更多强大的功能特征。
GIT跟SVN一样有自己的集中式版本库或服务器。但,GIT更倾向于被使用于分布式模式,也就是每个开发人员从中心版本库/服务器上chect out代码后会在自己的机器上克隆一个自己的版本库。,如果被困在一个不能连接网络的地方时,就像在飞机上,地下室,电梯里等,你仍然能够提交文件,查看历史版本记录,创建项目分支,等。对一些人来说,这好像没多大用处,但当突然遇到没有网络的环境时,这个将解决大麻烦。
同样,这种分布式的操作模式对于开源软件社区的开发来说也是个巨大的恩赐,不必再像以前那样做出补丁包,通过email方式发送出去,你只需要创建一个分支,向项目团队发送一个推请求。这能让代码保持最新,而且不会在传输过程中丢失。GitHub.com 就是一个这样的优秀案例。
有些谣言传出来说subversion将来的版本也会基于分布式模式。但至少目前还看不出来。

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

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

GIT分支和SVN的分支不同

分支在SVN中一点不特别,就是版本库中的另外的一个目录。如果想知道是否合并了一个分支,需要手工运行像这样的命令svn propget svn:mergeinfo ,来确认代码是否被合并。所以,经常会发生有些分支被遗漏的情况。
然而,处理GIT的分支却是相当的简单和有趣。可以从同一个工作目录下快速的在几个分支间切换。很容易发现未被合并的分支,能简单而快捷的合并这些文件。

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

目前为止这是跟SVN相比GIT缺少的最大的一个特征。SVN的版本号实际是任何一个相应时间的源代码快照。
但是我们可以使用GIT的SHA-1来唯一的标识一个代码快照。这个并不能完全的代替SVN里容易阅读的数字版本号。但,用途应该是相同的。

GIT的内容完整性要优于SVN

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

以下是svn客户端常用命令一览:

查看最近3个版本日志
svn log [PATH] -v -l3
log消息代码 A :added  D:deleted  M:modified  R:replaced

查看某两个版本,用来对比
svn log -r 14:15

添加文件或目录到你的wc,打上新增标记。这些文件会在下一次你提交wc的时候提交到svn服务器。
在提交前,你也可以用svn revert撤销新增的文件。
svn add file.java

取消提交
svn revert --recursive file.java

显示某个已受控文件的每一行的最后修改版本和作者
svn blame file.java

输出指定目标的内容,这里的目标一般是文件。
svn cat file.java 显示file.java内容。
svn cat file.java -r 2 ##显示版本号为二的file.java内容。
svn cat file.java --revision HEAD ##显示最新版本的file.java内容。

将wc中的文件从逻辑上分组.
svn changelist CLNAME TARGET...
svn changelist --remove TARGET
别名:cl
svn cl clName file.java file2.java file3.java  ##将file.java等三个文件加入名叫clName的changelist 
svn commit --changelist clName -m "ci"  ##将clName下的所有文件提交

检出
svn checkout URL[@REV]... [PATH]
别名:co
svn checkout file:///var/svn/repos/test  file:///var/svn/repos/quiz working-copies
svn checkout -r 2 file:///var/svn/repos/test mine  ##check out 版本号为2的项目

递归的清理WC中过期的锁和未完成的操作
svn cleanup

把你WC的更改提交到仓库
svn commit [PATH...]
别名:ci
svn commit -m "added howto section." ##默认情况下提交必须提供log message 

javaopy操作可以从WC到WC;WC到URL;URL到WC;URL到URL。现在SVN只支持同一个仓库内文件的拷贝,不允许跨仓库操作。
svn copy SRC[@REV]... DST
别名:cp
svn copy -r 11 file:///var/svn/repos/test/trunk \
           file:///var/svn/repos/test/tags/0.6.32-prerelease \
           -m "Forgot to tag at rev 11"
##copy命令是创建分支和标记的常用方式。copy到url的操作隐含了提交动作,所以需要提供log messages。

删除
svn delete PATH...
别名:del,remove,rm
访问库:如果PATH是库地址时会,删除WC内的文件不会。
svn del localfile.java    ##删除WC里的文件,在下一次提交WC的时候才会真正在仓库里将对应文件删除。
svn del file:///var/svn/repos/test/yourfile  ##删除仓库里的文件

比较并显示修改点
svn diff
别名:di
svn diff   ##最常用的方式,用来显示WC基于最近一次更新以后的所有的本地修改点。
svn diff -r 301 bin ## 比较WC和版本301中的bin目录的修改点
svn diff -r 3000:3500 file:///var/svn/repos/myProject/trunk   ##比较库里主干3000版和3500版的差异。
svn diff --summarize --xml http://svn.red-bean.javaom/repos/test@r2 http://svn.red-bean.javaom/repos/test  ##--summarize --xml 参数将差异情况以xml文档的方式显示出来。

导出一个干净的目录树,不包含所有的受控信息。可以选择从URL或WC中导出。
svn export [-r REV] URL[@PEGREV] [PATH]
svn export [-r REV] PATH1[@PEGREV] [PATH2]
访问库:如果访问的是URL则会。
svn export file:///var/svn/repos my-export   ##导出到my-export目录。

查看帮助文档
svn help 
访问库:否。

导入本地一个目录到库中。但是导入后,本地的目录并不会处于受控状态。
svn import [PATH] URL
别名:无
访问库:是。
svn import -m "New import" myproj http://svn.myProject.javaom/repos/trunk/misc

显示指定WC和URL信息。
svn info [TARGET[@REV]...]
别名:无
访问库:仅当访问的是库路径时。
svn info --xml http://svn.myProject.javaom/repos/test  ##将信息以xml格式显示。

显示目标下的文件和目录列表。
svn list [TARGET[@REV]...]
别名:ls
访问库:如果访问的是库地址就会。
svn list --verbose file:///var/svn/repos   ##--verbose参数表示显示详细信息。

对目标获得修改锁。如果目标已被其他用户锁定,则会抛出警告信息。用--force参数强制从其他用户那里获得锁。
svn lock TARGET...
别名:无
访问库:是
svn lock --force tree.jpg

合并两个受控源的不同之处,存放到一个WC里。
svn merge sourceURL1[@N] sourceURL2[@M] [WCPATH]
svn merge sourceWCPATH1@N sourceWCPATH2@M [WCPATH]
svn merge [[-c M]... | [-r N:M]...] [SOURCE[@REV] [WCPATH]]
访问库:只有当访问库地址时。
svn merge --reintegrate http://svn.example.javaom/repos/calc/branches/my-calc-branch  ##合并分支上的改变项到WC,往往用于分支合并到主干。
svn merge -r 156:157 http://svn.example.javaom/repos/calc/branches/my-calc-branch   ##将制定URL版本156到157的所有更新合并到WC。

在WC或库路径创建目录
svn mkdir PATH...
svn mkdir URL...
访问库:只有当访问库地址时。
svn mkdir newdir
 
svn move SRC... DST
别名:mv, rename, ren
描述:等同于svn copy命令跟个svn delete命令。WC到URL的重命名是不被允许的。
访问库:只有当访问库地址时。
svn move foo.java bar.java  ##将foo.java改名成bar.java。
 
svn propdel PROPNAME [PATH...]
svn propdel PROPNAME --revprop -r REV [TARGET]
别名:pdel, pd
描述:从受控文件,目录等删除属性。第二种是删除某个指定版本上的附加属性。
访问库:只有当访问库地址时。
svn propdel svn:mime-type someFile    ##从someFile上移除svn:mime-type这个属性。
 
svn propedit PROPNAME TARGET...
svn propedit PROPNAME --revprop -r REV [TARGET]
别名:pedit, pe
描述:编辑属性
访问库:只有当访问库地址时。
svn propedit svn:keywords  file.java  ##修改file.java上的svn:keywords属性。
 
svn propget PROPNAME [TARGET[@REV]...]
svn propget PROPNAME --revprop -r REV [URL]
别名:pget,pg
描述:从文件,目录或版本取得指定属性的值。
访问库:只有当访问库地址时。
svn propget svn:keywords file.java   ##从file.java中取得svn:keywords属性的值
 
svn proplist [TARGET[@REV]...]
svn proplist --revprop -r REV [TARGET]
别名:plist, pl
描述:列出文件、目录或版本上的所有附加属性
访问库:只有当访问库地址时。
svn proplist --verbose file.java
 
svn propset PROPNAME [PROPVAL | -F VALFILE] PATH...
svn propset PROPNAME --revprop -r REV [PROPVAL | -F VALFILE] [TARGET]
别名:pset,ps
描述:给文件、目录或版本附加属性并赋值
访问库:只有当访问库地址时。
svn propset svn:mime-type image/jpeg file.jpg   ##给file.jpg附加属性svn:mime-type 其值为image/jpeg
svn propset --revprop -r 25 svn:log "Journaled about trip to New York."
##给版本25补上log message
svn propset svn:ignore '.javalasspath' . 
##在本地忽略掉.javalasspath文件
 
svn resolve PATH...
别名:无
描述:将冲突的文件标记为已解决,并且删掉冲突产生的临时文件。注意这个命令并不是能把冲突解决,解决冲突还是得靠人工。
访问库:否
svn resolve --accept mine-full foo.java   ##1.5版本后,加上--accept参数,尝试自动处理冲突。
 
svn resolved PATH...
别名:无
描述:已过时,被resolve --accept取代。去除冲突的状态和冲突临时文件。
访问库:否
 
svn revert PATH...
别名:无
描述:还原WC中所有的本地更改。
访问库:否
svn revert --depth=infinity .   ##将整个目录所有文件还原
 
svn status [PATH...]
别名:stat, st
描述:输出WC中文件和目录的状态。如果WC提交,这些状态就会同步到库里。
一般状态有         ' '  没有修改
'A'  新增
'D'  删除
'M'  修改
'R'  替代
'C'  冲突
'I'  忽略
'?'  未受控
'!'  丢失,一般是将受控文件直接删除导致
访问库:加上--show-updates参数时会
svn status wc
 
svn switch URL[@PEGREV] [PATH]
svn switch --relocate FROM TO [PATH...]
别名:sw
描述:将WC转向一个其他的库地址同步
访问库:是
svn sw http://svn.myProject.javaom/repos/trunk/vendors .  ##将当前WC切换到另一个URL
 
svn unlock TARGET...
别名:无
描述:解锁
访问库:是
svn unlock somefile
 
svn update [PATH...]
别名:up
描述:更新WC,更新反馈有如下几种分类。
A  新增
B  锁破坏
D  删除
U  更新
C  冲突
G  合并
E  存在的
访问库:是
svn up -r22   ##更新到一个指定版本

创建分支
svn cp -m "create branch" http://svn_server/xxx_repository/trunk http://svn_server/xxx_repository/branches/br_feature001

获得分支
svn co http://svn_server/xxx_repository/branches/br_feature001

合并主干上的最新代码到分支上
cd br_feature001
svn merge http://svn_server/xxx_repository/trunk
如果需要预览该刷新操作,可以使用svn mergeinfo命令,如:
svn mergeinfo http://svn_server/xxx_repository/trunk --show-revs eligible
或使用svn merge --dry-run选项以获取更为详尽的信息。

分支合并到主干
一旦分支上的开发结束,分支上的代码需要合并到主干。SVN中执行该操作需要在trunk的工作目录下进行。命令如下:
cd trunk
svn merge --reintegrate http://svn_server/xxx_repository/branches/br_feature001
分支合并到主干中完成后应当删该分支,因为在SVN中该分支已经不能进行刷新也不能合并到主干。

合并版本并将合并后的结果应用到现有的分支上
svn -r 148:149 merge http://svn_server/xxx_repository/trunk

建立tags
产品开发已经基本完成,并且通过很严格的测试,这时候我们就想发布给客户使用,发布我们的1.0版本
svn copy http://svn_server/xxx_repository/trunk http://svn_server/xxx_repository/tags/release-1.0 -m "1.0 released"

删除分支或tags
svn rm http://svn_server/xxx_repository/branches/br_feature001
svn rm http://svn_server/xxx_repository/tags/release-1.0


git命令更多,之后在做详细介绍

通常集成开发环境都有集成svn,git相关插件,提供可视化操作。


欢迎扫描二维码,关注公众账号

svn,git的对照以及常用命令上篇