#!/bin/bash
#
#  Script: merge_branch_to_trunk
# 
#  Purpose: 
#      Merges a branch into the trunk
#
#  Programmer: Hank Childs
#  Creation:   May 15, 2007
#
#  Modifications:
#
#    Hank Childs, Sat Jun 23 16:47:06 PDT 2007
#    Disallow merging from an RC branch to the trunk.
#
#    Hank Childs, Thu Jul  5 16:13:57 PDT 2007
#    Suppress SVN noise.
#
#    Hank Childs, Mon Dec 17 15:44:53 PST 2007
#    Make sure that the trunk is up-to-date and has no checkouts.
#
#    Hank Childs, Thu Dec 20 09:21:03 PST 2007
#    Renamed -allow_checkouts to -allow_local_mods
#
#    Hank Childs, Sun Aug  3 12:18:05 PDT 2008
#    Allow merging from other developer's branches.
#
#    Mark C. Miller, Mon Aug 17 15:18:30 PDT 2009
#    Made it give a useful error message if it appears to have been
#    invoked for an RC merge.
#
#    Hank Childs, Mon Nov 23 16:45:41 PST 2009
#    Document -user argument.
#
# *****************************************************************************

issueHelp="no"
allowLocalMods="no"

P=$(which $0)
P2=${P%/*}
. ${P2}/visit_svn_helper

# Prevent print statements when changing directories
CDPATH=""

BRANCH=""
BRANCHNAME=""

user=$SVN_NERSC_NAME
if [[ $# == 3 ]] ; then
   if [[ "$2" == "-user" ]] ; then
       user=$3
   else
       issueHelp="yes"
   fi
elif [[ $# == 2 ]] ; then
   if [[ "$2" != "-allow_local_mods" ]] ; then
       issueHelp="yes"
   else
       allowLocalMods="yes"
   fi
elif [[ $# != 1 ]] ; then
   issueHelp="yes"
fi
if [[ "$1" == "-help" || "$1" == "-h" || "$1" == "-?" ]] ; then
   issueHelp="yes"
fi

if [[ "$issueHelp" != "yes" ]] ; then
   if [[ ! -f .branchname ]] ; then
      echo "ERROR: You must run this script at the top level of your working copy"
      echo ""
      issueHelp="yes"
   elif [[ ! -f .rootpath ]] ; then
      echo "ERROR: You must run this script at the top level of your working copy"
      echo ""
      issueHelp="yes"
   fi
fi

if [[ "$issueHelp" != "yes" ]] ; then
   TRUNKNAME=$(cat .branchname)
   if [[ "$TRUNKNAME" != "trunk" ]] ; then
      echo "You must be in the trunk when you run this script"
      echo ""
      issueHelp="yes"
   fi
fi

if [[ "$issueHelp" != "yes" ]] ; then
   WHOLE_TRUNK="yes"
   ROOTPATH=$(cat .rootpath)
   if [[ "$ROOTPATH" != "/" ]] ; then
      WHOLE_TRUNK="no"
   else
      if [[ ! -d src || ! -d data || ! -d docs || ! -d test || ! -d third_party || ! -d windowsbuild ]] ; then
      WHOLE_TRUNK="no"
      fi
   fi
   if [[ "$WHOLE_TRUNK" == "no" ]]; then
      echo "Your checkout is not of the entire trunk.  The merge will only "
      echo "take place over your checkout.  If you continue, any changes that "
      echo "are on directories not in your current checkout of the trunk will be lost!"
      stop="no"
      while [[ "$stop" == "no" ]] ; do
           echo "Do you want to continue? [yes/no]"
           read answer
           if [[ "$answer" == "yes" ]] ; then
              stop="yes"
           fi
           if [[ "$answer" == "no" ]] ; then
              stop="yes"
           fi
       done
       if [[ "$answer" == "no" ]] ; then
           exit 1
       fi
   fi

   BRANCHNAME=$1
   BRANCH=${VISIT_SVN_BRANCHES}/${user}/${BRANCHNAME}${ROOTPATH}
   svn ls $BRANCH 2>/dev/null > /dev/null
   if [[ $? != 0 ]] ; then
      svn ls ${VISIT_SVN_BRANCHES}/${BRANCHNAME}${ROOTPATH} 2>/dev/null > /dev/null
      if [[ $? == 0 ]] ; then
          echo "Although the branch $1 does not appear to exist in"
          echo "${VISIT_SVN_BRANCHES}/${user}"
          echo "it does appear to exist in"
          echo "${VISIT_SVN_BRANCHES}"
          echo "If you are trying to merge a release candidate (RC) branch,"
          echo "remember to use the merge_rctrunk_to_trunk script and not the"
          echo "merge_branch_to_trunk script."
      else 
          echo "The branch $1 does not appear to exist."
          echo "(Looking for it at $BRANCH)"
          echo "Try using the script ls_branches to locate your branch."
      fi
      issueHelp="yes"
   fi
fi

if [[ "$issueHelp" == "yes" ]] ; then
   echo ""
   echo "Usage:   ${0##*/} <branch> [-allow_local_mods] [-user username]"
   echo ""
   echo "Args:"    
   echo "\t-allow_local_mods\tForce merge, despite modifications in the working copy of the trunk."
   echo "\t-user\tMerge from SVN directory space of a different user"
   echo "Example: ${0##*/} my_dev_work"
   echo "\tThis command should be run at the top level of your checked out "
   echo "\ttrunk.  It will merge the work from my_dev_work into the trunk."
   echo ""
   
   exit 1
