检入“注释掉”代码

好吧,这是我目前的工作造成了一些摩擦,我真的没想到会这样。 组织内部软件开发是一个新的概念,我已经起草了一些编码指南的初稿。

我build议“注释掉”代码不应该被检入到存储库中。 我已经说明了这一点的原因是存储库维护文件的完整历史logging。 如果要删除function代码,请将其完全删除。 存储库保存您的更改,以便查看更改的内容。

这导致了另一个开发人员认为采取这种路线的限制太多的摩擦。 这个开发者希望能够评论他正在编写的一些代码,但是不完整。 然后这个代码将永远不会被检入,然后不会保存在任何地方。 我们将要使用TFS,所以我build议搁置这些变化将是最正确的解决scheme。 然而,这并不被接受,因为他希望能够检查可能部署或可能不部署的部分变更。

我们希望最终能够充分利用持续集成并自动部署到开发Web服务器。 目前还没有Web服务器或数据库服务器的开发版本,但将很快改变。

无论如何,你的想法是什么? 你相信“注释掉”代码在存储库中是有用的吗?

我非常有兴趣听到这个话题的其他人。

编辑:为了清楚起见,我们不使用私人分支机构。 如果我们这样做,我会说你做你想要的私人分支,但不要将注释掉的代码与主干或任何共享分支合并。

编辑:没有正当理由,我们不使用私人或每用户分支。 这不是我不同意的概念。 我们现在还没有设置。 也许这是最终的中间立场。 现在我们使用TFS搁架。

也有可能是其他人有不同的经验,但在我的检查半成品代码是一个可怕的想法,时期。

以下是我学习和尝试遵循的原则:

  • 经常登记 – 至less一次,但最好每天多次
  • 只检查完整的function
  • 如果第一个和第二个冲突(例如,使function工作需要一天以上),则任务太大 – 将其分解为更小的可完成任务。

意即:

  • 注释掉的代码不应该被检入,因为它不起作用
  • 评论不是一个有效的档案策略,所以无论是代码还没有完成,或者代码退出,评论和检查都没有任何意义。

所以总之,不! 如果代码没有准备好进入下一个阶段(无论哪一个是你的:IntTest / QA / UAT / PreProd / Prod),它不应该被提交给中继或多开发者分支。 期。

编辑:在阅读其他答案和评论后,我会补充说,我不认为这是一个好主意, 禁止评论的代码(不知道你怎么强制这一点)。 我要说的是,你应该让你的团队中的每个人都能够接受上述的哲学。 我工作的团队全心全意地拥抱。 因此,源代码pipe理是一个无畏的团队成员,帮助我们完成工作。

那些不接受这种哲学的人通常会造成破窗 ,而且经常受到源头控制的挫折。 他们认为这是一个必要的罪恶,最坏的情况是要避免的。 这导致了很less的checkin,这意味着changesets是巨大的,很难合并,这使复杂的挫折,使检查的东西,以避免更多,等等。这最终是一个态度的事情,而不是一个过程的事情。 阻挠精神障碍很容易; 很容易find为什么它不起作用的原因,就像很容易find不要饮食的原因,如果你不真的想。 但是,当人们想要做到这一点,并致力于改变他们的习惯,结果是戏剧性的。 你有责任有效地销售它。

“从不”在指南中很less用到。

您的同事有一个很好的例子,说明何时可以适当地签入被注释的代码:当它不完整时,如果在活动时签入,可能会中断应用程序。

大多数情况下,在一个pipe理良好的变更控制系统中,不需要注释码。 但是,并不是所有的评论代码都是“死的”。

我留下一个注释掉的代码:

// This approach doesn't work // Blah, blah, blah 

当这是解决问题的显而易见的方法时,却包含一些细微的缺陷。 当然,这个存储库会有它,但是存储库不会警告任何人将来不要走这条路。

注释代码不应该为了维护历史而检入。 这是源头控制的重点。

人们在这里谈论很多理想。 也许不同于其他人,我必须在多个项目中多次打断“真实世界”,才会中断我的工作。

