51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 6018|回复: 0

[转贴] Git 与 Subversion

[复制链接]
  • TA的每日心情
    奋斗
    2021-8-16 14:04
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]测试小兵

    发表于 2019-1-25 15:04:16 | 显示全部楼层 |阅读模式
    Git 与 Subversion

    当前,大多数开发中的开源项目以及大量的商业项目都使用 Subversion 来管理源码。作为最流行的开源版本控制系统,Subversion 已经存在了接近十年的时间。它在许多方面与 CVS 十分类似,后者是前者出现之前代码控制世界的霸主。

    Git 最为重要的特性之一是名为 git svn 的 Subversion 双向桥接工具。该工具把 Git 变成了 Subversion 服务的客户端,从而让你在本地享受到 Git 所有的功能,而后直接向 Subversion 服务器推送内容,仿佛在本地使用了 Subversion 客户端。也就是说,在其他人忍受古董的同时,你可以在本地享受分支合并,使暂存区域,衍合以及 单项挑拣等等。这是个让 Git 偷偷潜入合作开发环境的好东西,在帮助你的开发同伴们提高效率的同时,它还能帮你劝说团队让整个项目框架转向对 Git 的支持。这个 Subversion 之桥是通向分布式版本控制系统(DVCS, Distributed VCS )世界的神奇隧道。


    git svn

    Git 中所有 Subversion 桥接命令的基础是 git svn 。所有的命令都从它开始。相关的命令数目不少,你将通过几个简单的工作流程了解到其中常见的一些。

    值得警戒的是,在使用 git svn 的时候,你实际是在与 Subversion 交互,Git 比它要高级复杂的多。尽管可以在本地随意的进行分支和合并,最好还是通过衍合保持线性的提交历史,尽量避免类似与远程 Git 仓库动态交互这样的操作。

    避免修改历史再重新推送的做法,也不要同时推送到并行的 Git 仓库来试图与其他 Git 用户合作。Subersion 只能保存单一的线性提交历史,一不小心就会被搞糊涂。合作团队中同时有人用 SVN 和 Git,一定要确保所有人都使用 SVN 服务来协作——这会让生活轻松很多。


    初始设定

    为了展示功能,先要一个具有写权限的 SVN 仓库。如果想尝试这个范例,你必须复制一份其中的测试仓库。比较简单的做法是使用一个名为 svnsync 的工具。较新的 Subversion 版本中都带有该工具,它将数据编码为用于网络传输的格式。

    要尝试本例,先在本地新建一个 Subversion 仓库:

    1. $ mkdir /tmp/test-svn
    2. $ svnadmin create /tmp/test-svn
    复制代码

    然后,允许所有用户修改 revprop —— 简单的做法是添加一个总是以 0 作为返回值的 pre-revprop-change 脚本:

    1. $ cat /tmp/test-svn/hooks/pre-revprop-change
    2. #!/bin/sh
    3. exit 0;
    4. $ chmod +x /tmp/test-svn/hooks/pre-revprop-change
    复制代码

    现在可以调用 svnsync init 加目标仓库,再加源仓库的格式来把该项目同步到本地了:

    1. $ svnsync init file:///tmp/test-svn http://progit-example.googlecode.com/svn/
    复制代码

    这将建立进行同步所需的属性。可以通过运行以下命令来克隆代码:

    1. $ svnsync sync file:///tmp/test-svn
    2. Committed revision 1.
    3. Copied properties for revision 1.
    4. Committed revision 2.
    5. Copied properties for revision 2.
    6. Committed revision 3.
    7. ...
    复制代码

    别看这个操作只花掉几分钟,要是你想把源仓库复制到另一个远程仓库,而不是本地仓库,那将花掉接近一个小时,尽管项目中只有不到 100 次的提交。 Subversion 每次只复制一次修改,把它推送到另一个仓库里,然后周而复始——惊人的低效,但是我们别无选择。


    入门

    有了可以写入的 Subversion 仓库以后,就可以尝试一下典型的工作流程了。我们从 git svn clone 命令开始,它会把整个 Subversion 仓库导入到一个本地的 Git 仓库中。提醒一下,这里导入的是一个货真价实的 Subversion 仓库,所以应该把下面的 file:///tmp/test-svn 换成你所用的 Subversion 仓库的 URL:

    1. $ git svn clone file:///tmp/test-svn -T trunk -b branches -t tags
    2. Initialized empty Git repository in /Users/schacon/projects/testsvnsync/svn/.git/
    3. r1 = b4e387bc68740b5af56c2a5faf4003ae42bd135c (trunk)
    4.       A    m4/acx_pthread.m4
    5.       A    m4/stl_hash.m4
    6. ...
    7. r75 = d1957f3b307922124eec6314e15bcda59e3d9610 (trunk)
    8. Found possible branch point: file:///tmp/test-svn/trunk => \
    9.     file:///tmp/test-svn /branches/my-calc-branch, 75
    10. Found branch parent: (my-calc-branch) d1957f3b307922124eec6314e15bcda59e3d9610
    11. Following parent with do_switch
    12. Successfully followed parent
    13. r76 = 8624824ecc0badd73f40ea2f01fce51894189b01 (my-calc-branch)
    14. Checked out HEAD:
    15. file:///tmp/test-svn/branches/my-calc-branch r76
    复制代码

    这相当于针对所提供的 URL 运行了两条命令—— git svn init 加上 git svn fetch 。可能会花上一段时间。我们所用的测试项目仅仅包含 75 次提交并且它的代码量不算大,所以只有几分钟而已。不过,Git 仍然需要提取每一个版本,每次一个,再逐个提交。对于一个包含成百上千次提交的项目,花掉的时间则可能是几小时甚至数天。

    -T trunk -b branches -t tags 告诉 Git 该 Subversion 仓库遵循了基本的分支和标签命名法则。如果你的主干(译注:trunk,相当于非分布式版本控制里的master分支,代表开发的主线),分支或者标签以不同的方式命名,则应做出相应改变。由于该法则的常见性,可以使用 -s 来代替整条命令,它意味着标准布局(s 是 Standard layout 的首字母),也就是前面选项的内容。下面的命令有相同的效果:

    1. $ git svn clone file:///tmp/test-svn -s
    复制代码

    现在,你有了一个有效的 Git 仓库,包含着导入的分支和标签:

    1. $ git branch -a
    2. * master
    3.   my-calc-branch
    4.   tags/2.0.2
    5.   tags/release-2.0.1
    6.   tags/release-2.0.2
    7.   tags/release-2.0.2rc1
    8.   trunk
    复制代码

    值得注意的是,该工具分配命名空间时和远程引用的方式不尽相同。克隆普通的 Git 仓库时,可以以 origin/[branch] 的形式获取远程服务器上所有可用的分支——分配到远程服务的名称下。然而 git svn 假定不存在多个远程服务器,所以把所有指向远程服务的引用不加区分的保存下来。可以用 Git 探测命令 show-ref 来查看所有引用的全名。

    1. $ git show-ref
    2. 1cbd4904d9982f386d87f88fce1c24ad7c0f0471 refs/heads/master
    3. aee1ecc26318164f355a883f5d99cff0c852d3c4 refs/remotes/my-calc-branch
    4. 03d09b0e2aad427e34a6d50ff147128e76c0e0f5 refs/remotes/tags/2.0.2
    5. 50d02cc0adc9da4319eeba0900430ba219b9c376 refs/remotes/tags/release-2.0.1
    6. 4caaa711a50c77879a91b8b90380060f672745cb refs/remotes/tags/release-2.0.2
    7. 1c4cb508144c513ff1214c3488abe66dcb92916f refs/remotes/tags/release-2.0.2rc1
    8. 1cbd4904d9982f386d87f88fce1c24ad7c0f0471 refs/remotes/trunk
    复制代码

    而普通的 Git 仓库应该是这个模样:

    1. $ git show-ref
    2. 83e38c7a0af325a9722f2fdc56b10188806d83a1 refs/heads/master
    3. 3e15e38c198baac84223acfc6224bb8b99ff2281 refs/remotes/gitserver/master
    4. 0a30dd3b0c795b80212ae723640d4e5d48cabdff refs/remotes/origin/master
    5. 25812380387fdd55f916652be4881c6f11600d6f refs/remotes/origin/testing
    复制代码

    这里有两个远程服务器:一个名为 gitserver ,具有一个 master分支;另一个叫 origin,具有 master 和 testing 两个分支。

    注意本例中通过 git svn 导入的远程引用,(Subversion 的)标签是当作远程分支添加的,而不是真正的 Git 标签。导入的 Subversion 仓库仿佛是有一个带有不同分支的 tags 远程服务器。


    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-3-29 04:48 , Processed in 0.060948 second(s), 23 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表