【问题标题】:Commits to SVN branches affects trunk as well提交到 SVN 分支也会影响主干
【发布时间】:2014-12-09 13:37:44
【问题描述】:

我有一个问题,每当我使用 TortoiseSVN 从主干创建一个分支时,在我进行更新后,对该分支的所有提交也会显示在我的主干文件夹中,反之亦然。

我做的是:

  1. 使用 TortoiseSVN 将 /trunk 分支到 /branches/foo。在对话框中选择“将工作副本切换到新分支/标签”选项。
  2. 运行“更新”以将 /branches/foo 文件夹添加到我的工作副本中,该工作副本以项目目录为根。
  3. 更改 /branches/foo 中的文件
  4. 提交此更改
  5. 运行“更新” - 这会导致我的工作副本的 /trunk 文件夹中的同一文件也随着分支中所做的更改而更新

如何断开此链接 - 或创建一个分支而不将其与主干 1:1 链接?

我找到的唯一解决方案是复制整个主干文件夹并再次添加每个文件;虽然这不应该是必要的。

【问题讨论】:

  • 如果您以1.2. 等开头,格式将按照您想要的方式进行。看看我的编辑。
  • 将您的问题的详细信息和一些答案的 cmet 拼凑在一起,我想我收集了一些更相关的信息。我冒昧地将这些信息直接放在问题中。请检查这是否仍然是您的问题的准确描述。

标签: svn tortoisesvn branch


【解决方案1】:

从您的 cmets 的另一个答案来看,您似乎在使用 SVN 效率低下。我认为这是您问题的根源。

听起来您的工作副本是项目根目录,在您的计算机上,您可以看到每个分支、每个标签以及主干。当您进行更新时,您会在根项目中更新,并在每个分支中获取所有更改。

这不是 SVN 的预期用途。

预期用途是为每个感兴趣的分支检查一个工作副本。如果您正在使用主干,只需检查主干。如果您正在处理功能分支,只需检查该分支。您可以为多个任务拥有多个工作副本。

你现在的做法是,如果你的项目变得非常大,有大量的分支和标签,你在签出顶级文件夹时可能会占用千兆字节的空间,并且每个操作都需要一个很长时间才能完成。

为什么这与您的问题有关?以下是我假设发生的情况:

  1. 你的树干分支
  2. 您选择自动将工作副本切换到分支。 这只影响了您工作副本中的一个文件夹。现在您的“主干”文件夹根本不是主干,它实际上指向您的分支。这显然会在以后变得混乱。
  3. 您在“分支”文件夹中进行了更改并提交了它。
  4. 您在顶层执行了“更新”。
  5. 您会看到“分支”文件夹中的更改现在也位于“主干”文件夹中。

现在,由于您选择切换主干文件夹,您机器上的“主干”指向 SVN 存储库中的实际主干文件夹。它指向分支。这就是为什么您会在机器上看到“主干”的变化。如果您进入存储库浏览器,我希望您不会在主干中看到您的分支更改。如果你将你的trunk文件夹“切换”回trunk,你应该会看到你的更改从你机器上的trunk中消失了。

为避免将来出现这种情况,可以:

  • 将您的工作流程更改为指向单个主干或分支而不是整个项目的工作副本的推荐方法。如果您这样做,选择自动“切换工作副本”选项很有用,因为您可以从主干开始,将其分支,然后使用相同的工作副本继续在分支上工作。使用此方法,您通常会将整个工作副本“切换”到新位置,而不是工作副本中的单个文件夹,以避免混淆。
  • 继续做你正在做的事情,检查整个项目。 永远不要在你的工作副本中切换任何东西,因为如果你这样做,文件夹将不会指向你期望的位置。在这种方法中,“切换”只会造成混乱。从主干分支后,您必须更新才能看到分支,然后找到该分支并在那里开始工作。希望您的项目永远不会大到吃掉您的整个硬盘驱动器,或者如果威胁要这样做,请开始使用稀疏结帐。

