【问题标题】:How do I branch an individual file in SVN?如何在 SVN 中分支单个文件?
【发布时间】:2010-09-12 03:47:04
【问题描述】:

分支的颠覆概念似乎专注于为整个存储库创建一个 [不稳定的] 分支,以便在其上进行开发。是否有创建单个文件分支的机制?

对于一个用例,考虑一个具有多个特定于平台的源 (*.c) 实现的通用头 (*.h) 文件。这种类型的分支是永久性的。所有这些分支都会看到持续的发展,偶尔会出现跨分支合并。这与通常具有有限生命周期的不稳定开发/稳定发布分支形成鲜明对比。

想要对整个存储库进行分支(无论是否便宜),因为它会产生不合理的维护量以在主干和所有分支之间不断合并。目前我正在使用 ClearCase,它有一个不同的分支概念,这使得这很容易。我被要求考虑过渡到 SVN,但这种范式差异很重要。我更关心的是能够轻松地为单个文件创建替代版本,而不是削减稳定发布分支之类的事情。

【问题讨论】:

  • 您在另一条评论中注意到这实际上不是您的用例。当答案试图解决这个用例而不是你的实际用例时,不要感到惊讶。

标签: svn version-control branch


【解决方案1】:

您不必对整个存储库进行分支。您可以在项目中创建文件夹分支(例如包含文件夹)。正如其他人所指出的,您也可以只对单个文件进行“复制”。获得文件或文件夹的副本后,您可以“切换”到分支文件或文件夹以处理分支版本。

如果您在存储库中创建一个单独的分支文件夹,您可以通过服务器端命令将您的分支文件复制到那里:

svn 复制 svn://server/project/header.h svn://server/branched_files/header.h

然后您可以将该文件切换为使用 branches_files 存储库路径

【讨论】:

  • 这很尴尬,但可能可行。感谢您的意见。
【解决方案2】:

遗憾的是,我认为这里真正的答案是 ClearCase 比 Subversion 更好地处理这种情况。使用颠覆,您必须分支所有内容,但 ClearCase 允许一种“惰性分支”的想法,这意味着只有特定的一组文件被分支,其余的仍然遵循主干(或任何一个分支您指定)。

此处提供的其他解决方案并不能真正按您的意愿工作,它们只是将文件复制到不同的路径。现在你必须做一些奇怪的事情才能真正使用那个文件。

呃,对不起。这真的不是一个很好的答案。但是 Subversion 并没有很好的解决方案。它的模型是分支合并。

编辑:好的,所以扩展 crashmstr 所说的内容。你可以这样做:

svn cp $REP/trunk/file.h $REP/branched_files/file.h
svn co $REP/trunk
svn switch $REP/branched_files/file.h file.h

但是哇!,这容易出错吗?每当您执行 svn st 时,您都会看到:

svn st
    S  file.h

有点吵。而且,当您想在大型源存储库中分支一些文件或模块时,它会开始变得非常混乱。

实际上,这里可能有一个不错的项目,用于模拟 ClearCase 的带有 svn 属性和切换的分支文件之类的东西,围绕 bog 标准 svn 客户端编写一个包装器来处理所有这些混乱。

【讨论】:

    【解决方案3】:

    以下是我对您的问题的理解。您有以下树:

    时间.h 时间.c

    对于多种架构,您需要拒绝它:

    time.h 很常见 time.c (for x386), time.c (for ia64), time.c (for alpha),...

    此外,在您当前的 VCS 中,您可以根据需要从 time.c 创建尽可能多的分支,当您从 VCS 签出文件时,您会自动检查公共主干中的最新 time.h 和最新 time.c从你正在工作的分支。

    您担心的问题是,如果您在签出分支时使用 SVN,您将不得不经常从主干合并 time.h,否则会冒着处理旧文件(与主干相比)的风险你不能接受。

    根据您的源代码结构,可能会有解决方案。假设你有

    / /标题/ /headers/test.h /资源/ /source/test.c

    然后您可以分支/,并使用svn:externals 功能将您的标题链接到主干的头部。它仅适用于目录,并且在提交回 test.h 方面存在一些限制(您必须进入头目录才能使其工作)但它可以工作。

    【讨论】:

      【解决方案4】:

      Subversion“分支”只是存储库中某些内容的副本。所以如果你想分支一个文件,你就这样做:

      svn copy myfile.c myfile_branch.c
      

      【讨论】:

      • 你误会了。我想要一个具有两个备用分支的文件(或其他一些 CM 系统术语中的“历史”)。我不想要两个相关但不同的文件。
      • 在 Svn 中,分支只是(文件或目录的)副本。因此,当仅分支一个文件时,您可以将其保存在同一目录中(但使用此处建议的不同名称),或者将其放入不同的目录中......我怀疑 Subversion 是否提供任何其他选项。历史是分支的。
      • 我意识到一个分支只是一个副本。 (SVN 坚持在 UI 中公开它是我的主要抱怨之一。)我可以接受“你不能那样做”的答案。我宁愿不用锤子来打螺丝。我只是想了解可用的工具。
      【解决方案5】:

      我认为分支单个文件没有多大意义?有没有办法用trunk代码测试一下?

      如果您想撤销更改并在以后应用它们,您可以使用补丁来代替。

      【讨论】:

      • 如果他要对该文件进行大量更改并希望安全但将他的队友与他正在进行的工作隔离开来,这是一项合法的任务。
      • 有一点。我已经更新了这个问题,试图澄清用例。
      • 另一个例子——我们的项目正在从一个插件版本转换到另一个版本。这需要更改 Eclipse 属性。我们让他们检查。我们如何让人们同时运行旧版本和新版本的插件?如果一个分支除了 Eclipse 配置文件必须不同之外,其他分支相同,那就太好了。
      【解决方案6】:

      您确定您的 VCS 中确实需要此功能 吗?

      为什么不使用 C 预处理器并 #ifdef 去掉不需要的代码?或任何类似的工具。

      类似:

      // foo.h:
      void Foo();
      
      // foo_win32.c
      #ifdef _WIN32
      void Foo()
      {
         ...
      }
      #endif
      
      // foo_linux.c
      #ifdef _GNUC
      void Foo()
      {
         ...
      }
      #endif
      

      有时如果它不合适,那么它不是正确的解决方案。

      【讨论】:

      • 是的,我希望这是 VCS 的一项功能。用例只是一个易于理解的示例。我的实际情况稍微复杂一些,不仅限于 C。到目前为止,“不是正确的解决方案”对我来说不是 SVN。
      【解决方案7】:

      SVN 中的一个分支只是一个副本。我相信要按照您希望的方式进行操作,您必须将文件的每个版本都放在存储库的单独目录中,并将其检出到您的源文件夹中。 IE。将该文件视为一个单独的项目。

      【讨论】:

        【解决方案8】:

        Subversion 中的一个分支正是您所说的。所有文件都是主干的精确副本,您更改的文件除外。这就是 SVN Book 中谈到的“廉价复制”方法。唯一需要注意的是需要不时将主干合并到分支中,以确保在那里所做的更改反映在分支中。当然,如果不需要这些更改,则不需要进行主干->分支合并。

        允许自动合并主干更改(模拟 Clear Case 范例)的一种简单方法是使用预提交挂钩脚本在提交之前合并主干更改。(实际上,这始终是防止代码漂移的好策略)。

        【讨论】:

          猜你喜欢
          • 2010-09-19
          • 1970-01-01
          • 1970-01-01
          • 2010-10-02
          • 1970-01-01
          • 1970-01-01
          • 2012-01-29
          • 2010-11-25
          • 2013-03-12
          相关资源
          最近更新 更多