svn:用分支替换中继


155

使Subversion存储库的分支之一成为新主干的最佳方法是什么?

整个系统进行了重大的重写:内容已经移动,重写,替换,删除,重命名等。重写的代码已经过测试,可以替换旧的主干了。

基本上,旧的干线(中继5)被标记了,并将在此处结束。改写后的分支(分支6)将成为新的主线(分支7):

中继(1)->中继(2)->中继(5)->×+->新中继(7)
  \ \ |
  叉合并???
    \ \ |
     +->分支(3)->分支(4)->分支(6)-+

旧的“主干”中所有正在进行的更改已合并到“重写的分支”中

我怎样才能做到这一点?

Answers:


118

使用svn move将旧干线的内容移动到其他位置,然后将分支重命名为干线。

请注意,在svn中复制和移动就像文件操作一样。您可以使用它们来移动/复制存储库中的内容,并且这些更改也将进行版本控制。将“移动”视为“复制+删除”。

[编辑] Nilbus刚通知我,使用时将发生合并冲突svn move

我仍然认为这是正确的方法。它将引起冲突,但是如果您仔细合并,很可能不会丢失任何数据。如果那样困扰您,请使用更好的VCS,例如MercurialGit


1
如果执行此操作,则在原始主干中的工作副本中发生更改的任何人都将发生冲突,即使他们的更改应合并。这是因为文件被删除并重新添加-它们被视为具有单独历史记录的单独对象。
爱德华·安德森

@nilbus:您尝试过吗?IIRC,SVN显示文件已被删除和读取,但在内部,它将知道文件已被移动。
亚伦·迪古拉

是。我签了两份。在第一个副本中,我将目录A移至A2,并将目录B移至A。然后将A移至B,然后将A2移至A。(重命名并重命名。)在第二个签出中,我对文件进行了更改并尝试svn更新。由于我更改的文件“已删除”而发生冲突。在内部它不会保存文件的重复副本,但是遇到冲突时,看到的Delete确实会影响您。
爱德华·安德森

12
@nilbus:在这一点上,我想引用Linus Torvalds的话:“ Subversion的口号有一阵子是“ CVS做对了”,或者类似的事情,如果您以这种口号开始,那么无处可走走吧。没有办法正确地进行CVS。”
亚伦·迪古拉

3
是的 我会同意的。为了解决这个问题,我实际上使用svn-git签出了回购协议,并使用git将分支重新建立到主节点上。
爱德华·安德森

66

我同意使用svn move命令来实现此目标。

我知道这里的其他人认为这很不寻常,但是我喜欢这样做。当我有一个功能分支并准备将其与也已进行重大修改的主干合并时,我会将其合并到一个新分支,通常命名为<FeatureBranchName>-Merged。然后,我解决冲突并测试合并​​的代码。完成此操作后,我将后备箱移动到标签文件夹,这样我就不会丢失任何东西。最后,我将我<FeatureBranchName>-Merged移到后备箱。

此外,我更喜欢在移动时避免使用工作副本,这是命令示例:

svn move https://SVNUrl/svn/Repo/trunk https://SVNUrl/svn/Repo/tags/AnyName

svn move https://SVNUrl/svn/Repo/branches/BranchName-Merged https://SVNUrl/svn/Repo/trunk

注意:我用1.5


1
这可能不是最佳实践,但是当您有一个非常旧的主干并且每个人都在分支上工作时,好像它是主干一样,这肯定是最有效的。它解决了我的问题!
亚历克斯·佩林

12

我最近只是在看这个问题,而我很满意的解决方案就是执行

svn merge --ignore-ancestry主干URL分支URL

在我的行李箱的工作副本上。

这不会尝试以历史方式应用更改(保持主干中的更改)。它只是在分支和分支之间“应用差异”。在未修改的文件中,这不会为您的用户造成任何冲突。但是,您将从分支中丢失历史信息,但是无论如何执行合并都会发生这种情况。


1
在svn 1.5之后,您应该能够进行合并以保留历史记录。
NSherwin

9

建议您通过资源库浏览器工具进行这些更改。

