Git Mailing List Archive on lore.kernel.org
 help / color / Atom feed
From: Martin von Zweigbergk <martinvonz@gmail.com>
To: git@vger.kernel.org
Cc: Martin von Zweigbergk <martinvonz@gmail.com>
Subject: [RFC PATCH] add t3420-rebase-topology
Date: Mon, 17 Sep 2012 23:31:18 -0700
Message-ID: <1347949878-12578-1-git-send-email-martinvonz@gmail.com> (raw)

Add more test cases to check that the topology after a rebase is as
expected. Conflicts are not considered, but patch-equivalence is.
---

Tests pass and fail as indicated by the suffix
(_success/_failure). Your input especially appreciated on whether you
agree with the intent of the test cases. For example, do you agree
that 'rebase --onto does not re-apply patches in onto' is desirable?
And if you do, then do you also agree that 'rebase --root --onto
ignores patch in onto' is desirable? How about 'rebase --root is not a
no-op'? One might think that --force would be necessary, but on the
other hand, if that was the case, the only point (AFAICT) of "git
rebase --root <branch>" without --force would be to linearize history,
so I instead made the test case confirm that --root without --onto
effectively behaves as if --force was also passed.

Feedback on the structure/setup and style is of course also
appreciated.

 t/t3420-rebase-topology.sh | 348 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 348 insertions(+)
 create mode 100755 t/t3420-rebase-topology.sh