【讨论】:

  • 感谢您清理一切。这正是我一直在做的事情,也是我遇到问题的原因。我不知道 SVN 中有什么叫做“switch”的东西,分支不仅仅是文件夹。从现在开始,我会让我的团队以正确的方式使用 SVN,这样我们就可以避免这个问题。非常感谢您的帮助。
  • 以防万一不清楚,每个工作副本的单个主干/分支并不表示服务器上的任何存储库布局更改;只需更改您结帐的深度即可。
【解决方案2】:

Ben 和 David W 的帖子非常棒……感谢他们俩!他们的解释确实帮助我理解了主干、标签、分支如何存在于 SVN 服务器和 SVN 客户端上。除此之外,我有一些场景反映了上述答案并提供了额外的工作流程方法。

下面的场景显示了该文件夹上的本地文件夹结构和相关的 SVN 命令(缩进的文件夹是子文件夹)。另外,为简洁起见,我只显示了主干和分支文件夹(未显示标签文件夹)...为了便于讨论,可以添加标签文件夹并将其视为与分支文件夹完全相同。


场景A

这就是 O.P. 使用 SVN 的方式:

Project         << svn co http://server/svn/Project
    trunk
    branches
        branch1
        branch2

...这会检出整个存储库的完整副本(主干加上所有分支加上所有标签)。在除“Project”之外的任何子文件夹中执行“svn switch”会导致混淆,因为(原始)“工作副本”已经在“Project”中,并且您最终会在同一棵树的两个不同文件夹中获得两个工作副本。因此,本上面关于永远不要切换的建议是有道理的。尽管如此,如果您从不切换(子文件夹),则使用此工作流程是完全有效的。


场景 B

这就是 Ben 在上面讨论的内容(“改变你结账的深度”):

...if you want to work on the trunk:
Project         << svn co http://server/svn/Project/trunk
...if you want to work on branch2:
Project         << svn switch http://server/svn/Project/branches/branch2

...所以一个文件夹(“项目”)会随着时间的推移改变其上下文,因为您每次都执行 svn checkout 或 svn 切换到不同的 URL。但是了解本地文件夹的工作环境并不是很明显。在 TortoiseSVN 中,您可以右键单击并选择“切换”来查看当前 URL(然后取消切换)或从命令行使用“svn info”,但这些都是额外的步骤。尽管如此,这听起来像是使用 SVN 的一种非常常见的方式。


场景C

这是 David W 在上面讨论的场景 B 的一个变体……这种方法使(视觉上)正在处理哪个主干/分支/标签更加明显:

Project_trunk     << svn co http://server/svn/Project/trunk
Project_branch2   << svn co http://server/svn/Project/branches/branch2

...并且永远不要在上述本地文件夹上进行 svn 开关,因为这会导致混淆(例如,在 Project_branch2 上发出“svn switch http://server/svn/Project/trunk”会使本地 branch2 文件夹保存 repo 主干的内容)。无论如何,这种方法确实可以让您的本地文件夹包含的内容立即在视觉上显而易见。


场景 D

这是场景 A 和 C 的混合体,它使用项目名称将所有主干/标签/分支封装在一个顶级文件夹下,模仿 repo 上的结构:

Project           << (no SVN checkout performed on this folder)
    trunk         << svn co http://server/svn/Project/trunk
    branches      << (no SVN checkout performed on this folder)
        branch1   << svn co http://server/svn/Project/branches/branch1
        branch2   << svn co http://server/svn/Project/branches/branch2

在这种方法中,您可以通过避免对“项目”进行 SVN 签出来避免获取整个仓库,并且通过避免对文件夹“分支”进行 SVN 签出来避免获取所有分支。因此,就像场景 C 一样,它是对分支或主干的选择性检出,但它仍然像场景 A 中一样反映 repo 的结构。我提出这个是因为这是我可视化本地结构的第一种方式(作为远程的镜像)结构的一致性)。我喜欢它如何反映存储库上的结构,但是如果这在工作流程中提供了更多的清晰度,则值得商榷,因为您必须记住“特殊规则”以避免签出并打开文件夹“项目”和“分支”。

