我该如何在SVN中分支一个单独的文件?

9
分支的Subversion概念似乎集中在创建整个代码库的[不]稳定分支上进行开发。是否有一种机制可以创建单个文件的分支?
举个例子,考虑一个常见的头文件(*.h)文件,它具有多个特定于平台的源(*.c)实现。这种类型的分支是永久性的。所有这些分支都将进行持续开发,并偶尔进行跨分支合并。这与不稳定的开发/稳定的发布分支形成鲜明对比,后者通常具有有限的生命周期。
不想分支整个代码库(无论便宜还是昂贵),因为这会产生大量的维护工作,需要不断地在主干和所有分支之间进行合并。目前我正在使用ClearCase,它具有不同的分支概念,使这个过程变得容易。我被要求考虑转换到SVN,但这种范式差异很重要。我更关心能否轻松地为单个文件创建替代版本,而不是像切割稳定发布分支这样的事情。

1
你在另一个评论中提到这实际上不是你的使用情况。当答案试图解决这种情况而不是你实际的情况时,请不要感到惊讶。 - wnoise
8个回答

9
您无需分支整个代码库,您可以对项目中的文件夹(如 include 文件夹)进行分支。正如其他人所指出的,您也可以只复制单个文件。一旦您拥有了文件或文件夹的副本,您就可以“切换”到分支文件或文件夹上,以便开始使用分支版本。
如果您在代码库中创建了一个独立的分支文件夹,您可以通过服务器端命令将分支文件复制到其中:
svn copy svn://server/project/header.h svn://server/branched_files/header.h
然后,您可以将该文件切换为使用 branches_files 代码库路径。

这有点尴尬,但可能可行。感谢您的输入。 - Michael Carman

3

我理解您的问题如下:您有以下树:

time.h
time.c

你需要为多个架构拒绝它:

time.h 是通用的
time.c (适用于 x386), time.c (适用于 ia64), time.c (适用于 alpha),...

在您当前的版本控制系统中,您可以通过从 time.c 创建所需数量的分支来执行此操作,并且当您从版本控制系统中检出文件时,您会自动检查来自公共主干的最新 time.h 和来自您正在使用的分支的最新 time.c。

您关心的问题是,如果您使用 SVN 检出分支,则必须经常合并来自主干的 time.h,否则可能会在旧文件上工作(与主干相比),这种额外的开销对您来说是不可接受的。

根据源代码的结构,可能会有解决方案。想象一下您拥有的情况。

 
/
/headers/
/headers/test.h
/source/
/source/test.c

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


3
很遗憾,我认为ClearCase比Subversion更好地处理了这种情况。对于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

有点嘈杂。当你想在大型源代码仓库中分支出几个文件或模块时,它会变得非常混乱。

实际上,可能有一个不错的项目可以通过svn属性和切换来模拟类似ClearCase的分支文件,并编写一个包装器来处理所有混乱的标准svn客户端。


1
一个Subversion的“分支”只是你的代码库中某个东西的副本。所以如果你想要创建一个文件的分支,你只需要执行以下操作:
svn copy myfile.c myfile_branch.c

你误解了。我想要一个文件,有两个交替的分支(或者使用其他版本控制系统术语中的“历史记录”)。我不想要两个相关但是独立的文件。 - Michael Carman
在Svn中,分支只是一个文件或目录的副本。因此,当分支一个文件时,您可以将其保留在同一目录中(但使用不同的名称,如本文所建议),也可以将其放入不同的目录中...我怀疑Subversion提供任何其他选项。历史记录被分支。 - Alexander
1
我意识到分支只是一份拷贝。(SVN在UI中强调这一点是我对它的主要抱怨之一。)如果答案是“你不能那样做”,我也没关系。我不想用锤子来拧螺丝,我只是想了解有哪些工具可用。 - Michael Carman

1

我认为在单个文件上进行分支没有太大的意义吧?这样无法使用主干代码进行测试吗?

如果您想撤销更改并稍后应用它们,可以选择采用补丁。


1
如果他需要对该文件进行大量更改,并希望安全地将自己与正在进行的工作与团队隔离开来,那么这是一个合法的任务。 - Chris Farmer
有一个要点。我已经更新了问题,试图澄清使用情况。 - Michael Carman
另一个例子--我们的项目正在从一个插件版本转换到另一个版本。这需要更改eclipse属性。我们将它们进行了检查。如何让人们同时运行旧版本和新版本的插件?如果一个分支与另一个分支相同,除了必须不同的eclipse配置文件,那将是很好的。 - Bill K

1

你确定你真的需要在你的版本控制系统中使用这个功能吗?

为什么不使用C预处理器和#ifdef来消除你不需要的代码?或者使用类似的工具。

例如:

// foo.h:
void Foo();

// foo_win32.c
#ifdef _WIN32
void Foo()
{
   ...
}
#endif

// foo_linux.c
#ifdef _GNUC
void Foo()
{
   ...
}
#endif

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

是的,我希望这成为版本控制系统的一个功能。使用案例只是一个易于理解的示例。我的实际情况有些更加复杂,而且不仅限于C语言。到目前为止,“不是正确的解决方案”对我来说意味着不是SVN。 - Michael Carman

0

在SVN中,分支只是一份拷贝。我认为,如果你希望按照你的期望进行操作,你需要将文件的每个版本保存在存储库的不同目录中,并将其检出到源文件夹中。也就是说,将该文件视为一个单独的项目。


0
一个Subversion分支就是你所说的东西。所有文件与主干完全一样,除了您更改的那些文件。这就是《SVN Book》中所提到的“cheap copy”方法论。唯一需要注意的是,需要定期将主干合并到分支中,以确保在分支中进行的更改反映在分支中。当然,如果不希望进行这些更改,就不需要进行主干->分支合并。
允许自动合并主干更改(模拟Clear Case范例)的一种简单方法是使用预提交挂钩脚本,在提交之前合并主干更改(实际上,这总是防止代码漂移的好策略)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接