views:

2540

answers:

31

Ok, here is something that has caused some friction at my current job and I really didn't expect it to. Organized in house software development is a new concept here and I have drawn up a first draft of some coding guidelines.

I have proposed that "commented out" code should never be checked into the repository. The reason I have stated this is that the repository maintains a full history of the files. If you are removing the functional code then remove it altogether. The repository keeps your changes so it is easy to see what was changed.

This has caused some friction in that another developer believes that taking this route is too restrictive. This developer would like to be able to comment out some code that he is working on but is incomplete. This code then would never have been checked in before and then not saved anywhere. We are going to be using TFS so I suggested that shelving the changes would be the most correct solution. It was not accepted however because he would like to be able to checkin partial changes that may or may not be deployed.

We want to eventually get to a point where we are taking full advantage of Continuous Integration and automatically deploying to a development web server. Currently there is no development version of web servers or database servers but that will all be changed soon.

Anyway, what are your thoughts? Do you believe that "commented out" code is useful to have in the repository?

I'm very interested to hear from others on this topic.

Edit: For clarity sake, we don't use private branches. If we did then I'd say do what you want with your private branch but don't ever merge commented out code with the trunk or any shared branches.

Edit: There is no valid reason we don't use private or per user branches. It's not a concept I disagree with. We just haven't set it up that way yet. Perhaps that is the eventual middle ground. For now we use TFS shelving.

+74  A: 

There may be others with different experiences, but in mine checking in half-finished code is a horrible idea, period.

Here are the principles I have learned and try to follow:

  • Check in often - at least once, but preferably many times per day
  • Only check in complete functionality
  • If the first and second conflict (e.g. it takes more than a day to make the functionality work) then the task is too large - break it into smaller completable tasks.

This means:

  • Commented-out code should never be checked in since it is not functional
  • Commenting is not a valid archival strategy, so whether it's code yet-to-be-finished or code that's being retired, commenting and checking in doesn't make any sense.

So in summary, NO! If the code is not ready to go to the next stage (whichever that is for you: IntTest/QA/UAT/PreProd/Prod), it should not be committed to a trunk or multi-developer branch. Period.

Edit: After reading the other answers and comments, I'll add that I don't think it's necessarily a good idea to ban commented code (not sure how you'd enforce that anyway). What I will say is that you should get everyone on your team to buy in to the philosophy I described above. The team I work on embraces it wholeheartedly. As a result, source control is a frictonless team-member, one that helps us get our job done.

People who don't embrace that philosophy usually cause broken windows and are often frustrated by source control. They see it as a necessary evil at best, and something to avoid at worst; which leads to infrequent checkins, which means changesets are huge and hard to merge, which compounds frustration, makes checkins something to avoid even more, etc. This is ultimately an attitude thing, not really a process thing. It's easy to put up mental barriers against it; it's easy to find reasons why it won't work, just like it's easy to find reasons not to diet if you don't really want to. But when people do want to do it and are committed to changing their habits, the results are dramatic. The burden is on you to sell it effectively.

