代码之家  ›  专栏  ›  技术社区  ›  Synetech

?构建修订控制系统(SVN)以处理依赖项

  •  1
  • Synetech  · 技术社区  · 16 年前

    多年来,我一直在用一种简单的方式编程:我会将源文件保存在按语言和项目组织的目录中,偶尔进行手动备份,如果我聪明,我会在尝试新版本之前复制一份;这就差不多了。

    我最近决定开始使用修订控制。在检查了大量的文章和页面,尝试了很多不同的文章和页面之后,我最终决定进行颠覆(尽管由于基础的原因,它使项目的规模翻了一番)。


    我现在需要一些建议,在一些方面,我似乎找不到有用的信息。首先,我要检查一下我是否有正确使用RCS的基本过程:

    1. 将我的所有项目导入SVN存储库
    2. 删除原件
    3. 从存储库签出项目
    4. 努力工作
    5. 提交它

    是吗?那么新项目呢?我需要在文件夹中创建一个新项目,然后导入它吗?


    我在目录结构方面也遇到了问题,但首先,我可能应该安排我的设置。我是一个在我的家用机器上工作的开发人员。我的数据目录中有以下类型的布局:

      X:\Data
          \H
            \3rdParty
              \Graphics
            \Controls
              \ThisControl
              \ThatControl
            \Libraries
            \Classes
              \CFoo
              \CBar
          \VC
            \Big
              \CoolApp
                \res
            \Small
              \CoolerApp
                \res
                \misc
            \Test
              \CFooTest
    

    等等。

    我有几个经常使用的头目录(例如 第三方\图形 , 类cfo 等等)在我的IDE的include路径中。以前依赖关系已经存在问题,但现在对于rcs,它甚至更糟。例如, 库拉普 可能包括 这种控制 首席财务官 . 以前,如果我修改了 首席财务官 在工作时 库拉普 打破它,其他使用它的应用程序 库勒普 因此也会被破坏。

    我这样做而不是抄袭的原因 首席财务官 等。到 库拉普 __S和其他_目录是因为尝试将每个副本的更新合并回 h 文件夹。

    我本以为通过使用一个正式的rcs,这类问题就可以得到解决。但是,现在发生的是当我从 \vc\CaloApp 等,进入SVN存储库,组件如 首席财务官 ,*库\**等不包含在内,因为它们位于外部目录中,因此不受版本控制,从而破坏了整个要点。

    我正在寻找如何处理这种情况的技巧。例如,如果我有 cWIDGET 在里面 h 小测试 (一个测试容器,包括 cWIDGET VC 那么我该如何构造这样的东西 小测试 cWIDGET 获得版本控制,同时尽可能简化其他使用 cWIDGET 是否包括并使用最新版本?


    此外,我只能将所有项目导入到同一个存储库目录中,丢失 大的 , , 测试 等结构。我不能让颠覆来保持这种状态。


    最后,原始项目目录会变成什么?我至少看过一篇文章,上面说一旦导入到存储库中,它们就可以被删除。如果是这样的话,我可能会把它们拉上拉链然后放好。



    噢,我现在已经在Apache服务器上设置了Subversion,并安装了VisualVN、SVNServer和Collabnet SVN服务器。我已经让每个人都工作了,但我希望得到一些建议,因为我确定我只需要一个。



    非常感谢你。

    2 回复  |  直到 16 年前
        1
  •  2
  •   Jim T    16 年前

    好吧,我将集中在你问题的共享项目部分,因为我刚从一个工作场所来,在那里我们有多个项目和多个颠覆性的共享项目。

    我建议的第一件重要的事情是,你开始使用以下想法: “在硬盘上的任何位置对项目主干进行签出是构建解决方案所必需的全部内容。”

    还要记住 没有更改的工作副本没有值 . 不管你在磁盘上的哪个位置签出东西,删除一个工作副本都不应该让你惊慌失措,因为你可以再次签出主干然后马上启动。我发现在我以前的地方,我们非常小心地“设计”开发环境,把所有的东西都放在正确的地方。这是荒谬的,花在这上面的时间永远不会回来。做一次,在一个体面的源代码控制(如svn,或git,或tfs)做它,并且很高兴你现在可以通过工作拷贝像昨天的报纸。

    工作副本具有任何值的唯一时间是是否有尚未提交的任何修改。 任何有价值的工作副本都容易受到攻击 . 始终在可行的情况下尽快提交修改。任何形式的硬盘故障(包括工作副本损坏)、意外删除、从工作到不工作的更改等都有可能导致大量工作的丢失-这是很有价值的一点。如果半成品代码不适合在项目的主干中看到,那么就创建一个分支并提交给它。

    这意味着您将能够在驱动器的不同位置签出同一项目的多个版本,并对它们进行工作(例如,开发和实时错误修复版本)。它还意味着,检查主干将使该工作副本文件夹下的所有依赖库关闭。

    它还意味着拥有头/库所在位置的IDE级别定义是行不通的。这是Visual Studio引入的一个糟糕的想法,但它们也允许您使用单个项目设置中的相对文件夹(应该在哪里)来指定这些内容。相信我,如果您使用的是IDE级别的位置定义,那么在某个时候,您将要构建应用程序,并试图找出更改没有出现的原因。然后当你意识到你刚刚针对一个旧的、有缺陷的库版本构建了最后3个版本时,你会有一种沉闷的感觉。至少我做到了。

    为了解决这种乌托邦的情况,如果您将每个项目和库(例如,CoolApp、CFO、ThisControl、CWIDget)视为具有单独发布周期、集群等的单独项目,那么您的境况会更好。朝着独立思考这些事情的方向前进,分别发展和释放它们。

    这听起来开销很大,但是如果您希望在不破坏其他使用它的项目的情况下对共享组件进行更改,这是必要的。

    考虑到这一点,我建议您构建这样的存储库:

    /Projects
     /CoolApp
      /trunk
      /branches
      /tags
    /Libraries
     /CFoo
      /trunk
      /branches
      /tags
     /CWidget
      /trunk
      /branches
      /tags
     /ThisControl
      /trunk
      /branches
      /tags 
    /Vendor
     /NUnit
      /current
      /1.6
      /1.7
    

    如果您的存储库当前没有这样设置,您可以使用SVNCopy来构造它。您可以在顶层使用标记/主干/分支以及下面的所有内容,但在我看来,这样做使得概念上分离项目更加困难。

    现在只需检查主项目(CoolApp)的主干。当然-这不会按原样构建,因为没有任何依赖项目。 下一步是将其他项目添加为 外部因素 . 在使用Tortoissesvn的工作副本的顶级文件夹中,右键单击并转到svn->属性。添加名为“svn:externals”的新属性。以格式定义属性

    /repository_location[@revision]    working_copy_folder
    

    因此,对于CoolApp,您可以添加以下SVN:Externals定义:

    /Libraries/CFoo/trunk        CFoo
    /Libraries/CWidget/trunk     CWidget
    /Libraries/ThisControl/trunk ThisControl
    

    完成后,提交更改,然后进行“更新”,外部的内容也将被删除。

    您可以使用这种形式的外部定义构建任何工作副本文件夹结构。您必须修改解决方案文件才能在新位置查找项目,但这通常不是一个大问题。

    一旦你以这种方式工作起来,注意让外部物体指向一个主干通常是一个非常糟糕的主意。这是因为当库的主干因为另一个项目而更改时,当您对解决方案(或更新)执行新的签出时,您的完美解决方案将不会生成——即使您认为您没有更改其中的任何内容。 开始为库制作标记,并将外部对象指向它们。这是当您开始将库视为独立的项目时。

    这是另一个原则的情况: “对项目的任何更改都必须在主项目的主干中进行相应的修订。” 更改外部位置以指向新的库版本是一个很好的例子,可以说“嘿,我现在使用的是第2版的傻瓜”。上一段中的问题是因为代码在您的“下面”发生了变化。

    要修改一个库,您最好签出该库主干的工作副本,修改它并用新版本号标记它。然后在主项目中,将外部更改为指向新标记并更新。

    您可以通过将您的库位置从标记“切换”到主干来实现此过程的快捷方式。这样,当您提交时,您将把库更改提交到主干。但是,通过这种方式,您需要记住外部仍然指向标记-您仍然需要标记库并更改项目外部,否则将无法生成新的签出。

    如果您依赖任何第三方工具,如nant或nunit,那么将它们作为供应商分支添加到存储库中,并通过外部引用它们。VS允许您通过浏览来引用DLL,这比GAC更灵活。对于一个开发人员来说,这听起来可能不是什么问题,但是如果你尝试一次升级一个项目,你会发现签出项目的主干并知道你已经得到了正确版本的nunit(而不是必须卸载nunit并重新安装正确版本),这样做会更好。

    也请注意,没有必要 每一个 将解决方案中的项目作为单独的外部项目。只有在不同的项目之间可以或应该共享的东西才应该被分离出来。

    最后,一旦您启动并运行,我真的建议您使用构建引擎,如CruiseControl.net或Hudson(我的最爱)。这会在问题暴露在雷达下并从后面咬你之前给你快速反馈。

    好吧,我现在停下来,我不想去拿“最长答案”的徽章。

        2
  •  2
  •   nsanders    16 年前

    Subversion Book(免费在线)提供了几种建议的存储库配置:

    http://svnbook.red-bean.com/

    本页提供了有关进一步阅读的良好链接:

    http://svnbook.red-bean.com/en/1.5/svn.tour.importing.html#svn.tour.importing.layout

    SVN的一个非常好的地方是,在目录中移动是非常小的,这对CVS来说是不正确的。所以,不要觉得有压力来制定一个“最终的”组织权的蝙蝠。做一些有用的事情,玩弄结构直到你更喜欢它。

    另一件值得一提的事情是,SVN对数据使用了copy-on-write技术。因此,随时可以根据需要制作整个目录的“svn cp”副本。