fi

for i in src data docs test third_party windowsbuild ; do
  if [[ -d $i ]] ; then
      cd $i
      if [[ "$allowLocalMods" == "no" ]] ; then
        echo "Checking for pre-existing modifications on ${i}..."
        files=$(svn status -q)
        if [[ "$files" != "" ]] ; then
            echo "I believe you have the following files modified on ${i}:"
            echo "$files"
            echo "Aborting!"
            echo "(You can force this merge by reinvoking with -allow_local_mods)"
            exit 1
        fi
      fi
      echo "Making sure your working copy of the trunk/$i is up to date"
      svn update
      cd ..
  fi
done

echo ""
echo "Merging $BRANCH into the trunk"
echo ""

echo ""
echo "Getting record of last merge from this branch into the trunk..."
mkdir tmp_forRev$$
cd tmp_forRev$$
svn co --quiet --non-interactive ${VISIT_SVN_BRANCHES}/${user}/${BRANCHNAME}/svninfo
cd svninfo
REV=$(cat Rev_toTrunk)
isRC="no"
if [[ -f Rev_toRCTrunk ]] ; then
   isRC="yes"
fi
cd ../..
if [[ "$isRC" == "yes" ]] ; then
   echo ""
   echo "I believe the branch you are trying to merge from is an RC branch."
   echo ""
   echo "RC branches must be merged onto the RC trunk."
   echo "The RC trunk can then be merged to using merge_rctrunk_to_trunk."
   echo ""
   echo "Aborting!"
   echo ""
   rm -Rf tmp_forRev$$
   exit 1
fi
echo ""
echo "The revision of the last merge was $REV"
echo ""

for i in src data docs test third_party windowsbuild ; do
  if [[ -d $i ]] ; then
      cd $i
      echo ""
      echo "Merging directory \"$i\""
      echo ""
      svn merge -r ${REV}:HEAD ${VISIT_SVN_BRANCHES}/${user}/${BRANCHNAME}/${ROOTPATH}/$i
      cd ..
  fi
done
NEW_REV=$(get_latest_rev)

cd tmp_forRev$$/svninfo
echo "$NEW_REV" > Rev_toTrunk
echo ""
echo "Updating branch $BRANCHNAME to contain a record of this merge"
echo ""
svn commit --quiet -m "Update for revision sent to trunk from $BRANCHNAME, $REV to $NEW_REV"
cd ../..
rm -Rf tmp_forRev$$

echo ""
echo "The changes from the branch $BRANCHNAME have been put on your working copy."
echo "You need to review the changes and do an \"svn commit\" for these changes "
echo "to be saved.  Note that the branch has been updated with the info that this "
echo "merge took place and future merges into the trunk will not attempt to merge "
echo "these revisions again.  If you want to back out this merge, you will need "
echo "invoke the following command to update our bookkeeping: "
echo ""
echo "  set_branch_to_trunk_revision $BRANCHNAME $REV"
echo ""

exit 0

