{lang: 'hu'}

I love redmine and I use it for more than a year in my personal projects. (at work we use JIRA right now) It’s the same with Git. In retrospect I connected these two great tools in a very amateur way. As you may know you have to sync the git database manually with the redmine database. So my first approach was to create a bash script which does this and run this script every 2 hours. Even if the database hasn’t changed at all. After I realized this is not the best method in point of resource usage I started looking for another way to achieve the same result. As a result of a little thinking I managed to figure out the current solution which I think is quite good. And now I’m gonna share this solution with you.

As a first step let’s talk about the basics:

  • Let’s assume that you have an installed and configured redmine and git server
  • My Git repos are stored under /opt/repositories, but a symlink is pointing to this directory which path is /repositories (eg. /repositories/test.git) and the owner is the administrator user, and the group is the developers group
  • My redmine was configured to store git database in /var/lib/redmine/repositories which has the same rights like above

Let’s start with creating an empty repository or just a simple folder to hold the hook script. I chose the first one, because in this way it was more simple for me. After that, open up nano (or your favourite editor) and paste in the following lines:


#!/bin/sh
PROJECT_PATH=`pwd`
PROJECT=${PROJECT_PATH:18}

echo "Current project: "$PROJECT
echo "Updating redmine sourcecode database..."

cd /var/lib/redmine/repositories

if [ -d /var/lib/redmine/repositories/$PROJECT ]; then
        rm -rf /var/lib/redmine/repositories/$PROJECT
fi

git clone --mirror /opt/repositories/$PROJECT $PROJECT
chown -R administrator:developers $PROJECT
chmod -R 777 $PROJECT

Of course you need to modify a few parameters in this script:

  • The PROJECT variable’s value comes from the current directory (in which the post-update hook is executed), which is in my case /opt/repositories/. If you store the repositories in a different place then you have to modify the 18 length. (/opt/repositories/ is 18 characters long)
  • You need to modify the paths
  • And finally modify the user and the group in the chown command if yours differs

Save the file as post-update.sh
And here is the tricky part, because you need to have the proper rights to modify the owner and the rights on a directory or file. I achieved this with using a little C script and run that instead of the bash script (though indirectly we will run the bash script). This is how my post-update.c file looks like:


#include 
#include 
#include 
#include 

int main()
{
   setuid( 0 );
   system( "/opt/repositories/test.git/hooks/post-update.sh" );

   return 0;
}

The interesting part is the first command in the function body. With the setuid command the post-update.sh script will be executed as root. In this case it’s not dangerous, because it’s mandatory for the developer to auth before push action and in addition this only executes our bash script, nothing more.

We are almost done, just two steps are needed to finish:

  • Make an executable file from the C file:
    cd /repositories/test.git/hooks && gcc post-update.c -o post-update
  • Create a symlink which points to this newly created executable and place it in your Git repo which you want to be synced with redmine:
    ln -s /opt/repositories/test.git/hooks/post-update /opt/repositories/{repository_name}/hooks/post-update

That’s all, I hope it was useful. If you have any questions or a good idea how to improve it, don’t hesitate! 🙂