有时候,现实是,我必须签到部分完整的代码。 这有可能会丢失代码或签入不完整的代码。 无论多小,我总是不能“完成”一项任务。 但是,如果不检查所有代码,我将不会断开我的笔记本电脑与networking的连接。

如果有必要,我会创build自己的工作分支进行部分更改。

我肯定会强烈地拒绝检查注释掉的代码。 但是,我不会绝对禁止它。 有时 (如果很less),将注释掉的代码检查到源代码控制中是适当的。 说“永远不要做”太严格了。

我想我们都同意这些观点:

  • 永远不要检查死代码到源代码pipe理
  • 不要将损坏的(不起作用的)代码检查到源代码控制中,至less不要中断,而只能非常less地访问私有分支YMMV
  • 如果您为了debugging目的暂时注释掉了某些东西或损坏了某些东西,请不要检查代码,直到将代码恢复到正确的forms

有些人说,还有其他的类别,例如暂时删除的代码,或者是一个渐进式但不完整的改进,其中包括less量的注释代码作为下一步的文档,或者是一个非常短的 (最好是1行)注释片段显示一些永远不应该重新添加的代码。 注释掉的代码应该总是伴随着一个评论,说明它为什么被注释掉(而不是被删除),并给出了注释代码的预期生命周期。 例如,“下面的代码比好的更坏,所以被注释掉了,但是在发布XXX之前需要replace。”

如果您正在提供修补程序来阻止客户的stream血,并且没有立即find最终修复程序的机会,则上述评论是适当的。 提供修补程序后,注释掉的代码是一个提醒,你仍然有东西需要修复。

我何时检查注释掉的代码? 一个例子就是当我暂时取消一些我认为很有可能在不久的将来会以某种forms重新join的东西的时候。 注释掉的代码可以直接提醒,这是不完整的。 当然,旧版本是在源代码控制中,你可以使用FIXME注释作为一个标志,需要更多的东西。 但是,有时(如果不是经常的话)代码是更好的评论。

另外,当通过删除一行代码(或者更less的代码,两行代码)来修复一个bug的时候,我有时候会用注释来注释掉这行代码,而不会重新启用这个代码。 这种评论清晰,直接,简洁。

雷克斯M说:1)只检查完整的function,2)[如果]任务太大 – 分解成更小的可完成的任务。

对此回答:是的,这是理想的。 有时在生产代码的工作中没有任何一个选项可以实现,并且有一个紧急的关键问题需要解决。 有时候为了完成一个任务,你需要在现场放置一段代码。 当您试图find问题的根本原因时,这尤其适用于数据收集代码更改。

对于在一般性问题中被问到的具体实例…只要开发人员将注释掉的代码检查到一个没有人会看到但是该开发人员(也许是开发人员正在合作的人)的私人分支中,它没有什么坏处。 但是,开发人员应该(几乎)不会将这些代码传递到主干或等价物中。 中继线应该始终build立,并应始终运作。 将未完成的代码发送给主干几乎总是一个非常糟糕的主意。 如果您让开发人员将未完成的代码或临时代码检入私有分支,那么您必须依赖开发人员在交付中继之前不要忘记清理代码。

为了澄清回应其他答案的意见,如果代码被注释掉和签入,我的期望代码将运作,如果未注释下降的时间长度的代码已被注释掉。 显然,重构工具并不总是在重构中包含注释。 几乎总是,如果我把注释掉的代码投入到生产中,那么代码就可以作为一个精致的评论,比散文更具体,需要在那里做一些事情。 这不是应该有一个长寿的东西。

最后,如果你可以在每个源文件中find注释掉的代码,那么就是错误的。 将注释掉的代码以任何理由发送到主干应该是一个罕见的事件。 如果这种情况经常发生,那么就会变得混乱,失去价值。

我认为从来没有太强的条件。

我倾向于评论,签入,运行testing,思考,然后在下一个版本后删除评论。

一般来说,检查注释掉的代码是错误的,因为它会造成那些不是原作者并需要阅读或修改代码的人混淆。 无论如何,原来的作者经常在3个月过去后才会对代码感到困惑。

