Skip to content

Instantly share code, notes, and snippets.

@jbarrett
Created November 14, 2012 11:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbarrett/4071548 to your computer and use it in GitHub Desktop.
Save jbarrett/4071548 to your computer and use it in GitHub Desktop.
First pass at Git (+ Gitweb) integration with FogBugz. Notes in comments.
#!/bin/bash
# Git hook to link a commit's BugzID in Fogbugz.
#
# Instead of a filename, script populates URL with repository name.
# This saves us needing to configure a repository per-project in Fogbugz.
# Description, first word in file should be repository-name.git
DESC=description
# Sed Regex - Pull repository name from cwd in case description fails.
PATH_RE="^\/repos\/\(.*git\).*"
# Bash Regex - Pull BugzID from commit msg. Should yield '123' for:
# 'BugzID : 123', 'BuGsId: 123', 'bugid:123', 'bugzid :123zzz'
BUGZ_RE=".*bugz?s?id\ *:\ *([0-9]+).*"
# ...Once we enable case insensitive regex matching
shopt -s nocasematch
# Fogbugz URL
FB_HOST="your.fogbugz.host"
URL="http://$FB_HOST/fogbugz/cvsSubmit.asp?ixBug=<BUGZID>&sFile=<REPO>&sPrev=<PREV>&sNew=<NEW>&ixRepository=14"
BUGURL="https://$FB_HOST/fogbugz/default.asp?"
# We need curl or wget
get_downloader() {
CMD=`which curl`
if [ $? -eq 0 ] ; then
return
fi
CMD=`which wget`
if [ $? -eq 0 ] ; then
CMD=$CMD" -O -"
return
fi
CMD=""
}
# Attempt to get project name, first from description, then path
get_project_name() {
if [ -e $DESC ] ; then
read REPO < $DESC
REPO=`echo -n $REPO | sed 's/ .*//'`
if [[ $REPO =~ git$ ]] ; then
return
fi
fi
cwd=`pwd`
REPO=`echo $cwd | sed "s/${PATH_RE}/\1/"`
if [[ $REPO =~ git$ ]] ; then
return
fi
REPO=""
}
# Retrieve Bug numbers from BugID/BugzID in commit message
# Multiple BugIDs should be entered one-per-line.
get_bugzid() {
local rev=$1
BUGZID=()
while read msg ; do
[[ $msg =~ $BUGZ_RE ]] && BUGZID[${#BUGZID[@]}]=${BASH_REMATCH[1]}
done < <(git cat-file commit $1)
}
get_downloader
if [ "$CMD" = "" ] ; then
echo "No downloader available to send GET request"
echo "Not sending commits to Fogbugz"
exit 0
fi
get_project_name
if [ "$REPO" = "" ] ; then
echo "Unable to retrieve repository name"
echo "Not sending commits to Fogbugz"
exit 0
fi
# Main loop - get and submit commits to specified BugzID
while read PREV CURR REF ; do
LAST=${PREV:0:7}
# PREV is the remote HEAD for the branch. We need to walk the commits
# between PREV and CURR and get / submit the BugzID foreach.
for COMMIT in `git rev-list $PREV..$CURR | tac` ; do
COMMIT=${COMMIT:0:7}
get_bugzid $COMMIT
if [ "${BUGZID[0]}" = "" ] ; then
echo "No BugzID for commit $COMMIT"
LAST=$COMMIT
continue
fi
for BUG in ${BUGZID[@]} ; do
GET_URL=`echo -n $URL | sed -e "s/<BUGZID>/${BUG}/" -e "s/<REPO>/${REPO}/" -e "s/<PREV>/${LAST}/" -e "s/<NEW>/${COMMIT}/"`
[[ $BUG =~ ^[0-9]+$ ]] && $CMD $GET_URL > /dev/null 2>&1
if [ $? -eq 0 ] ; then
echo "Added revision $COMMIT to $BUGURL$BUG"
else
echo "Warning: Unable to GET $GET_URL using $CMD"
fi
done
LAST=$COMMIT
done
done
@jbarrett
Copy link
Author

This post-receive hook should add links to commits in gitweb, on a per-project rather than per-file basis. The hook should be installed in the hooks directory for each project on your git server.

We hijack the Source Control Integration model a little here - FogBugz expects a filename to be passed as part of the integration and there is no way to include project names other than creating a new FogBugz repository configuration for each project.

To allow having a single config for all projects we pass the project name as the filename - a few assumptions are made to get the project name:

  • Project name ends in .git
  • Description contains 'project-name.git' as its first word OR the directory housing the project inside the configured repositories directory is named 'project-name.git'

To configure the script you'll need to set PATH_RE to reflect the location of the repository on the server. You'll also need to set FB_HOST to be your FogBugz server's hostname. ixRepository in URL will need to reflect the url you receive from FogBugz when configuring a new repository:

In FogBugz, create a new custom repository called 'Git' or somesuch, your diff url should take the form:

https://your.git.host/gitweb/?p=^FILE;a=commitdiff;h=^R2;hp=^R1

For each successful integration request a link to the bug is provided, else error msg.

@jbarrett
Copy link
Author

Second revision allows for multiple bugs per commit, one per line.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment