I have just installed Trac 1.0.1 on a server that also holds a Git repository. I’d like to be able to close Trac tickets by including things like “fixes #3” in the Git commit messages. This should pretty easy—by including a post-receive
hook in my repository, I can execute some piece of code (e.g. a Python script) after each git push
to the server. But what piece of code to use?

- 15,430
- 13
- 79
- 123
1 Answers
After running around for a while and following a couple of dead ends (including the Trac Git page, which is vague on this topic, and the Git plugin, which won’t actually work (?!) until bug #7301 is fixed), I found the solution.
Connect your Git repository to Trac through the steps at “setting up a Trac environment”.
Enable the Commit Ticket Updater plugin, either through the “Admin” section of Trac or by editing
trac.ini
.Create a file called
post-receive
in thehooks
directory of your Git repository, with the following content:#!/usr/bin/ruby ARGF.lines do |line| fields = line.split oldrev = fields[0] newrev = fields[1] refname = fields[2].chomp if oldrev =~ /^0+$/ revspec = newrev else revspec = oldrev + '..' + newrev end other_branches = `git for-each-ref --format='%(refname)' refs/heads/ | grep -F -v "#{refname}"` other_branches = other_branches.chomp.gsub /[\r\n]+/, ' ' commits = `git rev-parse --not #{other_branches} | git rev-list --stdin #{revspec}` commits.each_line do |commit| system "trac-admin .../trac changeset added '(default)' #{commit.chomp}" end end
Of course, replace “.../trac” with the absolute path to your Trac installation.
I’m actually using Trac through Virtualenv. If you are too, add this to the top of the file:
require 'tempfile' def virtualenv_system(cmd) script = Tempfile.new('post_receive') script.write 'source .../virtualenvs/trac/bin/activate' script.write "\n" script.write cmd script.close system "bash #{script.path}" script.unlink end
and replace the
system
call withvirtualenv_system
.Make this
post-receive
file executable.
This is inspired by the approach given on the Repository Administration page, combined with this SO answer about getting all of the new commits in a post-receive script. I believe that this script, while long, behaves correctly when you are pushing multiple commits and/or pushing commits to branches other than the currently-checked-out one. (The script given on the Repository Administration page does not behave correctly in these situations—it only looks at the most recent commit message from HEAD.)
After this setup process, any Git commits that contain strings like “fixes #7” will close the corresponding tickets in Trac. You can configure this a little with the options listed on the Commit Ticket Updater page. Specifically, you might want to change the value of commit_ticket_update_envelope
; it’s not completely clear, but I think the default is set so that you have to include your commands in square brackets, like “Refactored MyAwesomeClass [fixes #42]”.
-
This sounds like the sort of thing you might consider using `git notes` for. http://git-scm.com/2010/08/25/notes.html – Klas Mellbourn Apr 07 '13 at 16:48
-
@KlasMellbourn That looks promising, although it would require even deeper integration into Trac ;-) – bdesham Apr 07 '13 at 17:03
-
The final assertion is wrong. Actually the default behavior is, that just 'fixes #42' triggers, but all other details seem good. Especially dealing with virtual environment is, what makes this answer valuable, very good. – hasienda Apr 09 '13 at 18:53