On Fri, 16 Feb 2007 07:43:48 +0100, Goswin von Brederlow <[EMAIL PROTECTED]> said:
> What I want to do is apply a patch to the common ancestry of a set > of branches but have the RCS system check that it doesn't break any > branch. Currently I have to apply the patch to one branch and then > replay, merge, pull, whatever it across all the branches that have > the same ancestry. OK. Your problem can be abstracted down to be the same on, topographically speaking, as the one of having a new upstream version come out, when you have a whole slew of branches, and have to apply the upstream change-set to every one of the branches you maintain. Your specific example can be mapped into this problem, which is, essentially, changes that have been applied to an ancestor branch needing to be propagated down every branch, and ensuring that there are no confilcts. I have scripted this, so certainly this is easy to do with arch. In order for the script to make sense to you, you need to understand a little bit about my working setup. Here is my setup, which is a fairly common paradigm for me (I started doing this with cvs-buildpackage): ,---- | $workdir_top/ # contains all the packages | $pkg/ # (has orig.tar.gz) | $pkg-$upstream_version/ | debian/ | common/ | upstream/ | $pkg--upstream--$revision | $pkg--feature-A--$revision | $pkg--feature-B--$revision | .... | $pkg--feature-N--$revision | $pkg--devo--$revision `---- The --devo-- branch is the integration branch, which contains all the features, and is used for building the binary. Now, suppose there is a new upstream version. I update the branch $pkg--upstream--$revision using tla_load_dir, but now I have N feature branches, and the integration branch, to take care of. Voila. I 'cd $workdir_top/$pkg/upstream', and run the following script. This script then: a) Applies the missing changes in the upstream branch to the integration branch. This is where I get to know if there is going to be any conflicts in the feature branches. Most of my packages, most of the time, require no manual intervention. Really. If there is any manual intervention needed, then, for all conflicts: i) I inspect the conflict, determine which feature branch would be affected; ii) fix the conflict in this throw away integration branch copy, and satisfy myself the resolution is OK iii) make the same changes to the affected feature branch. iv) Commit changes to the feature branch v) Undo upstream changes to the integration branch, and pull the changes made to the feature branch. At this point, if we were to re-try merging the upstream, then this conflict would be gone. At this point, I can just re-run the script from the top, and there will be no conflicts, since all conflicts have been fixed. b) Applies the missing changes in the upstream branch to all the feature branches, 1..N. c) It commits the new revision of the feature branch d) It does a sync tree in the integration branch, so future merges are gonna be fine. e) Finally, it commits the changes in the development branch. So, for the setup you have with upstream, debian, and ubuntu, you can generate a very similar shell script to apply common changes to ancestor branches -- and even generalize it more than I have needed to. I really like the scriptability of arch :) manoj
#!/bin/zsh # -*- Mode: Sh -*- # upgrade.sh --- # Author : Manoj Srivastava ( [EMAIL PROTECTED] ) # Created On : Thu Aug 11 13:55:22 2005 # Created On Node : glaurung.internal.golden-gryphon.com # Last Modified By : Manoj Srivastava # Last Modified On : Wed Sep 20 11:49:41 2006 (-18000 CDT) # Last Machine Used: glaurung.internal.golden-gryphon.com # Update Count : 17 # Status : Unknown, Use with caution! # HISTORY : # Description : # # arch-tag: 25520dc3-7d73-4b47-ab69-77483e2749d2 # progname="`basename \"$0\"`" set -e workdir_top=/usr/local/src/arch/packages--debian curdir=$(pwd) pkg=$(pwd | sed -e 's,^/usr/local/src/arch/packages--debian/,,' -e 's,/.*$,,') TLA=baz # uses baz status, so do not change withecho () { echo " $@" >&2 "$@" } action='withecho' #action='echo' usageversion () { cat >&2 <<END Usage: $progname [options] <package> Options: -h print this message -n "Dry-run" mode - No action taken, only print commands. -v Make the command verbose END } # parse Command line # Note that we use `"$@"' to let each command-line parameter expand to a # separate word. The quotes around `$@' are essential! # We need TEMP as the `eval set --' would nuke the return value of getopt. TEMP=$(getopt -a -s bash -o hnv -n 'arch_update' -- "$@") if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi # Note the quotes around `$TEMP': they are essential! eval set -- "$TEMP" while true ; do case "$1" in -h|--help) usageversion; exit 0 ; shift ;; -n) action='echo';docmd='NO' ; shift ;; -v) VERBOSE=1 ; shift ;; --) shift ; break ;; *) echo >&2 "Internal error!($i)" usageversion; exit 1 ;; esac done if [[ -n "$1" ]]; then pkg=$1 fi dev=$(${TLA} versions ${pkg}--devo | tail -n 1) ups=$(${TLA} versions ${pkg}--upstream | tail -n 1) cd $workdir_top/$pkg/upstream test -d $dev || echo $dev does not exist test -d $dev || exit 1 devo_changed= (set -e; echo "Synchronize the development branch with upstream ($dev)"; cd $dev >/dev/null; my_missing=$(${TLA} missing $ups) if [[ -n "$my_missing" ]]; then for missing in $(${TLA} missing $ups); do $action ${TLA} replay $missing devo_changed="YES" done fi echo "The development branch now synched with upstream ($dev)" echo '' ) my_branches=$(${TLA} branches $pkg | egrep -v '(devo|upstream)$') if [[ -n "$my_branches" ]]; then for branch in $(${TLA} branches $pkg | egrep -v '(devo|upstream)$'); do my_version=$(${TLA} versions $branch | tail -n 1) if [[ -n "$my_version" ]]; then for version in $(${TLA} versions $branch | tail -n 1); do if [ -d $version ]; then (set -e; echo "Work on $version"; cd $version>/dev/null; if ${TLA} lint>/dev/null; then my_missing=$(${TLA} missing $ups) if [[ -n "$my_missing" ]]; then for missing in $(${TLA} missing $ups); do $action ${TLA} replay $missing done $action ${TLA} commit -L 'Synch with upstream' fi if ${TLA} status | egrep -v '^(\*|${TLA})' >| /dev/null; then $action ${TLA} commit -L 'Synch with upstream' fi else echo >&2 $version has untagged files fi ) (set -e; echo " Make sure $dev is updated"; cd $dev >/dev/null; my_missing=$(${TLA} missing $version) if [[ -n "$my_missing" ]]; then for missing in $(${TLA} missing $version); do $action ${TLA} sync-tree $missing devo_changed="YES" done fi ) echo "Done in $version" echo '' fi done fi done fi (set -e; cd $dev >/dev/null; echo "Sync $dev with other branches" $action ${TLA} commit -L 'Synch with upstream and other branches' devo_changed= )
-- Every time I think I know where it's at, they move it. Manoj Srivastava <[EMAIL PROTECTED]> <http://www.debian.org/~srivasta/> 1024D/BF24424C print 4966 F272 D093 B493 410B 924B 21BA DABB BF24 424C