Code

Merge branch 'jk/maint-1.6.5-reset-hard' into maint-1.6.5
[git.git] / git-rebase--interactive.sh
index 3dc659dd5896ce6c887eb786718919aef82f4ac6..5014ae0579753a09d0c52742d0d0ddb8db5ac8c9 100755 (executable)
@@ -106,8 +106,8 @@ mark_action_done () {
        sed -e 1q < "$TODO" >> "$DONE"
        sed -e 1d < "$TODO" >> "$TODO".new
        mv -f "$TODO".new "$TODO"
-       count=$(grep -c '^[^#]' < "$DONE")
-       total=$(($count+$(grep -c '^[^#]' < "$TODO")))
+       count=$(sane_grep -c '^[^#]' < "$DONE")
+       total=$(($count+$(sane_grep -c '^[^#]' < "$TODO")))
        if test "$last_count" != "$count"
        then
                last_count=$count
@@ -147,7 +147,7 @@ die_abort () {
 }
 
 has_action () {
-       grep '^[^#]' "$1" >/dev/null
+       sane_grep '^[^#]' "$1" >/dev/null
 }
 
 pick_one () {
@@ -408,7 +408,12 @@ do_next () {
                ;;
        *)
                warn "Unknown command: $command $sha1 $rest"
-               die_with_patch $sha1 "Please fix this in the file $TODO."
+               if git rev-parse --verify -q "$sha1" >/dev/null
+               then
+                       die_with_patch $sha1 "Please fix this in the file $TODO."
+               else
+                       die "Please fix this in the file $TODO."
+               fi
                ;;
        esac
        test -s "$TODO" && return
@@ -420,7 +425,7 @@ do_next () {
        NEWHEAD=$(git rev-parse HEAD) &&
        case $HEADNAME in
        refs/*)
-               message="$GIT_REFLOG_ACTION: $HEADNAME onto $SHORTONTO)" &&
+               message="$GIT_REFLOG_ACTION: $HEADNAME onto $SHORTONTO" &&
                git update-ref -m "$message" $HEADNAME $NEWHEAD $OLDHEAD &&
                git symbolic-ref HEAD $HEADNAME
                ;;
@@ -442,6 +447,30 @@ do_rest () {
        done
 }
 
+# skip picking commits whose parents are unchanged
+skip_unnecessary_picks () {
+       fd=3
+       while read command sha1 rest
+       do
+               # fd=3 means we skip the command
+               case "$fd,$command,$(git rev-parse --verify --quiet $sha1^)" in
+               3,pick,"$ONTO"*|3,p,"$ONTO"*)
+                       # pick a commit whose parent is current $ONTO -> skip
+                       ONTO=$sha1
+                       ;;
+               3,#*|3,,*)
+                       # copy comments
+                       ;;
+               *)
+                       fd=1
+                       ;;
+               esac
+               echo "$command${sha1:+ }$sha1${rest:+ }$rest" >&$fd
+       done <"$TODO" >"$TODO.new" 3>>"$DONE" &&
+       mv -f "$TODO".new "$TODO" ||
+       die "Could not skip unnecessary pick commands"
+}
+
 # check if no other options are set
 is_standalone () {
        test $# -eq 2 -a "$2" = '--' &&
@@ -679,7 +708,7 @@ first and then run 'git rebase --continue' again."
                                        preserve=t
                                        for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
                                        do
-                                               if test -f "$REWRITTEN"/$p -a \( $p != $UPSTREAM -o $sha1 = $first_after_upstream \)
+                                               if test -f "$REWRITTEN"/$p -a \( $p != $ONTO -o $sha1 = $first_after_upstream \)
                                                then
                                                        preserve=f
                                                fi
@@ -707,7 +736,7 @@ first and then run 'git rebase --continue' again."
                        git rev-list $REVISIONS |
                        while read rev
                        do
-                               if test -f "$REWRITTEN"/$rev -a "$(grep "$rev" "$DOTEST"/not-cherry-picks)" = ""
+                               if test -f "$REWRITTEN"/$rev -a "$(sane_grep "$rev" "$DOTEST"/not-cherry-picks)" = ""
                                then
                                        # Use -f2 because if rev-list is telling us this commit is
                                        # not worthwhile, we don't want to track its multiple heads,
@@ -715,7 +744,7 @@ first and then run 'git rebase --continue' again."
                                        # be rebasing on top of it
                                        git rev-list --parents -1 $rev | cut -d' ' -s -f2 > "$DROPPED"/$rev
                                        short=$(git rev-list -1 --abbrev-commit --abbrev=7 $rev)
-                                       grep -v "^[a-z][a-z]* $short" <"$TODO" > "${TODO}2" ; mv "${TODO}2" "$TODO"
+                                       sane_grep -v "^[a-z][a-z]* $short" <"$TODO" > "${TODO}2" ; mv "${TODO}2" "$TODO"
                                        rm "$REWRITTEN"/$rev
                                fi
                        done
@@ -741,11 +770,13 @@ EOF
 
                cp "$TODO" "$TODO".backup
                git_editor "$TODO" ||
-                       die "Could not execute editor"
+                       die_abort "Could not execute editor"
 
                has_action "$TODO" ||
                        die_abort "Nothing to do"
 
+               test -d "$REWRITTEN" || skip_unnecessary_picks
+
                git update-ref ORIG_HEAD $HEAD
                output git checkout $ONTO && do_rest
                ;;