Rex M
I agree with your clarification--never check-in half-finishe code into the "trunk" or whatever that equivalent is. There should always be a branch/trunk that is the "this code is always working" version. Go ahead and check-in half finished to a private dev branch, local mirror, shelve, whatever.
James Schek
@James that is exactly my opinion as well :)
Jason Coco
The key words are "not committed to the trunk"; I agree with that. Working on a development branch with intermediate checkins, it can and does sometimes make sense to have stuff lurking that isn't as polished as it will be when it makes it to the trunk.
Jonathan Leffler
@Jonathan it depends on the branch. In my experience TFS does not lend itself well to creating formal branches that will only be used by a single developer.
Rex M
I agree it's very convenient to checkin really often, even code that it's not working but... never to the main branch! That's why modern SCMs allow you to create as many branches as you need, then on the "secondary or task branches" checkins become "checkpoints", quite useful while coding
pablo
I also hate finding dead code on the version control system, but if you disable (comment) some code to be reactivated later, especially on big teams, there's always a risk for the code to be rewritten instead of recovered... What do you think?
pablo
@pablo commenting definitely has plenty of risks and basically no real benefits.
Rex M
Rex M: What are the risks of commenting?
Eddie
@Eddie - I once spent 6 hours looking at a defect which was caused by someone commenting out code temporarily and never undoing the change. It was an unintentional consequence. It led me to suggesting this restriction.
John
@Eddie comments are, by definition, not compelled to stay in sync with the rest of the codebase. They can become stale and misleading and contribute to broken windows of the system. All of those things are risks to developer's time. We have enough of those already. It's easy enough to avoid this one
Rex M
@Rex M: IMO, Comments are an essential part of the code. In any code I maintain, comments are guaranteed to stay in sync with the rest of the codebase. Code where comments are out of sync is broken. You just may not know it yet.
Eddie
If you allow comments to drift out of sync with the source code, then just remove all comments. Their presence will cause direct harm if they are out of date.
Eddie
@John: It sounds like that defect was caused by a developer oversight. How would a ban on checking in commented-out code have prevented that developer from making this oversight? The ban just gives you TWO things to punish over instead of one. It doesn't prevent the oversight.
Eddie
@Eddie not talking about comments, talking about commented code. How are you supposed to find and update all the commented-out code which would be impacted by your changes?
Rex M
I wholeheartedly agree with your most recent update. And I see commented-out code as a refined version of a prose comment, not as something I expect to function correctly if I uncomment it. As you implicitly suggest above, IDEs will not include commented-out code in refactorings, + other reasons.
Eddie
@Eddie as prose, I think we are definitely on the same page. I am taking "commented code" in the question to mean "This isn't finished and doesn't work but I'm checking in anyway". That sets off alarms to me.
Rex M
@Eddie - It's just another step to prevent unintentional consequences and encourage developers, of which I am one, to pay closer attention to what they are doing.
John
@John: If you strongly discouraged checking in commented-out code, that seems reasonable. If you absolutely ban it, many here have made a case for edge cases where it is -- rarely but NOT never -- useful to do. However, almost all here seem to agree that the specific developer you're arguing with wants to do something that is a bad idea, something that is disruptive to the other developers and the project as a whole.
Eddie
I almost voted this up, but it is *really* rare that I get something I'm working on in check-in state in only one day of work. I suppose its possible that you are juat a much better developer than I, but I choose to believe that I work on harder stuff than you. :-)
T.E.D.
@null it's really just a mindset thing. It's very possible to structure practically any development task in such a way that incremental units of work are a day's worth or smaller, but it requires a shift in thinking and a change in approach. Of course, bad days happen, but if you are consistently going multiple days where your codebase is broken, that should be a red flag.
Rex M
@Rex I completely disagree, but's it's clear you and I have completely different work environments. "A day's work" may be compressing 8 hours of development into nine non-contiguous 20 minute blocks. The next day, I may get eleven non-contiguous 30 minute blocks. The day after, I may get two 60 minute blocks. Exactly how do I structure my development tasks as you describe?
James Schek
@James Schek - not sure I follow, without knowing what it is you're actually doing in these hypothetical chunks of time.
Rex M
@Rex Those are not hypothetical. They are real. I am trying to develop software in those chunks... i.e. design, write code, debug, write tests, perform tests, track down and fix bugs, etc.
James Schek
@James in the absence of an extended discussion, I don't know if I'm able to understand how your description of a work method is incompatible with the ideas in my answer.
Rex M
@Rex A task can be broken down into some indivisible unit of work that takes N-hours to complete. If I don't have N-hours of productive time in a single day, then what do propose?
James Schek
@James I have yet to see a software development objective that can't be broken into tasks as small as a few minutes if necessary. TDD, agile, etc. all demonstrate this. When you are working on a team with a centralized source, very few things net as large productivity and agility gains as forcing yourself to work at a task resolution fine enough to avoid spanning sessions of productivity.
Rex M
@James like I said in the answer, this is an attitude thing. It's easy to come up with reasons this approach won't work for you, just like it's easy to come up with reasons not to diet. If you look at the most successful teams in our industry, you'll see far more often than not, all the team members believe this and put in the effort to make it work. I promise, it pays off :)
Rex M
+1 I'm dealing with this in my current environment.
George Stocker
+2  A: 

I absolutely agree that commented out code shouldn't be checked into the repository, that is what source code control is for.

In my experience when a programmer checks in commented out code, it is because he/she is not sure what the right solution is and is happier leaving the alternate solution in the source in the hope that someone else will make that decision.

I find it complicates the code and makes it difficult to read.

I have no problem with checking in half finished code (so you get the benefit of source control) that isn't called by the live system. My problem is with finding sections of commented code with no explanation the dilemma was that resulted in the code being excluded.