我相信代码是属于公司或团队的,我们有责任让您的同事们更容易。 检查注释掉的代码而不添加关于为什么被保留的注释等于说:

我不介意你们最终会为什么这个东西在这里而感到困惑。 我的需要比你更重要,这就是我为什么这样做的原因。 我不觉得有必要向你或者其他任何人certificate为什么我这样做。

对于我来说,注释掉的代码通常被认为是不那么有思想的同事不尊重的标志

我大致赞同不应该注释掉注释掉代码的原则。源代码pipe理系统是一个共享资源,你的同事在一定程度上将它用作他的个人便笺。 这对其他用户来说并不是很体贴,特别是如果您订阅共享代码库所有权的想法。

下一个开发者看到注释掉的代码将不知道这是一个正在进行的工作。 他有自由改变吗? 这是死代码吗? 他不知道。

如果你的同事的变化没有处于可以检查的状态,他需要完成它,和/或学习做出更小的增量更改。

“检查可能部署或可能不部署的部分更改” – 大概也意味着可能会或可能不会被testing? 这是一个非常艰难的代码基地的滑坡。

当你需要添加一个像NOW一样的小function或bug修复,在接下来的3分钟内,你必须修复一个文件,你有一半的开发代码,我会说没关系,实际的需要统治着战场上的实用理想。

这表明了两种思想观念的根本区别:那些只检查工作代码,他们感到满意和感觉的人是值得保存的,那些检查他们的工作如此修改控制的人就是为了防止数据丢失。

我认为后者是“那些喜欢使用他们的版本控制系统作为穷人的磁带备份的人”,但是这会让我感到手足无措。

我的猜测是你是“良好的代码”阵营,他是“工作代码”阵营。

[编辑]

从评论,是的,我猜对了。

正如我所说,我和你在一起,但我可以告诉这是一个less数人的意见,这两个在这里stackoverflow和我的工作。 因此,我认为你不能把你的发展标准作为唯一的运作方式。 不,如果你想要的标准依旧。 一个好领导知道的一件事就是永远不要下达他们知道不会遵循的命令。

顺便说一句: 好的编辑将帮助保留旧版本。 例如,在Emacs中,我将keep-old-versions和keep-old-version设置为10,这样保留了我文件的最后10次保存。 你可以把它看作是一种帮助你反对作为备份控制的人群的方法。 但是,你永远不会赢得这个论点。

根据我的经验,开发人员开关被注释掉了代码。

有时,新的后端是并行构build的,激活开关在源代码控制中被注释掉。

我们在蓝月亮上需要一些奇异的function,但客户永远不需要的东西往往是这样实现的。 这些东西通常带有安全性或数据完整性绕过的高风险,所以我们不希望它们在开发之外活跃。 首先要求开发人员使用它来取消注释代码似乎是获取代码的最简单方法。

检查注释掉代码的另一个原因是:

您正在修改现有的代码,并发现了一个微妙的错误,一个容易忽略的错误,甚至可能乍看起来正确。 评论一下,把修补程序放在原处,为正在发生的事情添加注释,以及为什么修改它。 检查,以便您对修复的意见是在存储库中。

也许这里真正的问题是开发者是否应该被允许检查不完整的代码?

这种做法似乎与您实现持续集成的既定目标相矛盾。

这取决于。 如果它出于说明的目的而被留在那里,也许。 在重构过程中它可能是有用的。 否则,一般来说,不。 另外,注释掉未完成的代码必然是容易出错和时间下沉的。 更好的办法是将代码分解成更小的代码,并在工作时检查它们。

我的观点是:如果开发者正在自己的分支机构工作,或者在他们自己的沙箱区域工作,那么他们应该能够检查他们想要的任何东西。 当他们将代码检查到一个共享分支(一个function分支,或一个团队的分支,或当然MAIN /干线),代码应该尽可能原始(没有注释掉代码,没有更多的FIXMEs等)。

我认为“永不”是太强大的规则。 我会投票留下一些个人的余地是否有人检查评论代码到存储库。 最终的目标应该是编码员的生产力,而不是“一个原始的存储库”。

