hgmerge
changeset 1830 4ced57680ce7
parent 1798 d610fe0e6893
child 1880 05c7d75be925
equal deleted inserted replaced
1829:b0f6af327fd4 1830:4ced57680ce7
    15     EDITOR="vi"
    15     EDITOR="vi"
    16 fi
    16 fi
    17 
    17 
    18 # find decent versions of our utilities, insisting on the GNU versions where we
    18 # find decent versions of our utilities, insisting on the GNU versions where we
    19 # need to
    19 # need to
    20 MERGE=merge
    20 MERGE="merge"
    21 DIFF3=gdiff3
    21 DIFF3="gdiff3"
    22 DIFF=gdiff
    22 DIFF="gdiff"
    23 PATCH=gpatch
    23 PATCH="gpatch"
    24 
    24 
    25 type $MERGE >/dev/null 2>&1 || MERGE=
    25 type "$MERGE" >/dev/null 2>&1 || MERGE=
    26 type $DIFF3 >/dev/null 2>&1 || DIFF3=diff3
    26 type "$DIFF3" >/dev/null 2>&1 || DIFF3="diff3"
    27 type $DIFF  >/dev/null 2>&1 || DIFF=diff
       
    28 type $PATCH >/dev/null 2>&1 || PATCH=patch
       
    29 $DIFF3 --version >/dev/null 2>&1 || DIFF3=
    27 $DIFF3 --version >/dev/null 2>&1 || DIFF3=
       
    28 type "$DIFF"  >/dev/null 2>&1 || DIFF="diff"
       
    29 type "$DIFF"  >/dev/null 2>&1 || DIFF=
       
    30 type "$PATCH" >/dev/null 2>&1 || PATCH="patch"
       
    31 type "$PATCH" >/dev/null 2>&1 || PATCH=
    30 
    32 
    31 # find optional visual utilities
    33 # find optional visual utilities
    32 FILEMERGE='/Developer/Applications/Utilities/FileMerge.app/Contents/MacOS/FileMerge'
    34 FILEMERGE="/Developer/Applications/Utilities/FileMerge.app/Contents/MacOS/FileMerge"
    33 KDIFF3=kdiff3
    35 KDIFF3="kdiff3"
    34 TKDIFF=tkdiff
    36 TKDIFF="tkdiff"
       
    37 MELD="meld"
    35 
    38 
    36 type $FILEMERGE >/dev/null 2>&1 || FILEMERGE=
    39 type "$FILEMERGE" >/dev/null 2>&1 || FILEMERGE=
    37 type $KDIFF3    >/dev/null 2>&1 || KDIFF3=
    40 type "$KDIFF3"    >/dev/null 2>&1 || KDIFF3=
    38 type $TKDIFF    >/dev/null 2>&1 || TKDIFF=
    41 type "$TKDIFF"    >/dev/null 2>&1 || TKDIFF=
       
    42 type "$MELD"      >/dev/null 2>&1 || MELD=
    39 
    43 
    40 # random part of names
    44 # random part of names
    41 RAND="$RANDOM.$RANDOM.$RANDOM.$$"
    45 RAND="$RANDOM$RANDOM"
    42 
    46 
    43 # temporary directory for diff+patch merge
    47 # temporary directory for diff+patch merge
    44 HGTMP="${TMPDIR-/tmp}/hgmerge.$RAND"
    48 HGTMP="${TMPDIR-/tmp}/hgmerge.$RAND"
    45 
    49 
    46 # backup file
    50 # backup file
    66     mv "$BACKUP" "$LOCAL"
    70     mv "$BACKUP" "$LOCAL"
    67     cleanup
    71     cleanup
    68     exit 1
    72     exit 1
    69 }
    73 }
    70 
    74 
       
    75 # Ask if the merge was successful
       
    76 ask_if_merged() {
       
    77     while true; do
       
    78         echo "$LOCAL seems unchanged."
       
    79         echo "Was the merge successful? [y/n]"
       
    80         read answer
       
    81         case "$answer" in
       
    82             y*|Y*) success;;
       
    83             n*|N*) failure;;
       
    84         esac
       
    85     done
       
    86 }
       
    87 
    71 # Clean up when interrupted
    88 # Clean up when interrupted
    72 trap "failure" 1 2 3 6 15 # HUP INT QUIT ABRT TERM
    89 trap "failure" 1 2 3 6 15 # HUP INT QUIT ABRT TERM
    73 
    90 
    74 # Back up our file (and try hard to keep the mtime unchanged)
    91 # Back up our file (and try hard to keep the mtime unchanged)
    75 mv "$LOCAL" "$BACKUP"
    92 mv "$LOCAL" "$BACKUP"
    76 cp "$BACKUP" "$LOCAL"
    93 cp "$BACKUP" "$LOCAL"
    77 
    94 
    78 # Attempt to do a non-interactive merge
    95 # Attempt to do a non-interactive merge
    79 if [ -n "$MERGE" ]; then
    96 if [ -n "$MERGE" -o -n "$DIFF3" ]; then
    80     $MERGE "$LOCAL" "$BASE" "$OTHER" 2> /dev/null && success
    97     if [ -n "$MERGE" ]; then
    81     cp "$BACKUP" "$LOCAL"
    98         $MERGE "$LOCAL" "$BASE" "$OTHER" 2> /dev/null && success
    82 elif [ -n "$DIFF3" ]; then
    99     elif [ -n "$DIFF3" ]; then
    83     echo $DIFF3 -m "$BACKUP" "$BASE" "$OTHER"
   100         $DIFF3 -m "$BACKUP" "$BASE" "$OTHER" > "$LOCAL" && success
    84     $DIFF3 -m "$BACKUP" "$BASE" "$OTHER" > "$LOCAL" && success
   101     fi
    85     if [ $? -eq 2 ]; then
   102     if [ $? -gt 1 ]; then
    86         echo "$DIFF3 failed! Exiting." 1>&2
   103         echo "automatic merge failed! Exiting." 1>&2
    87         cp "$BACKUP" "$LOCAL"
       
    88         failure
   104         failure
    89     fi
   105     fi
    90     cp "$BACKUP" "$LOCAL"
       
    91 fi
   106 fi
    92 
   107 
    93 # on MacOS X try FileMerge.app, shipped with Apple's developer tools
   108 # on MacOS X try FileMerge.app, shipped with Apple's developer tools
    94 if [ -n "$FILEMERGE" ]; then
   109 if [ -n "$FILEMERGE" ]; then
    95     cp "$BACKUP" "$LOCAL"
   110     cp "$BACKUP" "$LOCAL"
    96     cp "$BACKUP" "$CHGTEST"
   111     cp "$BACKUP" "$CHGTEST"
    97     # filemerge prefers the right by default
   112     # filemerge prefers the right by default
    98     $FILEMERGE -left "$OTHER" -right "$LOCAL" -ancestor "$BASE" -merge "$LOCAL"
   113     $FILEMERGE -left "$OTHER" -right "$LOCAL" -ancestor "$BASE" -merge "$LOCAL"
    99     [ $? -ne 0 ] && echo "FileMerge failed to launch" && failure
   114     [ $? -ne 0 ] && echo "FileMerge failed to launch" && failure
   100     if test "$LOCAL" -nt "$CHGTEST"
   115     test "$LOCAL" -nt "$CHGTEST" && success || ask_if_merged
   101     then
       
   102         success
       
   103     else
       
   104         echo "$LOCAL seems unchanged. Was the merge successful?"
       
   105         select answer in yes no
       
   106         do
       
   107             test "$answer" == "yes" && success || failure
       
   108         done
       
   109     fi
       
   110     failure
       
   111 fi
   116 fi
   112 
   117 
   113 if [ -n "$DISPLAY" ]; then
   118 if [ -n "$DISPLAY" ]; then
   114     # try using kdiff3, which is fairly nice
   119     # try using kdiff3, which is fairly nice
   115     if [ -n "$KDIFF3" ]; then
   120     if [ -n "$KDIFF3" ]; then
   116 	$KDIFF3 --auto "$BASE" "$LOCAL" "$OTHER" -o "$LOCAL" || failure
   121         $KDIFF3 --auto "$BASE" "$BACKUP" "$OTHER" -o "$LOCAL" || failure
   117 	success
   122         success
   118     fi
   123     fi
   119 
   124 
   120     # try using tkdiff, which is a bit less sophisticated
   125     # try using tkdiff, which is a bit less sophisticated
   121     if [ -n "$TKDIFF" ]; then
   126     if [ -n "$TKDIFF" ]; then
   122 	$TKDIFF "$LOCAL" "$OTHER" -a "$BASE" -o "$LOCAL" || failure
   127         $TKDIFF "$BACKUP" "$OTHER" -a "$BASE" -o "$LOCAL" || failure
   123 	success
   128         success
       
   129     fi
       
   130 
       
   131     if [ -n "$MELD" ]; then
       
   132         cp "$BACKUP" "$CHGTEST"
       
   133         # protect our feet - meld allows us to save to the left file
       
   134         cp "$BACKUP" "$LOCAL.tmp.$RAND"
       
   135         # Meld doesn't have automatic merging, so to reduce intervention
       
   136         # use the file with conflicts
       
   137         $MELD "$LOCAL.tmp.$RAND" "$LOCAL" "$OTHER" || failure
       
   138         # Also it doesn't return good error code
       
   139         test "$LOCAL" -nt "$CHGTEST" && success || ask_if_merged
   124     fi
   140     fi
   125 fi
   141 fi
   126 
   142 
   127 # Attempt to do a merge with $EDITOR
   143 # Attempt to do a merge with $EDITOR
   128 if [ -n "$MERGE" ]; then
   144 if [ -n "$MERGE" -o -n "$DIFF3" ]; then
   129     echo "conflicts detected in $LOCAL"
   145     echo "conflicts detected in $LOCAL"
   130     $MERGE "$LOCAL" "$BASE" "$OTHER" 2>/dev/null || $EDITOR "$LOCAL"
   146     cp "$BACKUP" "$CHGTEST"
   131     success
   147     $EDITOR "$LOCAL" || failure
   132 fi
   148     # Some editors do not return meaningful error codes
   133 
   149     # Do not take any chances
   134 if [ -n "$DIFF3" ]; then
   150     test "$LOCAL" -nt "$CHGTEST" && success || ask_if_merged
   135     echo "conflicts detected in $LOCAL"
       
   136     $DIFF3 -m "$BACKUP" "$BASE" "$OTHER" > "$LOCAL" || {
       
   137         case $? in
       
   138             1)
       
   139                 $EDITOR "$LOCAL" ;;
       
   140             2)  echo "$DIFF3 failed! Exiting." 1>&2
       
   141                 cp "$BACKUP" "$LOCAL"
       
   142                 failure ;;
       
   143         esac
       
   144         success
       
   145     }
       
   146 fi
   151 fi
   147 
   152 
   148 # attempt to manually merge with diff and patch
   153 # attempt to manually merge with diff and patch
   149 if [ -n "$DIFF" -a -n "$PATCH" ]; then
   154 if [ -n "$DIFF" -a -n "$PATCH" ]; then
   150 
   155 
   151     (umask 077 && mkdir "$HGTMP") || {
   156     (umask 077 && mkdir "$HGTMP") || {
   152 	echo "Could not create temporary directory $HGTMP" 1>&2
   157         echo "Could not create temporary directory $HGTMP" 1>&2
   153 	failure
   158         failure
   154     }
   159     }
   155 
   160 
   156     $DIFF -u "$BASE" "$OTHER" > "$HGTMP/diff" || :
   161     $DIFF -u "$BASE" "$OTHER" > "$HGTMP/diff" || :
   157     if $PATCH "$LOCAL" < "$HGTMP/diff"; then
   162     if $PATCH "$LOCAL" < "$HGTMP/diff"; then
   158 	success
   163         success
   159     else
   164     else
   160 	# If rejects are empty after using the editor, merge was ok
   165         # If rejects are empty after using the editor, merge was ok
   161 	$EDITOR "$LOCAL" "$LOCAL.rej" && test -s "$LOCAL.rej" || success
   166         $EDITOR "$LOCAL" "$LOCAL.rej" || failure
       
   167         test -s "$LOCAL.rej" || success
   162     fi
   168     fi
   163     failure
   169     failure
   164 fi
   170 fi
   165 
   171 
   166 echo "hgmerge: unable to find merge, tkdiff, kdiff3, or diff+patch!"
   172 echo
       
   173 echo "hgmerge: unable to find any merge utility!"
       
   174 echo "supported programs:"
       
   175 echo "merge, FileMerge, tkdiff, kdiff3, meld, diff+patch"
       
   176 echo
   167 failure
   177 failure