diff-delta.c: Rationalize culling of hash buckets
[gitweb.git] / git-rebase--interactive.sh
index ac1f5a2d3f5c1bd706989b58d0e381821da05062..abc2b1c3e06bf1904ed92a691e917e8718e9e299 100755 (executable)
@@ -17,7 +17,7 @@ USAGE='(--continue | --abort | --skip | [--preserve-merges] [--verbose]
 require_work_tree
 
 DOTEST="$GIT_DIR/.dotest-merge"
-TODO="$DOTEST"/todo
+TODO="$DOTEST"/git-rebase-todo
 DONE="$DOTEST"/done
 MSG="$DOTEST"/message
 SQUASH_MSG="$DOTEST"/message-squash
@@ -96,13 +96,14 @@ die_abort () {
 }
 
 pick_one () {
-       case "$1" in -n) sha1=$2 ;; *) sha1=$1 ;; esac
+       no_ff=
+       case "$1" in -n) sha1=$2; no_ff=t ;; *) sha1=$1 ;; esac
        output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
        test -d "$REWRITTEN" &&
                pick_one_preserving_merges "$@" && return
        parent_sha1=$(git rev-parse --verify $sha1^ 2>/dev/null)
        current_sha1=$(git rev-parse --verify HEAD)
-       if [ $current_sha1 = $parent_sha1 ]; then
+       if test $no_ff$current_sha1 = $parent_sha1; then
                output git reset --hard $sha1
                test "a$1" = a-n && output git reset --soft $current_sha1
                sha1=$(git rev-parse --short $sha1)
@@ -116,7 +117,7 @@ pick_one_preserving_merges () {
        case "$1" in -n) sha1=$2 ;; *) sha1=$1 ;; esac
        sha1=$(git rev-parse $sha1)
 
-       if [ -f "$DOTEST"/current-commit ]
+       if test -f "$DOTEST"/current-commit
        then
                current_commit=$(cat "$DOTEST"/current-commit) &&
                git rev-parse HEAD > "$REWRITTEN"/$current_commit &&
@@ -130,7 +131,7 @@ pick_one_preserving_merges () {
        new_parents=
        for p in $(git rev-list --parents -1 $sha1 | cut -d\  -f2-)
        do
-               if [ -f "$REWRITTEN"/$p ]
+               if test -f "$REWRITTEN"/$p
                then
                        preserve=f
                        new_p=$(cat "$REWRITTEN"/$p)
@@ -188,8 +189,8 @@ nth_string () {
 }
 
 make_squash_message () {
-       if [ -f "$SQUASH_MSG" ]; then
-               COUNT=$(($(sed -n "s/^# This is [^0-9]*\([0-9]\+\).*/\1/p" \
+       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))
                echo "# This is a combination of $COUNT commits."
                sed -n "2,\$p" < "$SQUASH_MSG"
@@ -250,16 +251,18 @@ do_next () {
                case "$(peek_next_command)" in
                squash)
                        EDIT_COMMIT=
+                       USE_OUTPUT=output
                        cp "$MSG" "$SQUASH_MSG"
                ;;
                *)
                        EDIT_COMMIT=-e
+                       USE_OUTPUT=
                        test -f "$SQUASH_MSG" && rm "$SQUASH_MSG"
                esac
 
                failed=f
-               pick_one -n $sha1 || failed=t
                output git reset --soft HEAD^
+               pick_one -n $sha1 || failed=t
                author_script=$(get_author_ident_from_commit $sha1)
                echo "$author_script" > "$DOTEST"/author-script
                case $failed in
@@ -267,7 +270,7 @@ do_next () {
                        # This is like --amend, but with a different message
                        eval "$author_script"
                        export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
-                       output git commit -F "$MSG" $EDIT_COMMIT
+                       $USE_OUTPUT git commit -F "$MSG" $EDIT_COMMIT
                        ;;
                t)
                        cp "$MSG" "$GIT_DIR"/MERGE_MSG
@@ -286,7 +289,7 @@ do_next () {
        HEADNAME=$(cat "$DOTEST"/head-name) &&
        OLDHEAD=$(cat "$DOTEST"/head) &&
        SHORTONTO=$(git rev-parse --short $(cat "$DOTEST"/onto)) &&
-       if [ -d "$REWRITTEN" ]
+       if test -d "$REWRITTEN"
        then
                test -f "$DOTEST"/current-commit &&
                        current_commit=$(cat "$DOTEST"/current-commit) &&
@@ -403,7 +406,8 @@ do
 
                require_clean_work_tree
 
-               if [ ! -z "$2"]
+               mkdir "$DOTEST" || die "Could not create temporary $DOTEST"
+               if test ! -z "$2"
                then
                        output git show-ref --verify --quiet "refs/heads/$2" ||
                                die "Invalid branchname: $2"
@@ -416,7 +420,6 @@ do
 
                test -z "$ONTO" && ONTO=$UPSTREAM
 
-               mkdir "$DOTEST" || die "Could not create temporary $DOTEST"
                : > "$DOTEST"/interactive || die "Could not mark as interactive"
                git symbolic-ref HEAD > "$DOTEST"/head-name ||
                        die "Could not get HEAD"
@@ -426,7 +429,7 @@ do
                echo $ONTO > "$DOTEST"/onto
                test -z "$STRATEGY" || echo "$STRATEGY" > "$DOTEST"/strategy
                test t = "$VERBOSE" && : > "$DOTEST"/verbose
-               if [ t = "$PRESERVE_MERGES" ]
+               if test t = "$PRESERVE_MERGES"
                then
                        # $REWRITTEN contains files for each commit that is
                        # reachable by at least one merge base of $HEAD and
@@ -461,8 +464,9 @@ do
 #
 EOF
                git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \
-                       --abbrev=7 --reverse $UPSTREAM..$HEAD | \
-                       sed "s/^/pick /" >> "$TODO"
+                       --abbrev=7 --reverse --left-right --cherry-pick \
+                       $UPSTREAM...$HEAD | \
+                       sed -n "s/^>/pick /p" >> "$TODO"
 
                test -z "$(grep -ve '^$' -e '^#' < $TODO)" &&
                        die_abort "Nothing to do"