tail -f findings.out

Updating Trac tickets in svn commits

The ability to update and close Trac tickets associated with a given repo whenever a commit is made to that repo is pretty handy. No more committing, going to the Trac site, updating. I found several guides on setting this up floating around, this one being the most informative. However, I’d like to clearly state the steps here, as I found most of the guides rather muddled, when the process is really quite simple.

In these examples, I will assume:

  • Your SVN repo (master): /var/svn/repositories/code
  • Your Trac instance: /var/trac/code

Add and edit a post-commit script

In /var/svn/repositories/code/hooks, there should be a post-commit.tmpl added by the initialization of the repo. Copy this and edit the copy:

1
2
sudo cp post-commit.tmpl post-commit
sudo vim post-commit

The file consists of lots of informative comments, and some uncommented stuff a the bottom. Delete all the uncommented stuff and add:

1
2
3
4
5
REPOS="$1"
REV="$2"
TRAC_ENV="/var/trac/code"
/usr/bin/python /var/svn/repositories/code/hooks/trac-post-commit-hook.py \
-p "$TRAC_ENV" -r "$REV"

Add a trac-post-commit-hook.py file

In /var/svn/repositories/code/hooks, export the trac-post-commit-script:

1
2
sudo svn export http://svn.edgewall.com/repos/trac/trunk/contrib/trac-post-commit-hook \
trac-post-commit-hook.py

You shouldn’t need to edit this.

Depending on your permissions setup for your SVN repo, you will need to change the ownership of the trac-post-commit script, as well as the post-commit script made above. In my case, I have svn:svn on all associated files, so at this point I ran:

