Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Teach git-rebase a new option --root, which instructs it to rebase the entire history leading up to <branch>. This option must be used with --onto <newbase>, and causes commits that already exist in <newbase> to be skipped. (Normal operation skips commits that already exist in <upstream> instead.) One possible use-case is with git-svn: suppose you start hacking (perhaps offline) on a new project, but later notice you want to commit this work to SVN. You will have to rebase the entire history, including the root commit, on a (possibly empty) commit coming from git-svn, to establish a history connection. This previously had to be done by cherry-picking the root commit manually. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
- Loading branch information
Showing
2 changed files
with
126 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,86 @@ | |||
#!/bin/sh | |||
|
|||
test_description='git rebase --root | |||
Tests if git rebase --root --onto <newparent> can rebase the root commit. | |||
' | |||
. ./test-lib.sh | |||
|
|||
test_expect_success 'prepare repository' ' | |||
echo 1 > A && | |||
git add A && | |||
git commit -m 1 && | |||
echo 2 > A && | |||
git add A && | |||
git commit -m 2 && | |||
git symbolic-ref HEAD refs/heads/other && | |||
rm .git/index && | |||
echo 3 > B && | |||
git add B && | |||
git commit -m 3 && | |||
echo 1 > A && | |||
git add A && | |||
git commit -m 1b && | |||
echo 4 > B && | |||
git add B && | |||
git commit -m 4 | |||
' | |||
|
|||
test_expect_success 'rebase --root expects --onto' ' | |||
test_must_fail git rebase --root | |||
' | |||
|
|||
test_expect_success 'setup pre-rebase hook' ' | |||
mkdir -p .git/hooks && | |||
cat >.git/hooks/pre-rebase <<EOF && | |||
#!$SHELL_PATH | |||
echo "\$1,\$2" >.git/PRE-REBASE-INPUT | |||
EOF | |||
chmod +x .git/hooks/pre-rebase | |||
' | |||
cat > expect <<EOF | |||
4 | |||
3 | |||
2 | |||
1 | |||
EOF | |||
|
|||
test_expect_success 'rebase --root --onto <newbase>' ' | |||
git checkout -b work && | |||
git rebase --root --onto master && | |||
git log --pretty=tformat:"%s" > rebased && | |||
test_cmp expect rebased | |||
' | |||
|
|||
test_expect_success 'pre-rebase got correct input (1)' ' | |||
test "z$(cat .git/PRE-REBASE-INPUT)" = z--root, | |||
' | |||
|
|||
test_expect_success 'rebase --root --onto <newbase> <branch>' ' | |||
git branch work2 other && | |||
git rebase --root --onto master work2 && | |||
git log --pretty=tformat:"%s" > rebased2 && | |||
test_cmp expect rebased2 | |||
' | |||
|
|||
test_expect_success 'pre-rebase got correct input (2)' ' | |||
test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work2 | |||
' | |||
|
|||
test_expect_success 'setup pre-rebase hook that fails' ' | |||
mkdir -p .git/hooks && | |||
cat >.git/hooks/pre-rebase <<EOF && | |||
#!$SHELL_PATH | |||
false | |||
EOF | |||
chmod +x .git/hooks/pre-rebase | |||
' | |||
|
|||
test_expect_success 'pre-rebase hook stops rebase' ' | |||
git checkout -b stops1 other && | |||
GIT_EDITOR=: test_must_fail git rebase --root --onto master && | |||
test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops1 | |||
test 0 = $(git rev-list other...stops1 | wc -l) | |||
' | |||
|
|||
test_done |