Preventing a file from being committed to SVN 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:

stackoverflow: Subversion: prevent local modifications to one file from being committed?

stackoverflow: SVN Pre-commit hook for temporarly commented out code (in java)?

stackoverflow: SVN: Is there a way to mark a file as “do not commit”?

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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
:: Stops commits that contain the NOCOMMIT keyword.
setlocal
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.)

1
2
3
4
#!/bin/sh
REPOS="$1"
TXN="$2"
/usr/local/bin/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; }

Old comments

  • Georgi 2014-05-13 17:00:18 UTC

    Hi Michael,

    Thank you for the great article That’s what I needed. Just a few notes on the linux script:

    1. svnlook command should be “diff”, not “log”.
    2. There should be opening bracket before “echo”.
    3. I only got it to work when I added “exit 0;” at the end of the file.

    So my working script looks like:

1
2
3
4
5
6
    #!/bin/sh
    REPOS="$1"
    TXN="$2"
    SVNLOOK=/usr/bin/svnlook
    $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; }
    exit 0;
  • michael.gr 2014-05-13 17:22:40 UTC

    Thank you for contributing, Georgi!

  • Ben 2015-04-17 19:17:29 UTC

    Good call Michael: http://stackoverflow.com/questions/29707649/svn-pre-commit-hook-how-to-block-a-keyword-in-certain-file-types

  • Ben 2015-04-17 16:47:08 UTC

    This is soooo close to what I need, but not quite there. For some reason, I’ve been unable to do what I need, which is check for existence of a keyword in only certain filetypes. For instance, I do not want to allow .java files to have “http://” or “https://” in them. I’ve tried using –include=*.java but it seems to get ignored in my pre-commit file (works fine on the command line). Thoughts? Thanks in advance!

    • michael.gr 2015-04-17 18:38:00 UTC

      I do not know, Ben. But it sounds like a good question for stackoverflow.com