Symfony World blog is not maintained anymore. Check new sys.exit() programming blog.
Showing posts with label svn. Show all posts
Showing posts with label svn. Show all posts

svn log user

SVN log tool does not provide any option to filter output by the user. Using the --username option won't do the job, unfortunately.

But you may filter SVN changes commited by a chosen user using the following:

svn log | sed -n '/| username |/,/-----$/ p'
Basing on that, you may create a bash script, called svn-log-user for example, with the following content:
#!/bin/bash
svn log | sed -n "/| $1 |/,/-----$/ p"
Then, put it inside the /usr/local/bin directory or anywhere that is accessible from the path, run:
echo $PATH
to check which directories are in the path. Then, call it with:
./svn-log-user username

svn dump subrepo

Subversion tools enable you to dump only chosen parts of the original repository. This may be especially useful, when you want to separate a smaller project out from a bigger thing. svnadmin dump will be used along with svndumpfilter command. svndumpfilter must be run using one of the following subcommands: include or exclude. Depending on what is easier, you may specify which path prefixes (or directories) will be included into new subrepo dump - or which will be excluded.

For example, let's assume our original repository structure looks like the following:

/abc
  some content
/def
  some content
/ghi
  some content
/jkl
  some content
If we run:
$ svndumpfilter include /abc /def # pseudo command
our subrepo will consist of:
/abc
  some content
/def
  some content
but if we run:
$ svndumpfilter exclude /abc # pseudo command
our subrepo will consist of:
/def
  some content
/ghi
  some content
/jkl
  some content
I wrote pseudo command, since you have to stream the original repository first, so that svndumpfilter can filter its content. Real commands would look like:
$ svnadmin dump /home/tomasz/svn/original_repo | svndumpfilter include /abc /def --drop-empty-revs --renumber-revs > subrepo.svndump

$ svnadmin dump /home/tomasz/svn/original_repo | svndumpfilter exclude /abc --drop-empty-revs --renumber-revs > subrepo.svndump

Now let's take a look at some svndumpfilter options:

--drop-empty-revs

If filtering causes any revision to be empty (i.e., causes no change to the repository), removes these revisions from the final dump file.

--renumber-revs

Renumbers revisions that remain after filtering.

Thanks to above options, the result repository dump will look as if it always consisted of the chosen parts (no empty commits).

Command line SVN editor

For those of you who still use Subversion as the software versioning system, setting SVN_EDITOR option will be important sooner or later.

SVN properties such as svn:externals or svn:ignore need to be set manually by the developer. To do this, run svn propedit or svn propset command (IDEs such as NetBeans have built-in SVN support which does the same stuff). If you're working in the command line, run one of the following commands:

export SVN_EDITOR=vim
or
export SVN_EDITOR=nano
or
export SVN_EDITOR=mcedit (or whatever)

This sets the SVN editor for the current user session. If you want to store this option permanently (to be set whenever you log in to your machine), create/edit the ~/.bash_profile file and put the same content there.

svn blame: who made the bug?

Scene from "12 Angry Men" by Sidney Lumet (1957)

In bigger projects it happens quite often that an unknown team member has made a modification that caused a lot of trouble. And no one wants to confess... It is quite uncomfortable to analyse distinct revisions and changes of a file to find who caused the problem, as it is time consuming. This is where svn blame is the perfect tool - you execute it upon a chosen target to display revision number, team member and content line by line. You can easily find who is the author of a bug and when he committed it. It's intereting, that despite being very useful, this tool is not very known.

blame me if you can find me quickly!

The usage is very simple:

tducin@workshop:/var/www/admin/config/doctrine$ svn blame schema.yml
and you have the entire file analysed:
   367     dennis connection: master
   362     tducin
   362     tducin options:
   362     tducin   charset: utf8
   362     tducin   collate: utf8_general_ci
   362     tducin
  3755     george Status:
  3755     george   comment: "Statusy"
   491     dennis   actAs:
  1980     dennis     SoftDelete: ~
  1793     harold     Timestampable: ~
  1793     harold     Signable: ~
   492     tducin   columns:
   492     tducin     name:
  3755     george       type: string(64)
   492     tducin       notnull: true
  2628     tducin       comment: "nazwa"
  3755     george     notify_mail:
  3755     george       type: boolean
  3755     george       notnull: true
  3755     george       default: false
  3755     george       comment: "klient ma być powiadamiany mailowo"
  1541     dennis     stock_mode:
  1541     dennis       type: enum
  1541     dennis       values: [ reserved, sent, cancelled ]
  1541     dennis       default: reserved
  2628     dennis       comment: "tryb magazynowy: reserved, sent, cancelled"
  3755     george     force_reminder:
   892     tducin       type: boolean
   878     tducin       notnull: true
  3755     george       comment: "Wymuszenie dodania wpisu w kalendarzu"
  3755     george     block_update:
  3755     george       type: boolean
  3755     george       notnull: true
  3755     george       comment: "Blokada zmiany statusu"
  4078     harold   indexes:
  4078     harold     softdelete_idx:
  4078     harold       fields: [ deleted_at ]