为了平衡这种松懈,确保每个人都知道注释掉的代码有一个到期date。 任何人都可以删除评论的代码,如果它已经周围一整周,从来没有活跃。 (换一个礼拜,换一个礼拜给你看。)这样,你就有权在看到它的时候消除杂乱,而不会直接干扰人们的个人风格。

我绝对同意,注释掉的代码不应该被检入到存储库中,这就是源代码控制的目的。

根据我的经验,当程序员检查注释代码时,是因为他/她不确定正确的解决scheme是什么,并且更愿意将替代解决scheme留在源代码中,希望别人能够做出这个决定。

我发现代码复杂化,使阅读变得困难。

我没有检查一半完成的代码(所以你得到的源代码pipe理的好处)没有问题,而不是由现场系统调用。 我的问题是find评论代码的部分没有解释的困境是导致代码被排除在外。

我认为在源代码控制系统中签到注释代码应该非常小心,特别是如果用于注释代码的语言标签是通过代码块写的,例如:

 /* My commented code start here My commented code line 1 My commented code line 2 */ 

而不是在个人的基础上,如:

 // My commented code start here // My commented code line 1 // My commented code line 2 

(你明白了)

我会极其谨慎的原因是,根据技术,你应该非常小心你使用的差异/合并工具。 有了一定的源代码控制系统和一定的语言,diff / merge工具很容易混淆。 例如ClearCase的标准差异/合并对于合并.xml文件是非常糟糕的。

如果发生注释块行不能正确合并,那么当系统不应该运行时,你的代码将会在系统中激活。 如果代码不完整,打破构build,这可能是最不可能的,因为你会立即发现。

但是,如果代码通过构build,它可能会变得活跃,不应该在那里,从CM的angular度来看,这可能是一个噩梦的场景。 QA通常testing应该在那里,他们不testing不应该在那里的代码,所以你的代码可能会在你知道它之前最终在生产中,到时候它会被认为是代码在那里不应该,维护的成本倍增了很多倍(因为“bug”将在生产或客户中发现,最糟糕的地方或时间)。

我认为注释代码被认为是“浪费”。

我假设你正在团队环境中工作。 如果你正在自己的工作,你用“待办事项”注释掉代码,你会回来的,这是不同的。 但是在团队环境中,您可以放心地假设一旦注释掉了代码,它就会留在那里,而且很可能会导致更多的痛苦,而不是满意度。

如果你正在做同行评议,那么它可能会回答你的问题。 如果另一个开发人员检查你的代码,并说“为什么有这样的代码试图做'blah'”,那么你的代码没有通过代码审查,你不应该检查它。

注释掉的代码只会向其他开发者提出问题 – 因此浪费时间和精力。

您需要提出“ 为什么 ”代码被注释掉的问题。 一些build议:

如果您因为“不确定业务规则”而注释掉了代码,那么您可能遇到了“范围蠕变”的问题 – 最好不要将代码弄脏,而要求“很好,但我们没有时间执行“ – 用清晰的代码保持清洁,并testing实际存在的内容。

如果你正在评论代码,因为你“不知道这是否是最好的方法”,那么你的代码同行审查! 时代正在改变,你会看到你今天写的代码在2年,并认为这太可怕了! 但是,你不能去评论一些你可以做得更好的东西,但是你现在还找不到方法。 让长期维护代码库的人决定是否有更好的方法 – 只要编写代码,testing和工作,继续前进。

如果你正在注释代码,因为“某些东西不行”,那么修正它 ! 一个常见的情况是“破解testing”或“待办事项” 。 如果你有这些,你可以通过修复它们或者摆脱它们来节省很多时间。 如果他们能够被“打破”一段时间,他们很可能永远被打破。

所有这些潜在的情况(以及我在这里没有提到的)都浪费了时间和精力。 注释掉代码可能看起来像一个小问题,但可能是您的团队中更大的问题的一个指标。

