颠覆外部是一种反模式吗?

2024-01-24

Subversion 允许您使用以下方式嵌入其他存储库的工作副本外部因素 http://svnbook.red-bean.com/en/1.1/ch07s04.html,可以轻松地对项目中的第三方库软件进行版本控制。

虽然这些对于库的重用和版本控制来说似乎是理想的选择供应商软件 http://svnbook.red-bean.com/en/1.1/ch07s05.html,他们并非没有他们的批评者 https://stackoverflow.com/questions/222827/how-do-you-organize-your-version-control-repository#304036:

请不要使用 Subversion 外部组件(或其他工具中的类似组件),它们是反模式,因此没有必要

使用外部设备是否存在隐藏风险?请解释为什么它们被视为反模式。


我是问题中引用的作者,该引用来自之前的回答 https://stackoverflow.com/questions/222827/how-do-you-organize-your-version-control-repository#304036.

杰森对我这样的简短陈述表示怀疑,并要求做出解释,这是正确的。当然,如果我完全解释了该答案中的所有内容,我就需要写一本书了。

迈克也正确地指出了问题之一svn:external类似的功能是,目标源中的更改可能会破坏您自己的源,特别是如果该目标源位于您不拥有的存储库中。

在进一步解释我的评论时,让我首先说有“安全”的方法来使用svn:external-类似功能,就像任何其他工具或功能一样。然而,我将其称为反模式 http://c2.com/cgi/wiki?AntiPattern因为该功能更有可能被滥用。根据我的经验,它一直被滥用,我发现自己不太可能以这种安全的方式使用它,也永远不会推荐这种使用。请进一步注意,我并没有贬低 Subversion 团队的意思——我喜欢 Subversion,尽管我计划转到 Bazaar。

此功能的主要问题是它鼓励并且通常用于将一个构建的源(“项目”)直接链接到另一个构建的源,或者将项目链接到二进制文件(DLL、JAR 等)。这取决于什么。这些用法都不明智,而且它们构成了反模式。

正如我在其他答案中所说,我相信软件构建的一个基本原则是每个项目都构建一个二进制或主要可交付成果。这可以被认为是原理的应用关注点分离 http://c2.com/cgi/wiki?SeparationOfConcerns到构建过程。对于一个项目直接引用另一个项目的来源尤其如此,这也违反了原则封装 http://c2.com/cgi/wiki?EncapsulationDefinition。这种违规的另一种形式是尝试创建构建层次结构,以通过递归调用子构建来构建整个系统或子系统。 Maven 强烈鼓励/强制执行这种行为,这是我不推荐它的众多原因之一。

最后,我发现有各种实际问题使得这个功能不受欢迎。其一,svn:external有一些有趣的行为特征(但我暂时没有了解细节)。另一方面,我总是发现我需要这样的依赖项对我的项目(构建过程)显式可见,而不是作为某些源代码控制元数据隐藏。

那么,使用此功能的“安全”方式是什么?我认为这是仅由一个人临时使用的情况,例如“配置”工作环境的一种方式。我可以看到程序员可以在存储库中创建自己的文件夹(或为每个程序员一个),并在其中进行配置svn:external链接到他们当前正在处理的存储库的各个其他部分。然后,签出该文件夹将创建所有当前项目的工作副本。当添加或完成项目时,svn:external可以调整定义并适当更新工作副本。但是,我更喜欢一种不依赖于特定源代码控制系统的方法,例如使用调用签出的脚本来执行此操作。

根据记录,我最近一次接触到这个问题是在 2008 年夏天,当时一家咨询客户正在使用svn:external在大规模上——一切都交叉链接以产生单一的主工作副本。他们基于 Ant 和 Jython(针对 WebLogic)的构建脚本是在此主工作副本之上构建的。最终结果是:没有任何东西可以独立构建,实际上有数十个子项目,但没有一个可以安全地单独检查/工作。因此,该系统上的任何工作首先需要检出/更新超过 2 GB 的文件(他们也将二进制文件放入存储库中)。完成任何事情都是徒劳的,我在尝试了三个月后离开了(还存在许多其他反模式)。

编辑:阐述递归构建 -

