grep with unmerged index
[gitweb.git] / git-rebase--interactive.sh
index c9873114991ecfc90fe472b0565aad7022eaa1ff..f28c3df204214f691de87cb48c513f1eb5d767e6 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
@@ -78,7 +78,7 @@ mark_action_done () {
 
 make_patch () {
        parent_sha1=$(git rev-parse --verify "$1"^ 2> /dev/null)
-       git diff "$parent_sha1".."$1" > "$DOTEST"/patch
+       git diff-tree -p "$parent_sha1".."$1" > "$DOTEST"/patch
 }
 
 die_with_patch () {
@@ -96,19 +96,20 @@ 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 test $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)
                output warn Fast forward to $sha1
        else
-               output git cherry-pick $STRATEGY "$@"
+               output git cherry-pick "$@"
        fi
 }
 
@@ -164,6 +165,8 @@ pick_one_preserving_merges () {
                        eval "$author_script"
                        msg="$(git cat-file commit $sha1 | \
                                sed -e '1,/^$/d' -e "s/[\"\\]/\\\\&/g")"
+                       # No point in merging the first parent, that's HEAD
+                       new_parents=${new_parents# $first_parent}
                        # NEEDSWORK: give rerere a chance
                        if ! output git merge $STRATEGY -m "$msg" $new_parents
                        then
@@ -172,7 +175,7 @@ pick_one_preserving_merges () {
                        fi
                        ;;
                *)
-                       output git cherry-pick $STRATEGY "$@" ||
+                       output git cherry-pick "$@" ||
                                die_with_patch $sha1 "Could not pick $sha1"
                esac
        esac
@@ -189,7 +192,7 @@ nth_string () {
 
 make_squash_message () {
        if test -f "$SQUASH_MSG"; then
-               COUNT=$(($(sed -n "s/^# This is [^0-9]*\([0-9]\+\).*/\1/p" \
+               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"
@@ -260,9 +263,9 @@ do_next () {
                esac
 
                failed=f
+               author_script=$(get_author_ident_from_commit HEAD)
                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
                f)
@@ -301,7 +304,7 @@ do_next () {
        git update-ref -m "$message" $HEADNAME $NEWHEAD $OLDHEAD &&
        git symbolic-ref HEAD $HEADNAME && {
                test ! -f "$DOTEST"/verbose ||
-                       git diff --stat $(cat "$DOTEST"/head)..HEAD
+                       git diff-tree --stat $(cat "$DOTEST"/head)..HEAD
        } &&
        rm -rf "$DOTEST" &&
        warn "Successfully rebased and updated $HEADNAME."
@@ -316,7 +319,7 @@ do_rest () {
        done
 }
 
-while case $# in 0) break ;; esac
+while test $# != 0
 do
        case "$1" in
        --continue)
@@ -356,7 +359,6 @@ do
                output git reset --hard && do_rest
                ;;
        -s|--strategy)
-               shift
                case "$#,$1" in
                *,*=*)
                        STRATEGY="-s `expr "z$1" : 'z-[^=]*=\(.*\)'`" ;;
@@ -405,6 +407,7 @@ do
 
                require_clean_work_tree
 
+               mkdir "$DOTEST" || die "Could not create temporary $DOTEST"
                if test ! -z "$2"
                then
                        output git show-ref --verify --quiet "refs/heads/$2" ||
@@ -418,7 +421,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"
@@ -463,8 +465,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"