Cannonade
+13  A: 

I think never is too strong a condition.

I tend to comment out, checkin, run the tests, have a think and then remove comments after the next release.

Fortyrunner
If you haven't run the tests, then you shouldn't check it in yet. Don't check in code that will fail the tests or otherwise break the build.
John Saunders
@John Saunders: This depends on what checking in does in your source control system. If you're using something like ClearCase with UCM, then checkins are always on a private branch and a separate step is required to move to the equivalent of "TRUNK."
Eddie
Exactly, but unfortunatelly a huge number of developers out there think "commit" means "introducing changes into trunk", thanks to CVS and SVN I guess. Fortunately new systems like GIT are teaching new methods...
pablo
@john, I meant: comment out, test, checkin..! You are correct.
Fortyrunner
@pablo GIT FTW! :-)
James Schek
+35  A: 

"Never" is rarely a good word to use in guidelines.

Your colleague has a great example of when it might be appropriate to check in code that is commented out: When it is incomplete and might break the application if checked in while active.

For the most part, commenting out dead code is unnecessary in a well-managed change-controlled system. But, not all commented code is "dead."

Jekke
I disagree. If the code is incomplete, why is it being checked-in in the first place. Modern source control systems have mechanisms for uploading in-progress functionality without committing to the trunk.
Rex M
+1, sometimes this is the most appropriate thing to do. Not always, but not *never* either. **Never** is easy to say, but is too restrictive.
Eddie
@Rex I don't think there's enough information in the original post to determine the difference between uploading in-progress functionality and committing to the trunk.
Jason Coco
Rex--which is it? Never check in incomplete? Or never check-in incomplete to trunk? Those are not the same thing.
James Schek
@Jason "developer would like to be able to comment out some code that he is working on but is incomplete". Sounds like he wants to check-in in-progress functionality to me.
Rex M
@Rex agreed but to the trunk? Or just uploading it to the system (a branch?) We have no idea what their strategy is. I often "check in" incomplete work (meaning it's committed to the server but not yet in the trunk). We just don't know.
Jason Coco
@James I think we are talking about the trunk, otherwise this wouldn't be a discussion. No one cares what happens in a branch unless multiple developers are working in that branch, which makes it a trunk of sorts to those developers for the life of their involvement in it.
Rex M
@Jason that's what shelved sets are for. They are uploaded to the server but not part of the codebase others are touching.
Rex M
Shelves are useless. There is no history or change-log on shelves. There are several other workflow problems with shelves, but that's a different discussion. :-)
James Schek
@James I would not say they are useless. We use them extensively at my workplace and they have helped quite a bit.
Rex M
If a method compiles, and is not accessed by any active code path (No other method calls it) why not check it in ? If it represents more than a few hours work, That's what repositories are for !!
Charles Bretana
But I wouldn't comment it out...
Charles Bretana
@Charles Bretana - I think we are in complete agreement. Unless it is carried too far such as developers all have a method with their name in it just to get around the rule.
John
+4  A: 

I broadly agree with the principle that commented out code shouldn't be checked in. The source control system is a shared resource, and your colleague is, to an extent, using it as his personal scratch pad. This isn't very considerate to the other users, especially if you subscribe to the idea of shared ownership of the codebase.

The next developer to see that commented-out code would have no idea that it's a work in progress. Is he free to change it? Is it dead code? He doesn't know.

If your colleague's change isn't in a state where it can be checked in, he needs to finish it, and/or learn to make smaller, incremental changes.

"Checking in partial changes that may or may not be deployed" - presumably that also means may or may not be tested? That's a slippery slope to a very ropey code base.

sgreeve
Absolutely agree!
John
+1  A: 

I think "Never" is too strong a rule. I'd vote to leave some personal leeway around whether people check commented code in to the repository. The ultimate goal should be coder productivity, not "a pristine repository."

To balance that laxness out, make sure everyone knows that commented out code has an expiration date. Anyone is allowed to delete the commented code if it's been around for a full week and never been active. (Replace "a week" with whatever feels right to you.) That way, you reserve the right to kill clutter when you see it, without interfering too directly with people's personal styles.

ojrac
+3  A: 

Perhaps the real question here is whether developers should be allowed to check in incomplete code?

This practice would seem to be contradictory to your stated goal of implementing continuous integration.

Kyle W. Cartmell
+12  A: 

I would certainly discourage, strongly, ever checking in commented-out code. I would not, however, absolutely ban it. Sometimes (if rarely) it is appropriate to check commented-out code into source control. Saying "never do that" is too restrictive.

I think we all agree with these points:

  • Never check dead code into source control
  • Never check broken (non-functioning) code into source control, at least never to trunk and only very rarely to a private branch, YMMV
  • If you have temporarily commented something out or broken something for debugging purposes, don't check the code in until you restore the code to its correct form

Some of are saying there are other categories, such as temporarily removed code, or an incremental but incomplete improvement that includes a small amount of commented-out code as documentation of what comes next, or a very short (ideally 1 line) snippet of commented out code showing something that should never be re-added. Commented-out code should ALWAYS be accompanied by a comment that says why it is commented out (and not just deleted) and gives the expected lifetime of the commented-out code. For example, "The following code does more harm than good, so is commented out, but needs to be replaced before release XXX."

A comment like the above is appropriate if you are delivering a hotfix to stop a customer's bleeding and you don't have the immediate opportunity to find the ultimate fix. After delivering the hotfix, the commented-out code is a reminder that you still have something that needs fixing.

When do I check in commented-out code? One example is when I am tentatively removing something that I think there's a high probability will have to be re-added in the near future, in some form. The commented-out code is there to serve as a direct reminder that this is incomplete. Sure, the old version is in source control and you could just use a FIXME comment as a flag that something more is needed. However, sometimes (if not often) code is the better comment.

Also, when a bug is fixed by removing one line (or more rarely, two lines) of code, I'll sometimes just comment out the line with a comment to never re-enable that code with a reason why. This sort of comment is clear, direct, and concise.

Rex M said: 1) Only check in complete functionality, 2) [If] the task is too large - break it into smaller completable tasks.

