如何在SVN中分支单个文件?
分支的颠覆概念似乎集中在创建要在其上进行开发的整个存储库的[不稳定]分支上。是否有创建单个文件分支的机制?
对于一个用例,请考虑具有多个特定于平台的源(* .c)实现的公共头文件(* .h)。这种分支是永久分支。所有这些分支都会看到偶尔的跨分支合并的持续发展。这与通常具有有限寿命的不稳定的发育/稳定释放分支形成鲜明对比。
我不想分支整个存储库(无论是否便宜),因为它会造成不合理的维护量,以在主干和所有分支之间不断合并。目前,我正在使用ClearCase,它具有不同的分支概念,这使此操作变得容易。我被要求考虑过渡到SVN,但是这种范例差异很重要。我更关心的是能够轻松地为单个文件创建替代版本,而不是像剪切稳定的发布分支之类的事情。
解决方案
Subversion"分支"只是存储库中某些内容的副本。因此,如果我们想分支文件,则只需执行以下操作:
svn copy myfile.c myfile_branch.c
SVN中的分支只是一个副本。我相信,要按照我们希望的方式进行操作,必须将文件的每个版本都放在存储库中的单独目录中,然后将其签入源文件夹。 IE。将该文件视为一个单独的项目。
我们不必分支整个存储库。我们可以在项目中创建文件夹的分支(例如包含文件夹)。正如其他人指出的,我们也可以只复制一个文件。拥有文件或者文件夹的副本后,可以"切换"到分支文件或者文件夹以使用分支版本。
如果在存储库中创建单独的分支文件夹,则可以通过服务器端命令在其中复制分支文件:
svn copy svn://server/project/header.h svn://server/branched_files/header.h
然后,我们可以将该文件切换为使用branches_files
存储库路径
可悲的是,我认为真正的答案是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客户端编写包装器以处理所有混乱。
我认为分支单个文件没有太大意义吗?没有办法用中继代码对其进行测试?
如果要撤消更改并稍后应用它们,则可以改打补丁。
我们确定VCS中确实需要此功能吗?
为什么不使用C预处理程序并#ifdef删除不需要的代码?或者任何类似的工具。
就像是:
// foo.h: void Foo(); // foo_win32.c #ifdef _WIN32 void Foo() { ... } #endif // foo_linux.c #ifdef _GNUC void Foo() { ... } #endif
有时,如果不合适的话,那不是正确的解决方案。
这是我对问题的理解。我们有以下树:
time.h time.c
并且我们需要针对多种架构拒绝使用它:
time.h is comon time.c (for x386), time.c (for ia64), time.c (for alpha),...
同样,在当前的VCS中,我们可以根据需要从time.c创建多个分支,并从VCS检出文件时,自动从公共中继检查最新的time.h和从分支检查最新的time.c。你正在努力。
我们担心的问题是,如果在签出分支时使用SVN,则必须经常从主干合并time.h或者冒着处理旧文件(与主干相比)的风险,这是不可接受的给你。
但是,根据源代码的结构,可能会有解决方案。想像你有
/ /headers/ /headers/test.h /source/ /source/test.c
然后,我们可以分支/,并使用svn:externals功能将标头链接到行李箱的头部。它仅适用于目录,并且在提交回test.h方面有一些限制(我们必须进入标头目录才能使其工作),但是它可以工作。
Subversion中的一个分支正是我们在说的。除更改的文件外,所有文件都是主干的精确副本。这是SVN手册中讨论的"廉价复制"方法。唯一的警告是需要不时将主干合并到分支中,以确保在那里所做的更改反映在分支中。当然,如果不需要这些更改,则不需要进行主干->分支合并。
一种允许自动合并主干更改的简单方法(模拟Clear Case范例)是使用预提交钩子脚本在提交之前合并主干更改(实际上,这始终是一个防止代码漂移的好策略)。