ls-remote: fall-back to default remotes when no remote specified
[gitweb.git] / git-rebase--interactive.sh
index d72f549f61258e81f9a1be305441402f276c35ab..b817c4a76e54c31f5a21d8196729f0cfb31997cf 100755 (executable)
@@ -20,6 +20,7 @@ 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
+no-ff              cherry-pick all commits, even if unchanged
 m,merge            always used (no-op)
 i,interactive      always used (no-op)
  Actions:
@@ -110,6 +111,7 @@ VERBOSE=
 OK_TO_SKIP_PRE_REBASE=
 REBASE_ROOT=
 AUTOSQUASH=
+NEVER_FF=
 
 GIT_CHERRY_PICK_HELP="  After resolving the conflicts,
 mark the corrected paths with 'git add <paths>', and
@@ -223,15 +225,16 @@ has_action () {
 # Run command with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
 # GIT_AUTHOR_DATE exported from the current environment.
 do_with_author () {
-       GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" \
-       GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \
-       GIT_AUTHOR_DATE="$GIT_AUTHOR_DATE" \
-       "$@"
+       (
+               export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
+               "$@"
+       )
 }
 
 pick_one () {
-       no_ff=
-       case "$1" in -n) sha1=$2; no_ff=t ;; *) sha1=$1 ;; esac
+       ff=--ff
+       case "$1" in -n) sha1=$2; ff= ;; *) sha1=$1 ;; esac
+       case "$NEVER_FF" in '') ;; ?*) ff= ;; esac
        output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
        test -d "$REWRITTEN" &&
                pick_one_preserving_merges "$@" && return
@@ -240,16 +243,7 @@ pick_one () {
                output git cherry-pick "$@"
                return
        fi
-       parent_sha1=$(git rev-parse --verify $sha1^) ||
-               die "Could not get the parent of $sha1"
-       current_sha1=$(git rev-parse --verify HEAD)
-       if test -z "$no_ff" && test "$current_sha1" = "$parent_sha1"
-       then
-               output git reset --hard $sha1
-               output warn Fast-forward to $(git rev-parse --short $sha1)
-       else
-               output git cherry-pick "$@"
-       fi
+       output git cherry-pick $ff "$@"
 }
 
 pick_one_preserving_merges () {
@@ -387,7 +381,7 @@ update_squash_messages () {
                        sed -e 1d -e '2,/^./{
                                /^$/d
                        }' <"$SQUASH_MSG".bak
-               } >$SQUASH_MSG
+               } >"$SQUASH_MSG"
        else
                commit_message HEAD > "$FIXUP_MSG" || die "Cannot write $FIXUP_MSG"
                COUNT=2
@@ -396,7 +390,7 @@ update_squash_messages () {
                        echo "# The first commit's message is:"
                        echo
                        cat "$FIXUP_MSG"
-               } >$SQUASH_MSG
+               } >"$SQUASH_MSG"
        fi
        case $1 in
        squash)
@@ -412,11 +406,11 @@ update_squash_messages () {
                echo
                commit_message $2 | sed -e 's/^/#       /'
                ;;
-       esac >>$SQUASH_MSG
+       esac >>"$SQUASH_MSG"
 }
 
 peek_next_command () {
-       sed -n -e "/^#/d" -e "/^$/d" -e "s/ .*//p" -e "q" < "$TODO"
+       sed -n -e "/^#/d" -e '/^$/d' -e "s/ .*//p" -e "q" < "$TODO"
 }
 
 # A squash/fixup has failed.  Prepare the long version of the squash
@@ -484,7 +478,7 @@ do_next () {
                mark_action_done
                pick_one $sha1 ||
                        die_with_patch $sha1 "Could not apply $sha1... $rest"
-               echo "$1" > "$DOTEST"/stopped-sha
+               echo "$sha1" > "$DOTEST"/stopped-sha
                make_patch $sha1
                git rev-parse --verify HEAD > "$AMEND"
                warn "Stopped at $sha1... $rest"
@@ -570,6 +564,10 @@ do_next () {
                test ! -f "$DOTEST"/verbose ||
                        git diff-tree --stat $(cat "$DOTEST"/head)..HEAD
        } &&
+       {
+               git notes copy --for-rewrite=rebase < "$REWRITTEN_LIST" ||
+               true # we don't care if this copying failed
+       } &&
        if test -x "$GIT_DIR"/hooks/post-rewrite &&
                test -s "$REWRITTEN_LIST"; then
                "$GIT_DIR"/hooks/post-rewrite rebase < "$REWRITTEN_LIST"
@@ -728,9 +726,10 @@ first and then run 'git rebase --continue' again."
                                test -n "$amend" && git reset --soft $amend
                                die "Could not commit staged changes."
                        }
-                       record_in_rewritten "$(cat "$DOTEST"/stopped-sha)"
                fi
 
+               record_in_rewritten "$(cat "$DOTEST"/stopped-sha)"
+
                require_clean_work_tree
                do_rest
                ;;
@@ -786,6 +785,9 @@ first and then run 'git rebase --continue' again."
        -i)
                # yeah, we know
                ;;
+       --no-ff)
+               NEVER_FF=t
+               ;;
        --root)
                REBASE_ROOT=t
                ;;
@@ -827,8 +829,6 @@ first and then run 'git rebase --continue' again."
 
                if test ! -z "$1"
                then
-                       output git show-ref --verify --quiet "refs/heads/$1" ||
-                               die "Invalid branchname: $1"
                        output git checkout "$1" ||
                                die "Could not checkout $1"
                fi
@@ -971,7 +971,7 @@ EOF
                has_action "$TODO" ||
                        die_abort "Nothing to do"
 
-               test -d "$REWRITTEN" || skip_unnecessary_picks
+               test -d "$REWRITTEN" || test -n "$NEVER_FF" || skip_unnecessary_picks
 
                git update-ref ORIG_HEAD $HEAD
                output git checkout $ONTO && do_rest