]> asedeno.scripts.mit.edu Git - git.git/blobdiff - git-rebase--interactive.sh
shortlog: support --pretty=format: option
[git.git] / git-rebase--interactive.sh
index c2bedd622c7238359ab88592857bb50eeaa568f8..a35212d9de23e97055936b23dd8657a584116d76 100755 (executable)
 # The original idea comes from Eric W. Biederman, in
 # http://article.gmane.org/gmane.comp.version-control.git/22407
 
-USAGE='(--continue | --abort | --skip | [--preserve-merges] [--verbose]
-       [--onto <branch>] <upstream> [<branch>])'
+OPTIONS_KEEPDASHDASH=
+OPTIONS_SPEC="\
+git-rebase [-i] [options] [--] <upstream> [<branch>]
+git-rebase [-i] (--continue | --abort | --skip)
+--
+ Available options are
+v,verbose          display a diffstat of what changed upstream
+onto=              rebase onto given branch instead of upstream
+p,preserve-merges  try to recreate merges instead of ignoring them
+s,strategy=        use the given merge strategy
+m,merge            always used (no-op)
+i,interactive      always used (no-op)
+ Actions:
+continue           continue rebasing process
+abort              abort rebasing process and restore original branch
+skip               skip current patch and continue rebasing process
+"
 
-OPTIONS_SPEC=
 . git-sh-setup
 require_work_tree
 
@@ -25,10 +39,8 @@ SQUASH_MSG="$DOTEST"/message-squash
 REWRITTEN="$DOTEST"/rewritten
 PRESERVE_MERGES=
 STRATEGY=
+ONTO=
 VERBOSE=
-test -d "$REWRITTEN" && PRESERVE_MERGES=t
-test -f "$DOTEST"/strategy && STRATEGY="$(cat "$DOTEST"/strategy)"
-test -f "$DOTEST"/verbose && VERBOSE=t
 
 GIT_CHERRY_PICK_HELP="  After resolving the conflicts,
 mark the corrected paths with 'git add <paths>', and
@@ -56,9 +68,9 @@ output () {
 require_clean_work_tree () {
        # test if working tree is dirty
        git rev-parse --verify HEAD > /dev/null &&
-       git update-index --refresh &&
-       git diff-files --quiet &&
-       git diff-index --cached --quiet HEAD -- ||
+       git update-index --ignore-submodules --refresh &&
+       git diff-files --quiet --ignore-submodules &&
+       git diff-index --cached --quiet HEAD --ignore-submodules -- ||
        die "Working tree is dirty"
 }
 
@@ -78,8 +90,8 @@ mark_action_done () {
        sed -e 1q < "$TODO" >> "$DONE"
        sed -e 1d < "$TODO" >> "$TODO".new
        mv -f "$TODO".new "$TODO"
-       count=$(($(grep -ve '^$' -e '^#' < "$DONE" | wc -l)))
-       total=$(($count+$(grep -ve '^$' -e '^#' < "$TODO" | wc -l)))
+       count=$(grep -c '^[^#]' < "$DONE")
+       total=$(($count+$(grep -c '^[^#]' < "$TODO")))
        if test "$last_count" != "$count"
        then
                last_count=$count
@@ -110,7 +122,7 @@ die_abort () {
 }
 
 has_action () {
-       grep -vqe '^$' -e '^#' "$1"
+       grep '^[^#]' "$1" >/dev/null
 }
 
 pick_one () {
@@ -218,7 +230,7 @@ nth_string () {
 make_squash_message () {
        if test -f "$SQUASH_MSG"; then
                COUNT=$(($(sed -n "s/^# This is [^0-9]*\([1-9][0-9]*\).*/\1/p" \
-                       < "$SQUASH_MSG" | tail -n 1)+1))
+                       < "$SQUASH_MSG" | sed -ne '$p')+1))
                echo "# This is a combination of $COUNT commits."
                sed -e 1d -e '2,/^./{
                        /^$/d
@@ -366,10 +378,27 @@ do_rest () {
        done
 }
 
+# check if no other options are set
+is_standalone () {
+       test $# -eq 2 -a "$2" = '--' &&
+       test -z "$ONTO" &&
+       test -z "$PRESERVE_MERGES" &&
+       test -z "$STRATEGY" &&
+       test -z "$VERBOSE"
+}
+
+get_saved_options () {
+       test -d "$REWRITTEN" && PRESERVE_MERGES=t
+       test -f "$DOTEST"/strategy && STRATEGY="$(cat "$DOTEST"/strategy)"
+       test -f "$DOTEST"/verbose && VERBOSE=t
+}
+
 while test $# != 0
 do
        case "$1" in
        --continue)
+               is_standalone "$@" || usage
+               get_saved_options
                comment_for_reflog continue
 
                test -d "$DOTEST" || die "No interactive rebase running"
@@ -377,11 +406,12 @@ do
                # Sanity check
                git rev-parse --verify HEAD >/dev/null ||
                        die "Cannot read HEAD"
-               git update-index --refresh && git diff-files --quiet ||
+               git update-index --ignore-submodules --refresh &&
+                       git diff-files --quiet --ignore-submodules ||
                        die "Working tree is dirty"
 
                # do we have anything to commit?
-               if git diff-index --cached --quiet HEAD --
+               if git diff-index --cached --quiet --ignore-submodules HEAD --
                then
                        : Nothing to commit -- skip this
                else
@@ -401,6 +431,8 @@ do
                do_rest
                ;;
        --abort)