存储库是代码的备份。 如果我正在处理代码,但是没有完成,为什么不把它注释掉,并在一天结束时检查它。 这样,如果我的硬盘驱动器过夜,我不会失去任何工作。 我可以在早上检查代码,取消注释并继续。

我要评论的唯一原因是因为我不想打破一夜之间的构build。

在1)早期检查和2)始终保持仓库处于工作状态之间显然存在紧张关系。 如果你的开发人员不止一个,那么后者的优先级就会越来越高,因为你不能让一个开发人员为他自己的个人工作stream程而挑剔所有人。 这就是说 ,你不应该低估第一条准则的价值。 开发人员使用各种不同的心理栅栏,个性化的工作stream程是伟大的开发人员挤出那些额外的X的一种方式。 作为一个pipe理者,你的工作不要试图去了解所有这些细微差别 – 除非你是一个天才,你所有的开发者都是白痴,否则你将会失败,而是让你的开发者通过自己的决策成为最好的。

你在评论中提到你不使用私人分支。 我的问题是为什么不是? 好的,我对TFS一无所知,所以也许有很好的理由。 然而在使用git一年之后,我得说一个好的DVCS完全可以扩展这种紧张感。 有些情况下,我发现注释代码是有用的,因为我正在构build一个替代品,但是如果我将它强加于别人,我会失眠。 能够在本地进行分支意味着我可以为我的个人进程保留有意义的提交,而不必担心(甚至不会通知)下游开发者临时混乱。

只是呼应合唱。 不惜一切代价劝阻。 它使代码更难阅读,让人们不知道该代码的好坏,目前甚至不是应用程序的一部分。 您可以随时通过比较修订来查找更改。 如果有一些重大的手术,代码全部被注释掉,那么开发人员应该在检查/合并的修订说明中注明它。

不完整的/实验性的代码应该在一个分支中被开发完成。 头/主干应该是总是编译的主线,是什么运输。 一旦实验分支完成它/接受它应该合并到头/主线。 如果您需要支持文档,甚至有一个IEEE标准(IEEE 1042)来描述这一点。

我更希望看到可能被破坏的,可访问的代码,这些代码还没有被使用,但是通过相同的代码检查完全不可用。 由于所有版本控制软件都允许某种“工作副本”与主干分开,所以使用这些function确实是一个更好的主意。

New, non-functional code is fine in the trunk, because it is new. It probably doesn't break anything that already works. If it does break working code, then it should just go in a branch, so that other developers can (if they need to) check that branch out, and see what's broken.

" Scar Tissue " is what I call commented-out code. In the days before the widespread use of version-control systems, Code Monkeys would leave commented out code in the file in case they needed to revert functionality.

The only time it is acceptable to check-in "scar tissue" is

  1. If you have a private branch and
  2. You don't have time to make the code compile without errors and
  3. You are going on a long vacation and
  4. You don't trust your VCS, like if you use Visual Source Safe OR .
    [EDIT]
  5. You have a subtle bug that might be reintroduced if the incorrect code isn't left in as a reminder. (good point from other answers).

There is almost no excuse for #4 because there are plenty of freely available and robust VCS systems around, Git being the best example .

Otherwise, just let the VCS be your archive and code distributor. If another developer wants to look at your code, email him the diffs and let him apply the stuff he wants directly. In any event, the merge doesn't care why or how the coding of two files diverged.

Because it is code, scar-tissue can be more distracting even than a well-written comment. By its very nature as code, you make the maintenance programmer expend mental cpu-cycles figuring out if the scar-tissue has anything to do with his changes. It doesn't matter whether the scar is a week old or 10 years old, leaving scar-tissue in code imposes a burden upon those who must decypher the code afterwords.

[EDIT] I'd add that there are two major scenarios that need to be distinguished:

  • private development, either coding a personal project or checking in to a private branch
  • Maintenance development, where the code being checked in is intended to be put into production.

Just say "NO" to scar-tissue!

The idea of allowing source-control history to illustrate the "old way" of doing something rather than commenting it out and checking in the commenting-out along with an explanation is a good idea in theory.

