近期接手到公司一些项目是使用SVN管理代码,对于我这样一个git命令行的重度使用者,实在是颇感不便。比较了svn的命令行和和客户端,发现svn的客户端是比较友好的。但是我是个命令使用者,怎么能用客户端呢?(捂脸,主要是没钱买个好用的mac客户端)。所以就乖乖总结下svn命令行的使用。
下面对标git常用命令,看下在svn里是怎么实现相应的功能。
下载代码 git 1 git clone git ://gcc.gnu.org/git/gcc.git
svn 1 svn checkout svn://g cc.gnu.org/svn/g cc/trunk gcc
比较总结 git clone的是下载的是一个仓库的所有branch和tag的元数据,同时下载了master branch的所有文件,然后checkout到master branch。svn checkout则是checkout trunk目录下所有的文件。所以同一个项目里.svn 文件夹是要比.git 文件夹小。
查看日志 git
svn
比较总结 git log默认是输出到pager里的,但是svn log是不通过pager的,一股脑输出所有信息。因此只要日志超过一页,git log里用户最先看到的较新的提交记录,svn log里用户最先看到的是较旧的提交记录,会有些不自然。
可以在shell里给svn log 也默认加个pager,比如在zsh里给svn log加pager :
1 2 3 4 5 6 7 8 svn () { if [ "$1 " = "log" ] then command svn "$@ " | less -FX else command svn "$@ " fi }
查看当前状态 git
svn
比较总结 对于 svn status的结果解释可以查看书籍Subversion 版本控制 中的示例:
如果在工作副本的根目录不加任何参数地执行 svn status, Subversion 就会检查并报告所有 文件和目录的修改.
1 2 3 4 5 6 7 $ svn status ? scratch.c A stuff/loot A stuff/loot/new.c D stuff/old.c M bar.c $
在默认的输出模式下,其中最常的几种字符或状态是:
? item
文件, 目录或符号链接 item 不在版本 控制的名单中.
A item
文件, 目录或符号链接 item 是新增的, 在下一次提交时就会加入到仓库中.
C item
文件 item 有未解决的冲突, 意思是说从 服务器收到的更新和该文件的本地修改有所重叠,
Subversion 在处理 这些重叠的修改时发生了冲突. 用户必须解决掉冲突后才能向仓库 提交修改.
D item
文件, 目录或符号链接 item 已被删除, 在下一次提交时就会从仓库中删除 item.
M item
文件 item 的内容被修改.
git status 则更直观一些,没有使用字母的缩写。比如书籍Pro git 中的示例:
1 2 3 4 5 6 7 8 9 10 11 12 On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file : README modified: CONTRIBUTING.md Changes not staged for commit : (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory ) modified: CONTRIBUTING.md
获取更新 git
svn
添加文件 git
svn
提交修改 git 1 2 git commit -m "xxx" git push origin
svn
比较总结 因为git是分布式,本地有全量的仓库信息,所以设计上git commit是commit到本地的repo,git还需要通过push推送其他服务器,比如公司的中心服务器。svn commit是直接提交到中心服务器的。
查看diff git
svn
比较总结 我现在使用的是最常用的一种情况,比较当前未提交的修改跟上一个commit的区别。git要指定当前修改与哪个commit比较(比如HEAD),svn则不用。
revert 文件 git 1 2 git checkout xxxfile git reset --hard
svn 1 2 svn revert xxxfile # revert 一个文件svn revert xxxDirectory -R # revert 文件夹下所有修改
比较总结 对于revert文件,svn命令看起来要自然些,git用checkout表示使用该文件最新commit中的版本,自然的本地为提交的修改就被revert了。对于revert当前所有的修改,git 可以通过reset来实现。svn 则可以通过revert当前文件夹下所有为提交的修改来实现。另外git可以本地提交或者stash来暂存修改,而svn中没有。
创建分支 git
svn 1 svn copy http:// example.com/repos/my project/trunk http:/ /example.com/ repos/myproject/ branches/releaseForAug -m 'create branch for release on August'
比较总结 git中创建branch是元数据的修改,不需要拷贝项目文件。svn中创建branch是把项目文件和再拷贝一份,同时把新文件对应到旧的元数据上去。
创建tag git
svn 1 svn copy http:// example.com/repos/my project/trunk http:/ /example.com/ repos/myproject/ tags/releaseForAug -m 'create branch for release on August'
比较总结 git中创建tag是元数据的修改,只生成一个commit的引用。svn中创建tag和branch是一样的,都是复制。
结语 svn和git从设计上就有根本的不同,svn是集中式的,git是分布式。比如svn的copy有点像git的fork,但是由于svn是集中式,所以svn的copy只能在同一个repo下进行,这就限制了svn项目的分享,这也解释了为什么git出现后,github出现了。不过虽然两个项目设计上有如此大的不同,但是从开发流程上,我们仍然可以使用svn做我们想做的各种事情,比如提交,查看log,branch,tag等,所以svn还能用。两个不同的项目,殊途同归吧。