31

I want to have my PHP application labeled with the revision number which it uses, but I don't want to use CruiseControl or update a file and upload it every time. How should I do it?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Thomaschaaf
  • 17,847
  • 32
  • 94
  • 128

13 Answers13

53

SVN keywords is not a good solution. As others pointed out adding $Revision$ in a file only affects the specific file, which may not change for a long time.

Remembering to "edit" a file (by adding or removing a blank line) before every commit is pointless. You could as well just type the revision by hand.

One good way to do it (that I know of) is to have an automated deployment process (which is always a good thing) and using the command svnversion. Here is what I do:

Wherever I need the revision I do an include: <?php include 'version.php'; ?>. This "version.php" file only has the revision number. Moreover it is not part of the repository (it set to be ignored). Here is how I create it:

1) On projects where SVN is installed on the server, I also use it for deployment. Getting the latest version to the server I have a script that among other things does the following (it runs on the server):

cd /var/www/project
svn update
rm version.php
svnversion > version.php

2) On projects where SVN is not installed my deployment script is more complex: it creates the version.php file locally, zips the code, uploads and extracts it

daremon
  • 4,894
  • 2
  • 27
  • 27
  • The good thing of your answer is that is language agnostic: `svnversion` saves the revision number on a text file and it is the application that needs that value which accesses later that file. – AxeEffect Oct 15 '13 at 14:48
16

Assuming your webroot is a checked-out copy of the subversion tree, you could parse the /.svn/entries file and hook out the revision number (4th line here)...

In PHP:

$svn = File('.svn/entries');
$svnrev = $svn[3];
unset($svn);
Oli
  • 235,628
  • 64
  • 220
  • 299
  • 8
    Makes your application dependent on Svn internals. Sorry, a no-no – Brent.Longborough Sep 21 '08 at 17:37
  • 11
    @Brent.Longborough I would downvote your comment if I could, but I can't, so I'll leave this comment instead. – Annika Backstrom Mar 03 '10 at 18:49
  • Actually this looks more portable than using a possibly "not there" svnversion binary, especialy considering windows-systems, developer checkouts etc. – Christoph Strasen Nov 11 '10 at 10:59
  • I would up vote this, many people skip build process and do svn co at the production. In that case like it or not, i am coupled to svn internals and if I am coupled then why not use it. svnversion is a clean process if the build step is there. – shikhar Dec 30 '10 at 07:45
  • I would point out that this method is faster than calling a system command. It is easy to implement, and would pose no serious performance issues. – Jonathon Hill Jan 28 '11 at 19:55
  • 1
    Just to point out something: This number only get updated when folder gets updated. – mauris May 03 '11 at 11:10
  • 5
    Subversion 1.7 no longer uses the .svn/entries file for this purpose; you'll have to dig through the .svn/wc.db sqlite database if your target system has no svn binaries available. – rymo Sep 27 '12 at 16:31
9

This is how I got it to work. If your server is setup to allow shell_exec AND you have SVN installed just run:

$revision = `svnversion`;

or

$revision = shell_exec('svnversion');
Nathan J.B.
  • 10,215
  • 3
  • 33
  • 41
  • Oops! Must've been another late night. Thanks! Corrected :) – Nathan J.B. Feb 03 '12 at 15:59
  • 3
    How is this not the accepted answer. Works perfectly and way better than any other scheme it seems. You could even cron stuff to a text file. Thanks! Easy and perfect and exactly what the OP asked for – ladieu Sep 05 '12 at 18:16
4

From this answer:

You can do it by adding the following anywhere in your code

$Id:$ 

So for example Jeff did:

<div id="svnrevision">svn revision: $Id:$</div>

and when checked in the server replaced $Id:$ with the current revision number. I also found this reference.

There is also $Date:$, $Rev:$, $Revision:$

Community
  • 1
  • 1
Espo
  • 41,399
  • 21
  • 132
  • 159
  • 3
    Be carefull with this. As daremon mentioned, the SVN keyword won't update unless that file has changed. I have a codebase where this information is in an "About Window" that is very rarely changed. I frequently forget to "edit" that file so that the Rev ID is updated. – Matt Miller Jan 31 '09 at 20:57
3

Bit late now, but use a Subversion post-commit hook. In your repository's hooks folder, create a shell script like this one:

#!/bin/bash

REPOS="$1"
REV="$2"

cd /web/root
rm -f /web/root/templates/base.html
/usr/bin/svn update
/bin/sed -i s/REVISION/$REV/ /web/root/templates/base.html

This particular example assumes your live site is in /web/root and the development code is held elsewhere. When you commit a dev change, the script deletes the prior live template (to avoid conflict messages), runs the update and replaces occurrences of REVISION in the template with the actual revision number.

More on hooks here

Mark
  • 1,009
  • 1
  • 9
  • 8
2

In most cases the code on the server would actually contain an "Export" of the code, not a checkout, and therefore not contain the .svn folders. At least that's the setup I see most often. Do others actually check out their code onto the web server?

Kibbee
  • 65,369
  • 27
  • 142
  • 182
  • 1
    No, you're probably right there. That's probably best behaviour for a production server too... You might not want people snooping at the .svn dirs. – Oli Sep 21 '08 at 17:27
  • 5
    I hope you surely disallow access to .svn dirs in your server configuration or at least .htaccess. Otherwise, your whole code can be seen. – Artem Russakovskii May 13 '09 at 18:22
2

The easiest way is to use the Subversion "Keyword Substitution". There is a guide here in the SVN book (Version Control with Subversion).

You'll basically just have to add the text $Rev$ somewhere in your file. Then enable the keyword in your repository. On checkout SVN will substitute the revision number into the file.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Brian Gianforcaro
  • 26,564
  • 11
  • 58
  • 77
2

You can get close with SVN Keywords. Add $Revision$ where you want the revision to show, but that will only show the last revision that particular file was changed, so you would have to make a change to the file each time. Getting the global revision number isn't possible without some sort of external script, or a post-commit hook.

noah
  • 21,289
  • 17
  • 64
  • 88
2

You could also do it like this:

$status = @shell_exec('svnversion '.realpath(__FILE__));
if ( preg_match('/\d+/', $status, $match) ) {
    echo 'Revision: '.$match[0];
}
Christoffer
  • 25,035
  • 18
  • 53
  • 77
2

See my response to the similar question "Mark" svn export with revision.

If you capture the revision number when you export you can use:

svn export /path/to/repository | grep ^Exported > revision.txt

To strip everything but the revision number, you can pipe it through this sed command:

svn export /path/to/repository | grep ^Exported | sed 's/^[^0-9]\+\([0-9]\+\).*/\1/' > revision.txt
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
fijiaaron
  • 5,015
  • 3
  • 35
  • 28
1
$svn_rev=file_get_contents('/path.to.repository/db/current');
Inpassor
  • 21
  • 1
0

Another possibility to do this is to run a cron that executes the steps described in the "Deploy Process" (assuming it is a *nix/FreeBSD server).

Andrei Iarus
  • 2,329
  • 1
  • 14
  • 4
0

If performance is an issue, then you could do:

exec('svn info /path/to/repository', $output);
$svn_ver = (int) trim(substr($output[4], strpos($output[4], ':')));

This of course depends on your having done a checkout, and the presence of the svn command.

Jonathon Hill
  • 3,445
  • 1
  • 33
  • 31