Preventing a file from being committed if it contains a certain keyword

If you are a developer with any real-world experience to speak of, you have undoubtedly come across the following situation: you made a change which was not meant to be committed, (for instance, some debug statement or some mock-up of functionality meant to be filled-in later,) and then you forgot about it and went ahead and committed all of your code. This mishap can be a cause of severe frustration for your fellow co-workers, and the source for memorable "WTF moments" for the QA department.

Now, if you are like me, you like to automate things. Why should I have to remember to do something on my computer, when my computer can be tasked with reminding me to do it? Is a computer the ultimate automation tool or not?

The interwebz abound with questions on precisely how to achieve this bit of automation:

In short, if you are using SVN, here is how to do it:

Have a pre-commit hook in the repository which checks to see whether any file contains the string NOCOMMIT, and if so, it fails the commit.

So, when I alter a source file in a way which is not meant to be committed, I append a //NOCOMMIT comment right next to each change, and I do not have to worry about it anymore. If I do accidentally attempt to commit it, the pre-commit hook of the repository will block my commit and let me know which files contain the NOCOMMIT  keyword, so I can go into each one of those files and fix it.

I find this feature so useful that I honestly even use it when programming at home, where obviously, I am the only programmer in the team.

If you are using SVN on windows, you can paste the following into a file called pre-commit.bat in the hooks folder of your SVN repository:

:: Stops commits that contain the NOCOMMIT keyword.
set REPOS=%1
set TXN=%2
SVNLook diff %REPOS% -t %TXN% | findstr /I /M /L NOCOMMIT > nul
if %errorlevel% gtr 0 (
    exit 0
) else (
    echo Your commit has been blocked because it contains the keyword NOCOMMIT. 1>&2
exit 1

With SVN on Unix systems, something like the following will do the trick, though please note that I have not tested it.  (Note: suggestions from a comment by Georgi have been applied.)


$SVNLOOK diff -t "$TXN" "$REPOS" | grep -i "NOCOMMIT" > /dev/null && { echo "Your commit has been blocked because it contains the keyword NOCOMMIT." 1>&2; exit 1; }


Wonderful MSBuild

So, for some time now, whenever I try to 'batch build' from within Microsoft Visual Studio 2010, I get the following error:

C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2868,9): error MSB3021: Unable to copy file "x\Intermediate\y.dll" to "x\y.dll". Could not find file 'x\Intermediate\y.dll'.

Indeed, there is no file 'x\Intermediate\y.dll'. But when I switch configurations and try to build the regular (non-batch) way, it builds fine.

Amused, and since I can live without the batch-build functionality, I have just let it be all this time, writing it off as one more of those weird wonders of Microsoft.

Then today I figured out what the problem was. I am to blame, because I brought this upon myself. And I brought it upon myself while trying to circumvent some other, even more wonderful, weird wonder of Microsoft.

My MSBuild woes begun years ago, on my very first day of C# programming, when I saw those "bin" and "obj" directories in my project folder, and my first reaction was, of course, to want to make them go away.

There is an option in project properties to set the output folder, but not the intermediate folder. This takes care of the "bin" folder, but the stupid tool keeps creating an "obj" folder under the solution folder and puts all intermediate files in there, no matter what.

As you might understand, I decided that I just would not have any of that shit. I was determined to never write a single line of C# if I did not first find a way to make that annoying obj directory go away.

Needless to say, on my first day of C# programming I did not write any C# at all. I just banged my head against the keyboard triyng to find a way to get that folder to go away.

After a lot of googling around, I discovered allegations about the existence of some <IntermediateOutputPath> tag that goes inside a project file. So, I edited the .csproj file with my text editor and after each <OutputPath> tag I inserted an <IntermediateOutputPath> tag as follows:


(where x is my output path.)

Now, MSBuild would put the intermediate files in the folder that I specified, but it kept ALSO putting them in "obj" under my solution folder. That was just mind-blowing.

So, I took a drastic measure: I deleted the "obj" folder and I created an empty text file called "obj" in its place, which I marked as read-only and hidden, and I added it in the ignored files in SVN.

Strangely enough, this awful hack worked. Or at least it appeared to work. Just today I realized that it worked for the regular build, but it has been the reason why my batch-build does not work.

So, it appears that the only way to have batch-build functionality in Visual Studio is to resign to having a stupid "obj" folder under your project folder. Oh, well!


Movie: Sunshine (2007)

In the movie “Sunshine” by Danny Boyle [IMDB] there is a scene which is impossible to comprehend unless you have some knowledge of physics. The protagonist Robert Capa (Cillian Murphy) finds himself trapped in an airlock from which he must escape at any cost. The airlock contains a space suit, and has one outer hatch towards space, and one inner hatch towards the interior of the spaceship, which is locked.