For that one you can use post-commit hook, which checks the change list of transaction and if required merge the changes made in one location to another:
#!/usr/bin/env python
##
# @file sync.py
# @author Krzysztof Daniel Ciba (Krzysztof.Ciba@NOSPAMgmail.com)
# @date 06/05/2009
# @brief post-commit hook for syncing two locations in repository
import os, sys
import datetime
import getopt
try:
my_getopt = getopt.gnu_getopt
except AttributeError:
my_getopt = getopt.getopt
import StringIO
from subprocess import Popen
from subprocess import PIPE
twinPaths = { "/destpath/dest1" : "/some/path/src1" }
svnhome = "/PATH/TO/YOUR/REPO/"
svnroot = "file:///PATH/TO/YOUR/REPO"
svnCmd = "/usr/bin/svn"
svnlookCmd = "/usr/bin/svnlook"
## make sync between twin packages
# @param rev revision number
def sync(rev):
svnlook = svnlookCmd + " changed " + svnhome + " -r " + rev
changed = Popen( svnlook.split(), stdout=PIPE).communicate()[0]
changed = StringIO.StringIO( changed )
changed = changed.read()
changed = changed.split( "\n" )
twins = []
for line in changed:
if ( line != "" ):
change, where = line.split()
where = where.strip()
sys.stdout.write( change + " in " + where + "\n" )
for srcPath, dstPath in twinPaths.iteritems():
print where + " " + srcPath
if ( where.startswith( srcPath ) ):
twins.append( ( srcPath, dstPath ) )
noDupes = []
[ noDupes.append(i) for i in twins if not noDupes.count(i) ]
twins = noDupes
if ( len( twins ) ):
for ( srcPath, dstPath ) in twins:
srcURI = svnroot + "/" + srcPath + "@" + rev
dstURI = svnroot + "/" + dstPath
cmd = "#!/bin/sh\n"
cmd += svnCmd + " co " + dstURI + "\n"
cmd += svnCmd + " merge " + dstURI + " " + srcURI + " " + dstPath +"\n"
cmd += svnCmd + " ci " + dstPath + " -m 'syncing " + dstPath + " with " + srcPath + "'\n"
cmd += "rm -rf "+ dstPath +"\n"
sys.stdout.write( cmd )
stdin, stdout, stderr = os.popen3( cmd )
err = stderr.read()
stderr.close()
out = stdout.read()
if ( err != "" ): return False
return True
## write usage and exit
def usage_and_exit(error_msg=None):
import os.path
stream = error_msg and sys.stderr or sys.stdout
if error_msg:
stream.write("ERROR: %s\n\n" % error_msg)
stream.write("USAGE: %s -r REV REPOS\n"
% (os.path.basename(sys.argv[0])))
sys.exit(error_msg and 1 or 0)
## main processing
def main( argv ):
repos_path = None
rev = None
try:
opts, args = my_getopt(argv[1:], 'r:h?', ["help"])
except:
usage_and_exit("problem processing arguments/options")
for opt, value in opts:
if opt == '--help' or opt == '-h' or opt == '-?':
usage_and_exit()
elif opt == '-r':
rev = value
else:
usage_and_exit("unknown option '%s'" % opt)
if rev is None:
usage_and_exit("must provide -r argument")
if len(args) != 1:
usage_and_exit("only one argument allowed (the repository).")
if ( sync(rev) ): return 0
return 1
## start processing
if __name__ == '__main__':
sys.exit( main( sys.argv ) )
Then of course you should modify your post-commit file, in my case it is very simple:
#!/bin/sh
REPOS="$1"
REV="$2"
# synchronisation between packages
SYNC=/PATH/TO/REPO/hooks/sync.py
$SYNC -r "$REV" "$REPOS"
And that's it! Every change (commit) made in /some/path/src1 would be merged and committed to /destpath/dest1.
Brak komentarzy:
Prześlij komentarz