diff --git a/t/t3420-rebase-topology.sh b/t/t3420-rebase-topology.sh
new file mode 100755
index 0000000..024a2b4
--- /dev/null
+++ b/t/t3420-rebase-topology.sh
@@ -0,0 +1,348 @@
+#!/bin/sh
+
+test_description='effect of rebase on topology'
+. ./test-lib.sh
+
+
+#       q---C---r
+#      /
+# a---b---c---d!--e---p
+#      \
+#       f---g!--h
+#        \
+#         j-------E---k
+#          \       \
+#           n---H---w
+#
+# x---y---B
+#
+#
+# ! = empty
+# uppercase = cherry-picked
+# p = reverted e
+#
+# TODO:
+# prune graph to what's needed
+
+empty () {
+	git commit --allow-empty -m $1 &&
+	git tag $1
+}
+
+cherry_pick () {
+	git cherry-pick -n $1 &&
+	git commit -m $2 &&
+	git tag $2
+}
+
+revert () {
+	git revert -n $1 &&
+	git commit -m $2 &&
+	git tag $2
+}
+
+
+test_expect_success 'setup' '
+	test_commit a &&
+	test_commit b &&
+	test_commit c &&
+	empty d &&
+	test_commit e &&
+	revert e p &&
+	git checkout b &&
+	test_commit f &&
+	empty g &&
+	test_commit h &&
+	git checkout f &&
+	test_commit j &&
+	cherry_pick e E &&
+	test_commit k &&
+	git checkout j &&
+	test_commit n &&
+	cherry_pick h H &&
+	git merge -m w E &&
+	git tag w &&
+	git checkout b &&
+	test_commit q &&
+	cherry_pick c C &&
+	test_commit r &&
+	git checkout --orphan disjoint &&
+	git rm -rf . &&
+	test_commit x &&
+	test_commit y &&
+	cherry_pick b B
+'
+
+reset () {
+	git rebase --abort
+	git reset --hard
+}
+
+test_range () {
+	test "$(git log --reverse --topo-order --format=%s "$1" | xargs)" = "$2"
+}
+
+test_revisions () {
+	expected="$1"
+	shift
+	test "$(git log --format=%s --no-walk=unsorted "$@" | xargs)" = "$expected"
+}
+
+same_revision () {
+	test "$(git rev-parse $1)" = "$(git rev-parse $2)"
+}
+
+# the following 5 (?) tests copy t3400 tests, but check the history rather than status code and/or stdout
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' c j &&
+	same_revision HEAD~2 c &&
+	test_range c.. "f j"
+'
+}
+test_expect_success 'simple rebase' "$(run)"
+test_expect_success 'simple rebase -m' "$(run -m)"
+test_expect_success 'simple rebase -i' "$(run -i)"
+test_expect_success 'simple rebase -p' "$(run -p)"
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' b j &&
+	same_revision HEAD j
+'
+}
+test_expect_success 'rebase is no-op if upstream is an ancestor' "$(run)"
+test_expect_success 'rebase -m is no-op if upstream is an ancestor' "$(run -m)"
+test_expect_success 'rebase -i is no-op if upstream is an ancestor' "$(run -i)"
+test_expect_success 'rebase -p is no-op if upstream is an ancestor' "$(run -p)"
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' --force b j &&
+	! same_revision HEAD j &&
+	test_range b.. "f j"
+'
+}
+test_expect_success 'rebase --force' "$(run)"
+test_expect_success 'rebase -m --force' "$(run -m)"
+test_expect_success 'rebase -i --force' "$(run -i)"
+test_expect_failure 'rebase -p --force' "$(run -p)"
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' j b &&
+	same_revision HEAD j
+'
+}
+test_expect_success 'rebase fast-forwards if an ancestor of upstream' "$(run)"
+test_expect_success 'rebase -m fast-forwards if an ancestor of upstream' "$(run -m)"
+test_expect_success 'rebase -i fast-forwards if an ancestor of upstream' "$(run -i)"
+test_expect_success 'rebase -p fast-forwards if an ancestor of upstream' "$(run -p)"
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' p k &&
+	test_range p.. "f j k"
+'
+}
+test_expect_success 'rebase ignores patch in upstream' "$(run)"
+test_expect_failure 'rebase -m ignores patch in upstream' "$(run -m)"
+test_expect_success 'rebase -i ignores patch in upstream' "$(run -i)"
+test_expect_success 'rebase -p ignores patch in upstream' "$(run -p)"
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' c h &&
+	test_range c.. "f h"
+'
+}
+test_expect_success 'rebase ignores empty commit' "$(run)"
+test_expect_success 'rebase -m ignores empty commit' "$(run -m)"
+test_expect_success 'rebase -i ignores empty commit' "$(run -i)"
+test_expect_success 'rebase -p ignores empty commit' "$(run -p)"
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' --keep-empty c h &&
+	test_range c.. "f g h"
+'
+}
+test_expect_success 'rebase --keep-empty' "$(run)"
+test_expect_failure 'rebase -m --keep-empty' "$(run -m)"
+test_expect_success 'rebase -i --keep-empty' "$(run -i)"
+test_expect_failure 'rebase -p --keep-empty' "$(run -p)"
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' --keep-empty p h &&
+	test_range p.. "f g h"
+'
+}
+test_expect_success 'rebase --keep-empty keeps empty even if already in upstream' "$(run)"
+test_expect_failure 'rebase -m --keep-empty keeps empty even if already in upstream' "$(run -m)"
+test_expect_failure 'rebase -i --keep-empty keeps empty even if already in upstream' "$(run -i)"
+test_expect_failure 'rebase -p --keep-empty keeps empty even if already in upstream' "$(run -p)"
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' E w &&
+	test_range E.. "n H"
+'
+}
+test_expect_success 'rebase after merge' "$(run)"
+test_expect_success 'rebase -m after merge' "$(run -m)"
+test_expect_success 'rebase -i after merge' "$(run -i)"
+
+test_expect_success 'rebase -p is no-op in history with merges' '
+	reset &&
+	git rebase -p j w &&
+	same_revision HEAD w
+'
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' j w &&
+	test_range j.. "E n H" || test_range j.. "n H E"
+'
+}
+test_expect_success 'rebase of history with merges is linearized' "$(run)"
+test_expect_success 'rebase -m of history with merges is linearized' "$(run -m)"
+test_expect_success 'rebase -i of history with merges is linearized' "$(run -i)"
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' --onto p h k &&
+	test_range p.. "j k"
+'
+}
+test_expect_failure 'rebase --onto does not re-apply patches in onto' "$(run)"
+test_expect_failure 'rebase -m --onto does not re-apply patches in onto' "$(run -m)"
+test_expect_failure 'rebase -i --onto does not re-apply patches in onto' "$(run -i)"
+test_expect_failure 'rebase -p --onto does not re-apply patches in onto' "$(run -p)"
+
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' --onto f d r &&
+	test_range f.. "q C r"
+'
+}
+test_expect_failure 'rebase --onto does not lose patches in upstream' "$(run)"
+test_expect_success 'rebase -m --onto does not lose patches in upstream' "$(run -m)"
+test_expect_failure 'rebase -i --onto does not lose patches in upstream' "$(run -i)"
+test_expect_failure 'rebase -p --onto does not lose patches in upstream' "$(run -p)"
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' --root c &&
+	! same_revision HEAD c &&
+	test_range c "a b c"
+'
+}
+test_expect_success 'rebase --root is not a no-op' "$(run)"
+test_expect_success 'rebase -m --root is not a no-op' "$(run -m)"
+test_expect_success 'rebase -i --root is not a no-op' "$(run -i)"
+test_expect_success 'rebase -p --root is not a no-op' "$(run -p)"
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' --root --onto e y &&
+	test_range e.. "x y"
+'
+}
+test_expect_success 'rebase --root --onto' "$(run)"
+test_expect_failure 'rebase -m --root --onto' "$(run -m)"
+test_expect_success 'rebase -i --root --onto' "$(run -i)"
+test_expect_success 'rebase -p --root --onto' "$(run -p)"
+
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' --root --onto e B &&
+	test_range e.. "x y"
+'
+}
+test_expect_success 'rebase --root --onto ignores patch in onto' "$(run)"
+test_expect_failure 'rebase -m --root --onto ignores patch in onto' "$(run -m)"
+test_expect_success 'rebase -i --root --onto ignores patch in onto' "$(run -i)"
+test_expect_success 'rebase -p --root --onto ignores patch in onto' "$(run -p)"
+
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' e y &&
+	test_range e.. "x y"
+'
+}
+test_expect_success 'rebase without --root works on disjoint history' "$(run)"
+test_expect_failure 'rebase -m without --root works on disjoint history' "$(run -m)"
+test_expect_success 'rebase -i without --root works on disjoint history' "$(run -i)"
+test_expect_failure 'rebase -p without --root works on disjoint history' "$(run -p)"
+
+
+run () {
+echo '
+	reset &&
+	git rebase '"$@"' --root --onto p k &&
+	test_range p.. "f j k"
+'
+}
+test_expect_success 'rebase --root --onto with merge-base ignores --root' "$(run)"
+test_expect_failure 'rebase -m --root --onto with merge-base ignores --root' "$(run -m)"
+test_expect_success 'rebase -i --root --onto with merge-base ignores --root' "$(run -i)"
+test_expect_success 'rebase -p --root --onto with merge-base ignores --root' "$(run -p)"
+
+test_expect_success 'rebase -p re-creates merge from upstream' '
+	reset &&
+	git rebase -p k w &&
+	same_revision HEAD^ H &&
+	same_revision HEAD^2 k
+'
+
+test_expect_success 'rebase -p re-creates internal merge' '
+	reset &&
+	git rebase -p c w &&
+	test_revisions "f j n E H w" HEAD~4 HEAD~3 HEAD~2 HEAD^2 HEAD^ HEAD
+'
+
+test_expect_success 'rebase -p rebuilds history around dropped commit matching upstream' '
+	reset &&
+	git rebase -p h w &&
+	test_revisions "j E n w" HEAD~2 HEAD^2 HEAD^ HEAD
+'
+
+test_expect_success 'rebase -p drops merge commit when one entire side is dropped' '
+	reset &&
+	git rebase -p p w &&
+	test_range p.. "f j n H"
+'
+
+test_expect_failure 'rebase -p --onto drops commit in <onto>' '
+	reset &&
+	git rebase -p --onto p f w &&
+	test_range p.. "j n H"
+'
+
+test_expect_success 'rebase -p with two paths to $from' '
+	reset &&
+	git rebase -p --onto c j w &&
+	test_revisions "c n E H w" HEAD~3 HEAD~2 HEAD^2 HEAD^ HEAD
+'
+
+test_done
-- 
1.7.11.1.104.ge7b44f1

             reply index

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-18  6:31 Martin von Zweigbergk [this message]
2012-09-18  7:51 ` Junio C Hamano
2012-09-21 17:06   ` Martin von Zweigbergk
2012-09-18  7:53 ` Johannes Sixt
2012-09-26 17:07   ` Martin von Zweigbergk
2012-09-27 12:20     ` Chris Webb
2012-09-28 18:03       ` Martin von Zweigbergk
2012-09-29  8:08         ` Chris Webb
2013-05-29  6:39 ` [PATCH v2 0/7] Rebase topology test Martin von Zweigbergk
2013-05-29  6:39   ` [PATCH v2 1/7] add simple tests of consistency across rebase types Martin von Zweigbergk
2013-06-03 17:16     ` Martin von Zweigbergk
2013-06-03 18:05       ` Junio C Hamano
2013-06-03 18:12         ` Martin von Zweigbergk
2013-05-29  6:39   ` [PATCH v2 2/7] add tests for rebasing with patch-equivalence present Martin von Zweigbergk
2013-05-29  7:09     ` Johannes Sixt
2013-05-30  5:30       ` Martin von Zweigbergk
2013-05-30  5:41         ` Felipe Contreras
2013-05-30  6:14           ` Martin von Zweigbergk
2013-05-30  6:40             ` Felipe Contreras
2013-05-30  6:46               ` Martin von Zweigbergk
2013-05-30 12:54         ` Johannes Sixt
2013-05-30 15:01           ` Martin von Zweigbergk
2013-05-29  6:39   ` [PATCH v2 3/7] add tests for rebasing of empty commits Martin von Zweigbergk
2013-05-29  6:39   ` [PATCH v2 4/7] add tests for rebasing root Martin von Zweigbergk
2013-05-29  7:31     ` Johannes Sixt
2013-05-30  5:51       ` Martin von Zweigbergk
2013-05-29  6:39   ` [PATCH v2 5/7] add tests for rebasing merged history Martin von Zweigbergk
2013-05-29  7:57     ` Johannes Sixt
2013-05-31  5:42       ` Martin von Zweigbergk
2013-05-29 10:33     ` Johannes Sixt
2013-05-29  6:39   ` [PATCH v2 6/7] t3406: modernize style Martin von Zweigbergk
2013-05-29  6:39   ` [PATCH v2 7/7] tests: move test for rebase messages from t3400 to t3406 Martin von Zweigbergk
2013-05-29  7:10   ` [PATCH v2 0/7] Rebase topology test Felipe Contreras
2013-05-29 12:50     ` Ramkumar Ramachandra
2013-05-29 13:54       ` Felipe Contreras
2013-05-31  6:49   ` [PATCH v3 " Martin von Zweigbergk
2013-05-31  6:49     ` [PATCH v3 1/7] add simple tests of consistency across rebase types Martin von Zweigbergk
2013-05-31  6:49     ` [PATCH v3 2/7] add tests for rebasing with patch-equivalence present Martin von Zweigbergk
2013-05-31  6:49     ` [PATCH v3 3/7] add tests for rebasing of empty commits Martin von Zweigbergk
2013-05-31  6:49     ` [PATCH v3 4/7] add tests for rebasing root Martin von Zweigbergk
2013-05-31  6:49     ` [PATCH v3 5/7] add tests for rebasing merged history Martin von Zweigbergk
2013-05-31  6:49     ` [PATCH v3 6/7] t3406: modernize style Martin von Zweigbergk
2013-05-31  6:49     ` [PATCH v3 7/7] tests: move test for rebase messages from t3400 to t3406 Martin von Zweigbergk
2013-06-03 20:42     ` [PATCH v5 0/7] Rebase topology test Martin von Zweigbergk
2013-06-03 20:42       ` [PATCH v5 1/7] add simple tests of consistency across rebase types Martin von Zweigbergk
2013-06-03 22:28         ` Junio C Hamano
2013-06-04  5:14           ` Martin von Zweigbergk
2013-06-04  5:49             ` Junio C Hamano
2013-06-04  6:15             ` Johannes Sixt
2013-06-05  4:31               ` Martin von Zweigbergk
2013-06-03 20:42       ` [PATCH v5 2/7] add tests for rebasing with patch-equivalence present Martin von Zweigbergk
2013-06-03 20:42       ` [PATCH v5 3/7] add tests for rebasing of empty commits Martin von Zweigbergk
2013-06-03 20:42       ` [PATCH v5 4/7] add tests for rebasing root Martin von Zweigbergk
2013-06-03 20:42       ` [PATCH v5 5/7] add tests for rebasing merged history Martin von Zweigbergk
2013-06-04 17:18         ` Junio C Hamano
2013-06-05  5:44           ` Martin von Zweigbergk
2013-06-05  6:12           ` Johannes Sixt
2013-06-03 20:42       ` [PATCH v5 6/7] t3406: modernize style Martin von Zweigbergk
2013-06-03 20:42       ` [PATCH v5 7/7] tests: move test for rebase messages from t3400 to t3406 Martin von Zweigbergk
2013-06-07  6:11       ` [PATCH v6 0/8] Rebase topology test Martin von Zweigbergk
2013-06-07  6:11         ` [PATCH v6 1/7] add simple tests of consistency across rebase types Martin von Zweigbergk
2013-06-07  6:11         ` [PATCH v6 2/7] add tests for rebasing with patch-equivalence present Martin von Zweigbergk
2013-06-07  6:11         ` [PATCH v6 3/7] add tests for rebasing of empty commits Martin von Zweigbergk
2013-06-07  6:11         ` [PATCH v6 4/7] add tests for rebasing root Martin von Zweigbergk
2013-06-07  6:11         ` [PATCH v6 5/7] add tests for rebasing merged history Martin von Zweigbergk
2013-06-07  6:11         ` [PATCH v6 6/7] t3406: modernize style Martin von Zweigbergk
2013-06-07  6:11         ` [PATCH v6 7/7] tests: move test for rebase messages from t3400 to t3406 Martin von Zweigbergk
2013-06-07 16:43         ` [PATCH v6 0/8] Rebase topology test Junio C Hamano
2013-06-07 19:37         ` Johannes Sixt
2013-06-18  7:28         ` [PATCH mz/rebase-tests] rebase topology tests: fix commit names on case-insensitive file systems Johannes Sixt
2013-06-18 15:45           ` Junio C Hamano
2013-06-18 15:53           ` Martin von Zweigbergk
2013-06-19  5:52             ` Johannes Sixt
2013-05-31 12:19 [PATCH v3 5/7] add tests for rebasing merged history Johannes Sixt
2013-06-01 21:36 ` [PATCH v4 " Martin von Zweigbergk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1347949878-12578-1-git-send-email-martinvonz@gmail.com \
    --to=martinvonz@gmail.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Mailing List Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/git/0 git/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 git git/ https://lore.kernel.org/git \
		git@vger.kernel.org
	public-inbox-index git

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.git


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git