In response: Yes, this is the ideal. Sometimes neither option is achievable when you are working on production code and have an immediate, critical problem to fix. Sometimes to complete a task, you need to put a version of code in the field for a while. This is especially true for data gathering code changes when you're trying to find the root cause of a problem.

For the specific instance being asked about in the more general question ... as long as the developer is checking commented-out code into a private branch that no-one will see but that developer (and perhaps someone the developer is collaborating with), it does little harm. But that developer should (almost) never deliver such code into trunk or an equivalent. Trunk should always build and should always function. Delivering unfinished code to trunk is almost always a very bad idea. If you let a developer check unfinished or temporary code into a private branch, then you have to rely on the developer to not forget to scrub the code before delivering into trunk.

To clarify in response to comments to other answers, if code is commented out and checked in, my expectation that the code will function if uncommented drops with the length of time the code has been commented out. Obviously, refactoring tools will not always include comments in their refactoring. Almost always, if I put commented-out code into production, the code is there to serve as a refined comment, something more specific than prose, that something needs to be done there. It is not something that should have a long life.

Finally, if you can find commented-out code in every source file, then something is wrong. Delivering commented-out code into trunk for any reason should be a rare event. If this occurs often, then it becomes clutter and loses its value.

Eddie
To whomever downvoted this: I would appreciate a comment as to what in what I said is -- in your opinion -- wrong.
Eddie
"the commented-out code is a reminder" - that's what an issue tracking system is for. You should delete the code and create a ticket referencing the changeset.
camh
@camh: An issue tracking system won't provide the same context as a reminder that is in the code itself, in context, with a succinct comment in place about the problem. Issue tracking isn't integrated with the IDE that deeply. Your suggestion discards a *lot* of information for the sake of dogma.
Eddie
@Eddie - I get the distinct impression you work on mostly small scale stuff. In large applications, comments like that are pretty useless and only serve to add additional clutter.
John
@John: No, I work on stuff with millions of SLOC and tens of thousands of source files. If you think the kind of comment I'm referring to is clutter, then this means that you don't understand me and/or that I'm not being clear enough. I am talking about an edge case, not a common occurrence, as I've said many times in threads in response to your question. And hey, isn't your shop the one that doesn't do private branches? Don't get arrogant on me.
Eddie
@John: For an example, see my last comment to http://stackoverflow.com/questions/758279/checking-in-of-commented-out-code/758645#758645 -- and give me a better way of preventing RE-introduction of that bug. Or to @camh, tell me how an issue tracking system would prevent re-introduction of that bug. When you work on mission-critical 5-9's equipment, stuff like this matters.
Eddie
@Eddie - Sorry to offend you but it doesn't change the fact that I disagree. I do believe it just clutters the code. Like I said in the very link you posted, if it were just one line I have no problem mentioning in a one line comment why a specific thing shouldn't be done. That's not commented out code so much as proper documentaion. Also as I stated multiple times, we use TFS and shelving instead of private branches.
John
@John: How am I not supposed to be offended at "I get the distinct impression you work on mostly small scale stuff"? aka, just because we disagree on something pretty small, I must be inexperienced? You are of course always entitled to your opinion, and it's fine that we disagree. But notice when I disagree with you, I don't criticize your experience level just because we see things differently. In fact, I 98% or 99% agree with you. I just don't like absolutism.
Eddie
@Eddie - I know more than a few developers that have never worked on large scale stuff that are far and away better programmers than I am. I didn't mean what you are reading into my comment by any stretch. I was simply saying that "in my experience" leaving traces of commented out code clutters the code base. In a large team if everyone did it you would end up with a real mess. I've seen it multiple times. BTW: I'm doing small scale stuff right now since I recently changed jobs.
John
@John: If every developer in a large team did this with the frequency that I do, you would have to search to find it in the code base. Although I've used the qualifier "rare" in many comments, I didn't see it clearly enough in my answer. So I have edited my answer to make more clear what I've been trying to say. And now that I understand your definition, I have worked on both large and small scale stuff.
Eddie
@Eddie - The current incarnation of your answer is much closer to being in agreement with what I would consider best practice. As always when it comes to best practices though, you will never get 100% agreement from everyone that anything is a legitimate best practice. I didn't expect to when I posted my question :)
John
+15  A: 

