应该将临时代码置于版本控制之下,如何进行?


29

这是临时/本地代码的一些示例。为了使用代码库,它是必需的,但是成为其中的一部分将是有害的:

  1. 项目文件。可能需要编辑路径才能反映当前PC上的布局。
  2. 生成文件。例如,在调试过程中可能需要关闭优化,但对于CI服务器则不需要。
  3. 肮脏的丑陋骇客。例如return 7在一个函数的中间,为了测试某些东西(取决于该函数),并怀疑它的值是7。我分行的生活

我尝试将它们保持在git commit中,在将其推送到存储库然后推送之前,我总是将其重新定位到顶部HEAD~。这非常不便,不适用于svn。藏起来让我更加恐惧-“我记得推后弹开吗?”。

每次汇编汇编提交时,使代码脱离版本控制都会带来令人不快的噪音,而且它可能在某个星期五晚上偶然被引入到提交中。

对于这样的一次性代码,什么是理智的解决方案?


在临时项目使用期间,是否需要从原始项目中更新此临时代码?
JeffO 2014年

@JeffO,不确定我是否了解您。肮脏的代码片段很小,很少与正在开发的代码发生冲突。但是,@ Blrfl对他们来说,成为主流是非常危险的。想象一下,在炎热的夏天里糟糕的合并之后return 7,在trunk星期五的晚上。
Vorac 2014年

@Vorac-这就是代码审查和测试的目的!我可以向您展示比这更糟糕的-尽管乍一看看起来还是不错的,但代码仍然无法正常工作。Return 7..如果他们是如此的明显!
gbjbaanb 2014年

@Vorac:那是最哲学的评论。
Blrfl 2014年

2
有没有办法告诉您您所处的环境?例如,如果它检测到您处于开发环境中,而不是在val / prod中,则可以将其设置为执行代码。这样,您在提交时就不必不断添加/删除占位符代码。
萨焦2014年

Answers:


46

所有代码都是临时的。当我进行更改时,偶尔会引入占位符-我绘制的图标,等待设计者真正的图标,我所知道的函数将调用我的同事正在编写但尚未完成(或启动)的库,多余的日志将被删除或以有条件的方式进行记录,一旦测试团队注意到它们,我将解决的错误等

因此,请检查所有内容。对您的所有开发使用功能分支,然后可以将最终版本合并到主干中,而没有人需要知道在开发周期中进行了哪些破解,修补和修复,他们只需要请参阅最终版本。但是,如果您定期致力于分支机构,那么如果一天发生了严重错误,或者在午餐时间到酒吧后继续编码,您将能够看到值得保留的东西。

版本控制不是工件存储库或文档存储系统。关于掌握变化的历史。将您喜欢的所有内容都放在那儿,因为有一天您可能想看看它到底是什么,而那一天正是您意识到SCM真正意义所在。

PS。真正的临时文件(例如.obj或构建工件)在SCM中没有位置。这些对任何人都没有价值。您可以说出它们是什么-如果删除它们,您将不在乎,甚至注意到它们已消失。


5
同意 分支是要走的路。创建一个分支,在该处执行任何操作,并在完成后合并完成的代码。磁头应视为客户端可以随时下载和使用的发行版本。
卡梅隆·麦凯2014年

从我看来,很好的答案是,GIT引入了本地版本控制,部分目的是为了帮助希望了解其本地工作记录的人们。临时代码应保留在开发人员的机器中,直到他准备将其提交到存储库中为止
InformedA 2014年

2
我要打印一张大海报,上面写着“所有代码都是暂时的”,然后贴在墙上。可能在Comic Sans中。
Bob Tway 2014年

2
@MattThrower在泡沫报价中,来自Clippy的嘴巴吗?
gbjbaanb 2014年

1
但是,未运行的代码或未编译的代码不应提交给版本控制。
图兰斯·科尔多瓦

17

项目文件。可能需要编辑路径才能反映当前PC上的布局。

对于项目文件,最好的策略是何时可以通过脚本生成项目文件。将实际的项目文件添加到忽略对象中,然后根据需要简单地重新生成项目文件。例如,在Java项目中,我使用gradle可以生成eclipse项目。

生成文件。例如,在调试过程中可能需要关闭优化,但对于CI服务器则不需要。

您应该能够在优化和调试模式之间切换,而无需修改Makefile。而是使用不在存储库中的命令行标志,环境变量或单独的文件来控制它们。

肮脏的丑陋骇客。例如,在函数中间返回7,以便根据函数测试某些东西,并怀疑在值7处中断。或者7是尚未实现的按钮的代码,我正在实现该按钮,需要在我的分支机构的整个生命中进行测试。

您不能编写引发可疑故障案例的测试吗?

在大多数情况下,您应该能够调整工作流程,以免对存储库中的文件进行这些更改。这些在本地更改的文件应添加到项目的忽略机制中,而不应位于存储库中。在某些情况下,您仍然会进行不想放入存储库中的临时更改。对于这些,添加一个特殊的序列,例如:XXX,并添加一个预提交钩子,该钩子拒绝仍在其中的提交。


