Software Engineering 101….ARGH!
Some days, I just can’t handle the aggrevation…
I thought it was generally known that binary build output does not belong in source control, so I was quite dismayed when I grabbed an update to our source tree today and found myself downloading a 2MB .msi file (the output of one of our installer projects).
After discussing this with the other developers on my team, it became apparent that what I thought was a common, well known practice regarding source control is in fact, not so well known.
After presenting my arguments with little avail, I started to scour the web to find evidence support my stance:
What Files Should Not Be Source Controlled?
Build outputs that include assembly dynamic-link libraries (DLLs), Interop assembly DLLs and executable files (EXEs). Note that you are advised to add assemblies that are not built as part of your system build process (such as third-party controls and libraries) to Source Control within the projects that reference them.
Generally, avoid storing build output in version control. Provided that your source code is versioned properly, you should be able to recreate any previous release through the build process.
Files that you cannot add to source control include the following:
…Build output files, for example, *.dll and *.exe files.
We do not include the *.xml outputs in source control for the same reason that we do not include *.htm outputs; you can’t run a new build without checking out the files! In my view, whether an output is a *.dll or a *.htm or a *.xml is irrelevant; it’s build output, so it shouldn’t be source controlled. Just source control the inputs and you have everything you need to get the outputs.
It is very important to us to be able to run an automated build (no human intervention). To the extent that a future version does include a dialog that offers to check out files, I hope it will either not run at all if the files are not source-controlled, or it can be suppressed by project settings.
Best Practice: Checkin all the Canonical Stuff, and Nothing else.
Although you can store anything you want in a repository, that doesn’t mean you should. The best practice here is to store everything which is necessary to do a build, and nothing else. I call this “the canonical stuff.”
To put this another way, I recommend that you do not store any file which is automatically generated. Checkin your hand-edited source code. Don’t checkin EXEs and DLLs. If you use a code generation tool, checkin the input file, not the generated code file. If you generate your product documentation in several different formats, checkin the original format, the one that you manually edit.
If you have two files, one of which is automatically generated from the other, then you just don’t need to checkin both of them. You would in effect be managing two expressions of the same thing. If one of them gets out of sync with the other, then you have a problem.
So not only is it a pain in the ass to have to download large binary files for a one line code changes, it also means that simply compiling the code (with no changes in the actual code) may cause a version change…argh!
I think that such a practice of disallowing build output in the repository also forces the team members to ensure that their code is buildable anywhere…a great quality when it comes to codebases as it means that onboarding new members or transitioning development machines, the code is ready to go.