Commented out code should never be checked-in for the purpose of maintaining history. That is the point of source control.

People are talking a lot of ideals here. Maybe unlike everyone else, I have to work on multiple projects with multiple interruptions with the "real world" ocassionally interrupted my workday.

Sometimes, the reality is, I have to check-in partially complete code. It's either risk losing the code or check-in incomplete code. I can't always afford to "finish" a task, no matter how small. But I will not disconnect my laptop from the network without checking-in all code.

If necessary, I will create my own working branch to commit partial changes.

James Schek
@James your last bit is the key - if you can't check in working code, then find another place to put it. Whether that's a branch or a shelved set or whatever.
Rex M
If I could upvote this one more than once, I would. My sentiments precisely!
Ola Eldøy
+2  A: 

It depends. If it's being left there for purposes of illustration, maybe. It could possibly be useful during refactoring. Otherwise, and generally, no. Also, commenting out unfinished code is bound to be both failure-prone and a time sink. Better he break the code into smaller pieces and check them in when they work.

riney
+4  A: 

This shows a fundamental difference in two schools of thought: Those who only check in working code that they are satisfied with and feel is worthy of saving, and those who check in their work so the revision control is there to backstop them against data loss.

I'd charactarize the latter as "those who like to use their revision control system as a poor-man's tape backup", but that would be tipping my hand as to which camp I'm in. :-)

My guess is that you are of the "good code" camp, and he is of the "working code" camp.

[EDIT]

From the comments, yes I guessed right.

As I said, I'm with you, but as near as I can tell this is a minority opinion, both here on stackoverflow and where I work. As such, I don't think you can really enshrine it in your development standards as the only way to operate. Not if you want the standards followed anyway. One thing a good leader knows is to never give an order they know won't be followed.

btw: Good editors will help with keeping old versions. For example, in Emacs I set kept-old-versions and kept-old-versions to 10, which has it keep around the last 10 saves of my files. You might look into that as a way to help your argument against the revision-control-as-backup crowd. However, you won't ever win the argument.

