Merge SVN directories

One of the applications of my customer in being maintained by an external vendor. The vendor delivers code to a separated SVN repository, by importing it every time as a new tag. This causes a few difficulties:

  • SVN is not able to report code differences between two versions
  • all available at the company tooling has to be configured to scan additional SVN repository

To resolve this problem I wrote a script, which extracts newly delivered code from “external” SVN repository and commits it as a single change to a trunk in another repository.

The script uses SVN CLI and has been tested with both 1.6 and 1.7 versions. The following limitations are known… and any improvement suggestions are very welcome:

  • it behaves like CVS, renaming of a file or directory is seen as deletion of the old file and adding a new one. The fact of renaming is lost to importing of the code by vendor

The script is also available in Bitbucket

1#!/bin/sh -e
2 
3# Extract code from source SVN URL and merges it with an existing code in target URL
5 
6die () {
7    local error_code="$?"
8    echo >&2 "$@"
9    test $error_code == 0 && exit 1;
10    exit $error_code
11}
12 
13usage=$"This script extracts code from source SVN URL and merges it with an existing code in target URL.\n\
14Two parameters:\n\
151) source_svn_url,\n\
162) target_svn_url,\n\
17\n\
18$0 source_svn_url target_svn_url\n\
19"
20 
21[ "$#" -ge 1 ] || die "Wrong parameters. $usage"
22source_uri=$1
23target_uri=$2
24 
25# Testing is svn CLI is present
26svnRun=`which svn 2> /dev/null`
27if [ ! $svnRun ]
28then
29  die "svn CLI is not found on PATH"
30fi
31 
32SCRDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
33 
34# 1. Export source folder
35echo "Exporting source code from $source_uri"
36svn export $source_uri source
37 
38# 2. Check-out target folder
39echo "Checking out target code from $target_uri"
40svn checkout $target_uri target
41 
42# 3. Delete all target file, but keep .svn and pom.xml
43echo "Deleting targer files, keeping SVN metadata"
44find target -type f -mindepth 1  \! -iwholename "*/.svn/*" \! -iwholename "*/.svn" -exec rm -f {} \;
45find target -empty -mindepth 1  \! -iwholename "*/.svn/*" \! -iwholename "*/.svn" -exec rm -rf {} \;
46 
47# 4. Copy source files over target .svn
48echo "Copying source over target SVN metadata"
49cp -R source/* target/
50 
51# 5. Delete empty folders and folders with .svn only
52find target -depth -mindepth 1 -type d \! -iwholename "*/.svn/*" \! -iwholename "*/.svn" -exec perl $SCRDIR/rm_empty_dir.pl {} \;
53 
54cd target
55 
56# 6. Add new files to SVN
57added=`svn status | grep "? " | wc -l`;
58echo "$added files are added"
59if [ $added -gt 0 ]
60then
61  svn status | grep "? " | awk '{print $2}' | xargs svn add
62fi
63 
64# 7. Delete missing files from SVN
65deleted=`svn status | grep "! " | wc -l`;
66echo "$deleted files are deleted"
67if [ $deleted -gt 0 ]
68then
69  svn status | grep "! " | awk '{print $2}' | xargs svn delete
70fi
71 
72# 8. Commit results of the merger
73echo "Commiting changes back to target SVN"
74svn -m "merging with code from $source_uri" commit
75 
76# End of the file

Leave a Reply

Your email address will not be published.

Please, enter correct number below to prevent spam (required)