Subversion branch inheritance by convention: svnMergeChildren

From FVue
Jump to: navigation, search

Introduction

I'm looking for a solution to put configuration files of multiple hosts under version control and so far I've come up with the solution below.

The configuration files share some kind of inheritance: A change in the global configuration file should be propagated to all host configuration files. For example, consider a .bashrc configuration file running on 4 computers on 2 domains:

                             +--------+
global:                      | bashrc |
                             +----+---+
                                 /_\
                                  |
                     +------------+-------------+
                     |                          |
                +----+---+                 +----+----+  
domain:         | planet |                 | country |
                +----+---+                 +----+----+
                    /_\                        /_\
                     |                          |
               +-----+-----+              +-----+------+  
               |           |              |            |
          +----+---+   +---+---+      +---+---+   +----+----+
host:     | saturn |   | pluto |      | spain |   | england |
          +--------+   +-------+      +-------+   +---------+

Maintenance would be made easier if I could specify inheritance in subversion, for example:

  .bashrc                    Example setting
-----------   -------------------------------------------------

+---------+
| global  |   # This personal setting should go everywhere
| bashrc  |   set -o vi
+----+----+
    /_\
     |
+----+----+
| domain  |   # This domain has a centralized project directory
| planet  |   CDPATH=/usr/share/proj
+----+----+
    /_\
     |
+----+----+
|  host   |   # This host is running the latest Vim
| saturn  |   export VIMRUNTIME=/usr/local/share/vim/vim70
+---------+

I've created a short shell script svnMergeChildren.sh which merges parent changes to all children

Usage

Create a repository with directories for every class (i.e. domain/host), using the convention:

EACH DIRECTORY MUST BE PREFIXED WITH ITS PARENT NAME

(Note: You can apply this to filenames as well, naming it "File inheritance by convention" :-)

trunk
|- bashrc
|- bashrc-planet
|- bashrc-planet.saturn
|- bashrc-planet.pluto
|- bashrc-country
|- bashrc-country.england
|- bashrc-country.spain</nowiki>

On every host, checkout the repository and link to the right branch:

svn checkout .../repos/branches/pluto ./workdir/bashrc-planet.pluto
ln -s ./workdir/bashrc-planet.pluto/.bashrc

On the host which is used for development, merge parent changes to all children using svnMergeChildren.sh:

#!/bin/bash
#--- svnMergeChildren.sh --------------------------------------------
# Copyright (C) 2006  Freddy Vulto
# Version: 2.0.0
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA  02110-1301, USA
#
# The latest version of this software can be obtained here:
# http://fvue.nl/svnMergeChildren/

set -o errexit  # Exit on error
set -o nounset  # Trigger error when expanding unset variables

function svnMergeChildren() {
        # If no arguments, or -h, or --help, show usage
    [[ $# == 0 || $1 == -h || $1 == --help ]] && {
        echo -n Merge children: Apply the difference between 
        echo two sources to multiple working copy paths
        echo Usage: $(basename $0) ... NAME_PARENT
        echo
        echo See \'svn help merge\' for ... arguments.
        echo
        echo For more information, see http://fvue.nl/svnMergeChildren/
        return $(test $# -gt 0)
    }
        # Get last parameter
    parent=${!#}
        # Unset last positional parameter
    args=( "$@" ); unset args[${#args[@]}-1]; set -- "${args[@]}"
        # Indicate non-verbose if either -q or --quiet specified
    for i; do [ "$i" = -q -o "$i" = --quiet ] && beVerbose=0; done
        # Loop through children
    shopt -s failglob nullglob; for i in "$parent"?*; do
        (( "${beVerbose-1}" )) && echo svn merge "$@" "$i"
        svn merge "$@" "$i"
    done
} # svnMergeChildren()

svnMergeChildren "$@"

Scenario 1: Merge changes in global .bashrc to all children

Suppose you've made a modification (say revision 2) in the global .bashrc you'd like to see propagated into all children. Here's the command to do so (leave out --dry-run for an actual run):

svnMergeChildren.sh -r1:2 --dry-run file:///proj/bash/repos/trunk/bashrc bashrc

Scenario 2: Merge changes in domain .bashrc to domain children

Suppose you've made a modification (say revision 3) in the .bashrc planet domain you'd like to see propagated into all children of the planet domain. Here's the command to do so (leave out --dry-run for an actual run):

svnMergeChildren.sh -r2:3 --dry-run file:///proj/bash/repos/trunk/bashrc-planet bashrc-planet

Download

Test

The download contains an additional test suite. The test suite requires dejagnu, tcl and expect to be installed.

To run the tests:

cd test
./runAll

Example output

WARNING: Couldn't find tool init file
Test Run By freddy on Sun Nov 12 10:42:20 2006
Native configuration is i686-suse-linux

                === all tests ===

Schedule of variations:
    unix

Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
WARNING: Couldn't find tool config file for unix, using default.
Running ./all/all.exp ...

                === all Summary ===

# of expected passes            7

Release notes

svnMergeChildren-2.0.0, Nov 12, 2006

* Renamed svnMergeChilds to svnMergeChildren


svnMergeChilds-1.0.2, Nov 12, 2006

* Shortened line length.


svnMergeChilds-1.0.1, Nov 11, 2006

* Fixed support for parameters with whitespace.
* Removed invocation of excess subshells.

Journal

20061007

Ten Ways to Sunday: Source Control Inheritance

20061030

First attempt of a shell script to ease the job.

20061112

Comments

blog comments powered by Disqus