Re: beating mergemaster to /etc/rc.d

From: Anton Berezin <tobez_at_FreeBSD.org>
Date: Wed, 12 Jan 2005 09:33:00 +0100
On Thu, Oct 14, 2004 at 07:18:52PM +0700, Max Khon wrote:

> Personally, I do not understand why requests for the feature
> "list of files to install automatically" are still rejected.

A colleague of mine came up with an idea which I did not see before:

Optionally, if CVS revisions are different, and CVS repository is
available, fetch the file with the same revision as the installed one
from CVS, and compare it with the installed one.  If they are identical,
mergemaster can safely assume that the file was not modified by hand and
can therefore overwrite it without doing a diff loop hoop-la.

I gave it a shot yesterday, and would appreciate any testing and
feedback, especially because my shell skills suck.

--- /usr/sbin/mergemaster	Wed Dec 22 11:31:30 2004
+++ mergemaster	Tue Jan 11 23:27:20 2005
_at__at_ -30,6 +30,7 _at__at_ display_usage () {
   echo '  -P  Preserve files that are overwritten'
   echo "  -m /path/directory  Specify location of source to do the make in"
   echo "  -t /path/directory  Specify temp root directory"
+  echo "  -R cvsroot  Specify cvs repository and instruct to use it"
   echo "  -d  Add date and time to directory name (e.g., /var/tmp/temproot.`date +%m%d.%H.%M`)"
   echo "  -u N  Specify a numeric umask"
   echo "  -w N  Specify a screen width in columns to sdiff"
_at__at_ -238,7 +239,7 _at__at_ fi
 
 # Check the command line options
 #
-while getopts ":ascrvhipCPm:t:du:w:D:" COMMAND_LINE_ARGUMENT ; do
+while getopts ":ascrvhipCPm:t:R:du:w:D:" COMMAND_LINE_ARGUMENT ; do
   case "${COMMAND_LINE_ARGUMENT}" in
   s)
     STRICT=yes
_at__at_ -284,6 +285,9 _at__at_ while getopts ":ascrvhipCPm:t:du:w:D:" C
   t)
     TEMPROOT=${OPTARG}
     ;;
+  R)
+    CVSROOT=${OPTARG}
+    ;;
   d)
     TEMPROOT=${TEMPROOT}.`date +%m%d.%H.%M`
     ;;
_at__at_ -896,21 +900,69 _at__at_ for COMPFILE in `find . -type f -size +0
       echo " *** Temp ${COMPFILE} and installed are the same, deleting"
       rm "${COMPFILE}"
     else
-      # Ok, the files are different, so show the user where they differ.
-      # Use user's choice of diff methods; and user's pager if they have one.
-      # Use more if not.
-      # Use unified diffs by default.  Context diffs give me a headache. :)
-      #
-      case "${AUTO_RUN}" in
+      DO_DIFF_LOOP=yes
+
+      case "${CVSROOT}" in
       '')
-        # prompt user to install/delete/merge changes
-        diff_loop
         ;;
       *)
-        # If this is an auto run, make it official
-        echo "   *** ${COMPFILE} will remain for your consideration"
+        CVSFILE=`grep "[$]${CVS_ID_TAG}:" ${DESTDIR}${COMPFILE#.} 2>/dev/null |
+                 sed -e "s#.*[$]${CVS_ID_TAG}: \(src/.*\),v .*#\1#" 2>/dev/null`
+        CVSREV=`grep "[$]${CVS_ID_TAG}:" ${DESTDIR}${COMPFILE#.} 2>/dev/null |
+                sed -e "s#.*[$]${CVS_ID_TAG}: src/.*,v \([0-9.]*\) .*#\1#" 2>/dev/null`
+        case "${CVSFILE}" in
+        '')
+          ;;
+        *)
+          case "${CVSREV}" in
+          '')
+            ;;
+          *)
+            CVSFILE_N=`echo "${CVSFILE}"|wc -l`
+            CVSREV_N=`echo "${CVSREV}"|wc -l`
+            if [ ${CVSFILE_N} -eq 1 -a ${CVSREV_N} -eq 1 ]; then
+              CVSTEMP=`mktemp -t mmcvs`
+              cvs -d ${CVSROOT} co -r${CVSREV} -p ${CVSFILE} >${CVSTEMP} 2>/dev/null
+              if diff -q ${DIFF_OPTIONS} "${DESTDIR}${COMPFILE#.}" "${CVSTEMP}" > \
+                /dev/null 2>&1; then
+                rm -f ${CVSTEMP}
+                echo ''
+                echo "  *** The installed version of ${COMPFILE} is the same as"
+                echo "      its CVS revision ${CVSREV}, overwriting it"
+                echo ''
+                if mm_install "${COMPFILE}"; then
+                  echo "   *** ${COMPFILE} installed successfully"
+                else
+                  echo "   *** Problem installing ${COMPFILE}, it will remain to merge by hand"
+                fi
+                unset DO_DIFF_LOOP
+              fi # same file in CVS and in DESTDIR, can overwrite it
+              rm -f ${CVSTEMP}
+            fi # CVSFILE and CVSREV can be used
+            ;;
+          esac # CVSREV non-empty
+          ;;
+        esac # CVSFILE non-empty
         ;;
-      esac # Auto run test
+      esac # cvs root test
+
+      if [ -n "${DO_DIFF_LOOP}" ]; then
+        # Ok, the files are different, so show the user where they differ.
+        # Use user's choice of diff methods; and user's pager if they have one.
+        # Use more if not.
+        # Use unified diffs by default.  Context diffs give me a headache. :)
+        #
+        case "${AUTO_RUN}" in
+        '')
+          # prompt user to install/delete/merge changes
+          diff_loop
+          ;;
+        *)
+          # If this is an auto run, make it official
+          echo "   *** ${COMPFILE} will remain for your consideration"
+          ;;
+        esac # Auto run test
+      fi # Yes, do a diff loop
     fi # Yes, the files are different
   fi # Yes, the file still remains to be checked
 done # This is for the do way up there at the beginning of the comparison

Cheers,
\Anton.
-- 
The moronity of the universe is a monotonically increasing function. --
Jarkko Hietaniemi
Received on Wed Jan 12 2005 - 07:33:03 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:26 UTC