多年来(特别是过去十年),我为财富 500 强公司和大型政府机构构建了庞大的系统,涉及数十个子项目,这些子项目排列在多层目录层次结构中。我已经使用 Microsoft Visual Studio 项目/解决方案来组织基于 .NET 的系统,使用 Ant 或 Maven 2 来组织基于 Java 的系统,并且我已经开始使用 distutils 和 setuptools (easyinstall) 来组织基于 Python 的系统。这些系统还包括通常位于 Oracle 或 Microsoft SQL Server 中的大型数据库。

我在设计这些大型构建时取得了巨大的成功,以实现易用性和可重复性。我的设计标准是,新开发人员可以在第一天出现,获得一个新工作站(可能直接来自戴尔,只需安装典型的操作系统),获得一份简单的安装文档(通常只有一页安装说明),并能够在无人监督、无人协助的情况下,在半天或更短的时间内完全设置工作站并从源头构建完整的系统。调用构建本身涉及打开命令外壳,更改为源树的根目录,并发出一行命令来构建所有内容。

尽管取得了成功,但构建如此庞大的构建系统需要非常小心并严格遵守可靠的设计原则,就像构建大型业务关键型应用程序/系统一样。我发现一个关键部分是每个项目(生成单个工件/可交付成果)必须有一个构建脚本,该脚本必须有一个定义良好的接口(用于调用构建过程的部分的命令),并且它必须站立独立于所有其他(子)项目。从历史上看,构建整个系统很容易,但仅构建一个系统就很难/不可能。直到最近,我才学会仔细确保每个项目真正独立。

实际上,这意味着必须至少有两层构建脚本。最底层是生成每个可交付成果/工件的项目构建脚本。每个这样的脚本都驻留在其项目源代码树的根目录中(实际上,该脚本定义了其项目源代码树),这些脚本对源代码控制一无所知,它们期望从命令行运行,它们引用项目中相关的所有内容到构建脚本,它们根据一些可配置设置(环境变量、配置文件等)引用其外部依赖项(工具或二进制工件,没有其他源项目)。

第二层构建脚本也旨在从命令行调用,但它们了解源代码控制。事实上,第二层通常是使用项目名称和版本调用的单个脚本,然后它将指定项目的源检查到新的临时目录(可能在命令行上指定)并调用其构建脚本。

可能需要更多的变化来适应持续集成服务器、多个平台和各种发布场景。

有时需要第三层脚本来调用第二层脚本(它调用第一层),以便构建整个项目集的特定子集。例如,每个开发人员可能都有自己的脚本来构建他们今天正在处理的项目。可能有一个脚本来构建所有内容,以便生成主文档或计算指标。

无论如何,我发现尝试将系统视为项目层次结构会适得其反。它将项目相互联系起来,以便它们不能单独自由构建,也不能在任意位置(持续集成服务器上的临时目录)或以任意顺序构建(假设满足依赖关系)。通常,尝试强制建立层次结构会破坏可能尝试的任何 IDE 集成。

最后,构建庞大的项目层次结构可能会导致性能过于密集。例如,在 2007 年春天,我尝试使用 Ant 构建一个适度的源层次结构(Java 加 Oracle),但最终失败了,因为构建总是因 Java OutOfMemoryException 而中止。这是在具有 3.5 GB 交换空间的 2 GB RAM 工作站上,我已将 JVM 调整为能够使用所有可用内存。就代码量而言,应用程序/系统相对微不足道,但递归构建调用最终会耗尽内存,无论我给它多少内存。当然,它也需要很长时间才能执行(30-60 分钟很常见,然后才会中止)。我知道如何很好地进行调整,但最终我只是超出了工具的限制(在本例中为 Java/Ant)。

因此,帮自己一个忙,将构建构建为独立项目,然后将它们组合成一个完整的系统。保持轻便灵活。享受。

编辑:有关反模式的更多信息

严格来说,反模式是一种常见的解决方案,看起来它解决了问题,但实际上并没有,因为它留下了重要的空白,或者因为它引入了额外的问题(通常比原始问题更糟糕)。解决方案必然涉及一个或多个工具以及将它们应用于当前问题的技术。因此,将工具或工具的特定功能称为反模式是一种延伸,而且人们似乎正在检测这种延伸并做出反应——这很公平。

另一方面,由于关注工具而不是技术似乎是我们行业的常见做法,因此受到关注的是工具/功能(在 StackOverflow 上对问题进行的随意调查似乎很容易说明这一点)。我的评论以及这个问题本身都反映了这种做法。