我的(主观)结论是,最明显的工作流程是上面的 B 和 C,因为它们没有需要记住的特殊情况,但如果适合您,当然可以使用 A 和 D。无论如何,浏览这些场景帮助我想象和理解如何处理主干、标签和分支。希望对其他人有所帮助!

【讨论】:

    【解决方案3】:

    我认为您误解了 Subversion(尤其是 TortioseSVN)的工作原理。

    在 Subversion 中,当您执行 checkout 时,您会创建一个工作目录。当您对您的分支的该工作目录执行 update 时,您正在将该工作目录更改为您的分支(如果我了解您的工作流程)。主干没有改变,只是你的工作目录。

    Subversion 的一个优点是它很容易拥有多个工作目录。 (你可以在 Git 中,但你最终会得到整个存储库的多个副本)。因此,对每个分支进行单独的结帐。我有一个名为workdir 的目录,在该目录下,我的所有分支都在它自己的目录中(workdir\trunkworkdir\foo 等)这样,我就不会混淆哪个分支或主干在我的工作目录中。

    【讨论】:

    • 谢谢,虽然我仍然不确定它是如何工作的,以及 SVN 中的“工作目录”是什么。我已经习惯了 HG,你只看到你的活动分支 - 但在 SVN 中,我同时看到所有分支,只是放在不同的文件夹中。我的假设是,这意味着如果我进入一个文件夹 (/branches/foo) 并更改了一个文件,此更改不会对另一个文件夹 (/trunk) 中的同名文件产生任何影响。但是,当我更改一个时,我可以看到两个文件夹的构建作业都被触发,因为两个文件都更改了。
    • 不确定你做了什么。在 SVN 中,主干、分支和标签只是一个巨大的 repo 树中的目录。您通常签出子树(即单个分支上的单个项目)。更改一个分支上的文件不应影响其他分支或该主干。
    • 工作目录是您检出 repo 有限视图的地方(通常是单个分支或主干上的单个项目)。您可以对不同的工作目录进行多次签出。 (例如 D:\workdir\foo-branch\myprojD:\workdir\trunk\myproj)。您可以将工作目录切换 到另一个分支,但我通常不建议这样做。使用数百 GB 的磁盘,空间通常不是问题,并且分开放置可以防止混淆。
    • 我想知道您是否在同一个工作目录中签出了两个不同的版本,这导致了您的问题。在两个完全不同的目录中执行两个新的结帐——一个用于您的分支,一个用于您的主干。看看这是否会阻止您在更新分支时更新您的主干。
    【解决方案4】:

    每次您在 Tortoise 中创建分支时,它都会询问您是要切换到分支还是保留在主干中,如果您不切换,您正在提交的所有更改仍将提交到主干..

    此外,Update 将使用服务器版本更新您的本地文件,并且提交会将您的文件发送到服务器(如果您切换到它,则发送到选定的服务器文件夹、主干或其中一个分支)

    【讨论】:

    • 当我创建分支时,我选择了“将工作副本切换到新分支”。但是,当我随后在新的分支文件夹中编辑文件时,同样的更改也复制到了 SVN 服务器上的主干文件夹。我了解到我在其中进行更改的文件夹,即更改后的文件夹。我总是在根文件夹上运行更新,以获取对所有分支的所有更改,并且我总是从根文件夹提交,以将我的更改提交到单独更改的分支文件夹。这在我复制主干以分支时有效,但在我 SVN 分支时无效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 2011-03-19
    • 2019-09-13
    • 2010-11-22
    • 2016-11-23
    • 2012-10-19
    相关资源
    最近更新 更多