有时,我需要对文件进行小小的修改,同时在同一文件中编写生产代码。svn不支持部分文件提交,因此在这种情况下很痛苦。我的大多数同事只是将hacks转移到分支机构并在合并到时清除它们trunk。但是,我更容易分心(在合并过程中会犯错误,并且svn中的合并是神圣且不可改变的),因此问题变得更容易了。
Vorac 2014年

@Vorac,我将研究subversion挂钩,这些挂钩可让您在提交时运行脚本。如果包含XXX或类似名称的脚本,应该可以拒绝合并。
Winston Ewert 2014年

1
@Vorac:如果您使用TortoiseSVN,则可以对文件使用“提交后还原”进行部分提交,请使用diff工具或编辑器临时删除您不想提交的块,然后提交。Tortoise将立即恢复完整文件,如果准备好,您可以提交剩余的块。这可以通过快速备份文件并在首次提交后将其还原来完成。
leokhorn

5

版本控制应包含构建应用程序所需的代码和配置。

这意味着:

  • 短时间内引入的临时性内容(例如,定位错误的位置或尝试某种语言的功能所需的时间)不应放在版本控制中:保留它直到您需要,然后在执行commit时将其删除

  • 适用于特定计算机的本地文件可以保存在分支中。

    我会避免将它们仅保留在本地,因为在笔记本电脑被盗或病毒迫使您重新安装操作系统时,要重做所有这些事情太麻烦了(顺便说一句,您发现上次备份是两年前完成的) 。

    另一方面,请注意文件结构:本地配置是可以的,直到它变得不堪重负,并迫使您对参与该项目的42个开发人员中的每个文件进行单个更改。

    留意删除机器之间特殊性的机会。这可能意味着:

    • 授予对dev SQL服务器的访问权限,以替换开发人员计算机上的本地实例,

    • 对于公共包裹使用Pypinpm等包裹分发服务,对内部包裹使用私人对应服务,

    • 要求团队成员安装相同版本的软件,

    • 使软件更新尽可能透明,

    • 或者可以一键式将操作系统和所需的软件部署到计算机上(加上每个开发人员安装他喜欢的Vim,Emacs,Chrome和Firefox等的时间)。

所以:

项目文件。可能需要编辑路径才能反映当前PC上的布局。

为什么不在每台PC上使用相同的布局?项目中的路径应相对于项目文件,这意味着项目位于何处都没有关系。最好使软件和库的版本相同,以避免仅在某些计算机上出现的,无法为团队其他成员复制的神秘错误。

例:

在使用Visual Studio创建的项目中,您可能会发现:

  • 文件本身。路径是相对的,项目是否位于我的机器上,H:\Development\Hello World Project\而团队中的其他成员将项目检入到无关紧要C:\Work\HelloWorld\

  • 依赖关系,即第三方库和内部库。两种类型都应由NuGet处理,这会使所有与冲突相关的讨论都已过时。如果您没有与我相同的库版本,请要求NuGet更新依赖关系。就这么简单(当它运行良好时,并非总是如此)。

    请注意,将内部库也保存在私有NuGet中也很重要。将一堆库存储在共享文件夹中或通过团队中的电子邮件发送会导致混乱和令人沮丧的CI服务器。

  • 设置。团队共享相同的设置至关重要。如果团队的一半决定将警告视为错误,而团队的一半将警告保持原样,则团队第一部分的成员将花费时间从团队第二部分中消除开发人员生成的警告。

  • 与实用程序相关的设置。这些非常棘手,因为团队中的某些成员可能已经安装了某些实用程序,而其他人却没有安装。

    强烈建议安装相同的工具集。如果某些程序员想要使用StyleCop,而其他程序员则不想,则团队将无法完成工作。如果某些人使用代码合同,而其他人不使用代码合同,则它们将遇到相同的问题。

生成文件。例如,在调试过程中可能需要关闭优化,但对于CI服务器则不需要。

在版本控制中保留几个makefile。在CI服务器上构建调试版本并将其推送到遇到棘手错误的客户端也很常见。

肮脏的丑陋骇客。例如,在函数中间返回7,以便根据函数测试某些东西,并怀疑在7值处中断。

我会首先避免这样的代码。为了测试某些东西,请使用单元测试。如果出于调试目的确实需要几秒钟交换一些代码,则可以执行此操作,但是无论如何您将在几分钟后删除此代码,因此无需提交它。

描述时,您应该编写一个测试。例如,如果您要确保:

class TemperatureConverter
{
    public int CelsiusToFahrenheit(int temperature)
    {
        ...
    }
}

temperature不如AbsoluteZero常量时抛出异常,您不应该玩代码本身。相反,创建一个单元测试,它将:

  • 自我记录您的代码,
  • 提高代码的可靠性,
  • 确保维护者在修改上述方法时可以依靠回归测试,
  • 为您团队中可能需要进行相同测试的其他开发人员提供服务。

2
不幸的是,我没有编写测试的经验。当前平台涉及ARM cpu,可根据USB命令配置一些硬件。硬件没有反馈到CPU。
Vorac 2014年