1
sudo chown svn:svn /var/svn/repositories/code/hooks/*

Change perms on your Trac db dir

When you perform the commit, svn will execute what is in post-commit, which hits the trac-post-commit script, which then tries to update your Trac instance. For that to be possible, it needs access to your Trac db. How to do that totally depends on what access method you have for svn. In my case, I use svn+ssh, so it is my user (and others that commit, so configuring for an ’svn’ group is easier) that needs access. If you aren’t sure, or to test, this should work:

1
sudo chmod -R a+w /var/trac/code/db

Test

Now when you perform a commit to something in the code repo in our example and the change is associated with, say, ticket 456, your comment could be:

* Fixed problem X, logged state Y. closes ticket:456

And immediately thereafter, ticket 456 would have a comment such as:

1
(In [REVNUMBER])  * Fixed problem X, logged state Y. closes ticket:456

and be closed.


The Trac FAQ entry on hooks to commits has additional troubleshooting steps for configuration. As long as you don’t have a crazy svn and/or Trac setup, however, this should be relatively easy to get going.

Tags: , , , , , ,
January 25, 2009 - 1:41 PM Comments (4)

Recursively ignoring multiple file patterns in subversion

There are a few filetypes that you likely don’t want to add into any subversion repository, such as .pyc, .log, and .bak files. Not only do they not need to be in the repo, but you also probably don’t appreciate them sullying the output of things like

1
svn status

either. Deleting all such files before each commit isn’t a good option either. SVN allows you to ignore certain file patterns in the current directory (assuming it’s under version control) and in all children via a command such as:

svn propset -R svn:ignore "*.pyc" MYDIR

But if you then try to add another pattern, such as “*.log”, the initial value of the svn:ignore property is overwritten! To overcome this, create a file containing the patterns you want to ignore, one per line. I created a .svnignore file and added it into my personal SVN, symlinked from my home directory. That way I can use it on each box I work on, on various repos as needed, since the patterns are pretty universal.

Say you have made a file called .svnignore containing:

1
2
*.pyc
*.log

Then you would run:

svn propset -R svn:ignore -F .svnignore MYDIR

And the two patterns in the file would be ignored in MYDIR and all its children. If you want to add or remove a pattern later, just change the .svnignore file and re-run the same command.

You can also setup such ignores globally for a given SVN repo, but I tend to shy away from that sort of change, since I might just decide that I want some logfile checked in at one point or another. Setting the patterns per repo allows for a bit more flexibility.

One annoying note: When you add new directories to your repo, you have to run the command again. Otherwise the svn options for the new folder won’t contain your ignore patterns.

Tags: , , ,
January 5, 2009 - 11:14 PM Comments (3)

Tortoise and SSH key authentication

While setting up Tortoise recently, I couldn’t easily find how to tell it I wanted to use keys for SSH authentication. This post helpfully described how Tortoise actually uses PuTTY for its SSH connections, and how to get key-based auth working. In essence, you connect to your SVN server with PuTTY, then you use the saved session name when doing the checkout via Tortoise. This way you can define what key and user you want to use, and Tortoise won’t bother you for them again.

Tags: , , , , ,
November 3, 2008 - 1:38 AM No Comments

Handy Alias: Grab latest svn log

I keep having the occasion to view the log comments for the current revision in my SVN repository. This means:

  • Knowing the number of the current revision,
  • Passing this to
    1
    svn log -r

Instead of doing that by hand, I made an alias to do it for me:

alias svnlastlog="svn info | grep 'Last Changed Rev' | cut -d ' ' -f 4 | xargs -I mystr svn log -r mystr"

So if you are in a directory that is versioned, you just run that command, and (after being prompted to authenticate to your repo, if applicable), out comes the log entry for the current revision. Perhaps there is a built in command to do this already, but I could not find it via Google and the SVN Book.

Tags: , ,
October 7, 2007 - 3:33 PM Comments (2)

An awesome xargs option and cleaning up SVN accidents

I started using a wonderfully helpful option for xargs recently, after Master Ian showed me its use in a particularly thorny case. Before seeing the cool option, I will give the case as an example of its use:

I am still learning about the best (or even proper) way to use some aspects of SVN. In this particular case, I need to take all the files in a directory that was in the repo, move them into a new directory in the same directory, add another new directory, and copy new files into that.

To better explain the example, here is the structure I had in place, initially:

  • Directory 1 (In SVN)
    • FilesetA

And this is what I wanted in the end:

  • Directory 1
    • Directory1.1
      • FilesetA
    • Directory1.2
      • FilesetB

What I should have done is: made the 2 new directories (1.1 and 1.2) within the first one, copied the new files into one (FilesetB), add and commit both new directories and their contents. Then I should have run

1
svn mv

on the files in the top directory (FilesetA) into the second new directory.

What I actually did was: created the two new directories, simply

1
mv

‘ed FilesetA into one, copied in FilesetB into the other, and then

1
svn add

‘ed the two new directories and their contents. Then I had a problem. I still had FilesetA in Directory 1 in the repo, but not locally. So I needed to svn rm those, but I could not since they did not exist locally any more!

In the end, I copied the FilesetA out into a temp directory, when up to the directory above my repository, check the entire thing out again,

1
svn rm

‘ed the FilesetA in Directory 1, and then needed to add FilesetA back into Directory 1.1. This was why I moved it to a temp directory. The problem was that that set had several nested directories with

1
.svn

directories in them. I had to remove these before adding them into the SVN’ed directories, else mass confusion would result. So I ran:

find . -type d | xargs -I % rm -rf %/.svn

This gem found all directories from the current directory down, and passed them to rm -rf. However, I could not just pipe the results and use xargs, as I needed to append “/.svn” to specify the right directories to remove. This is where -I comes in handy. This option replaces all instances of the string following it with the results of the first command (before the pipe). In this case the string was “%”, for similarity to Python syntax, but any string could be used. The man page uses “replace-str”. So in this particular case, if FilesetA included Directory 1.1.1 and 1.1.2, the command would resolve to: “rm -rf Directory1.1.1/.svn Directory1.1.2/.svn”, which is precisely what was needed!

For some reason, I had a hard time understanding the option from the man page, but Ian translated it to Python for me:

for dir in [find . -type d]:  cmd = "rm -rf %s/.svn" % dir  os.popen(cmd)

This was much clearer to me. What it basically comes down to is:

OPERATION1 | xargs -I replaceme ANOTHEROPERATION replaceme OTHERTHINGS

translates into

ANOTHEROPERATION OPERATIO1RESULTS OTHERTHINGS

.

Tags: , ,
August 1, 2007 - 9:31 AM No Comments

Twitter links powered by Tweet This v1.6.1, a WordPress plugin for Twitter.