T.E.D.
This was stated here as well. In my mind however, the repository is not a data loss prevention tool. It is a revision control system. Since we are using TFS he can use shelving to backup incomplete code. He could also use a backup tool or put the code on a backed up share.
John
IDE backups don't protect against data loss. Corporate backup systems don't always meet the needs of code data-loss. Source control is a system that can easily handle both needs. It's relatively easy to develop a policy that meets the needs of both camps rather than exclude one or the other.
James Schek
In what way do my Emacs backups not protect me, James? BTW: I agree wholeheatedly with your last sentence.
T.E.D.
Emacs backups are meant for reverting to a previous state on a particular file. Directing backup files to a file server is not enabled by default and requires me to beg the sysadmin for space on a file server. If I had a FS, I would just tar the whole project to the FS and be done with it. Further, the complete "state" of a workspace/project is important "data" to me. Emacs (and most IDE's) have no mechanism to save that.
James Schek
@ted.dennison: Looking at the scores of the top two answers, I would say your opinion is the *majority* opinion on SO.
Eddie
Revision control is not MERELY a protection against data loss. It provides persistent, infinite undo. I'd say you can't buy that, but you can, it's called revision control. For release builds we put a freeze on new features and sometimes excise features we know won't be ready. Come the day, there is a frenzied cycle between the dev and test teams and when the dust settles we branch and tag. Those excised features are often present as large quantities of commented out code, which is generally uncommented right after the release.
Peter Wone
@Eddie: I was noticing that too. However, you really can't take ratings as gospel for popularity of opinion. Many folks are much more inclined to rate up than down. I'd say its more of an indication that *some* folks strongly agree. I've seen other revision control questions here where the pro-revision control-as-backup answers got way upmodded.
T.E.D.
@Peter Wone: I think I pretty much agree with that, except I don't think it's meant to be a protection against data loss at all. It is precisely, as you indicate, for when you have a state of the entire project you want saved for possible future retrieval. The chief reason is that you may have handed that version off to someone (eg: a customer), and might need to debug that version later. Almost as good is if you verified that everything worked in that version, so you want to save it as a fallback. Either way, everything should compile!
T.E.D.
Eclipse also has local history, so it helps also to avoid temporarily commenting out code.
thSoft
@thSoft - Yeah, its not exactly a new to emacs thing. Back in the day all the VMS editors used to work that way. IMHO a good text editor will support it.
T.E.D.
A: 

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.

DJ
Maybe you need better diff tools?
jw
One reason not to do that would be so that you can see who wrote the original line trivially (eg. git blame)
dasil003
Yikes. To me, this would be analogous to saying "I always flush before using the toilet. But not afterward."
benjismith
A: 

I think there are better alternatives to commented-out code.

One option which allows this other developer to check in temporary or experimental code is to have per-developer #defines (assuming you're using a language that supports it).

I have worked at places where every coder had their own #define, matching their username, which they could use for things that only they were interested in. Eventually when the code was ready for prime-time, the #if checks were removed.

For instance you might have

#if JOEBLO
// This code is experimental

// ... code goes here ...

#endif // JOEBLO

Regarding Rex M's answer, I think there are sometimes cases when the incremental check-in you want to make (to record progress) does not function well enough to enable for everyone. In such cases, the #define is useful.

Another alternative is to locally use a DVCS like Mercurial to track your changes, then when you get to a stable "ready for the public" state, you push those changes out to the team. Be careful of submitting too much at once, though.

jw
I believe this is actually worse. Reason being, JOEBLO is checking in code that works one way on his machine and another on soemone else's. Further it wouldn't work the same on the deployment server either.
John
Seems like this would cause endless "works fine on MY machine" headaches.
benjismith
Surprisingly, we had practically no problems like that. Obviously it should be used with care. It was typically used to turn off/on a particular well-enclosed feature, not sprinkled throughout the code.
jw
Also was useful to put diagnostic info in such blocks that would only be particularly relevant to one or a few people who understood it.
jw
+3  A: 

My view: if developers are working on their own branches, or in their own sandbox area, then they should be able to check in whatever they want. It's when they check code into a shared branch (a feature branch, or a team's branch, or of course MAIN/trunk) that the code should be as pristine as possible (no commented out code, no more FIXMEs, etc).

jean
There isn't a single meaningful project in the world without TODOs and FIXMEs or HACKs in the main trunk. Dream on.
Robert Gould
@Robert just because it happens a lot doesn't mean we shouldn't try to avoid it.
Rex M
Wow, this really is a dream. Production code with no FIXMEs? It must be absolutely feature complete with no bugs and no unexplained behavior. Oh wait, code that is like that doesn't exist! :)
Eddie
Yes, clearly a dream - I was just trying to say that the bar to committing into a shared branch is much higher than committing into your personal sandbox / work-in-progress branch.
jean
@jean: Yes, we agree on that totally.
Eddie
+4  A: 

When you need to add a small feature or bug fix like NOW, within the next 3 minutes and you have to fix a file you have some half developed code on I'd say it's ok, practical needs rule over pragmatic ideals on the battlefield.

