Merge branch 'cw/rebase-i-root'
authorJunio C Hamano <gitster@pobox.com>
Mon, 16 Jul 2012 04:38:41 +0000 (21:38 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 16 Jul 2012 04:38:42 +0000 (21:38 -0700)
"git rebase [-i] --root $tip" can now be used to rewrite all the
history down to the root.

* cw/rebase-i-root:
  t3404: make test 57 work with dash and others
  Add tests for rebase -i --root without --onto
  rebase -i: support --root without --onto

1  2 
Documentation/git-rebase.txt
git-rebase--interactive.sh
git-rebase.sh
t/t3404-rebase-interactive.sh
t/t3412-rebase-root.sh

index 2d71e4b975db3355c6de9005e77a701e18723539,85b5e4425cded0886712543f1d0453e0e859e3de..b30ed352e5a3f87d24119624966c33b4c194df5a
@@@ -8,9 -8,9 +8,9 @@@ git-rebase - Forward-port local commit
  SYNOPSIS
  --------
  [verse]
 -'git rebase' [-i | --interactive] [options] [--onto <newbase>]
 +'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
        [<upstream>] [<branch>]
- 'git rebase' [-i | --interactive] [options] [--exec <cmd>] --onto <newbase>
 -'git rebase' [-i | --interactive] [options] [--onto <newbase>]
++'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
        --root [<branch>]
  'git rebase' --continue | --skip | --abort
  
Simple merge
diff --cc git-rebase.sh
index 5bddfa9690e8dfbedd07e31dc7e768b60f156213,bde2be88a0198819401d31224d35059ad167be68..1cd0633b80a8daf00dbc50657ccba228bd578a73
@@@ -31,8 -30,8 +31,8 @@@ Example:       git-rebase master~1 topi
  SUBDIRECTORY_OK=Yes
  OPTIONS_KEEPDASHDASH=
  OPTIONS_SPEC="\
 -git rebase [-i] [options] [--onto <newbase>] [<upstream>] [<branch>]
 -git rebase [-i] [options] [--onto <newbase>] --root [<branch>]
 +git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
- git rebase [-i] [options] [--exec <cmd>] --onto <newbase> --root [<branch>]
++git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]
  git-rebase [-i] --continue | --abort | --skip
  --
   Available options are
@@@ -411,10 -402,14 +416,15 @@@ the
        die "invalid upstream $upstream_name"
        upstream_arg="$upstream_name"
  else
-       test -z "$onto" && die "You must specify --onto when using --root"
+       if test -z "$onto"
+       then
+               empty_tree=`git hash-object -t tree /dev/null`
+               onto=`git commit-tree $empty_tree </dev/null`
+               squash_onto="$onto"
+       fi
        unset upstream_name
        unset upstream
 +      test $# -gt 1 && usage
        upstream_arg=--root
  fi
  