+               is_standalone "$@" || usage
+               get_saved_options
                comment_for_reflog abort
 
                git rerere clear
@@ -418,6 +450,8 @@ do
                exit
                ;;
        --skip)
+               is_standalone "$@" || usage
+               get_saved_options
                comment_for_reflog skip
 
                git rerere clear
@@ -425,7 +459,7 @@ do
 
                output git reset --hard && do_rest
                ;;
-       -s|--strategy)
+       -s)
                case "$#,$1" in
                *,*=*)
                        STRATEGY="-s "$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
@@ -436,25 +470,26 @@ do
                        shift ;;
                esac
                ;;
-       -m|--merge)
+       -m)
                # we use merge anyway
                ;;
-       -C*)
-               die "Interactive rebase uses merge, so $1 does not make sense"
-               ;;
-       -v|--verbose)
+       -v)
                VERBOSE=t
                ;;
-       -p|--preserve-merges)
+       -p)
                PRESERVE_MERGES=t
                ;;
-       -i|--interactive)
+       -i)
                # yeah, we know
                ;;
-       ''|-h)
-               usage
+       --onto)
+               shift
+               ONTO=$(git rev-parse --verify "$1") ||
+                       die "Does not point to a valid commit: $1"
                ;;
-       *)
+       --)
+               shift
+               test $# -eq 1 -o $# -eq 2 || usage
                test -d "$DOTEST" &&
                        die "Interactive rebase already started"
 
@@ -463,17 +498,11 @@ do
 
                comment_for_reflog start
 
-               ONTO=
-               case "$1" in
-               --onto)
-                       ONTO=$(git rev-parse --verify "$2") ||
-                               die "Does not point to a valid commit: $2"
-                       shift; shift
-                       ;;
-               esac
-
                require_clean_work_tree
 
+               UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
+               test -z "$ONTO" && ONTO=$UPSTREAM
+
                if test ! -z "$2"
                then
                        output git show-ref --verify --quiet "refs/heads/$2" ||
@@ -483,12 +512,8 @@ do
                fi
 
                HEAD=$(git rev-parse --verify HEAD) || die "No HEAD?"
-               UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
-
                mkdir "$DOTEST" || die "Could not create temporary $DOTEST"
 
-               test -z "$ONTO" && ONTO=$UPSTREAM
-
                : > "$DOTEST"/interactive || die "Could not mark as interactive"
                git symbolic-ref HEAD > "$DOTEST"/head-name 2> /dev/null ||
                        echo "detached HEAD" > "$DOTEST"/head-name
@@ -530,9 +555,9 @@ do
 # Rebase $SHORTUPSTREAM..$SHORTHEAD onto $SHORTONTO
 #
 # Commands:
-#  pick = use commit
-#  edit = use commit, but stop for amending
-#  squash = use commit, but meld into previous commit
+#  p, pick = use commit
+#  e, edit = use commit, but stop for amending
+#  s, squash = use commit, but meld into previous commit
 #
 # If you remove a line here THAT COMMIT WILL BE LOST.
 # However, if you remove everything, the rebase will be aborted.
@@ -549,6 +574,7 @@ EOF
                has_action "$TODO" ||
                        die_abort "Nothing to do"
 
+               git update-ref ORIG_HEAD $HEAD
                output git checkout $ONTO && do_rest
                ;;
        esac