#!/bin/sh
# join-branch.sh: join a sibling branch
# 
################################################################
# Copyright (C) 2001, 2002 Tom Lord
# 
# See the file "COPYING" for further information about
# the copyright and warranty status of this work.
# 

set -e 
command_line="$*"

################################################################
# special options
# 
# Some options are special:
# 
#       --version | -V
#       --help | -h
# 
if test $# -ne 0 ; then

  for opt in "$@" ; do
    case $opt in

      --version|-V) exec larch --version
                    ;;


      --help|-h)
                printf "join-branch a sibling branch\\n"
                printf "usage: join-branch [options] old-dir new-dir [[archive/]revision]\\n"
                printf "usage: join-branch --in-place [options] dir [[archive/]revision]\\n"
                printf "\\n"
                printf " -V --version                  print version info\\n"
                printf " -h --help                     display help\\n"
                printf "\\n"
                printf " -R --root root                specify the local archive root\\n"
                printf " -A --archive archive          specify the archive name\\n"
                printf "\\n"
		printf " --in-place                    modify an existing directory\\n"
		printf " --force                       apply the patch even if the tree\\n"
		printf "                                 already has a patch log for the\\n"
		printf "                                 indicated revision\\n"
                printf "\\n"
                exit 0
                ;;

      *)
                ;;
    esac
  done
fi

################################################################
# Ordinary Options
# 
# 

archroot=
archive=

in_place=

quiet=--quiet
report=--report
verbose=
silent_opt=
quiet_opt=
report_opt=
verbose_opt=
debug_opt=

force=


while test $# -ne 0 ; do

  case "$1" in 

    --force)    shift
    		force=--force
		;;

    ----restart) shift
    		__restart=----restart
		;;

    --no-lint)  shift
    		no_lint=--no-lint
		;;

    --silent)	shift
    		quiet=
		report=
		verbose=
		silent_opt=--silent
		quiet_opt=
		report_opt=
		verbose_opt=
		;;

    --quiet)	shift
    		quiet=--quiet
		report=
		verbose=
		silent_opt=
		quiet_opt=--quiet
		report_opt=
		verbose_opt=
		;;

    --report)	shift
    		quiet=--quiet
		report=--report
		verbose=
		silent_opt=
		quiet_opt=
		report_opt=--report
		verbose_opt=
		;;

    --verbose)	shift
    		quiet=--quiet
		report=--report
		verbose=--verbose
		silent_opt=
		quiet_opt=
		report_opt=
		verbose_opt=--verbose
		;;

    --debug)	shift
    		larch heading "join-branch: debugging output enabled\\n"
    		set -x
		debug_opt=--debug
		;;


    -R|--root)          shift
                        if test $# -eq 0 ; then
                          printf "join-branch: -R and --root require an argument\\n" 1>&2
                          printf "try --help\\n" 1>&2
                          exit 1
                        fi
                        archroot="$1"
                        shift
                        ;;

    -A|--archive)       shift
                        if test $# -eq 0 ; then
                          printf "join-branch: -A and --archive require an argument\\n" 1>&2
                          printf "try --help\\n" 1>&2
                          exit 1
                        fi
                        archive="$1"
                        shift
                        ;;

    --in-place)		shift
    			in_place=--in-place
			;;

    --)			shift
    			break
			;;
			
    -*)                 printf "join-branch: unrecognized option (%s)\\n" "$1" 1>&2
                        printf "try --help\\n" 1>&2
                        exit 1
                        ;;

    *)                  break
                        ;;
  esac

done



################################################################
# Ordinary Arguments
# 

if test -z "$in_place" ; then
  n_dir_args=2
else
  n_dir_args=1
fi

req_args=$(($n_dir_args + 1))

if test $# -ne $req_args ; then
  printf "usage: join-branch [options] old-dir new-dir [[archive/]revision]\\n" 1>&2
  printf "       join-branch --in-place [options] dir [archive/]revision\\n" 1>&2
  printf "try --help\\n" 1>&2
  exit 1
fi

old_dir="$1"
shift

if test -z "$in_place" ; then
  new_dir="$1"
  shift
else
  new_dir="$old_dir"
fi

if test $# -ne 0 ; then
  archive_version="$1"
  shift
else
  archive_version=
fi

################################################################
# Sanity Check and Process Defaults
# 

here="`pwd`"

cd "$old_dir"
old_dir="`pwd`"

cd "$here"
cd "`dirname \"$new_dir\"`"
output_dir="`pwd`"
new_base="`basename \"$new_dir\"`"
new_dir="$output_dir/$new_base"

cd "$old_dir"
old_dir="`larch tree-root --accurate`"

larch valid-package-name -e join-branch --patch-level -- "$archive_version"

archive="`larch parse-package-name -R \"$archroot\" -A \"$archive\" --arch \"$archive_version\"`"
spec="`larch parse-package-name --non-arch \"$archive_version\"`"
category="`larch parse-package-name --basename \"$archive_version\"`"
branch="`larch parse-package-name \"$archive_version\"`"
version="`larch parse-package-name --package-version \"$spec\"`"

