If you are a
you have come to the right place.
For the impatient, the script is posted at the end of the article.
Before we delve into writing the script, let us summarize the environment.
svnlook is a tool to examine revisions in the repository. With the help of svnlook we can determine who made the last commit and what has changed.
Try these commands on the SVN server.
Determine the author of the commit.
svnlook author /var/svn/myproject/
On my computer the output is as below
[root@localhost ~]# svnlook author /var/svn/myproject/ james
Determine what has changed in the last commit.
svnlook changed /var/svn/myproject/
The output on my computer is
A apple/ A apple/juice.php A grape.php
The output of the `svnlook changed` command shows that three files have been added to the repository.
Determine the log message of the last commit.
svnlook log /var/svn/myproject/
Remember, when you commit to the repository you include a log message. The output looks like
[root@localhost ~]# svnlook log /var/svn/myproject/ my second commit
Fetch the diff of the last commit.
svnlook diff /var/svn/myproject/
The output on my computer:
[root@localhost ~]# svnlook diff /var/svn/myproject/ Added: apple/juice.php =================================================================== --- apple/juice.php (rev 0) +++ apple/juice.php 2009-09-03 17:40:55 UTC (rev 2) @@ -0,0 +1,2 @@ +test:wq +
Now, let's assemble the pieces to write the complete script.
Let's hook into post commit event of the SVN server. Copy the post-commit.tmpl file to /var/svn/myproject/hooks/post-commit
cp /var/svn/myproject/hooks/post-commit.tmpl /var/svn/myproject/hooks/post-commit
Make sure the shebang is there on the first line of the post-commit file.
#!/bin/sh
When a commit is made, this script, post-commit is called and two parameters are passed to it.
Let's call our PHP script from post-commit.
REPOS="$1" REV="$2" /usr/bin/php /var/svn/myproject/hooks/commit-email.php $REPOS $REV
Comment out everything else if the file. After editing, the post-commit file should like like this
#!/bin/sh REPOS="$1" REV="$2" /usr/bin/php /var/svn/myproject/hooks/commit-email.php $REPOS $REV
Let's place our PHP script at /var/svn/myproject/hooks/commit-email.php as specified in the post-commit file.
Let's begin writing our PHP script
#!/usr/bin/php <?php $repository = isset($argv[1]) ? $argv[1] : ''; $revision = isset($argv[2]) ? $argv[2] : '';
You can invoke the script from the command line like below
/usr/bin/php /var/svn/myproject/hooks/commit-email.php /var/svn/myproject/ 2
We pass two arguments to the script. The first argument is the 'repository' and the second is the revision number of the last commit. These arguments are available in the global array variable $argv.
$argv[1] contains the first argument passed to the script. The path to the repository is the first argument in our setup.
$argv[2] contains the second argument passed to the script. The revision number of the last commit is the second argument in our setup.
Next step is to grab the author of the commit, information about what has changed and the log message of the commit.
<?php
$author = exec('svnlook author ' . $repository);
$changed = exec('svnlook changed ' . $repository);
$log = exec('svnlook log ' . $repository);
?>Next, we grab the diff. Sometimes, the contents of diff may be very large. If the commit diff is huge, exec('svnlook diff ' . $repository) may freeze. To avoid this from happening, we use popen.
<?php
$diff = '';
$fp = popen('svnlook diff ' . $repository, "r");
while(!feof($fp)) {
$diff .= fread($fp, 1024);
flush();
}
pclose($fp);
?>Compose the body of the email.
<?php
$project_name = 'My project name';
$body = "Hello,
$author has just committed revision $revision in $project_name and said $log.
The following files have changed :
$changed
The changelog is given below
$diff";
?>Send the email using the aggregated information.
<?php
$to = 'you@example.com';
$subject = "$project_name subversion commit summary";
$headers = 'From: your-admin-email@example.com' . "\r\n" .
'Reply-To: your-admin-email@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $body, $headers);
?>A sample email I received from the SVN commit mailer PHP script is as below:
Hi, james has just committed revision 2 in My project name and said my 'second commit'. The following files have changed : A grape.php The changelog is given below Added: apple/juice.php =================================================================== --- apple/juice.php (rev 0) +++ apple/juice.php 2009-09-03 17:40:55 UTC (rev 2) @@ -0,0 +1,2 @@ +test:wq +
The entire script is pasted below.
<?php
#!/usr/bin/php
<?php
/**
* The repository and the revision number are passed as arguments
*/
$repository = isset($argv[1]) ? $argv[1] : '';
$revision = isset($argv[2]) ? $argv[2] : '';
/**
* Lookup author, commit message and what has changed using svnlook
*/
$author = exec('svnlook author ' . $repository);
$changed = exec('svnlook changed ' . $repository);
$log = exec('svnlook log ' . $repository);
/**
* Grab the diff of the commit
*/
$diff = '';
$fp = popen('svnlook diff ' . $repository, "r");
while(!feof($fp)) {
$diff .= fread($fp, 1024);
flush();
}
pclose($fp);
/**
* Your project name
*/
$project_name = 'My project name';
$body = "Hi,
$author has just committed revision $revision in $project_name and said $log.
The following files have changed :
$changed
The changelog is given below
$diff";
/**
* Your email address
*/
$to = 'you@example.com';
$subject = "$project_name subversion commit summary";
/**
* The email headers. Change it to your email address
*/
$headers = 'From: your-admin-email@example.com' . "\r\n" .
'Reply-To: your-admin-email@binaryvibes.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $body, $headers);
?>You can also download the script from the Code Album github repository.
Depending on your server infrastructure, you might want to send emails via SMTP. If the number of commits and recipients are large you might want to setup an email queue system. I will cover these topics in upcoming articles.
Isn't it cool to have a PHP SVN post-commit hook script?
Reference
Instant SVN server setup
nice and very good quick guidance
i looked with glance this web site is very good. eventhough i'm still new comer to web development on PHP.
i am engaged to learn to this open source system for a mission to look for more earn as a freelancer web developer.
i'll stay more to learn php thro this web site in line on my desired to have a web site in a quite good and valuable for as extra business.
thanks a lot.
Liston
Jakarta
Well Done!!
Hi Sudhir,
Good job with the post. I am not an expert in PHP programming but there seems to be an error in your script. the closing tag for the first php opening tag is not there.
Also, I think it will be useful to tell the users on where to put this file or how to reference it from post-commit.tmpl file
Keep it up.
Regards
Rohit
Re: Well Done!!
Hi Rohit,
Thanks for the comment.
The PHP script is correct and is tested. The closing tag is optional in PHP and recommended to not to have it.
I have used complete paths to demonstrate the usage.
If you have a specific problem with the script, let me know.
Sudheer
Binary Vibes
Problem with log message
Hello,
First thank you for your nice script. But I have problems with log message.
I think UTF8 decode is missed because I have strange chars for French accents : "message de test 11032010023503 accents : ?\195?\169 ?\195?\168 ?\195?\167 ?\195?\160"
In fact, in $log = exec('svnlook log ' . $repository); the problem appear.
Any idea ?
Regards,
W:
Re: Problem with log message
Fixed !
in post-commit :
REPOS="$1"
REV="$2"
export LANG="fr_FR.UTF-8"
/usr/bin/php /var/svn/myproject/hooks/commit-email.php $REPOS $REV
in php script :
$log = exec('svnlook log ' . $repository);
$log = iconv("UTF-8", "ISO-8859-1", $log); // because mail body do not support UTF-8
Regards,
W:
Thanks for the problem report
Thanks for the problem report and the fix!
Sudheer
Binary Vibes
How to move the files from repository to my web root folder?
Hi..,
First of all thank you for this wonderful script, it was really useful,
I have an issue,
On my server I have
/var/www/websitefolder [ websitefolder=> is the folder holding the files of my website ]
/var/svn/testrepository [testrepository =>Is the folder holding my SVN repositry of the website ]
Now my issue is, after comiting from the local machine from the post-commit script I want to update the changed file from the "testrepository" to "websitefolder"
This can be achived by simply putting this : /usr/bin/svn update /var/www/websitefolder/ --non-interactive, inside the post-commit script.
But this method creates a .svn folder inside "websitefolder" folder, which I dont want to be created at all.
By tweekng your code I can get the file name , but how do we move it to the /var/www/websitefolder ?
tweeked code :
$repository = isset($argv[1]) ? $argv[1] : '';
$revision = isset($argv[2]) ? $argv[2] : '';
$repositry = $repository;
/**
* * Lookup author, commit message and what has changed using svnlook
* */
$author = exec('svnlook author ' . $repository);
$changed = exec('svnlook changed ' . $repository);
$log = exec('svnlook log ' . $repository);
list($status,$fname) = explode(" ",$changed);
$fname => is the file name of the changed file
$repositry => holds the path to the files
Please suggest a way..,
Thanks
Ragesh
Build script
I'd recommend you to make a build and deploy script. At minimum the script should perform :
Remove .svn directories
Of course the script has to be tested on a staging server before you run it on the production server.
You might also want to look into Phing and Ant.
Sudheer
Binary Vibes
Commit hook running from shell but not from client side commit
Hi,
How are you thank you for the script that you have provided. I am using tortoise svn on client side and our server is Linux based when i run the post commit from shell it works but when i commit something on client side then the post-commit hooks does not get executed.
could you elaborate on this i am a total beginner as far as Linux is concerned.
Post the exact command you
Post the exact command you used to run the post-commit script
Sudheer
Binary Vibes
Post new comment