rev-list: documentation and test for --left/right-only
[gitweb.git] / git-rebase--interactive.sh
index 4d8a2a0e4e2b6f5f70e75269dde082d13838b5f2..5873ba4bc3b2a94cd7754ae572072fd745dc059d 100755 (executable)
@@ -28,6 +28,7 @@ continue           continue rebasing process
 abort              abort rebasing process and restore original branch
 skip               skip current patch and continue rebasing process
 no-verify          override pre-rebase hook from stopping the operation
+verify             allow pre-rebase hook to run
 root               rebase all reachable commmits up to the root(s)
 autosquash         move commits that begin with squash!/fixup! under -i
 "
@@ -667,9 +668,27 @@ get_saved_options () {
 # comes immediately after the former, and change "pick" to
 # "fixup"/"squash".
 rearrange_squash () {
-       sed -n -e 's/^pick \([0-9a-f]*\) \(squash\)! /\1 \2 /p' \
-               -e 's/^pick \([0-9a-f]*\) \(fixup\)! /\1 \2 /p' \
-               "$1" >"$1.sq"
+       # extract fixup!/squash! lines and resolve any referenced sha1's
+       while read -r pick sha1 message
+       do
+               case "$message" in
+               "squash! "*|"fixup! "*)
+                       action="${message%%!*}"
+                       rest="${message#*! }"
+                       echo "$sha1 $action $rest"
+                       # if it's a single word, try to resolve to a full sha1 and
+                       # emit a second copy. This allows us to match on both message
+                       # and on sha1 prefix
+                       if test "${rest#* }" = "$rest"; then
+                               fullsha="$(git rev-parse -q --verify "$rest" 2>/dev/null)"
+                               if test -n "$fullsha"; then
+                                       # prefix the action to uniquely identify this line as
+                                       # intended for full sha1 match
+                                       echo "$sha1 +$action $fullsha"
+                               fi
+                       fi
+               esac
+       done >"$1.sq" <"$1"
        test -s "$1.sq" || return
 
        used=
@@ -679,14 +698,26 @@ rearrange_squash () {
                *" $sha1 "*) continue ;;
                esac
                printf '%s\n' "$pick $sha1 $message"
+               used="$used$sha1 "
                while read -r squash action msg
                do
-                       case "$message" in
-                       "$msg"*)
+                       case " $used" in
+                       *" $squash "*) continue ;;
+                       esac
+                       emit=0
+                       case "$action" in
+                       +*)
+                               action="${action#+}"
+                               # full sha1 prefix test
+                               case "$msg" in "$sha1"*) emit=1;; esac ;;
+                       *)
+                               # message prefix test
+                               case "$message" in "$msg"*) emit=1;; esac ;;
+                       esac
+                       if test $emit = 1; then
                                printf '%s\n' "$action $squash $action! $msg"
                                used="$used$squash "
-                               ;;
-                       esac
+                       fi
                done <"$1.sq"
        done >"$1.rearranged" <"$1"
        cat "$1.rearranged" >"$1"
@@ -719,6 +750,7 @@ do
                OK_TO_SKIP_PRE_REBASE=yes
                ;;
        --verify)
+               OK_TO_SKIP_PRE_REBASE=
                ;;
        --continue)
                is_standalone "$@" || usage
@@ -862,7 +894,7 @@ first and then run 'git rebase --continue' again."
 
                if test ! -z "$1"
                then
-                       output git checkout "$1" ||
+                       output git checkout "$1" -- ||
                                die "Could not checkout $1"
                fi
 
@@ -989,7 +1021,7 @@ first and then run 'git rebase --continue' again."
 #  e, edit = use commit, but stop for amending
 #  s, squash = use commit, but meld into previous commit
 #  f, fixup = like "squash", but discard this commit's log message
-#  x <cmd>, exec <cmd> = Run a shell command <cmd>, and stop if it fails
+#  x, exec = run command (the rest of the line) using shell
 #
 # If you remove a line here THAT COMMIT WILL BE LOST.
 # However, if you remove everything, the rebase will be aborted.