Robert Gould
Where does change management fit into this scenario? I agree that there are shops where everything is always a major fire but it doesn't mean things should be done that way. I'd also suggest that it could be a reason for the problem. Not enough control over the code base.
John
I totally agree this sort of thing SHOULD be avoided, but for some reason, management doesn't seem to agree :)
Robert Gould
+3  A: 

In my experience, developer switches are commented out code.

Sometimes, new back-ends are built in parallel, with the activating switchs commented out in source control.

Some bizarre feature we need once on a blue moon but no customer will ever need is often implemented that way. These things usually carry a high risk of security or data integrity bypass so we don't want them active outside of development. Requiring a developer who would use it to uncomment the code first seems to be the easiest way of getting it.

Joshua
+1  A: 

Repositories are backup of code. If I am working on code but it is not completed, why not comment it out and check it in at the end of the day. That way if my hard drive dies overnight I will not have lost any work. I can check out the code in the morning uncomment it and keep on going.

The only reason I would comment it out is because I would not want to break the overnight build.

gbrandt
A repository is a version control system not a backup tool in my mind.
John
@John: Many developers will see it as both.
Eddie
@Eddie, they will, but it's not. For backups there's all sorts of good options, version-control isn't really one of them, is it?
David Thomas
@ricebowl: I'm not saying I agree with those developers! Many places won't pay to back up individual developers' boxes. Checking in incomplete work to a private branch before going on a long vacation functions as a decent backup of the work accomplished so far. Developers are pragmatic.
Eddie
A: 

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.

Mark Simpson
+6  A: 

In general, checking in commented-out code is wrong as it creates confusion amongst those who are not the original author and need to read or amend the code. In any event, the original author often ends up confused about the code after 3 months have passed.

I espouse the belief that the code belongs to the company, or team, and that it is your responsibility to make things easy for your peers. Checking in commented-out code without also adding a comment about why it is being retained is tantamount to saying:

I don't mind if you end up all confused over why this stuff is here. My needs are more important that yours which is why I have done this. I do not feel any need to justify to you, or anyone else, why I have done this.

For me commented-out code is normally a big f**k you from a less that thoughtful co-worker.

The last line of your post is dead on. I wish I could up vote you more than once
MikeJ
Sometimes what is convenient for you is not the only consideration. Of course one of the important responsibilities for a developer is to make things easy on future developers, but that does have to compete with other interests. Looking at something very slightly inconvenient and immediately assuming it was added just to piss you off shows a very self-important attitude on your part.
Andrew Shelansky
+1  A: 

There is clearly a tension between 1) checking in early, and 2) always maintaining the repository in a working state. If you have more than a few developers, the latter is going to take increasing precedence, because you can't have one developer crapping all over everyone else for his own personal workflow. That said, you shouldn't underestimate the value of the first guideline. Developers use all different kinds of mental fenceposts, and individualized workflows are one way that great developers squeeze out those extra Xs. As a manager your job not to try to understand all these nuances—which you will fail at unless you are a genius and all your developers are idiots—but rather enable your developers to be the best they can be through their own decision-making.

You mention in the comment that you don't use private branches. My question for you is why not? Okay, I don't know anything about TFS, so maybe there are good reasons. However after using git for a year, I've gotta say that a good DVCS totally diffuses this tension. There are cases where I find commenting out code to be useful as I'm building a replacement, but I will lose sleep over it if I'm inflicting it on others. Being able to branch locally means I can keep meaningful commits for my individual process without having to worry about (or even notify) downstream developers of temporary messes.

dasil003
The reason we don't use private branches is because we only recently started using source control at all. I'm very new to the company and it is my responsibility to help straighten all this out. I don't disagree with the concept but for now we use shelving in TFS instead.
John
A: 

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.

James Black
If you have a whole team of people developing and then maintaining code this way, it quickly becomes unreadable. With the right version control system, you can easily find differences between arbitrary versions.
Eddie
+1  A: 

Just echoing the chorus. Discourage this at all costs. It makes the code harder to read and leaves folks wondering whats good/bad about that code that isnt even part the application at the present time. You can always find changes by comparing revisions. If there was some major surgery and code was commented out en-masse the dev should have noted it in the revision notes on checkin/merge.

incomplete/experimental code should be in a branch to be developed to completion. the head/trunk should be the mainline that always compiles and is whats shipping. once the experimental branch is complete it/accepted it should be merged into the head/mainline. There is even an IEEE standard (IEEE 1042) describing this if you need support documentation.

