Merge branch 'ns/rebase-auto-squash'
authorJunio C Hamano <gitster@pobox.com>
Wed, 20 Jan 2010 22:42:04 +0000 (14:42 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 20 Jan 2010 22:42:04 +0000 (14:42 -0800)
* ns/rebase-auto-squash:
rebase -i --autosquash: auto-squash commits

Conflicts:
git-rebase--interactive.sh

1  2 
git-rebase--interactive.sh
index d0b59c96c4cba1cd645f834818b5d613ca059ca3,935e9e1b1cf9491c67fbb8ad0421b938bafb274f..2e56e64a179bb719e680fbefad1c7fc84fe13199
@@@ -28,6 -28,7 +28,7 @@@ abort              abort rebasing proce
  skip               skip current patch and continue rebasing process
  no-verify          override pre-rebase hook from stopping the operation
  root               rebase all reachable commmits up to the root(s)
+ autosquash         move commits that begin with squash!/fixup! under -i
  "
  
  . git-sh-setup
@@@ -46,6 -47,7 +47,7 @@@ ONTO
  VERBOSE=
  OK_TO_SKIP_PRE_REBASE=
  REBASE_ROOT=
+ AUTOSQUASH=
  
  GIT_CHERRY_PICK_HELP="  After resolving the conflicts,
  mark the corrected paths with 'git add <paths>', and
@@@ -338,7 -340,7 +340,7 @@@ make_squash_message () 
  }
  
  peek_next_command () {
 -      sed -n "1s/ .*$//p" < "$TODO"
 +      sed -n -e "/^#/d" -e "/^$/d" -e "s/ .*//p" -e "q" < "$TODO"
  }
  
  do_next () {
@@@ -519,25 -521,37 +521,56 @@@ get_saved_options () 
        test -f "$DOTEST"/rebase-root && REBASE_ROOT=t
  }
  
+ # Rearrange the todo list that has both "pick sha1 msg" and
+ # "pick sha1 fixup!/squash! msg" appears in it so that the latter
+ # comes immediately after the former, and change "pick" to
+ # "fixup"/"squash".
+ rearrange_squash () {
+       sed -n -e 's/^pick \([0-9a-f]*\) \(squash\)! /\1 \2 /p' \
+               -e 's/^pick \([0-9a-f]*\) \(fixup\)! /\1 \2 /p' \
+               "$1" >"$1.sq"
+       test -s "$1.sq" || return
+       used=
+       while read pick sha1 message
+       do
+               case " $used" in
+               *" $sha1 "*) continue ;;
+               esac
+               echo "$pick $sha1 $message"
+               while read squash action msg
+               do
+                       case "$message" in
+                       "$msg"*)
+                               echo "$action $squash $action! $msg"
+                               used="$used$squash "
+                               ;;
+                       esac
+               done <"$1.sq"
+       done >"$1.rearranged" <"$1"
+       cat "$1.rearranged" >"$1"
+       rm -f "$1.sq" "$1.rearranged"
+ }
 +LF='
 +'
 +parse_onto () {
 +      case "$1" in
 +      *...*)
 +              if      left=${1%...*} right=${1#*...} &&
 +                      onto=$(git merge-base --all ${left:-HEAD} ${right:-HEAD})
 +              then
 +                      case "$onto" in
 +                      ?*"$LF"?* | '')
 +                              exit 1 ;;
 +                      esac
 +                      echo "$onto"
 +                      exit 0
 +              fi
 +      esac
 +      git rev-parse --verify "$1^0"
 +}
 +
  while test $# != 0
  do
        case "$1" in
@@@ -643,9 -657,12 +676,12 @@@ first and then run 'git rebase --contin
        --root)
                REBASE_ROOT=t
                ;;
+       --autosquash)
+               AUTOSQUASH=t
+               ;;
        --onto)
                shift
 -              ONTO=$(git rev-parse --verify "$1") ||
 +              ONTO=$(parse_onto "$1") ||
                        die "Does not point to a valid commit: $1"
                ;;
        --)
                fi
  
                test -s "$TODO" || echo noop >> "$TODO"
+               test -n "$AUTOSQUASH" && rearrange_squash "$TODO"
                cat >> "$TODO" << EOF
  
  # Rebase $SHORTREVISIONS onto $SHORTONTO
@@@ -823,7 -841,7 +860,7 @@@ EO
  
                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"