diff-format.txt: Combined diff format documentation supplement
[gitweb.git] / git-merge.sh
index b834e79c98af51a9f3ad4927a2d11c999349b0e4..789f4de595d2657c9c348b4d52b47e2c42543ad2 100755 (executable)
@@ -3,14 +3,13 @@
 # Copyright (c) 2005 Junio C Hamano
 #
 
-
-USAGE='[-n] [--no-commit] [-s <strategy>]... <merge-message> <head> <remote>+'
+USAGE='[-n] [--no-commit] [--squash] [-s <strategy>]... <merge-message> <head> <remote>+'
 . git-sh-setup
 
 LF='
 '
 
-all_strategies='recursive octopus resolve stupid ours'
+all_strategies='recur recursive recursive-old octopus resolve stupid ours'
 default_twohead_strategies='recursive'
 default_octopus_strategies='octopus'
 no_trivial_merge_strategies='ours'
@@ -18,8 +17,7 @@ use_strategies=
 
 index_merge=t
 if test "@@NO_PYTHON@@"; then
-       all_strategies='resolve octopus stupid ours'
-       default_twohead_strategies='resolve'
+       all_strategies='recur recursive resolve octopus stupid ours'
 fi
 
 dropsave() {
@@ -42,31 +40,70 @@ restorestate() {
        fi
 }
 
-finish () {
-       test '' = "$2" || echo "$2"
-       case "$merge_msg" in
+finish_up_to_date () {
+       case "$squash" in
+       t)
+               echo "$1 (nothing to squash)" ;;
        '')
-               echo "No merge message -- not updating HEAD"
+               echo "$1" ;;
+       esac
+       dropsave
+}
+
+squash_message () {
+       echo Squashed commit of the following:
+       echo
+       git-log --no-merges ^"$head" $remote
+}
+
+finish () {
+       if test '' = "$2"
+       then
+               rlogm="$rloga"
+       else
+               echo "$2"
+               rlogm="$rloga: $2"
+       fi
+       case "$squash" in
+       t)
+               echo "Squash commit -- not updating HEAD"
+               squash_message >"$GIT_DIR/SQUASH_MSG"
                ;;
-       *)
-               git-update-ref HEAD "$1" "$head" || exit 1
+       '')
+               case "$merge_msg" in
+               '')
+                       echo "No merge message -- not updating HEAD"
+                       ;;
+               *)
+                       git-update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1
+                       ;;
+               esac
                ;;
        esac
-
-       case "$no_summary" in
+       case "$1" in
        '')
-               git-diff-tree -p -M "$head" "$1" |
-               git-apply --stat --summary
+               ;;
+       ?*)
+               case "$no_summary" in
+               '')
+                       git-diff-tree --stat --summary -M "$head" "$1"
+                       ;;
+               esac
                ;;
        esac
 }
 
+case "$#" in 0) usage ;; esac
+
+rloga=
 while case "$#" in 0) break ;; esac
 do
        case "$1" in
        -n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
                --no-summa|--no-summar|--no-summary)
                no_summary=t ;;
+       --sq|--squ|--squa|--squas|--squash)
+               squash=t no_commit=t ;;
        --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
                no_commit=t ;;
        -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
@@ -74,7 +111,7 @@ do
        -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
                case "$#,$1" in
                *,*=*)
-                       strategy=`expr "$1" : '-[^=]*=\(.*\)'` ;;
+                       strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
                1,*)
                        usage ;;
                *)
@@ -88,6 +125,9 @@ do
                        die "available strategies are: $all_strategies" ;;
                esac
                ;;
+       --reflog-action=*)
+               rloga=`expr "z$1" : 'z-[^=]*=\(.*\)'`
+               ;;
        -*)     usage ;;
        *)      break ;;
        esac
@@ -102,6 +142,7 @@ shift
 
 # All the rest are remote heads
 test "$#" = 0 && usage ;# we need at least one remote head.
+test "$rloga" = '' && rloga="merge: $@"
 
 remoteheads=
 for remote
@@ -153,8 +194,7 @@ f,*)
 ?,1,"$1",*)
        # If head can reach all the merge then we are up to date.
        # but first the most common case of merging one remote.
-       echo "Already up-to-date."
-       dropsave
+       finish_up_to_date "Already up-to-date."
        exit 0
        ;;
 ?,1,"$head",*)
@@ -206,8 +246,7 @@ f,*)
        done
        if test "$up_to_date" = t
        then
-               echo "Already up-to-date. Yeeah!"
-               dropsave
+               finish_up_to_date "Already up-to-date. Yeeah!"
                exit 0
        fi
        ;;
@@ -289,7 +328,7 @@ if test '' != "$result_tree"
 then
     parents=$(git-show-branch --independent "$head" "$@" | sed -e 's/^/-p /')
     result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents) || exit
-    finish "$result_commit" "Merge $result_commit, made by $wt_strategy."
+    finish "$result_commit" "Merge made by $wt_strategy."
     dropsave
     exit 0
 fi
@@ -311,11 +350,17 @@ case "$best_strategy" in
        git-merge-$best_strategy $common -- "$head_arg" "$@"
        ;;
 esac
-for remote
-do
-       echo $remote
-done >"$GIT_DIR/MERGE_HEAD"
-echo "$merge_msg" >"$GIT_DIR/MERGE_MSG"
+
+if test "$squash" = t
+then
+       finish
+else
+       for remote
+       do
+               echo $remote
+       done >"$GIT_DIR/MERGE_HEAD"
+       echo "$merge_msg" >"$GIT_DIR/MERGE_MSG"
+fi
 
 if test "$merge_was_ok" = t
 then