SVN repository auto update

Scene from "Brazil" by Terry Gilliam (1985)

I found an article (in Polish) describing a subversion hook that will automatically update a server working copy. This seems perfect - after commiting a new revision, all changes are available online (entire development team can test the most up to date version, your boss may see the newest results, etc).

Anyway, I don't see any reason to use C here, so I've made my own version updating the repository using shell command:

svn up /home/website/domains/dev.website.com/website
  --no-auth-cache --username user --password pass
The --no-auth-cache option is important here - authorization data is not going to be remembered here. Other two options define the authorization data.

troubleshooting

You may have problems with file permissions, if the user which holds the repository is different than the user which hold the working copy (this was in my case). The problem I got was permission denied for .../.svn/lock file, which is a temporary file, existing only when the revision is being checked/committed. Oops... There is no one good solution for this - it depends on the server configuration. It can be adding one user to the group of another, changing the owner of the entire working copy files (no matter in which /home subdirectory it is, as long as web server can handle requests, etc).

force to log message SVN python

Scene from "It Happened One Night" by Frank Capra (1934)

Another blog post about Subversion. Few days ago someone asked me if I know how to block commiting a subversion revision that has no log message defined. I didn't, but I thought it's a good idea, because it could help to track bugs, changes, etc. There's no such configuration, but it can be achieved using SVN hooks.

tried to do this in PHP...

There are many resources in the web giving examples to do this using a windows batch file - but I'm a linux user. At first, I wanted to do this in PHP. Although my final solution is not PHP, maybe someone will find following code snippets useful.

So I started searching through many pages on the web to find PHP shell scripts that could block committing a revision with no log message. The first step is, of course, to create an executable pre-commit file in the hooks directory of the repository. Then make the shell use the PHP parser to execute our script. Next, define path to svnlook binary and execute it:

#!/usr/local/bin/php -q
<?php
 
$SVNLOOK = '/usr/bin/svnlook';
exec("$SVNLOOK log -t {$argv[2]} {$argv[1]}", $output, $result);
We have the output and the result of the command available. So we may just check if the message (which revision a user is just trying to commit) is empty (I guess there is no other way than to use svnlook). If the log message is empty, the revision shall be stopped - and this happens, when exit status code is different than 0 (of course, a message explaining the cause is appreciated):
if (empty($result))
{
  fwrite(STDERR, "Commit blocked, need to pass the log message.");
  exit(1);
}
else
  exit(0);
This all should work, but 99,9% of all servers will have the exec function disabled by default (in both CLI and web server PHP configuration; along with other system functions):
disable_functions = exec,system,passthru,shell_exec,escapeshellarg,escapeshellcmd,proc_close,proc_open,dl,popen,show_source
Even if you manage to remove those functions from the configuration, you lower the server security, which may risk dangerous script injection. So I forgot about using PHP...

...and finally moved to python

Finally, I managed to succeed using python:

#!/usr/bin/python
 
import sys, os, string
 
SVNLOOK='/usr/bin/svnlook'
 
def main(repos, txn):
  log_cmd = '%s log -t "%s" "%s"' % (SVNLOOK, txn, repos)
  log_msg = os.popen(log_cmd, 'r').readline().rstrip('n')
  if len(log_msg) < 10:
    sys.stderr.write ("\n> Revision comment must be defined\n")
    sys.exit(1)
  else:
    sys.exit(0)
 
if __name__ == '__main__':
  if len(sys.argv) < 3:
    sys.stderr.write("\n> Usage: %s REPOS TXN\n" % (sys.argv[0]))
  else:
    main(sys.argv[1], sys.argv[2])

svnsync tutorial

Scene from magnificent "One Flew Over the Cuckoo's Nest" By Miloš Forman

I was forced to use this tool when I wanted to move my old project repository into a new server (until then, its SVN repository was hosted on a free SVN hosting). The hosting provider forced me to pay for the svnadmin dump, so I searched for an alternative solution and svnsync did the job.

In comparison to svnadmin dump/load, svnsync is migrating subversion repository with no svnadmin access. The migration can be done when you have a working copy (checkout) of the source repository and a clean (svnadmin create) version of the target repository. The repository synchronization is just reading all revisions one by one and copying them into the target repository, unchanged.

First, take a look at this article. Here you can find that a hook needs to be created in the target repository: hooks/pre-revprop-change (removing .tmpl and granting executable permissions for the script). What is not mentioned in the article above is that you should probably put

#!/bin/sh 
exit 0;
as the hooks/pre-revprop-change script content, to avoid the error, as written in another article.

Now, initialize the synchronization (example call below):

svnsync init [target repository] [source repository]
svnsync init file:///home/user/svn/test-repo svn://free-hosting/that-forced-me-to-pay/for-the-svn-dump

and copy all revisions, while being in the working copy of the source repository (example call below again):

svnsync --non-interactive sync [target repository]
svnsync --non-interactive sync file:///home/user/svn/test-repo

Be patient and wait until it's finished. Afterwards, remove the useless hooks/pre-revprop-change script - and you're done!