然而,有时进行这种延伸似乎特别合理,例如在本例中。有些工具似乎“引导”用户使用特定的技术来应用它们,以至于有些人认为工具塑造思想 http://c2.com/cgi/wiki?ProgrammingLanguagesShapeThoughts(稍微改写)。我主要是本着这种精神建议svn:external是一个反模式。

为了更严格地说明问题,反模式是设计一个构建解决方案,包括在源代码级别将项目捆绑在一起,或者隐式版本化项目之间的依赖关系,或者允许此类依赖关系隐式更改,因为这些都会调用非常负面的结果。的性质svn:external类似的特征使得避免这些负面后果变得非常困难。

正确处理项目之间的依赖关系涉及解决这些动态以及基本问题,并且工具和技术会走上不同的道路。应该考虑的一个例子是Ivy http://ant.apache.org/ivy/,它以类似于 Maven 的方式提供帮助,但没有许多缺点。我正在研究 Ivy 和 Ant,作为我解决 Java 构建问题的短期解决方案。从长远来看,我希望将核心概念和功能融入到一个开源工具中,以促进多平台解决方案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

颠覆外部是一种反模式吗? 的相关文章

  • Git 与 master 合并,无需签出 master

    每次我需要的时候merge develop with master I do git checkout master git merge develop 有时我忘记切换出去master 因此 我在运行时错误地更改了代码master 它可能会
  • 将 git 与 svn 一起使用的好习惯

    Subversion 几年前就很流行 现在 git 也开始流行 越来越多的人想用 git 取代 Subversion 问题是很多项目都是基于 Subversion 的 所以问题是如何将 git 与 Subversion 一起使用 不要完全取
  • 如何在 svn 存储库中本地忽略 .git 和 .gitignore?

    我有一个 SVN 工作副本 由 TortoiseSVN 管理 在该工作副本中 我使用 git 进行本地版本控制和分支 当然 我想隐藏svn的 git目录和 gitignore文件 但是 忽略它们意味着将属性添加到不再是本地的存储库中 我不希
  • 不同GIT版本的GIT合并结果不同

    在不同的 GIT 版本上运行 merge 命令我们得到不同的结果 命令是 git merge no ff origin master codeline Results 版本2 1 4 gt 合并成功 版本1 7 1 gt 同一提交上的同一合
  • 二进制增量存储

    我正在寻找一种二进制增量存储解决方案来版本化大型二进制文件 数字音频工作站文件 使用 DAW 文件时 与用于存储原始数据 波形 的大量数据相比 大多数更改 尤其是在混音结束时 都非常小 如果我们的 DAW 文件有一个版本控制系统 让我们可以
  • TortoiseSVN 不允许我添加任何文件

    我正在尝试使用 TortoiseSVN 1 8 1 将文件添加到 SVN 存储库 我右键单击这些文件并选择 TortoiseSVN gt Add 然后 我选择弹出窗口中的所有文件 然后单击 确定 单击 确定 后 会弹出另一个对话框 所有文件
  • svn:修订版本中不存在路径

    我想在颠覆中创建标签 在命令行上我尝试了以下操作 svn复制http myserver mycompany com 8080 svn SVN Main trunk http myserver mycompany com 8080 svn S
  • 列出其他人(即不是我)所做的提交?

    是否有一种标准方法可以列出 git 存储库中其他人 即不是我自己 所做的所有提交 I tried git log not author username 但看起来 not仅适用于修订版 的联机帮助页git log似乎没有提供反转谓词的方法
  • 使用 GIT 自动增加 AssemblyFileVersion

    好吧 我知道这可能不是传统的 但除此之外 我使用 AssemblyFileVersion 作为我的 构建名称 字符串 它的格式如下 File Version information for an assembly consists of t
  • 在两个单独的分支或存储库中管理项目后端和前端?

    我启动了一个移动应用程序项目 该项目将具有服务器端和应用程序本身 所以 在master分支我创建了2个项目myapp server and myapp然后我创建了另外 2 个分支backend and frontend我只想将与它们相对应的
  • 无法提交到 svn - 访问被拒绝

    我正在使用 SVN 开发一个小项目 我查看了该项目 svn co http mylocalserver projectx 我进行了更改 更新并添加了文件 svn add file1 php file2 php 但是 每次我想使用此命令提交更
  • 如何查看提交修订后所做的更改并解析它以获取评论?

    我希望自动化一些与 SubVersion 相关的任务 所以我使用了 SharpSvn 不幸的是我找不到太多的文档 我希望能够在用户提交新修订后查看更改 以便我可以解析代码以获取特殊注释 然后将其上传到我的票证系统中 如果您只想浏览 Shar
  • git 可以与 Xcode 集成吗?

    有没有办法将 git 存储库与 Xcode 内置的 SCM 功能一起使用 Xcode 4 原生支持 git WWDC 2010 上的开发者工具国情咨文演讲 在这里了解更多 Xcode 4 中的新增功能 http developer appl
  • SVN 行结束样式

    当我尝试在 SVN 中提交文件时 它显示错误为 提交失败 详细信息如下 提交 svn 行结束样式不一致 检查目录 文件上的 svn 属性 如果您定义了 svn eol style 但您的文件包含不同的样式 Unix 与 DOS 则提交将失败
  • 让 hudson 将源签出到特定目录

    这似乎是一个简单的任务 但在我的一生中 我无法让 Hudson 将我的源代码签出到特定目录 我可以在命令行上使用 svn 查看源代码 我尝试在源代码管理下指定本地模块设置 但没有骰子 我将其设置为 c source trunk 并在运行构建
  • 将 SVN 存储库从 Google Code 传输到 RiouxSVN

    我在 Google Code 上有存储库 现在我想将这些代码存储库从 Google Code 移动到 RiouxSVN 问题是我不知道如何实现这一点 我曾尝试使用 svnadmin 和 svnrdump 但无法成功 对于 svnrdump
  • 使用 VisualSVN Server 和 Cruisecontrol.net 检查内容集成中的修改失败

    我正在使用 CruiseControl net 进行持续集成 我使用 VisualSvn 服务器 使用 Windows 身份验证 为我的项目创建了一个存储库 两台服务器都托管在同一系统 Os Microsoft Windows Server
  • 单元测试类是否应该与其余代码一起置于版本控制之下?

    如果我为开发项目创建测试套件 这些类是否应该与项目代码的其余部分一起受版本控制 是的 没有理由不将它们置于源代码管理中 如果测试发生变化怎么办 如果接口发生变化 需要测试更改怎么办
  • git 显示已添加到 gitignore 的文件中的更改?

    我已经将 log2 文件夹和 main js 文件添加到 gitignore 如屏幕截图所示 但即使执行后git rm cached r我仍然可以看到 git 正在检测 main js 和 log2 文件夹内文件的更改 怎么会 这些的常见问
  • 带有 LDAP 身份验证的 SVN 不起作用

    我首先从我的设置开始 为此我们有 2 台服务器 Server1 将用于所有源代码 文件等 在 Server2 上 我们拥有所有用户信息和登录信息 两台服务器都运行在 Centos 6 4 上 现在我们要在 server1 上设置一个 SVN

