svn - svn子树,从一个存储库更新,提交给另一个

标签 svn svn-externals subtree svn-export

在SVN信息库中有一个大项目。我想在其他应用程序中使用该项目的某些模块,因此我考虑从我的主要SVN存储库中 check out 它们,以便使我的代码保持更新。

如何才能“导出”存储库中的一个文件夹/模块,以便仅将该模块 checkout 到其他项目中?我要在其中包含该模块的其他项目也位于他们自己的SVN存储库中。

在简历中,我希望能够对主存储库进行SVN更新,但可以对项目存储库进行提交。

我希望清楚我想做什么。

回应DavidW anwser:

  • 我有一个包含多个项目的存储库,但我可能会对此进行更改
    如有必要。
  • 我想保留源代码。它是一个PHP项目。一世
    正在 fork 模块。 (我有一个全局通用项目,如果我的
    客户端需要一些特定的功能
  • 我想为该客户端创建一个单独的项目(也在svn中单独)。但是我想
    有办法将在主项目中所做的一些更改合并到
    客户项目。 (例如:全局错误修复或功能性)。
  • 最佳答案

    几个问题:

  • 您是在谈论多个存储库,还是同一存储库中的多个项目?
  • 如果您借用了另一个模块的代码,是将其与另一个模块保持同步,还是要 fork 该模块?
  • 您真的想与共享什么?您是否必须共享源代码或已编译的输出(Unix C/C +中的*.so*.a,Java中的*.jar等)。

  • 您将给出的答案在很大程度上取决于您对这些问题的答案。

    假设代码实际上是共享的。您在其中一项中要做的就是在另一项中要做的。您在
    项目的中进行了更改,其他项目中的代码也进行了更改。

    在这种情况下,请使用svn:externals。这是放置在目录上的属性。它的作用是将Subversion URL与子目录名称相关联。例如:
    $ svn propset svn:externals "http://svn.vegibanc.com/svn/trunk/project/stuff utils" .
    

    将属性放置在当前目录上。当您进行更新或 checkout 时,将在项目中创建一个名为utils的目录,Subversion会自动将http://svn.vegibanc.com/svn/trunk/project/stuff checkout 到该目录中。这是魔术,但像所有魔术一样,它既有光明的一面,又有黑暗的一面。

    首先是光面:

    这是在两个项目之间共享代码。您在utils目录中进行更改并提交更改,并且stuff中的project子目录将被更新。我用它在我的项目中构建工具。如果我升级工具,则​​所有项目都将获得升级的工具。

    现在,阴暗面:

    如果像我向您展示的那样定义svn:externals,您将深为后悔。想象一下,如果您决定将工作分支以发布。好了,您的utils目录仍指向trunkproject/stuff。如果您分支到版本2.1,并且trunk现在可以在2.2上运行,那么您会在utils中获得不需要的内容。

    更糟糕的是,如果创建标签,则该标签将继续更改,因为主干中的utils目录仍在更改。

    因此,强烈建议您指定URL的确切版本:
    $ svn propset svn:externals "-r23283 ^/trunk/project/stuff@23283 utils" .
    $ svn propset svn:externals "^/tags/2.3.3/project/stuff utils" .
    

    首先,我指的是URL的特定修订版。这是完全不变的。如果需要将其指向另一个版本,则需要更改svn:externals属性本身。

    第二个是指向特定标签。因为可以更改标签,所以它并不安全,但是我可以将外部依赖项视为发布的一种方式。我正在使用2.3.3版的东西实用程序。

    两者都使用^快捷方式,该快捷方式仅表示Subversion存储库根。这样,如果您将Subversion存储库移至另一个系统,或从http更改为svn,则外部组件仍然可以使用。
    当然,如果以这种方式进行操作,将永远无法更改svn:externals下的代码。而且,这不是您想要的。

    您也可以使用相对 URL,但是它们更危险一些。

    想象一下您的两个项目是这样的,您想将东西目录变成utils目录的svn:external链接:
    http://svn.vegibanc.com/svn/trunk/project/foo/stuff
    http://svn.vegibanc.com/svn/trunk/project/bar/utils
    

    该项目分支在一起并标记在一起。您可以这样做:
    $ co http://svn.vegibanc.com/svn/trunk/project/bar bar-trunk
    $ cd project-bar
    $ svn propset svn:externals "../foo/stuff utils" .
    

    这会将东西目录从外部链接到您的utils目录。但是,它是以相对方式完成的。如果您这样做:
    $ cp http://svn.vegibanc.com/svn/trunk http://svn.vegibank.com/svn/branches/2.3
    

    您的utils目录仍将在外部链接到foo项目下的stuff目录,但是它们都位于2.3分支上。

    更改bar/utils中的代码将更改foo/stuff中的代码,反之亦然。您仍在共享代码,但是这两个项目仍在同一分支中。

    稍后,如果您这样标记:
    $ cp http://svn.vegibank.com/svn/branches/2.3 http://svn.vegibank.com/svn/tags/2.3.0
    

    您的标签2.3.0不太可能更改,因为外部链接及其链接到的内容都被该标签包围。

    以上假设您正在共享代码,并且任何一个项目中的更改都将影响另一个项目。

    更好的方法是让foo创建可以存储在发布服务器上的某种已编译对象(例如JAR文件或* .so)。您将此已编译对象视为具有其自身版本控制的项目,并且您的项目将取决于此对象的特定版本。不幸的是,这并不总是有效。

    如果仅是 fork 代码,请从存储库中的一个位置到另一个位置执行svn cp。您可以进行更改而不会影响其他项目,反之亦然。更好的是,您可以在两个位置之间来回合并更改以使它们保持一定程度的同步。

    希望这能回答您的问题。如果您可以扩展问题并为我们提供所需的更多详细信息,我将能够更新我的答案。

    关于svn - svn子树,从一个存储库更新,提交给另一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15948209/

    相关文章:

    svndumptool 的正则表达式

    svn - TortoiseSVN:为什么我不能将外部(项目)添加到我的工作副本的 ROOT 中?

    git - 使用git但不使用git子模块在子目录中安装wordpress

    svn - 如何使用SVN日志检测修改的属性

    svn 不更新,不恢复,但文件在服务器上

    svn - 如何在不获取所有其他目录和子目录的情况下获取外部 Subversion

    python - 子树提取NLTK树

    svn - 从 SVN 更新时是否可以始终覆盖本地更改?

    git - 从存储库中恢复已删除的文件