MikeJ
Very helpful, thanks.
John
Mostly in agreement. But what do you do when you need to ship experimental code because you are trying to identify the root cause of a site's problem? When talking development, I agree with you, but when talking support, sometimes you *need* to ship experimental code.
Eddie
@Eddie - I agree with the experimental code needing to ship from time to time. But it shouldn't be commented out when it is no longer needed in my opinion.
John
@Eddie - i understand. but the branch is a complete copy of the head/release version at the time you create the branch. ifyou make a mod, it should be buildable/shippable. if you like the changes in branch you mergee them back into the head end or you keep it handy for debug/profiling when needed.
MikeJ
@John: Absolutely agree. Once the experimental code is no longer experimental, it should be left in place or totally removed, whichever is appropriate. @MikeJ: Good response.
Eddie
+4  A: 

Another reason for checked in commented out code:

You're modifying existing code, and found a subtle bug, one that is easy to overlook, and perhaps might even look correct at first glance. Comment it out, put the fix in its place, and add comments for what is going on, and why it was modified. Check that in, so that your comments on the fix are in the repository.

thursdaysgeek
+1: Leaving the commented-out code in place -- if and only if it is concise and inobtrusive -- prevents someone from forgetting "don't do this" and reintroducing the bug. ESPECIALLY when the fix involves removing lines of code, not rewriting lines of code.
Eddie
Definitely on the removing lines of code. That's a good point.
thursdaysgeek
I disagree. Leaving a comment about what to avoid is necessary, but not in code form, rather than describing it in words.
thSoft
+12  A: 

One case where I leave commented out code:

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

when that is the obvious approach to the problem but it contains some subtle flaw. Sure, the repository would have it but the repository wouldn't warn anyone in the future not to go down that road.

Loren Pechtel
If it was limited to one line then this could be an exception. I'd rather see a concise block comment (a few lines tops) that mentions the reasons for taking one approach vs another. In that case I wouldn't consider that to be "commented out" but documented.
John
+1. An example I've seen is where something was broken because the code set an soTIMEOUT. The fix was to remove it. If you just remove the line of code, then someone may later re-introduce it, thinking they are fixing a bug by doing so, but actually they are re-introducing a bug.
Eddie
Yeah, that's my idea--ensuring that the bug isn't reintroduced in the future. By leaving the actual code they can see that it wasn't just a bug in how the original was written.
Loren Pechtel
+1  A: 

I think checking-in commented code in a source code control system should be done with extreme caution, especially if the language tags used to comment the code are written by blocks, i.e.:

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

Rather than on an individual line basis, like:

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

(you get the idea)

The reason I would use extreme caution is that depending of the technology, you should be very careful about the diff/merge tool you are using. With certain source code control system and certain language, the diff/merge tool can be easily confused. The standard diff/merge of ClearCase for example is notoriously bad for merging .xml files.

If it happens that the commenting blocks lines are not merge properly, presto your code will become active in the system when it shouldn't be. If the code is incomplete and break the build, that is probably the least evil, as you will spot it immediately.

But if the code passes the build, it may become active when it shouldn't be there, and from a CM perspective, that could be a nightmare scenario. QA generally test what should be there, they don't test for code that is not supposed to be there, so your code may end up in production before you know it, and by the time it would be realized the code is there when it shouldn't, the cost in maintenance have multiplied many folds (as the "bug" will be discovered in production or by the customer, worst place or time ever).

Thomas Corriol
Yes, I agree. We have also specifically disallowed the /* */ style of commenting in all of our C# programs.
John
A: 

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.

thomasrutter
A: 

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).

Arafangion
A: 

"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!

Kelly French
A: 

I would prefer to see possibly broken, accessible code that isn't being used yet checked in over the same code being completely unavailable. Since all version control software allows some sort of 'working copy' separate from the trunk, it's really a much better idea to use those features instead.

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.

TokenMacGuy
A: 

In C++, I use #if 0 for commented code and find it legitimate. Refactoring tools still work on it, so technically it is almost maintained. And, it's distinctly colored by syntax highlighting.

I think such feature would be useful for all:

  • this code is not operational
  • it still belongs here
  • and it must be very visible at this very point, because it is relevant.

Always delete commented code if it has no real comment explaining what is so special about this code and why is it so important, despite being inoperational.

Pavel Radzivilovsky
A: 

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.

Andrew Shelansky