index 68d61480fbeee024ca463ca0d5771bdfdf980866,060f9d87d26b6c9285bee46d7dc514ea53b1723c..8078db6856ba4428e9d6b13f5e02076da7963b09
@@@ -755,121 -755,35 +755,152 @@@ test_expect_success 'rebase-i history w
        test_cmp expect actual
  '
  
 +
 +test_expect_success 'prepare for rebase -i --exec' '
 +      git checkout master &&
 +      git checkout -b execute &&
 +      test_commit one_exec main.txt one_exec &&
 +      test_commit two_exec main.txt two_exec &&
 +      test_commit three_exec main.txt three_exec
 +'
 +
 +
 +test_expect_success 'running "git rebase -i --exec git show HEAD"' '
 +      git rebase -i --exec "git show HEAD" HEAD~2 >actual &&
 +      (
 +              FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
 +              export FAKE_LINES &&
 +              git rebase -i HEAD~2 >expect
 +      ) &&
 +      sed -e "1,9d" expect >expected &&
 +      test_cmp expected actual
 +'
 +
 +
 +test_expect_success 'running "git rebase --exec git show HEAD -i"' '
 +      git reset --hard execute &&
 +      git rebase --exec "git show HEAD" -i HEAD~2 >actual &&
 +      (
 +              FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
 +              export FAKE_LINES &&
 +              git rebase -i HEAD~2 >expect
 +      ) &&
 +      sed -e "1,9d" expect >expected &&
 +      test_cmp expected actual
 +'
 +
 +
 +test_expect_success 'running "git rebase -ix git show HEAD"' '
 +      git reset --hard execute &&
 +      git rebase -ix "git show HEAD" HEAD~2 >actual &&
 +      (
 +              FAKE_LINES="1 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
 +              export FAKE_LINES &&
 +              git rebase -i HEAD~2 >expect
 +      ) &&
 +      sed -e "1,9d" expect >expected &&
 +      test_cmp expected actual
 +'
 +
 +
 +test_expect_success 'rebase -ix with several <CMD>' '
 +      git reset --hard execute &&
 +      git rebase -ix "git show HEAD; pwd" HEAD~2 >actual &&
 +      (
 +              FAKE_LINES="1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd" &&
 +              export FAKE_LINES &&
 +              git rebase -i HEAD~2 >expect
 +      ) &&
 +      sed -e "1,9d" expect >expected &&
 +      test_cmp expected actual
 +'
 +
 +
 +test_expect_success 'rebase -ix with several instances of --exec' '
 +      git reset --hard execute &&
 +      git rebase -i --exec "git show HEAD" --exec "pwd" HEAD~2 >actual &&
 +      (
 +              FAKE_LINES="1 exec_git_show_HEAD exec_pwd 2
 +                              exec_git_show_HEAD exec_pwd" &&
 +              export FAKE_LINES &&
 +              git rebase -i HEAD~2 >expect
 +      ) &&
 +      sed -e "1,11d" expect >expected &&
 +      test_cmp expected actual
 +'
 +
 +
 +test_expect_success 'rebase -ix with --autosquash' '
 +      git reset --hard execute &&
 +      git checkout -b autosquash &&
 +      echo second >second.txt &&
 +      git add second.txt &&
 +      git commit -m "fixup! two_exec" &&
 +      echo bis >bis.txt &&
 +      git add bis.txt &&
 +      git commit -m "fixup! two_exec" &&
 +      (
 +              git checkout -b autosquash_actual &&
 +              git rebase -i --exec "git show HEAD" --autosquash HEAD~4 >actual
 +      ) &&
 +      git checkout autosquash &&
 +      (
 +              git checkout -b autosquash_expected &&
 +              FAKE_LINES="1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD" &&
 +              export FAKE_LINES &&
 +              git rebase -i HEAD~4 >expect
 +      ) &&
 +      sed -e "1,13d" expect >expected &&
 +      test_cmp expected actual
 +'
 +
 +
 +test_expect_success 'rebase --exec without -i shows error message' '
 +      git reset --hard execute &&
 +      test_must_fail git rebase --exec "git show HEAD" HEAD~2 2>actual &&
 +      echo "--exec option must be used with --interactive option" >expected &&
 +      test_i18ncmp expected actual
 +'
 +
 +
 +test_expect_success 'rebase -i --exec without <CMD>' '
 +      git reset --hard execute &&
 +      test_must_fail git rebase -i --exec 2>tmp &&
 +      sed -e "1d" tmp >actual &&
 +      test_must_fail git rebase -h >expected &&
 +      test_cmp expected actual &&
 +      git checkout master
 +'
 +
+ test_expect_success 'rebase -i --root re-order and drop commits' '
+       git checkout E &&
+       FAKE_LINES="3 1 2 5" git rebase -i --root &&
+       test E = $(git cat-file commit HEAD | sed -ne \$p) &&
+       test B = $(git cat-file commit HEAD^ | sed -ne \$p) &&
+       test A = $(git cat-file commit HEAD^^ | sed -ne \$p) &&
+       test C = $(git cat-file commit HEAD^^^ | sed -ne \$p) &&
+       test 0 = $(git cat-file commit HEAD^^^ | grep -c ^parent\ )
+ '
+ test_expect_success 'rebase -i --root retain root commit author and message' '
+       git checkout A &&
+       echo B >file7 &&
+       git add file7 &&
+       GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" &&
+       FAKE_LINES="2" git rebase -i --root &&
+       git cat-file commit HEAD | grep -q "^author Twerp Snog" &&
+       git cat-file commit HEAD | grep -q "^different author$"
+ '
+ test_expect_success 'rebase -i --root temporary sentinel commit' '
+       git checkout B &&
+       (
+               FAKE_LINES="2" &&
+               export FAKE_LINES &&
+               test_must_fail git rebase -i --root
+       ) &&
+       git cat-file commit HEAD | grep "^tree 4b825dc642cb" &&
+       git rebase --abort
+ '
  test_done
index 1e9d1a737c5369d1b41bfa75f5939ad41004b944,e4f9da8536556eb9b0711d85ba411877fbc31c7e..0b521057283bf106da8ce55f25f61c7ec7e3ad35
@@@ -22,16 -22,6 +22,11 @@@ test_expect_success 'prepare repository
        test_commit 4 B
  '
  
- test_expect_success 'rebase --root expects --onto' '
-       git checkout -B fail other &&
-       test_must_fail git rebase --root
- '
 +test_expect_success 'rebase --root fails with too many args' '
 +      git checkout -B fail other &&
 +      test_must_fail git rebase --onto master --root fail fail
 +'
 +
  test_expect_success 'setup pre-rebase hook' '
        mkdir -p .git/hooks &&
        cat >.git/hooks/pre-rebase <<EOF &&