Code

Merge branch 'mz/rebase' into pu
authorJunio C Hamano <gitster@pobox.com>
Mon, 31 Jan 2011 03:03:21 +0000 (19:03 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 31 Jan 2011 03:03:21 +0000 (19:03 -0800)
* mz/rebase: (31 commits)
  rebase -i: remove unnecessary state rebase-root
  rebase -i: don't read unused variable preserve_merges
  git-rebase--am: remove unnecessary --3way option
  rebase -m: don't print exit code 2 when merge fails
  rebase -m: remember allow_rerere_autoupdate option
  rebase: remember strategy and strategy options
  rebase: remember verbose option
  rebase: extract code for writing basic state
  rebase: factor out sub command handling
  rebase: make -v a tiny bit more verbose
  rebase -i: align variable names
  rebase: show consistent conflict resolution hint
  rebase: extract am code to new source file
  rebase: extract merge code to new source file
  rebase: remove $branch as synonym for $orig_head
  rebase -i: support --stat
  rebase: factor out call to pre-rebase hook
  rebase: factor out clean work tree check
  rebase: factor out reference parsing
  rebase: reorder validation steps
  ...

Conflicts:
git-rebase--interactive.sh

1  2 
.gitignore
Makefile
git-rebase--interactive.sh
git-rebase.sh

diff --cc .gitignore
Simple merge
diff --cc Makefile
Simple merge
index 5873ba4bc3b2a94cd7754ae572072fd745dc059d,a9f44d81f27d63696aa36ea2cd8fdb932cca133d..71b996b5d3e63660e5b5a2c8e9597acc7664383f
@@@ -724,294 -638,157 +638,157 @@@ rearrange_squash () 
        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
-       --no-verify)
-               OK_TO_SKIP_PRE_REBASE=yes
-               ;;
-       --verify)
-               OK_TO_SKIP_PRE_REBASE=
-               ;;
-       --continue)
-               is_standalone "$@" || usage
-               get_saved_options
-               comment_for_reflog continue
-               test -d "$DOTEST" || die "No interactive rebase running"
-               # Sanity check
-               git rev-parse --verify HEAD >/dev/null ||
-                       die "Cannot read HEAD"
-               git update-index --ignore-submodules --refresh &&
-                       git diff-files --quiet --ignore-submodules ||
-                       die "Working tree is dirty"
-               # do we have anything to commit?
-               if git diff-index --cached --quiet --ignore-submodules HEAD --
+ case "$action" in
+ continue)
+       # do we have anything to commit?
+       if git diff-index --cached --quiet --ignore-submodules HEAD --
+       then
+               : Nothing to commit -- skip this
+       else
+               . "$AUTHOR_SCRIPT" ||
+                       die "Cannot find the author identity"
+               amend=
+               if test -f "$AMEND"
                then
-                       : Nothing to commit -- skip this
-               else
-                       . "$AUTHOR_SCRIPT" ||
-                               die "Cannot find the author identity"
-                       amend=
-                       if test -f "$AMEND"
-                       then
-                               amend=$(git rev-parse --verify HEAD)
-                               test "$amend" = $(cat "$AMEND") ||
-                               die "\
+                       amend=$(git rev-parse --verify HEAD)
+                       test "$amend" = $(cat "$AMEND") ||
+                       die "\
  You have uncommitted changes in your working tree. Please, commit them
  first and then run 'git rebase --continue' again."
-                               git reset --soft HEAD^ ||
-                               die "Cannot rewind the HEAD"
-                       fi
-                       do_with_author git commit --no-verify -F "$MSG" -e || {
-                               test -n "$amend" && git reset --soft $amend
-                               die "Could not commit staged changes."
-                       }
+                       git reset --soft HEAD^ ||
+                       die "Cannot rewind the HEAD"
                fi
+               do_with_author git commit --no-verify -F "$MSG" -e || {
+                       test -n "$amend" && git reset --soft $amend
+                       die "Could not commit staged changes."
+               }
+       fi
  