2
如果临时代码可能具有持久的影响,即使实现了这些效果,即使不再需要该代码,我也认为将代码保留在某个地方是明智的,以防出现关于效果是否正确实现的疑问。例如,如果产品的某些数据库格式在开发过程中发生了更改,则可以编写一种一次性的实用程序来更改格式。在转换了旧格式的唯一现存数据库之后,可能永远不需要该实用程序,但是仍然有必要检查转换是如何完成的。
超级猫2014年

对于Visual Studio项目文件,我在使用CMake生成文件方面有丰富的经验,这为在源代码和编译后的代码在文件系统中的确切位置提供了一些灵活性。然后,我对CMake输入文件(而不是VS项目文件)进行版本控制。但这仍然符合您的格言,“版本控制应包含构建应用程序所需的代码和配置。” 我完全同意!
David K

使用VS时,您有时需要小心以确保没有绝对路径溜进去。在升级到Win64并使第三方平台的库从迁移C:\Program Files\...到时,我遇到了多个问题,涉及引用破坏C:\Program Files (x86)\...
Dan Neely 2014年

@DanNeely:这就是为什么NuGet应该处理第三方库。
2014年

2

我们@@在代码中使用注释来指示尚未准备就绪,出于测试目的等的任何内容。

这样我们就可以提交,同事不必等待太久就可以同步,并且可以看到仍在进行中的工作(例如,了解为什么零件尚未完全工作)。

@@在进入Beta测试的最后阶段之前,我们进行了全球性的搜索以防止任何“剩余”。

使用纪律,我认为没有理由只是犯。这样,我们就没有单独的分支,只有一个额外的“协议”可以遵循。


作为额外的好处,这些待办事项(通常是小事情)始终在代码中。处理它们的开发人员可以快速查看它们,而无需保留单独的列表。
您知道开发的过程:您在一个地方工作,但是不断将自己的思想当作堆栈使用(“ 在这里完成后,我应该在那改变它 ”)。只是快速记一下便@@可以防止堆栈溢出。

我什@@name至用来指出需要与“名称”讨论的问题。


1

2仓鼠解决方案:

  • 您可以使用预提交挂钩检查代码中是否存在诸如HAMSTER之类的异常关键字。只是不要让人们提交已经被仓鼠打扰的代码,并在您进行肮脏的黑客攻击时使用它。

  • 例如,在C语言中,另一个选择是使用#ifdef HAMSTER,那么代码将仅在具有编译器标记HAMSTER的计算机上运行。



0

以下是一些我经常在各种情况下使用的解决方案,当应用于自己的工作流程时,您可能会认为有帮助:

  1. 可以压缩的轻质树枝。

    Git在这方面很棒。侵入分支,进行大量提交,然后重新整理或压缩您的历史记录以消除干扰。

  2. 在SCM顶部使用补丁程序队列。

    我经常发现自己使用StGit将补丁浮动到当前分支的顶部。分支完成后,可以在合并,压缩或重新设置基准之前将它们从堆栈中弹出,或者如果要保留它们,可以将它们合并到主代码库中。

  3. RCS用作小型实验的“带外” SCM。

    有时,您只想以一次性方式检查正在处理中的文件,而无需随后清理历史记录。我通常在Git或SVN内部使用RCS。我告诉Git忽略RCS工件,在RCS中检查正在进行的工作,当我喜欢结果时,我只是扔掉*,v文件或整个RCS目录。在git clean -fdx您将工作投入到“真正的” SCM之前,请不要运行或类似操作,否则您会后悔的。

  4. 命名的藏匿处。

    另一个Git主义,但很方便:git stash save --include-untracked <some-cool-title>在紧要关头很有用。您可以通过这种方式保存,弹出和应用进行中的工作,并通过git stash list或查看各个检查点git reflog --all。其他SCM可能具有类似的功能,但是您的里程可能与此相差很大。


0

某些临时代码实际上只是不正确的构建/测试/开发方法的体现,希望它们的存在会激发未来的改进。

至少在git上,您应该可以随意摆弄任意数量的功能分支,直到它们准备好合并到master / trunk中为止。

版本控制应该可以为您提供帮助,而且我常常会欣赏过去从错误(或者可能只是不直观的决定)的方式中获得的见解,并为当前做出更明智的决定。


0

我相信某些系统会在评论中看到关于TODO的警告,因此

// TODO: remove this hack.

如果您可以在开发环境的某个部分找到相关选项,或者只是在构建文件中添加某种grep命令,则可能仅需要这些。也可以安排// HACK或拾取任意字符串。

这比以特定方式组织代码并希望人们会记住不要使用它要简单。这也使遵循@gbjbaanb的建议更加安全(如果可以确保每个人都看到警告!)。

将您喜欢的所有内容都放在那儿,因为有一天您可能想看看它到底是什么,而那一天正是您意识到SCM真正意义所在。


0

将代码置于源代码管理中永远不会有害。

您提到的每一项都应该在源代码管理中。

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.