随机推荐

  • 通过虚拟线程中的调用在主线程中执行Python函数

    我有一个 Python 脚本 用于处理来自 NET Remoting 的异步回调 这些回调在虚拟 工作 线程中执行 从我的回调处理程序内部 我需要调用我在脚本中定义的函数 但我需要该函数在主线程中执行 主线程是向服务器发送命令的远程客户端
  • 使用Java创建视频播放器

    我需要为我的项目使用 Java 创建一个视频播放器 我已经在网上查过很多例子了 其中一些运行 但不显示任何屏幕 我只能听到视频的声音 请帮我解决这个问题 我正在使用下面的导入 import javax media 编辑 下面是我使用的代码
  • 背景图像 url() 在实时服务器上有效,但当我在浏览器中打开 index.html 时却不起作用?

    由于其他属性适用 因此正确选择了该元素 没有控制台错误 我努力了 img 英雄 jpg 当我点击 VS Code 中的链接时有效 img 英雄 jpg 当我点击时起作用 英雄 jpg 当我点击时工作 img 英雄 jpg 不起作用 完整路径
  • 将动态 Web 项目导入 Eclipse

    我一直在 Eclipse 中开发一个动态 Web 项目 我最近重新安装了我的操作系统 并且使用了干净的 Eclipse 我可以导入我的网络项目 但是当我尝试吃午饭 在服务器上运行 时 我总是收到此消息 The selection canno
  • 倾斜的div边框透明度

    所以 我知道如何使用 after 和边框为现代布局制作倾斜的 div 但是 我想知道您是否可以使用它通过透明度裁剪掉 div 的一部分 例如 假设我有一排带有背景图像的卡片 我想要在这些卡片上产生倾斜效果 但是 这里的倾斜只是页面 不是卡片
  • /rest-auth/password/reset/ 处的 NoReverseMatch

    我有一个带有角度前端的 Django 应用程序 当我尝试从前端发送密码重置请求时 出现以下错误 使用参数 和关键字反转 password reset confirm 参数 u uidb64 MTE u token u 3z4 eadc7ab
  • HTTP 网站上出现“阻止加载混合活动内容”

    Problem 我正在开发一个使用 HTTP 协议提供服务的网站 在开发中 我使用 Webpack 及其 webpack dev server 它在本地提供页面服务http localhost 9090 我很惊讶地在 Firefox 58
  • 如何创建唯一 ID,例如 YouTube?

    我一直想知道他们是如何以及为什么这样做 一个例子 http youtube com watch v DnAMjq0haic http youtube com watch v DnAMjq0haic 这些 ID 是如何生成的 并且不会重复 这
  • ASP.NET Identity 出现“创建模型时无法使用上下文”异常

    为什么当我们调用 AccountApiController Register 方法时会发生这种情况 什么试图使用上下文 什么试图创建上下文 我们如何避免这种情况 我们如何调试这个 Message 发生错误 ExceptionMessage
  • 覆盖命名空间中导入的函数

    As the termplotR 中的函数包含一些奇怪的代码 这些代码给我带来了烦人的错误 我想在我自己的测试代码中覆盖它 直到找到更永久的解决方案 问题是更改的函数没有被加载mgcv包裹 这mgcv包从其命名空间中的 stats 包加载
  • 在 Django Admin 中为 list_filter 创建自定义过滤器

    我想为 django admin 制作自定义过滤器 而不是普通的 is staff 和 is superuser 我读过这个列表过滤器 https docs djangoproject com en dev ref contrib admi
  • 通过 PHP 和 cURL 访问 NodeJS / Socket.io

    我正在运行 nodejs socket io v 0 7 服务器将数据推送到 Web 客户端 这很有用 为了扩展应用程序 我需要通过 php 触发 影响 socket io 我知道一个使用 cURL over http 和 nodejs h
  • 推荐的货币价值四舍五入方法

    首先看到下面的问题 SetRoundMode rmUp 并将 round 值四舍五入 如 10 结果为 10 0001 https stackoverflow com questions 565797 setroundmodermup an
  • 错误:胆怯地拒绝“sudo brew install”为 Mac OSX Mountain Lion 安装glue 0.3

    我正在尝试为 OXS Mountain Lion 安装glue 0 3 并在安装自制软件后遇到此错误 错误 懦弱地拒绝sudo brew install您可以将brew 与sudo 一起使用 但前提是brew 可执行文件由root 拥有 但
  • 玩2.3 多个模块的requireJs优化和shim

    这是我当前的 Play 2 2 x requireJS 设置 2 3之后还能继续用吗 我在 2 3 文档中找不到 requireJs 或 requireJsShim requireJs Seq mainAccount js mainOrg
  • 如何使用递归编程在列表框中填充多个类别

    I have a categories table which is set up to allow an infinite number of sub category levels I would like to mimic the f
  • 在 Windows Phone 上实现可滚动表格

    我需要创建一个电视指南应用程序 要求是 UI 必须是您可以在此处看到的 UI 的副本 raspored bnet hr http raspored bnet hr 正如您所看到的 有很多数据 所以 基本上它是一个大的可滚动表格 由于 Win
  • 将 C++ 模板参数限制为子类

    如何强制模板参数T成为特定类的子类Baseclass 像这样的东西 template
  • Django Ckeditor 图像浏览器找不到图像

    所以我正在建立一个简单的博客来跟踪我的项目 我决定使用 CKeditor 作为所见即所得编辑器 除了图像部分之外 我能够使其所有内容正常工作 当我点击 图像浏览 时 我无法查看服务器中的图像 并且每当我上传图像时 它都会上传 但我无法查看它
  • 颠覆外部是一种反模式吗?

    Subversion 允许您使用以下方式嵌入其他存储库的工作副本外部因素 http svnbook red bean com en 1 1 ch07s04 html 可以轻松地对项目中的第三方库软件进行版本控制 虽然这些对于库的重用和版本控