通过工作副本尝试大型删除+移动操作是杀死工作副本的一种好方法。如果您被迫使用工作副本,请在每次删除或移动操作后执行增量提交,并在每次提交后更新您的工作副本。


到Repo的链接将很方便(为方便起见-保存Google搜索:))
Brian M. Hunt

3
抱歉。拼写使它看起来像我在指的是特定工具(已编辑)。实际上,大多数SVN GUI工具都应具有存储库浏览器功能。仅供参考:我使用陆龟tortoisesvn.tigris.org
克里斯·纳瓦

4

如果要使分支成为新的主干(即)以摆脱自创建分支以来在主干中所做的所有更改,则可以1.创建主干的一个分支(用于备份)2.“还原更改(在分支上选择所有修订版。3.将分支合并回主干。

历史应该这样保留。

问候,罗杰


3

@Aaron Digulla和@kementeus解决方案是可行的。对于Subversion 1.4存储库,复制/移动操作会使将来迁移到其他存储库结构或拆分存储库变得困难。

我认为1.5的改进包括更好的移动/复制历史记录解析,因此对于1.5存储库而言,这可能不是问题。

对于1.4存储库,我建议使用svnadmin dumpsvndumpfilter执行现有主干在其他地方的移动,然后以相同的机制将分支移动到主干。将两个转储文件加载到测试存储库中,进行验证,然后将其移至生产环境。

当然,在启动之前,请备份现有的存储库。

这样可以保留历史记录,而无需明确记录移动/复制,并且使将来的重组,保存历史记录变得更加容易。


编辑:根据要求,来自1.4 Red-Bean书中的1.4行为的文档,筛选存储库历史记录

另外,复制的路径会给您带来一些麻烦。Subversion支持存储库中的复制操作,该存储库中通过复制一些现有路径来创建新路径。在存储库生存期内的某个时候,您可能已经将文件或目录从svndumpfilter排除的某个位置复制到了它所包含的位置。为了使转储数据自给自足,svndumpfilter需要仍然显示新路径的添加项(包括副本创建的任何文件的内容),而不必将添加项表示为来自过滤后的转储数据流中不存在的源副本。但是,由于Subversion存储库转储格式仅显示每个修订版本中进行了更改,因此复制源的内容可能不容易获得。如果您怀疑存储库中有此类副本,则可能需要重新考虑一组包含/排除的路径,也许还包括麻烦的复制操作来源的路径。

这适用于使用进行的迁移/重组svndumpfilter。有时候,有些额外的工作现在可以在以后节省很多额外的工作,并且通过svndumpfilter在以后的迁移/重组中保持易于使用的可用性,可以以相对较低的成本降低风险。


为什么“ svn move”还不够?您的建议似乎就像用大锤压扁苍蝇。
罗布·威廉姆斯

我被这个1.4行为所困扰-如果SVN储存库包含目录或分支/标签的移动(重命名),则使用svndumpfilter来帮助将储存库重组/迁移到新结构可能会失败,因为它无法处理历史记录好。有文档记录,我将参考文献进行挖掘。如果您喜欢
Ken Gentle

您可以添加对此行为的引用吗?
Jacco

2

尽管上面的答案会起作用,但这不是最佳实践。最新的svn服务器和客户端轨道将为您合并。因此,svn知道您已将哪些修订合并到分支中以及从何处合并。在保持分支最新,然后将其合并回主干时,这很有帮助。

但是,无论您使用的是哪个版本的Subversion,都有一种最佳实践方法可以将分支中的更改恢复到主干。它在Subversion手册中概述:Subversion的版本控制,第4章。分支和合并,保持分支同步


感谢官方信息,以便我可以通过官方方法将分支合并到主干。关键字是reintegrate
Junyo '18

-3

在SVN中,这是一个非常奇怪/不寻常的配置,即使我认为它也根本不是一个“好习惯”,无论如何,我想您可以执行以下操作:

  • 签出所有sourcetree(svn co therootsourcetree)
  • 卸下行李箱(SVN rm行李箱)
  • 将分支复制到主干(svn cp branch / thebranch / trunk)
  • 删除分支(svn rm分支/分支)
  • 提交更改

祝好运


9
这破坏了通过“ svn move”保留的历史痕迹。
罗布·威廉姆斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.