In the real world, however, nobody ever looks at source control history on the files they are working on unless it is part of an official review process of some sort (done only periodically), or if something doesn't work, and the developer can't figure out why.

Even then, looking back more than about 3 versions basically never happens.

Partially, this is because source-control systems don't make this sort of casual review easy. Usually you have to check out an old version or diff against an old version, you just see two versions, and there's no good concise view of what changed that can give you an at-a-glance idea of what changed.

Partially, it is the combination of human nature and the needs of the team. If I have to fix something, and I can fix it in a few hours, I'm not likely to spend an hour investigating old versions of the code that haven't been "live" in a month (which, with each developer checking in often, means back many revisions), unless I happen to know that there's something in there (such as if I remember a discussion about changing something related to what I'm doing now).

If the code is deleted and checked back in, then, for all intents and purposes (except for the limited purpose of a complete roll-back) it ceases to exist. Yes, it is there for backup purposes, but without a person in the role of code librarian, it is going to get lost.

My source control tree on my current project is about 10 weeks old, on a team of only about 4 engineers, and there are about 200 committed change lists. I know that my team does not do as good of a job as it should of checking in as soon as there is something solid and ready to go. That makes it pretty rough to rely on reading the code history for every part of the code to catch every important change.

Right now, I'm working on a project in initial development mode, which is very different from a project in a maintenance mode. Many of the same tools are used in both environments, but the needs differ quite a bit. For example, often there is a task that requires two or more engineers to work somewhat closely together to build something (say a client and a server of some sort).

If I'm writing the server, I might write up the code for the draft interface that the client will use and check it in completely non-functional, so that the engineer writing the client can update. This is because we have the policy that says that the only way to send code from one engineer to another is through the source control system.

If the task is going to take long enough, it would be worth creating a branch perhaps for the two of us to work on (though that is against policy in my organization — engineers and individual team leads don't have the necessary permissions on the source-control server). Ultimately, its a trade-off, which is why we try not to institute too many "always" or "never" policies.

I would probably respond to such a no-commented-code-ever policy by saying that it was a bit naive. Well-intentioned, perhaps, but ultimately unlikely to achieve its purpose.

Though seeing this post is going to make be go back through the code I checked in last week and remove the commented-out portion that was both never final (though it worked) and also never likely to be desired again.

I don't know – I always comment out the original lines before I make changes – it helps me revert them back if I change my mind. And yes I do check them in.

I do however strip out any old commented code from the previous check-in.

I know I could look at the diff logs to see what's changed but it's a pain – it's nice to see the last changes right there in the code.

A nice compromise is to write a little tool that dumps your checked out/modified files to a network backup drive. That way, you can modify til your heart's content and have your work backed up, but you never have to check in experimental or unfinished code.

I think that checking in commented out code should be valid as, just because the new change passed tests it may be more helpful to see what was there before and see if the new change is really an improvement.

If I have to go back several versions to see an earlier change that now leads to a performance hit then that would be very annoying.

Sometimes the commented out code is a good history, but, put dates as to when the code was commented out. Later, someone that is working near there can just delete the commented out code as it has been proven not to be needed.

It would also be good to know who commented out that code so that if some rationale is needed then they can be asked.

I prefer to write new functionality, ensure the unit tests pass, check it in, then allow others to use it and see how it works.

If the developer has commented out some code because it is not yet complete, then the correct "source control" way to deal with this would be for that developer to keep it in a separate branch of his own, until that code is ready to check in.

With a DVCS (like git, bazaar, or mercurial) this is dead easy as it requires no changes in the central repository. Otherwise, perhaps you could talk about giving developers their own branches on the server if they are working on specific features that will take them a long enough time (ie, days).

There is nothing wrong with checking in commented out code in some situations, it's just that this is one situation where there may be a better way to do it, so the developer can track changes to his source even though it isn't ready to be checked in to the main repository.

Clearly, the developer who is checking in commented-out code should be working in a separate branch, merging in changes from the trunk branch as neccessary.

It is up to the VCS system to assist the developer in this workflow (git is one excellent VCS system that works with this very nicely).

Interesting Posts