if    test -z "$force" \
   -a larch wd-check-for-patch-log "$archive/$version" \
   -a larch log-ls "$archive/$spec" \
; then
  printf "\\n" 1>&2
  printf "join-branch: tree already has log entry for patch\\n" 1>&2
  printf "  tree: %s\\n" "$old_dir" 1>&2
  printf "  revision: %s\\n" "$archive/$spec" 1>&2
  printf "\\n" 1>&2
  exit 1
fi

lvl="`larch parse-package-name --lvl \"$spec\"`"



################################################################
# Greetings
# 

if test "(" -z "$__restart" -a ! -z "$quiet" ")" -o ! -z "$report" ; then
  larch heading "join-branch\\n"
  printf "arguments: %s\\n"  "$command_line" | fold -w 60 | larch body-indent
  larch heading --sub "join-branch start time: %s\\n" "`date`"
  if test -z "$in_place" ; then
    larch heading --sub "old project tree: %s\\n" "$old_dir"
    larch heading --sub "new project tree: %s\\n" "$new_dir"
  else
    larch heading --sub "NOTE: modifying project tree in place (--in-place)\\n"
    larch heading --sub --sub "project tree: %s\\n" "$old_dir"
  fi
  larch heading --sub "archive: %s\\n" "$archive"
  larch heading --sub "revision: %s\\n" "$spec"
fi


################################################################
# Ensure that We Have an Archive Connection 
# 

if test "$WITHARCHIVE" != "$archive" ; then

  if test ! -z "$quiet" ; then
    larch heading --sub "restarting with connection to archive\\n"
  fi


  if test -z "$in_place" ; then
    exec larch with-archive -A "$archive"  \
	  	  larch join-branch \
			  -R "$archroot" -A "$archive" \
			  $silent_opt $quiet_opt $report_opt $verbose_opt $debug_opt \
			  ----restart \
			  -- "$old_dir" "$new_dir" $archive_version
  else
    exec larch with-archive -A "$archive"  \
	  	  larch join-branch \
			  -R "$archroot" -A "$archive" \
			  $silent_opt $quiet_opt $report_opt $verbose_opt $debug_opt \
			  ----restart \
			  --in-place \
			  -- "$old_dir" $archive_version
  fi

  exit 2
fi

################################################################
# Ensure that the Joined Revision is a Continuation Revision of an Ancestor
# 

wftp-home
if ! wftp-cd "$category/$branch/$version/$lvl" 2> /dev/null ; then
  printf "\\n" 1>&2
  printf "join-branch: revision not found in archive\\n" 1>&2
  printf "  archive: %s\\n" "$archive" 1>&2
  printf "  revision: %s\\n" "$spec" 1>&2
  printf "\\n" 1>&2
  exit 1
fi

if ! wftp-get CONTINUATION > /dev/null 2>&1 ; then
  printf "\\n" 1>&2
  printf "join-branch: revision is not a continuation revision\\n" 1>&2
  printf "  archive: %s\\n" "$archive" 1>&2
  printf "  revision: %s\\n" "$spec" 1>&2
  printf "\\n" 1>&2
  exit 1
fi

continuation="`wftp-get CONTINUATION`"

if ! larch valid-package-name --archive --lvl -- "$continuation" ; then
  printf "\\n" 1>&2
  printf "join-branch: CORRUPT ARCHIVE?\\n" 1>&2
  printf "\\n" 1>&2
  printf "  archive: %s\\n" "$archive" 1>&2
  printf "  revision: %s\\n" "$spec" 1>&2
  printf "\\n" 1>&2
  printf "  Revision appears to be a continuation revision, but not of a\\n" 1>&2
  printf "  valid revision.  The continued revision is (illegally) specified\\n" 1>&2
  printf "  in the archive as:\\n" 1>&2
  printf "\\n" 1>&2
  printf "     %s\\n" "$continuation" 1>&2
  printf "\\n" 1>&2
  exit 1
fi

cd "$old_dir"
log_entry="`larch log-ls --full -- \"$continuation\"`"

if test "$log_entry" != "$continuation" ; then
  printf "\\n" 1>&2
  printf "join-branch: unable to join branch at desired revision\\n" 1>&2
  printf "  archive: %s\\n" "$archive" 1>&2
  printf "  revision: %s\\n" "$spec" 1>&2
  printf "\\n" 1>&2
  printf "  That revision is a continuation of revision:\\n" 1>&2
  printf "\\n" 1>&2
  printf "    %s\\n" "$continuation" 1>&2
  printf "\\n" 1>&2
  printf "  but the project tree has no log entry for that revision.\\n" 1>&2
  printf "\\n" 1>&2
  printf "\\n" 1>&2
  exit 1
fi

################################################################
# Do It
# 

if test -z "$in_place" ; then 
  larch nested larch replay --exact "$old_dir" "$new_dir" "$archive/$spec"
else
  larch nested larch replay --exact --in-place "$old_dir" "$archive/$spec"
fi

# tag: Tom Lord Mon Dec 31 17:48:29 2001 (branching-and-merging/join.sh)
#
