Opened 13 years ago
Last modified 17 months ago
#10730 new enhancement
Provide Git hooks to call trac-admin
Reported by: | Peter Suter | Owned by: | |
---|---|---|---|
Priority: | normal | Milestone: | next-stable-1.6.x |
Component: | plugin/git | Version: | |
Severity: | normal | Keywords: | hook |
Cc: | hvr@… | Branch: | |
Release Notes: | |||
API Changes: | |||
Internal Changes: |
Description
As mentioned on TracGit#hooks and as discussed in #10594, we should provide a post-receive hook script for Git to call trac-admin.
References
- th:GitPlugin#post-receivehookscripts lists several such shell scripts.
- We provide such hooks for Subversion as shell scripts in
contrib
(trac-svn-hook / trac-svn-post-commit-hook.cmd). - We provide such hooks for Mercurial as Python scripts in the plugin's directory (#10225 / hooks.py).
Attachments (1)
Change History (19)
comment:1 by , 13 years ago
comment:2 by , 13 years ago
Milestone: | → next-stable-1.0.x |
---|---|
Owner: | set to |
I'll have a try, possibly even for 1.0 (but not for the beta).
comment:3 by , 13 years ago
Cc: | added |
---|
comment:4 by , 12 years ago
Here's a nice hook (see discussion of Nilesh and Giotti) for gitolite http://nileshgr.com/2012/08/08/trac-and-git-the-right-way.html The hook is at http://pastie.org/4782090
follow-up: 6 comment:5 by , 12 years ago
This hook is useful when running multiple repositories for one, or several Trac environments in conjunction with gitolite (https://github.com/sitaramc/gitolite#readme).
The hook assumes that the "filename" of the git-repository has the same name as the Trac environment, followed by a separator (defined in the script), and the name of the repository. However, the name of the repository inside Trac, should omit the environment name (i.e. let it appear how you want inside Trac). If the repository name consists of only one word (e.g. there is only one repository for the environment), the hook will fall back to the default name provided in the script (Trac uses (Default), unless something was changed).
When using this post-receive hook, the git repositories' directory name should be named according to the pattern:
<environment name><separator><trac-repository-name>,
whereas the repository name inside, or as called in Trac should skip the <environment name> resulting in just:
<trac-repository-name>
Example: If you have the environments Android and iOS, each with two git repositories Repo-One and Repo-Two; the git repositories should be named: Android-Repo-One, Android-Repo-Two, iOS-Repo-One, and iOS-Repo-Two in gitolite.conf, but just Repo-One and Repo-Two inside Trac.
As you can see in the above example, you can re-use the separator in the name of the git-repository, if you please. However, the hook will fail on environments with the name containing the separator, i.e. a push to the repository Environment-One-Repo-One results in the hook trying to run trac-admin for the environment Environment, instead of Environment-One.
I'm not sure, whether "off-loading" the last bit of the Trac-environment-path to the repository name poses a security risk, e.g. if someone would push a repository with i.e. a semicolon in the name, but I believe gitolite should catch any attempts to push to a non-existing repository and exit prior to running the hook.
giotti
Here's the hook:
Code highlighting:
#!/bin/bash # Gitolite-Trac post-receive hook # Script written by Nilesh Govindrajan; http://nileshgr.com # Updated by giotti to support multiple repositories. # Assumptions: # 1: all trac environments are saved under one common directory # defined in tracenv. e.g. /path/to/all/my/trac/envs # 2: all repositories of an environment follow the naming-pattern # <environment><delimeter><repository name>[<delimeter><repository name continued>...], # e.g. someproject-somerepository, or someproject-somerepository-with-extra-text # 3: The Name of the repo itself (defined in trac) is the same as the git-repository # without the environment name; e.g. somerepository, or # somerepository-with-extra-text, instead of someproject-somerepository # 4: Capitalization is the same throughout gitolite and trac (see todo in # changelog. # # Changelog: # 1.02 # - Added skipping the hook, when gitolite-admin is detected # - Added multi-repository support for all environments in one directory-tree # - TODO: implement capitalization mapping of trac <-> git, # e.g. when repo is "Foo-Bar" and trac env is "foo" with repo "Bar" # This script is released under the GNU GPL v3 # Licensed changed to BSD as suggested by Giotti set -u tracenv=/var/www/trac/projects # Full path to trac environment except for the last bit tracadmin=/usr/local/bin/trac-admin # Path to trac-admin tracdefault='"(default)"' # Trac default repository name (usually: "(default)") logfile=/var/www/trac/log/post-receive.log # you can always log to /dev/null delimeter="-" # you can select a different separation-delimeter here (e.g. "_") date > ${logfile} # init logfile (if you want a continuous log, change ">" to ">>" # Check that the repo in question is something other than gitolite-admin, otherwise exit. if [ "${GL_REPO}" != "gitolite-admin" ] then reponame="${GL_REPO}" else echo "gitolite-admin modification detected. Exiting post-receive hook..." >> ${logfile} exit 0 fi # save current IFS OIFS=$IFS # split $GL_REPO by delimeter IFS="$delimeter" && parts=($GL_REPO) #create new repo-string containing all array parts except the first (e.g. ${parts[0]}) reponame="${parts[*]:1}" if [ -z "$reponame" ]; then reponame=$tracdefault; fi # (or set to trac-default) # append first part of GL_REPO parts to tracenv tracenv="$tracenv/${parts[0]}" # restore original IFS IFS=$OIFS # log our selection echo "GL_REPO was set to: ${GL_REPO}. Using repo-name: $reponame on trac-environment: $tracenv" >> ${logfile} while read -s line do [ -z "$line" ] && break commithash=$(echo $line | cut -d' ' -f2) # prepare changeset command cmd1="$tracadmin $tracenv changeset added $reponame $commithash" # prepare resync command to be called, when deleting commits & using "git push -f" cmd2="$tracadmin $tracenv repository resync $reponame" # run either changeset or repository resync eval "$cmd1" || eval "$cmd2" # log commands echo "CMD1: $cmd1" >> ${logfile} echo "CMD2: $cmd2" >> ${logfile} done
Source: https://gist.github.com/3768589
comment:6 by , 12 years ago
Replying to giotti:
I'm not sure, whether "off-loading" the last bit of the Trac-environment-path to the repository name poses a security risk, e.g. if someone would push a repository with i.e. a semicolon in the name, but I believe gitolite should catch any attempts to push to a non-existing repository and exit prior to running the hook.
Sorry for the FUD. A hook is only symlinked to the hooks-directory of existing repositories. In addition, GL_REPO would be unset, since it would be impossible to connect to a non-existing repository. According to sitaram from #gitolite@freenode:
[…]forget gitolite, why would *git* execute a hook on a non-existing repo? In fact, how can a hook even *exist* when the repo doesn't?[…]
and
if a hook is running in a repo called foo/bar, gitolite will set GL_REPO to foo/bar, and will not allow it to be somehow set to some other value.
comment:7 by , 11 years ago
It is a little bit confusing, that there is no trac-post-receive-hook script in the Trac distribution. When one is looking at the GitPlugin page, there are several scripts attached and it is not easy to see, which one is the "best". Trac should come with a "blessed" script, please.
follow-up: 11 comment:8 by , 11 years ago
I've created post-receive:ticket:10602 which git repository and trac environment can be specified via environment variables and git config
. I'll create the same script for Windows and add comments to scripts later.
comment:9 by , 11 years ago
TracRepositoryAdmin#Git currently also contains some recommendations for a post-receive
script. And there's another script at attachment:post-receive-hook.py:wiki:TracGit. If these are problematic they should maybe be removed to avoid confusion.
comment:10 by , 11 years ago
Yeah. I think we should additionally provide those git hook scripts in contrib directory like trunk/contrib/trac-svn-hook.
Also, if many commits are pushed, the hook script in TracRepositoryAdmin#Git is very slow since trac-admin
is executed each commit. We should improve it.
by , 10 years ago
Attachment: | trac-git-hook-post-receive.sh added |
---|
comment:11 by , 10 years ago
I've created post-receive:ticket:10602 which git repository and trac environment can be specified via environment variables and
git config
. I'll create the same script for Windows and add comments to scripts later.
trac-git-hook-post-receive.sh. I created post-receive hook as a shell script.
comment:12 by , 10 years ago
Owner: | removed |
---|
comment:13 by , 8 years ago
Milestone: | next-stable-1.0.x → next-stable-1.2.x |
---|
Moved ticket assigned to next-stable-1.0.x since maintenance of 1.0.x is coming to a close. Please move the ticket back if it's critical to fix on 1.0.x.
comment:14 by , 8 years ago
comment:15 by , 8 years ago
Keywords: | hook added |
---|
comment:16 by , 8 years ago
#12763 closed as a duplicate and provides an example hook. The hook in comment:11 looks good to me. It would be good to have some logging. trunk/contrib/trac-svn-hook logs to svn-hooks-<reponame>.log
, which is helpful in debugging issues.
comment:17 by , 5 years ago
Milestone: | next-stable-1.2.x → next-stable-1.4.x |
---|
Quoting cboos from #10594: