Merge branch 'mz/rebase-tests'
* mz/rebase-tests: rebase topology tests: fix commit names on case-insensitive file systems tests: move test for rebase messages from t3400 to t3406 t3406: modernize style add tests for rebasing merged history add tests for rebasing root add tests for rebasing of empty commits add tests for rebasing with patch-equivalence present add simple tests of consistency across rebase types
This commit is contained in:
commit
8ff80a2f05
@ -65,3 +65,36 @@ EOF
|
|||||||
test_set_editor "$(pwd)/fake-editor.sh"
|
test_set_editor "$(pwd)/fake-editor.sh"
|
||||||
chmod a+x fake-editor.sh
|
chmod a+x fake-editor.sh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# checks that the revisions in "$2" represent a linear range with the
|
||||||
|
# subjects in "$1"
|
||||||
|
test_linear_range () {
|
||||||
|
revlist_merges=$(git rev-list --merges "$2") &&
|
||||||
|
test -z "$revlist_merges" &&
|
||||||
|
expected=$1
|
||||||
|
set -- $(git log --reverse --format=%s "$2")
|
||||||
|
test "$expected" = "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
reset_rebase () {
|
||||||
|
test_might_fail git rebase --abort &&
|
||||||
|
git reset --hard &&
|
||||||
|
git clean -f
|
||||||
|
}
|
||||||
|
|
||||||
|
cherry_pick () {
|
||||||
|
git cherry-pick -n "$2" &&
|
||||||
|
git commit -m "$1" &&
|
||||||
|
git tag "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
revert () {
|
||||||
|
git revert -n "$2" &&
|
||||||
|
git commit -m "$1" &&
|
||||||
|
git tag "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
make_empty () {
|
||||||
|
git commit --allow-empty -m "$1" &&
|
||||||
|
git tag "$1"
|
||||||
|
}
|
||||||
|
@ -40,13 +40,6 @@ test_expect_success 'prepare repository with topic branches' '
|
|||||||
echo Side >>C &&
|
echo Side >>C &&
|
||||||
git add C &&
|
git add C &&
|
||||||
git commit -m "Add C" &&
|
git commit -m "Add C" &&
|
||||||
git checkout -b nonlinear my-topic-branch &&
|
|
||||||
echo Edit >>B &&
|
|
||||||
git add B &&
|
|
||||||
git commit -m "Modify B" &&
|
|
||||||
git merge side &&
|
|
||||||
git checkout -b upstream-merged-nonlinear &&
|
|
||||||
git merge master &&
|
|
||||||
git checkout -f my-topic-branch &&
|
git checkout -f my-topic-branch &&
|
||||||
git tag topic
|
git tag topic
|
||||||
'
|
'
|
||||||
@ -66,28 +59,6 @@ test_expect_success 'rebase against master' '
|
|||||||
git rebase master
|
git rebase master
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'rebase against master twice' '
|
|
||||||
git rebase master >out &&
|
|
||||||
test_i18ngrep "Current branch my-topic-branch is up to date" out
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rebase against master twice with --force' '
|
|
||||||
git rebase --force-rebase master >out &&
|
|
||||||
test_i18ngrep "Current branch my-topic-branch is up to date, rebase forced" out
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rebase against master twice from another branch' '
|
|
||||||
git checkout my-topic-branch^ &&
|
|
||||||
git rebase master my-topic-branch >out &&
|
|
||||||
test_i18ngrep "Current branch my-topic-branch is up to date" out
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rebase fast-forward to master' '
|
|
||||||
git checkout my-topic-branch^ &&
|
|
||||||
git rebase my-topic-branch >out &&
|
|
||||||
test_i18ngrep "Fast-forwarded HEAD to my-topic-branch" out
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'the rebase operation should not have destroyed author information' '
|
test_expect_success 'the rebase operation should not have destroyed author information' '
|
||||||
! (git log | grep "Author:" | grep "<>")
|
! (git log | grep "Author:" | grep "<>")
|
||||||
'
|
'
|
||||||
@ -106,31 +77,9 @@ test_expect_success 'rebase from ambiguous branch name' '
|
|||||||
git rebase master
|
git rebase master
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'rebase after merge master' '
|
|
||||||
git checkout --detach refs/tags/topic &&
|
|
||||||
git branch -D topic &&
|
|
||||||
git reset --hard topic &&
|
|
||||||
git merge master &&
|
|
||||||
git rebase master &&
|
|
||||||
! (git show | grep "^Merge:")
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rebase of history with merges is linearized' '
|
|
||||||
git checkout nonlinear &&
|
|
||||||
test 4 = $(git rev-list master.. | wc -l) &&
|
|
||||||
git rebase master &&
|
|
||||||
test 3 = $(git rev-list master.. | wc -l)
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rebase of history with merges after upstream merge is linearized' '
|
|
||||||
git checkout upstream-merged-nonlinear &&
|
|
||||||
test 5 = $(git rev-list master.. | wc -l) &&
|
|
||||||
git rebase master &&
|
|
||||||
test 3 = $(git rev-list master.. | wc -l)
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rebase a single mode change' '
|
test_expect_success 'rebase a single mode change' '
|
||||||
git checkout master &&
|
git checkout master &&
|
||||||
|
git branch -D topic &&
|
||||||
echo 1 >X &&
|
echo 1 >X &&
|
||||||
git add X &&
|
git add X &&
|
||||||
test_tick &&
|
test_tick &&
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# Copyright (c) 2006 Yann Dirson, based on t3400 by Amos Waterland
|
|
||||||
#
|
|
||||||
|
|
||||||
test_description='git rebase should detect patches integrated upstream
|
|
||||||
|
|
||||||
This test cherry-picks one local change of two into master branch, and
|
|
||||||
checks that git rebase succeeds with only the second patch in the
|
|
||||||
local branch.
|
|
||||||
'
|
|
||||||
. ./test-lib.sh
|
|
||||||
|
|
||||||
test_expect_success 'prepare repository with topic branch' '
|
|
||||||
test_commit A &&
|
|
||||||
git checkout -b my-topic-branch &&
|
|
||||||
test_commit B &&
|
|
||||||
test_commit C &&
|
|
||||||
git checkout -f master &&
|
|
||||||
test_commit A2 A.t
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'pick top patch from topic branch into master' '
|
|
||||||
git cherry-pick C &&
|
|
||||||
git checkout -f my-topic-branch
|
|
||||||
'
|
|
||||||
|
|
||||||
test_debug '
|
|
||||||
git cherry master &&
|
|
||||||
git format-patch -k --stdout --full-index master >/dev/null &&
|
|
||||||
gitk --all & sleep 1
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rebase topic branch against new master and check git am did not get halted' '
|
|
||||||
git rebase master &&
|
|
||||||
test_path_is_missing .git/rebase-apply
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rebase --merge topic branch that was partially merged upstream' '
|
|
||||||
git reset --hard C &&
|
|
||||||
git rebase --merge master &&
|
|
||||||
test_path_is_missing .git/rebase-merge
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rebase ignores empty commit' '
|
|
||||||
git reset --hard A &&
|
|
||||||
git commit --allow-empty -m empty &&
|
|
||||||
test_commit D &&
|
|
||||||
git rebase C &&
|
|
||||||
test "$(git log --format=%s C..)" = "D"
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rebase --keep-empty' '
|
|
||||||
git reset --hard D &&
|
|
||||||
git rebase --keep-empty C &&
|
|
||||||
test "$(git log --format=%s C..)" = "D
|
|
||||||
empty"
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'rebase --keep-empty keeps empty even if already in upstream' '
|
|
||||||
git reset --hard A &&
|
|
||||||
git commit --allow-empty -m also-empty &&
|
|
||||||
git rebase --keep-empty D &&
|
|
||||||
test "$(git log --format=%s A..)" = "also-empty
|
|
||||||
D
|
|
||||||
empty"
|
|
||||||
'
|
|
||||||
|
|
||||||
test_done
|
|
@ -477,19 +477,11 @@ test_expect_success 'interrupted squash works as expected (case 2)' '
|
|||||||
test $one = $(git rev-parse HEAD~2)
|
test $one = $(git rev-parse HEAD~2)
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'ignore patch if in upstream' '
|
test_expect_success '--continue tries to commit, even for "edit"' '
|
||||||
HEAD=$(git rev-parse HEAD) &&
|
|
||||||
git checkout -b has-cherry-picked HEAD^ &&
|
|
||||||
echo unrelated > file7 &&
|
echo unrelated > file7 &&
|
||||||
git add file7 &&
|
git add file7 &&
|
||||||
test_tick &&
|
test_tick &&
|
||||||
git commit -m "unrelated change" &&
|
git commit -m "unrelated change" &&
|
||||||
git cherry-pick $HEAD &&
|
|
||||||
EXPECT_COUNT=1 git rebase -i $HEAD &&
|
|
||||||
test $HEAD = $(git rev-parse HEAD^)
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success '--continue tries to commit, even for "edit"' '
|
|
||||||
parent=$(git rev-parse HEAD^) &&
|
parent=$(git rev-parse HEAD^) &&
|
||||||
test_tick &&
|
test_tick &&
|
||||||
FAKE_LINES="edit 1" git rebase -i HEAD^ &&
|
FAKE_LINES="edit 1" git rebase -i HEAD^ &&
|
||||||
|
@ -4,27 +4,17 @@ test_description='messages from rebase operation'
|
|||||||
|
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
quick_one () {
|
test_expect_success 'setup' '
|
||||||
echo "$1" >"file$1" &&
|
test_commit O fileO &&
|
||||||
git add "file$1" &&
|
test_commit X fileX &&
|
||||||
test_tick &&
|
test_commit A fileA &&
|
||||||
git commit -m "$1"
|
test_commit B fileB &&
|
||||||
}
|
test_commit Y fileY &&
|
||||||
|
|
||||||
test_expect_success setup '
|
git checkout -b topic O &&
|
||||||
quick_one O &&
|
git cherry-pick A B &&
|
||||||
git branch topic &&
|
test_commit Z fileZ &&
|
||||||
quick_one X &&
|
|
||||||
quick_one A &&
|
|
||||||
quick_one B &&
|
|
||||||
quick_one Y &&
|
|
||||||
|
|
||||||
git checkout topic &&
|
|
||||||
quick_one A &&
|
|
||||||
quick_one B &&
|
|
||||||
quick_one Z &&
|
|
||||||
git tag start
|
git tag start
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
cat >expect <<\EOF
|
cat >expect <<\EOF
|
||||||
@ -34,12 +24,32 @@ Committed: 0003 Z
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
test_expect_success 'rebase -m' '
|
test_expect_success 'rebase -m' '
|
||||||
|
|
||||||
git rebase -m master >report &&
|
git rebase -m master >report &&
|
||||||
sed -n -e "/^Already applied: /p" \
|
sed -n -e "/^Already applied: /p" \
|
||||||
-e "/^Committed: /p" report >actual &&
|
-e "/^Committed: /p" report >actual &&
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'rebase against master twice' '
|
||||||
|
git rebase master >out &&
|
||||||
|
test_i18ngrep "Current branch topic is up to date" out
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'rebase against master twice with --force' '
|
||||||
|
git rebase --force-rebase master >out &&
|
||||||
|
test_i18ngrep "Current branch topic is up to date, rebase forced" out
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'rebase against master twice from another branch' '
|
||||||
|
git checkout topic^ &&
|
||||||
|
git rebase master topic >out &&
|
||||||
|
test_i18ngrep "Current branch topic is up to date" out
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'rebase fast-forward to master' '
|
||||||
|
git checkout topic^ &&
|
||||||
|
git rebase topic >out &&
|
||||||
|
test_i18ngrep "Fast-forwarded HEAD to topic" out
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'rebase --stat' '
|
test_expect_success 'rebase --stat' '
|
||||||
|
@ -11,14 +11,6 @@ Run "git rebase -p" and check that merges are properly carried along
|
|||||||
GIT_AUTHOR_EMAIL=bogus_email_address
|
GIT_AUTHOR_EMAIL=bogus_email_address
|
||||||
export GIT_AUTHOR_EMAIL
|
export GIT_AUTHOR_EMAIL
|
||||||
|
|
||||||
# Clone 1 (trivial merge):
|
|
||||||
#
|
|
||||||
# A1--A2 <-- origin/master
|
|
||||||
# \ \
|
|
||||||
# B1--M <-- topic
|
|
||||||
# \
|
|
||||||
# B2 <-- origin/topic
|
|
||||||
#
|
|
||||||
# Clone 2 (conflicting merge):
|
# Clone 2 (conflicting merge):
|
||||||
#
|
#
|
||||||
# A1--A2--B3 <-- origin/master
|
# A1--A2--B3 <-- origin/master
|
||||||
@ -36,16 +28,6 @@ export GIT_AUTHOR_EMAIL
|
|||||||
# \--A3 <-- topic2
|
# \--A3 <-- topic2
|
||||||
# \
|
# \
|
||||||
# B2 <-- origin/topic
|
# B2 <-- origin/topic
|
||||||
#
|
|
||||||
# Clone 4 (merge using second parent as base):
|
|
||||||
#
|
|
||||||
# A1--A2--B3 <-- origin/master
|
|
||||||
# \
|
|
||||||
# B1--A3--M <-- topic
|
|
||||||
# \ /
|
|
||||||
# \--A4 <-- topic2
|
|
||||||
# \
|
|
||||||
# B2 <-- origin/topic
|
|
||||||
|
|
||||||
test_expect_success 'setup for merge-preserving rebase' \
|
test_expect_success 'setup for merge-preserving rebase' \
|
||||||
'echo First > A &&
|
'echo First > A &&
|
||||||
@ -58,20 +40,6 @@ test_expect_success 'setup for merge-preserving rebase' \
|
|||||||
git checkout -f master &&
|
git checkout -f master &&
|
||||||
echo Third >> A &&
|
echo Third >> A &&
|
||||||
git commit -a -m "Modify A2" &&
|
git commit -a -m "Modify A2" &&
|
||||||
|
|
||||||
git clone ./. clone1 &&
|
|
||||||
(cd clone1 &&
|
|
||||||
git checkout -b topic origin/topic &&
|
|
||||||
git merge origin/master
|
|
||||||
) &&
|
|
||||||
|
|
||||||
git clone ./. clone4 &&
|
|
||||||
(
|
|
||||||
cd clone4 &&
|
|
||||||
git checkout -b topic origin/topic &&
|
|
||||||
git merge origin/master
|
|
||||||
) &&
|
|
||||||
|
|
||||||
echo Fifth > B &&
|
echo Fifth > B &&
|
||||||
git add B &&
|
git add B &&
|
||||||
git commit -m "Add different B" &&
|
git commit -m "Add different B" &&
|
||||||
@ -101,16 +69,6 @@ test_expect_success 'setup for merge-preserving rebase' \
|
|||||||
git commit -a -m "Modify B2"
|
git commit -a -m "Modify B2"
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'rebase -p fakes interactive rebase' '
|
|
||||||
(
|
|
||||||
cd clone1 &&
|
|
||||||
git fetch &&
|
|
||||||
git rebase -p origin/topic &&
|
|
||||||
test 1 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) &&
|
|
||||||
test 1 = $(git rev-list --all --pretty=oneline | grep "Merge remote-tracking branch " | wc -l)
|
|
||||||
)
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success '--continue works after a conflict' '
|
test_expect_success '--continue works after a conflict' '
|
||||||
(
|
(
|
||||||
cd clone2 &&
|
cd clone2 &&
|
||||||
@ -138,15 +96,4 @@ test_expect_success 'rebase -p preserves no-ff merges' '
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'rebase -p works when base inside second parent' '
|
|
||||||
(
|
|
||||||
cd clone4 &&
|
|
||||||
git fetch &&
|
|
||||||
git rebase -p HEAD^2 &&
|
|
||||||
test 1 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) &&
|
|
||||||
test 1 = $(git rev-list --all --pretty=oneline | grep "Modify B" | wc -l) &&
|
|
||||||
test 1 = $(git rev-list --all --pretty=oneline | grep "Merge remote-tracking branch " | wc -l)
|
|
||||||
)
|
|
||||||
'
|
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
350
t/t3421-rebase-topology-linear.sh
Executable file
350
t/t3421-rebase-topology-linear.sh
Executable file
@ -0,0 +1,350 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
test_description='basic rebase topology tests'
|
||||||
|
. ./test-lib.sh
|
||||||
|
. "$TEST_DIRECTORY"/lib-rebase.sh
|
||||||
|
|
||||||
|
# a---b---c
|
||||||
|
# \
|
||||||
|
# d---e
|
||||||
|
test_expect_success 'setup' '
|
||||||
|
test_commit a &&
|
||||||
|
test_commit b &&
|
||||||
|
test_commit c &&
|
||||||
|
git checkout b &&
|
||||||
|
test_commit d &&
|
||||||
|
test_commit e
|
||||||
|
'
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "simple rebase $*" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* c e &&
|
||||||
|
test_cmp_rev c HEAD~2 &&
|
||||||
|
test_linear_range 'd e' c..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase success -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase success -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* is no-op if upstream is an ancestor" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* b e &&
|
||||||
|
test_cmp_rev e HEAD
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase success -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase success -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* -f rewrites even if upstream is an ancestor" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* -f b e &&
|
||||||
|
! test_cmp_rev e HEAD &&
|
||||||
|
test_cmp_rev b HEAD~2 &&
|
||||||
|
test_linear_range 'd e' b..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase success -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase failure -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* fast-forwards from ancestor of upstream" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* e b &&
|
||||||
|
test_cmp_rev e HEAD
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase success -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase success -p
|
||||||
|
|
||||||
|
# f
|
||||||
|
# /
|
||||||
|
# a---b---c---g---h
|
||||||
|
# \
|
||||||
|
# d---gp--i
|
||||||
|
#
|
||||||
|
# gp = cherry-picked g
|
||||||
|
# h = reverted g
|
||||||
|
#
|
||||||
|
# Reverted patches are there for tests to be able to check if a commit
|
||||||
|
# that introduced the same change as another commit is
|
||||||
|
# dropped. Without reverted commits, we could get false positives
|
||||||
|
# because applying the patch succeeds, but simply results in no
|
||||||
|
# changes.
|
||||||
|
test_expect_success 'setup of linear history for range selection tests' '
|
||||||
|
git checkout c &&
|
||||||
|
test_commit g &&
|
||||||
|
revert h g &&
|
||||||
|
git checkout d &&
|
||||||
|
cherry_pick gp g &&
|
||||||
|
test_commit i &&
|
||||||
|
git checkout b &&
|
||||||
|
test_commit f
|
||||||
|
'
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* drops patches in upstream" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* h i &&
|
||||||
|
test_cmp_rev h HEAD~2 &&
|
||||||
|
test_linear_range 'd i' h..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase failure -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase success -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* can drop last patch if in upstream" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* h gp &&
|
||||||
|
test_cmp_rev h HEAD^ &&
|
||||||
|
test_linear_range 'd' h..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase failure -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase success -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* --onto drops patches in upstream" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* --onto f h i &&
|
||||||
|
test_cmp_rev f HEAD~2 &&
|
||||||
|
test_linear_range 'd i' f..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase failure -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase success -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* --onto does not drop patches in onto" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* --onto h f i &&
|
||||||
|
test_cmp_rev h HEAD~3 &&
|
||||||
|
test_linear_range 'd gp i' h..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase success -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase success -p
|
||||||
|
|
||||||
|
# a---b---c---j!
|
||||||
|
# \
|
||||||
|
# d---k!--l
|
||||||
|
#
|
||||||
|
# ! = empty
|
||||||
|
test_expect_success 'setup of linear history for empty commit tests' '
|
||||||
|
git checkout c &&
|
||||||
|
make_empty j &&
|
||||||
|
git checkout d &&
|
||||||
|
make_empty k &&
|
||||||
|
test_commit l
|
||||||
|
'
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* drops empty commit" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* c l &&
|
||||||
|
test_cmp_rev c HEAD~2 &&
|
||||||
|
test_linear_range 'd l' c..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase success -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase success -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* --keep-empty" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* --keep-empty c l &&
|
||||||
|
test_cmp_rev c HEAD~3 &&
|
||||||
|
test_linear_range 'd k l' c..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase failure -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase failure -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* --keep-empty keeps empty even if already in upstream" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* --keep-empty j l &&
|
||||||
|
test_cmp_rev j HEAD~3 &&
|
||||||
|
test_linear_range 'd k l' j..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase failure -m
|
||||||
|
test_run_rebase failure -i
|
||||||
|
test_run_rebase failure -p
|
||||||
|
|
||||||
|
# m
|
||||||
|
# /
|
||||||
|
# a---b---c---g
|
||||||
|
#
|
||||||
|
# x---y---bp
|
||||||
|
#
|
||||||
|
# bp = cherry-picked b
|
||||||
|
# m = reverted b
|
||||||
|
#
|
||||||
|
# Reverted patches are there for tests to be able to check if a commit
|
||||||
|
# that introduced the same change as another commit is
|
||||||
|
# dropped. Without reverted commits, we could get false positives
|
||||||
|
# because applying the patch succeeds, but simply results in no
|
||||||
|
# changes.
|
||||||
|
test_expect_success 'setup of linear history for test involving root' '
|
||||||
|
git checkout b &&
|
||||||
|
revert m b &&
|
||||||
|
git checkout --orphan disjoint &&
|
||||||
|
git rm -rf . &&
|
||||||
|
test_commit x &&
|
||||||
|
test_commit y &&
|
||||||
|
cherry_pick bp b
|
||||||
|
'
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* --onto --root" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* --onto c --root y &&
|
||||||
|
test_cmp_rev c HEAD~2 &&
|
||||||
|
test_linear_range 'x y' c..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase failure -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase success -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* without --onto --root with disjoint history" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* c y &&
|
||||||
|
test_cmp_rev c HEAD~2 &&
|
||||||
|
test_linear_range 'x y' c..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase failure -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase failure -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* --onto --root drops patch in onto" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* --onto m --root bp &&
|
||||||
|
test_cmp_rev m HEAD~2 &&
|
||||||
|
test_linear_range 'x y' m..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase failure -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase success -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* --onto --root with merge-base does not go to root" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* --onto m --root g &&
|
||||||
|
test_cmp_rev m HEAD~2 &&
|
||||||
|
test_linear_range 'c g' m..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase success -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase failure -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* without --onto --root with disjoint history drops patch in onto" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* m bp &&
|
||||||
|
test_cmp_rev m HEAD~2 &&
|
||||||
|
test_linear_range 'x y' m..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase failure -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase failure -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* --root on linear history is a no-op" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* --root c &&
|
||||||
|
test_cmp_rev c HEAD
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase failure ''
|
||||||
|
test_run_rebase failure -m
|
||||||
|
test_run_rebase failure -i
|
||||||
|
test_run_rebase failure -p
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* -f --root on linear history causes re-write" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* -f --root c &&
|
||||||
|
! test_cmp_rev a HEAD~2 &&
|
||||||
|
test_linear_range 'a b c' HEAD
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase success -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
test_run_rebase success -p
|
||||||
|
|
||||||
|
test_done
|
258
t/t3425-rebase-topology-merges.sh
Executable file
258
t/t3425-rebase-topology-merges.sh
Executable file
@ -0,0 +1,258 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
test_description='rebase topology tests with merges'
|
||||||
|
. ./test-lib.sh
|
||||||
|
. "$TEST_DIRECTORY"/lib-rebase.sh
|
||||||
|
|
||||||
|
test_revision_subjects () {
|
||||||
|
expected="$1"
|
||||||
|
shift
|
||||||
|
set -- $(git log --format=%s --no-walk=unsorted "$@")
|
||||||
|
test "$expected" = "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# a---b-----------c
|
||||||
|
# \ \
|
||||||
|
# d-------e \
|
||||||
|
# \ \ \
|
||||||
|
# n---o---w---v
|
||||||
|
# \
|
||||||
|
# z
|
||||||
|
test_expect_success 'setup of non-linear-history' '
|
||||||
|
test_commit a &&
|
||||||
|
test_commit b &&
|
||||||
|
test_commit c &&
|
||||||
|
git checkout b &&
|
||||||
|
test_commit d &&
|
||||||
|
test_commit e
|
||||||
|
|
||||||
|
git checkout c &&
|
||||||
|
test_commit g &&
|
||||||
|
revert h g &&
|
||||||
|
git checkout d &&
|
||||||
|
cherry_pick gp g &&
|
||||||
|
test_commit i &&
|
||||||
|
git checkout b &&
|
||||||
|
test_commit f
|
||||||
|
|
||||||
|
git checkout d &&
|
||||||
|
test_commit n &&
|
||||||
|
test_commit o &&
|
||||||
|
test_merge w e &&
|
||||||
|
test_merge v c &&
|
||||||
|
git checkout o &&
|
||||||
|
test_commit z
|
||||||
|
'
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* after merge from upstream" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* e w &&
|
||||||
|
test_cmp_rev e HEAD~2 &&
|
||||||
|
test_linear_range 'n o' e..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
test_run_rebase success ''
|
||||||
|
test_run_rebase success -m
|
||||||
|
test_run_rebase success -i
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
expected=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* of non-linear history is linearized in place" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* d w &&
|
||||||
|
test_cmp_rev d HEAD~3 &&
|
||||||
|
test_linear_range "\'"$expected"\'" d..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
#TODO: make order consistent across all flavors of rebase
|
||||||
|
test_run_rebase success 'e n o' ''
|
||||||
|
test_run_rebase success 'e n o' -m
|
||||||
|
test_run_rebase success 'n o e' -i
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
expected=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* of non-linear history is linearized upstream" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* c w &&
|
||||||
|
test_cmp_rev c HEAD~4 &&
|
||||||
|
test_linear_range "\'"$expected"\'" c..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
#TODO: make order consistent across all flavors of rebase
|
||||||
|
test_run_rebase success 'd e n o' ''
|
||||||
|
test_run_rebase success 'd e n o' -m
|
||||||
|
test_run_rebase success 'd n o e' -i
|
||||||
|
|
||||||
|
test_run_rebase () {
|
||||||
|
result=$1
|
||||||
|
shift
|
||||||
|
expected=$1
|
||||||
|
shift
|
||||||
|
test_expect_$result "rebase $* of non-linear history with merges after upstream merge is linearized" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase $* c v &&
|
||||||
|
test_cmp_rev c HEAD~4 &&
|
||||||
|
test_linear_range "\'"$expected"\'" c..
|
||||||
|
"
|
||||||
|
}
|
||||||
|
#TODO: make order consistent across all flavors of rebase
|
||||||
|
test_run_rebase success 'd e n o' ''
|
||||||
|
test_run_rebase success 'd e n o' -m
|
||||||
|
test_run_rebase success 'd n o e' -i
|
||||||
|
|
||||||
|
test_expect_success "rebase -p is no-op in non-linear history" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase -p d w &&
|
||||||
|
test_cmp_rev w HEAD
|
||||||
|
"
|
||||||
|
|
||||||
|
test_expect_success "rebase -p is no-op when base inside second parent" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase -p e w &&
|
||||||
|
test_cmp_rev w HEAD
|
||||||
|
"
|
||||||
|
|
||||||
|
test_expect_failure "rebase -p --root on non-linear history is a no-op" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase -p --root w &&
|
||||||
|
test_cmp_rev w HEAD
|
||||||
|
"
|
||||||
|
|
||||||
|
test_expect_success "rebase -p re-creates merge from side branch" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase -p z w &&
|
||||||
|
test_cmp_rev z HEAD^ &&
|
||||||
|
test_cmp_rev w^2 HEAD^2
|
||||||
|
"
|
||||||
|
|
||||||
|
test_expect_success "rebase -p re-creates internal merge" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase -p c w &&
|
||||||
|
test_cmp_rev c HEAD~4 &&
|
||||||
|
test_cmp_rev HEAD^2^ HEAD~3 &&
|
||||||
|
test_revision_subjects 'd n e o w' HEAD~3 HEAD~2 HEAD^2 HEAD^ HEAD
|
||||||
|
"
|
||||||
|
|
||||||
|
test_expect_success "rebase -p can re-create two branches on onto" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase -p --onto c d w &&
|
||||||
|
test_cmp_rev c HEAD~3 &&
|
||||||
|
test_cmp_rev c HEAD^2^ &&
|
||||||
|
test_revision_subjects 'n e o w' HEAD~2 HEAD^2 HEAD^ HEAD
|
||||||
|
"
|
||||||
|
|
||||||
|
# f
|
||||||
|
# /
|
||||||
|
# a---b---c---g---h
|
||||||
|
# \
|
||||||
|
# d---gp--i
|
||||||
|
# \ \
|
||||||
|
# e-------u
|
||||||
|
#
|
||||||
|
# gp = cherry-picked g
|
||||||
|
# h = reverted g
|
||||||
|
test_expect_success 'setup of non-linear-history for patch-equivalence tests' '
|
||||||
|
git checkout e &&
|
||||||
|
test_merge u i
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "rebase -p re-creates history around dropped commit matching upstream" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase -p h u &&
|
||||||
|
test_cmp_rev h HEAD~3 &&
|
||||||
|
test_cmp_rev HEAD^2^ HEAD~2 &&
|
||||||
|
test_revision_subjects 'd i e u' HEAD~2 HEAD^2 HEAD^ HEAD
|
||||||
|
"
|
||||||
|
|
||||||
|
test_expect_success "rebase -p --onto in merged history drops patches in upstream" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase -p --onto f h u &&
|
||||||
|
test_cmp_rev f HEAD~3 &&
|
||||||
|
test_cmp_rev HEAD^2^ HEAD~2 &&
|
||||||
|
test_revision_subjects 'd i e u' HEAD~2 HEAD^2 HEAD^ HEAD
|
||||||
|
"
|
||||||
|
|
||||||
|
test_expect_success "rebase -p --onto in merged history does not drop patches in onto" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase -p --onto h f u &&
|
||||||
|
test_cmp_rev h HEAD~3 &&
|
||||||
|
test_cmp_rev HEAD^2~2 HEAD~2 &&
|
||||||
|
test_revision_subjects 'd gp i e u' HEAD~2 HEAD^2^ HEAD^2 HEAD^ HEAD
|
||||||
|
"
|
||||||
|
|
||||||
|
# a---b---c---g---h
|
||||||
|
# \
|
||||||
|
# d---gp--s
|
||||||
|
# \ \ /
|
||||||
|
# \ X
|
||||||
|
# \ / \
|
||||||
|
# e---t
|
||||||
|
#
|
||||||
|
# gp = cherry-picked g
|
||||||
|
# h = reverted g
|
||||||
|
test_expect_success 'setup of non-linear-history for dropping whole side' '
|
||||||
|
git checkout gp &&
|
||||||
|
test_merge s e &&
|
||||||
|
git checkout e &&
|
||||||
|
test_merge t gp
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_failure "rebase -p drops merge commit when entire first-parent side is dropped" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase -p h s &&
|
||||||
|
test_cmp_rev h HEAD~2 &&
|
||||||
|
test_linear_range 'd e' h..
|
||||||
|
"
|
||||||
|
|
||||||
|
test_expect_success "rebase -p drops merge commit when entire second-parent side is dropped" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase -p h t &&
|
||||||
|
test_cmp_rev h HEAD~2 &&
|
||||||
|
test_linear_range 'd e' h..
|
||||||
|
"
|
||||||
|
|
||||||
|
# a---b---c
|
||||||
|
# \
|
||||||
|
# d---e
|
||||||
|
# \ \
|
||||||
|
# n---r
|
||||||
|
# \
|
||||||
|
# o
|
||||||
|
#
|
||||||
|
# r = tree-same with n
|
||||||
|
test_expect_success 'setup of non-linear-history for empty commits' '
|
||||||
|
git checkout n &&
|
||||||
|
git merge --no-commit e &&
|
||||||
|
git reset n . &&
|
||||||
|
git commit -m r &&
|
||||||
|
git reset --hard &&
|
||||||
|
git clean -f &&
|
||||||
|
git tag r
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "rebase -p re-creates empty internal merge commit" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase -p c r &&
|
||||||
|
test_cmp_rev c HEAD~3 &&
|
||||||
|
test_cmp_rev HEAD^2^ HEAD~2 &&
|
||||||
|
test_revision_subjects 'd e n r' HEAD~2 HEAD^2 HEAD^ HEAD
|
||||||
|
"
|
||||||
|
|
||||||
|
test_expect_success "rebase -p re-creates empty merge commit" "
|
||||||
|
reset_rebase &&
|
||||||
|
git rebase -p o r &&
|
||||||
|
test_cmp_rev e HEAD^2 &&
|
||||||
|
test_cmp_rev o HEAD^ &&
|
||||||
|
test_revision_subjects 'r' HEAD
|
||||||
|
"
|
||||||
|
|
||||||
|
test_done
|
Loading…
Reference in New Issue
Block a user