svn子树,从一个repo更新,提交到其他

时间:2013-04-11 11:58:37

标签: svn svn-externals subtree svn-export

A在SVN存储库中有一个大项目。我想在其他应用程序中使用该项目的一些模块,所以我考虑从我的主要SVN存储库中检出它们,以便我可以更新我的代码。

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

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

我希望清楚我想做什么。

回应DavidW anwser:

  • 我有一个包含多个项目的存储库,但我可能会更改它 如有必要。
  • 我想要成为源代码。它是一个php项目。一世 我正在分发模块。 (我有一个全球通用项目,如果我的 客户需要一些特定的功能,
  • 我想为该客户创建一个单独的项目(也在svn中单独)。但我想要 有办法将主项目中的一些变化合并到 客户项目。 (例如:全局错误修复或功能)。

2 个答案:

答案 0 :(得分:1)

几个问题:

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

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

我们假设代码实际上是共享的。你在一个人做的是你想要做的另一个。您在您的项目中进行了更改,其他项目中的代码也会更改。

在这种情况下,请使用svn:externals。这是您放置在目录上的属性。它的作用是将Subversion URL与子目录名称相关联。例如:

$ svn propset svn:externals "http://svn.vegibanc.com/svn/trunk/project/stuff utils" .

将属性放在当前目录中。当您执行更新或结帐时,将在您的项目中创建名为utils的目录,Subversion将自动将http://svn.vegibanc.com/svn/trunk/project/stuff签出到该目录中。这很神奇,但就像所有魔法一样,它既有光明又有黑暗。

首先是光明方面:

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

现在,黑暗面:

如果你像我展示的那样定义svn:externals,你会深感遗憾。想象一下,如果你决定将你的工作分支到一个版本。好吧,您的utils目录仍然指向trunk的{​​{1}}。如果您为2.1版本分支,并且主干现在正在使用2.2,那么您将获得project/stuff中您不想要的内容。

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

因此,强烈建议您指定网址的完全版本:

utils

首先,我指的是网址的 特定 版本。它完全不变。如果我需要将其指向另一个修订版,我需要更改$ svn propset svn:externals "-r23283 ^/trunk/project/stuff@23283 utils" . $ svn propset svn:externals "^/tags/2.3.3/project/stuff utils" . 属性本身。

第二个指向特定标签。它不是安全,因为标签可以更改,但我可以通过这种方式将我的外部依赖关系视为一个版本。我正在使用 stuff 实用程序的2.3.3版。

两者都使用svn:externals快捷方式,这意味着 Subversion Repository Root 。这样,如果您将Subversion存储库移动到另一个系统,或者从^更改为http,您的外部仍然可以正常工作。 当然,如果你这样做,你永远无法改变svn下的代码。而且,这不是你想要的。

您也可以使用相对网址,但他们会更加危险。

想象一下你的两个项目,你想让 stuff 目录成为 utils 目录的svn:externals链接:

svn:external

该项目分支在一起并标记在一起。你可以这样做:

http://svn.vegibanc.com/svn/trunk/project/foo/stuff
http://svn.vegibanc.com/svn/trunk/project/bar/utils

这会将 stuff 目录从外部链接到 utils 目录。但是,它是以相对的方式完成的。如果你这样做:

$ co http://svn.vegibanc.com/svn/trunk/project/bar bar-trunk
$ cd project-bar
$ svn propset svn:externals "../foo/stuff utils" .

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

更改$ cp http://svn.vegibanc.com/svn/trunk http://svn.vegibank.com/svn/branches/2.3 中的代码会更改bar/utils中的代码,反之亦然。您仍在共享代码,但两种项目仍处于同一分支中。

稍后,如果你这样标记:

foo/stuff

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

以上假设您正在共享代码,而任一项目中的更改都会影响另一项。

更好的方法是$ cp http://svn.vegibank.com/svn/branches/2.3 http://svn.vegibank.com/svn/tags/2.3.0 创建一个可以存储在发布服务器上的某种编译对象(如JAR文件或* .so)。您将此编译对象视为具有自己的版本控制的自己的项目,您的项目将取决于此对象的特定版本。不幸的是,这并不总是有效。

如果您只是分叉代码,请从存储库中的一个位置到另一个位置执行foo。您可以在不影响其他项目的情况下进行更改,反之亦然。更好的是,您可以在两个位置之间来回合并更改,以使它们保持同步。

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

答案 1 :(得分:1)

  • 如果你想在Subversion存储库中使用共享代码 - 它是svn:externals
  • 如果您希望将共享代码上的主线端口更改为客户特定版本的共享代码 - 它是svn lingo中的“供应商分支”

组合a)和b)将给你所需的结果

  1. 选择一个节点(客户存储库的外部主干),您将链接到dev-repo中的共享节点
  2. 创建外部定义(如果您需要在提交dev-repo后手动更新定义的成本,那么首选PEG修订版)
  3. 将节点复制到该位置,其中in必须位于实时项目(svn cp ...
  4. 代码...
  5. 当您想要转移到客户仓库的dev-repo中进行更改时 - 将外部更新为所需的修订版,将“供应商”节点合并为“实时”
  6. 样品:

    如果你有客户的回购

    • / vendor / lib(其中lib是来自外国回购的目录) * / trunk / common / lib(客户上面的lib版本)

    合并来自lib-mainline的更改是从/ vendor / lib合并到/ trunk / common / lib(在主干的工作副本的相应节点中)

    大卫关于外部的说明仍然有效,正确和有用