-               record_in_rewritten "$(cat "$DOTEST"/stopped-sha)"
-               require_clean_work_tree "rebase"
-               do_rest
-               ;;
-       --abort)
-               is_standalone "$@" || usage
-               get_saved_options
-               comment_for_reflog abort
-               git rerere clear
-               test -d "$DOTEST" || die "No interactive rebase running"
-               HEADNAME=$(cat "$DOTEST"/head-name)
-               HEAD=$(cat "$DOTEST"/head)
-               case $HEADNAME in
-               refs/*)
-                       git symbolic-ref HEAD $HEADNAME
-                       ;;
-               esac &&
-               output git reset --hard $HEAD &&
-               rm -rf "$DOTEST"
-               exit
-               ;;
-       --skip)
-               is_standalone "$@" || usage
-               get_saved_options
-               comment_for_reflog skip
-               git rerere clear
-               test -d "$DOTEST" || die "No interactive rebase running"
-               output git reset --hard && do_rest
-               ;;
-       -s)
-               case "$#,$1" in
-               *,*=*)
-                       STRATEGY="-s "$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
-               1,*)
-                       usage ;;
-               *)
-                       STRATEGY="-s $2"
-                       shift ;;
-               esac
-               ;;
-       -m)
-               # we use merge anyway
-               ;;
-       -v)
-               VERBOSE=t
-               ;;
-       -p)
-               PRESERVE_MERGES=t
-               ;;
-       -i)
-               # yeah, we know
-               ;;
-       --no-ff)
-               NEVER_FF=t
-               ;;
-       --root)
-               REBASE_ROOT=t
-               ;;
-       --autosquash)
-               AUTOSQUASH=t
-               ;;
-       --no-autosquash)
-               AUTOSQUASH=
-               ;;
-       --onto)
-               shift
-               ONTO=$(parse_onto "$1") ||
-                       die "Does not point to a valid commit: $1"
-               ;;
-       --)
-               shift
-               test -z "$REBASE_ROOT" -a $# -ge 1 -a $# -le 2 ||
-               test ! -z "$REBASE_ROOT" -a $# -le 1 || usage
-               test -d "$DOTEST" &&
-                       die "Interactive rebase already started"
-               git var GIT_COMMITTER_IDENT >/dev/null ||
-                       die "You need to set your committer info first"
+       record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
  
-               if test -z "$REBASE_ROOT"
-               then
-                       UPSTREAM_ARG="$1"
-                       UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
-                       test -z "$ONTO" && ONTO=$UPSTREAM
-                       shift
-               else
-                       UPSTREAM=
-                       UPSTREAM_ARG=--root
-                       test -z "$ONTO" &&
-                               die "You must specify --onto when using --root"
-               fi
-               run_pre_rebase_hook "$UPSTREAM_ARG" "$@"
+       require_clean_work_tree "rebase"
+       do_rest
+       ;;
+ skip)
+       git rerere clear
  
-               comment_for_reflog start
+       do_rest
+       ;;
+ esac
  
-               require_clean_work_tree "rebase" "Please commit or stash them."
+ git var GIT_COMMITTER_IDENT >/dev/null ||
+       die "You need to set your committer info first"
  
-               if test ! -z "$1"
-               then
-                       output git checkout "$1" -- ||
-                               die "Could not checkout $1"
-               fi
+ comment_for_reflog start
  
              HEAD=$(git rev-parse --verify HEAD) || die "No HEAD?"
-               mkdir "$DOTEST" || die "Could not create temporary $DOTEST"
if test ! -z "$switch_to"
+ then
 -      output git checkout "$switch_to" ||
++      output git checkout "$switch_to" -- ||
+               die "Could not checkout $switch_to"
+ fi
  
-               : > "$DOTEST"/interactive || die "Could not mark as interactive"
-               git symbolic-ref HEAD > "$DOTEST"/head-name 2> /dev/null ||
-                       echo "detached HEAD" > "$DOTEST"/head-name
+ orig_head=$(git rev-parse --verify HEAD) || die "No HEAD?"
+ mkdir "$state_dir" || die "Could not create temporary $state_dir"
  
-               echo $HEAD > "$DOTEST"/head
-               case "$REBASE_ROOT" in
-               '')
-                       rm -f "$DOTEST"/rebase-root ;;
-               *)
-                       : >"$DOTEST"/rebase-root ;;
-               esac
-               echo $ONTO > "$DOTEST"/onto
-               test -z "$STRATEGY" || echo "$STRATEGY" > "$DOTEST"/strategy
-               test t = "$VERBOSE" && : > "$DOTEST"/verbose
-               if test t = "$PRESERVE_MERGES"
-               then
-                       if test -z "$REBASE_ROOT"
-                       then
-                               mkdir "$REWRITTEN" &&
-                               for c in $(git merge-base --all $HEAD $UPSTREAM)
-                               do
-                                       echo $ONTO > "$REWRITTEN"/$c ||
-                                               die "Could not init rewritten commits"
-                               done
-                       else
-                               mkdir "$REWRITTEN" &&
-                               echo $ONTO > "$REWRITTEN"/root ||
-                                       die "Could not init rewritten commits"
-                       fi
-                       # No cherry-pick because our first pass is to determine
-                       # parents to rewrite and skipping dropped commits would
-                       # prematurely end our probe
-                       MERGES_OPTION=
-                       first_after_upstream="$(git rev-list --reverse --first-parent $UPSTREAM..$HEAD | head -n 1)"
-               else
-                       MERGES_OPTION="--no-merges --cherry-pick"
-               fi
-               SHORTHEAD=$(git rev-parse --short $HEAD)
-               SHORTONTO=$(git rev-parse --short $ONTO)
-               if test -z "$REBASE_ROOT"
-                       # this is now equivalent to ! -z "$UPSTREAM"
-               then
-                       SHORTUPSTREAM=$(git rev-parse --short $UPSTREAM)
-                       REVISIONS=$UPSTREAM...$HEAD
-                       SHORTREVISIONS=$SHORTUPSTREAM..$SHORTHEAD
-               else
-                       REVISIONS=$ONTO...$HEAD
-                       SHORTREVISIONS=$SHORTHEAD
-               fi
-               git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \
-                       --abbrev=7 --reverse --left-right --topo-order \
-                       $REVISIONS | \
-                       sed -n "s/^>//p" |
-               while read -r shortsha1 rest
+ : > "$state_dir"/interactive || die "Could not mark as interactive"
+ write_basic_state
+ if test t = "$preserve_merges"
+ then
+       if test -z "$rebase_root"
+       then
+               mkdir "$REWRITTEN" &&
+               for c in $(git merge-base --all $orig_head $upstream)
                do
-                       if test t != "$PRESERVE_MERGES"
-                       then
-                               printf '%s\n' "pick $shortsha1 $rest" >> "$TODO"
-                       else
-                               sha1=$(git rev-parse $shortsha1)
-                               if test -z "$REBASE_ROOT"
-                               then
-                                       preserve=t
-                                       for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
-                                       do
-                                               if test -f "$REWRITTEN"/$p -a \( $p != $ONTO -o $sha1 = $first_after_upstream \)
-                                               then
-                                                       preserve=f
-                                               fi
-                                       done
-                               else
-                                       preserve=f
-                               fi
-                               if test f = "$preserve"
-                               then
-                                       touch "$REWRITTEN"/$sha1
-                                       printf '%s\n' "pick $shortsha1 $rest" >> "$TODO"
-                               fi
-                       fi
+                       echo $onto > "$REWRITTEN"/$c ||
+                               die "Could not init rewritten commits"
                done
-               # Watch for commits that been dropped by --cherry-pick
-               if test t = "$PRESERVE_MERGES"
+       else
+               mkdir "$REWRITTEN" &&
+               echo $onto > "$REWRITTEN"/root ||
+                       die "Could not init rewritten commits"
+       fi
+       # No cherry-pick because our first pass is to determine
+       # parents to rewrite and skipping dropped commits would
+       # prematurely end our probe
+       MERGES_OPTION=
+       first_after_upstream="$(git rev-list --reverse --first-parent $upstream..$orig_head | head -n 1)"
+ else
+       MERGES_OPTION="--no-merges --cherry-pick"
+ fi
+ SHORTHEAD=$(git rev-parse --short $orig_head)
+ SHORTONTO=$(git rev-parse --short $onto)
+ if test -z "$rebase_root"
+       # this is now equivalent to ! -z "$upstream"
+ then
+       SHORTUPSTREAM=$(git rev-parse --short $upstream)
+       REVISIONS=$upstream...$orig_head
+       SHORTREVISIONS=$SHORTUPSTREAM..$SHORTHEAD
+ else
+       REVISIONS=$onto...$orig_head
+       SHORTREVISIONS=$SHORTHEAD
+ fi
+ git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \
+       --abbrev=7 --reverse --left-right --topo-order \
+       $REVISIONS | \
+       sed -n "s/^>//p" |
+ while read -r shortsha1 rest
+ do
+       if test t != "$preserve_merges"
+       then
+               printf '%s\n' "pick $shortsha1 $rest" >> "$TODO"
+       else
+               sha1=$(git rev-parse $shortsha1)
+               if test -z "$rebase_root"
                then
-                       mkdir "$DROPPED"
-                       # Save all non-cherry-picked changes
-                       git rev-list $REVISIONS --left-right --cherry-pick | \
-                               sed -n "s/^>//p" > "$DOTEST"/not-cherry-picks
-                       # Now all commits and note which ones are missing in
-                       # not-cherry-picks and hence being dropped
-                       git rev-list $REVISIONS |
-                       while read rev
+                       preserve=t
+                       for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-)
                        do
-                               if test -f "$REWRITTEN"/$rev -a "$(sane_grep "$rev" "$DOTEST"/not-cherry-picks)" = ""
+                               if test -f "$REWRITTEN"/$p -a \( $p != $onto -o $sha1 = $first_after_upstream \)
                                then
-                                       # Use -f2 because if rev-list is telling us this commit is
-                                       # not worthwhile, we don't want to track its multiple heads,
-                                       # just the history of its first-parent for others that will
-                                       # 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)
-                                       sane_grep -v "^[a-z][a-z]* $short" <"$TODO" > "${TODO}2" ; mv "${TODO}2" "$TODO"
-                                       rm "$REWRITTEN"/$rev
+                                       preserve=f
                                fi
                        done
+               else
+                       preserve=f
+               fi
+               if test f = "$preserve"
+               then
+                       touch "$REWRITTEN"/$sha1
+                       printf '%s\n' "pick $shortsha1 $rest" >> "$TODO"
                fi
+       fi
+ done
  
-               test -s "$TODO" || echo noop >> "$TODO"
-               test -n "$AUTOSQUASH" && rearrange_squash "$TODO"
-               cat >> "$TODO" << EOF
+ # Watch for commits that been dropped by --cherry-pick
+ if test t = "$preserve_merges"
+ then
+       mkdir "$DROPPED"
+       # Save all non-cherry-picked changes
+       git rev-list $REVISIONS --left-right --cherry-pick | \
+               sed -n "s/^>//p" > "$state_dir"/not-cherry-picks
+       # Now all commits and note which ones are missing in
+       # not-cherry-picks and hence being dropped
+       git rev-list $REVISIONS |
+       while read rev
+       do
+               if test -f "$REWRITTEN"/$rev -a "$(sane_grep "$rev" "$state_dir"/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,
+                       # just the history of its first-parent for others that will
+                       # 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)
+                       sane_grep -v "^[a-z][a-z]* $short" <"$TODO" > "${TODO}2" ; mv "${TODO}2" "$TODO"
+                       rm "$REWRITTEN"/$rev
+               fi
+       done
+ fi
+ test -s "$TODO" || echo noop >> "$TODO"
+ test -n "$autosquash" && rearrange_squash "$TODO"
+ cat >> "$TODO" << EOF
  
  # Rebase $SHORTREVISIONS onto $SHORTONTO
  #
diff --cc git-rebase.sh
Simple merge