| 1 | #!/bin/sh |
| 2 | |
| 3 | test_description='git rebase --root |
| 4 | |
| 5 | Tests if git rebase --root --onto <newparent> can rebase the root commit. |
| 6 | ' |
| 7 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
| 8 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
| 9 | |
| 10 | . ./test-lib.sh |
| 11 | |
| 12 | log_with_names () { |
| 13 | git rev-list --topo-order --parents --pretty="tformat:%s" HEAD | |
| 14 | git name-rev --annotate-stdin --name-only --refs=refs/heads/$1 |
| 15 | } |
| 16 | |
| 17 | |
| 18 | test_expect_success 'prepare repository' ' |
| 19 | test_commit 1 A && |
| 20 | test_commit 2 A && |
| 21 | git symbolic-ref HEAD refs/heads/other && |
| 22 | rm .git/index && |
| 23 | test_commit 3 B && |
| 24 | test_commit 1b A 1 && |
| 25 | test_commit 4 B |
| 26 | ' |
| 27 | |
| 28 | test_expect_success 'rebase --root fails with too many args' ' |
| 29 | git checkout -B fail other && |
| 30 | test_must_fail git rebase --onto main --root fail fail |
| 31 | ' |
| 32 | |
| 33 | test_expect_success 'setup pre-rebase hook' ' |
| 34 | test_hook --setup pre-rebase <<-\EOF |
| 35 | echo "$1,$2" >.git/PRE-REBASE-INPUT |
| 36 | EOF |
| 37 | ' |
| 38 | cat > expect <<EOF |
| 39 | 4 |
| 40 | 3 |
| 41 | 2 |
| 42 | 1 |
| 43 | EOF |
| 44 | |
| 45 | test_expect_success 'rebase --root --onto <newbase>' ' |
| 46 | git checkout -b work other && |
| 47 | git rebase --root --onto main && |
| 48 | git log --pretty=tformat:"%s" > rebased && |
| 49 | test_cmp expect rebased |
| 50 | ' |
| 51 | |
| 52 | test_expect_success 'pre-rebase got correct input (1)' ' |
| 53 | test "z$(cat .git/PRE-REBASE-INPUT)" = z--root, |
| 54 | ' |
| 55 | |
| 56 | test_expect_success 'rebase --root --onto <newbase> <branch>' ' |
| 57 | git branch work2 other && |
| 58 | git rebase --root --onto main work2 && |
| 59 | git log --pretty=tformat:"%s" > rebased2 && |
| 60 | test_cmp expect rebased2 |
| 61 | ' |
| 62 | |
| 63 | test_expect_success 'pre-rebase got correct input (2)' ' |
| 64 | test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work2 |
| 65 | ' |
| 66 | |
| 67 | test_expect_success 'rebase -i --root --onto <newbase>' ' |
| 68 | git checkout -b work3 other && |
| 69 | git rebase -i --root --onto main && |
| 70 | git log --pretty=tformat:"%s" > rebased3 && |
| 71 | test_cmp expect rebased3 |
| 72 | ' |
| 73 | |
| 74 | test_expect_success 'pre-rebase got correct input (3)' ' |
| 75 | test "z$(cat .git/PRE-REBASE-INPUT)" = z--root, |
| 76 | ' |
| 77 | |
| 78 | test_expect_success 'rebase -i --root --onto <newbase> <branch>' ' |
| 79 | git branch work4 other && |
| 80 | git rebase -i --root --onto main work4 && |
| 81 | git log --pretty=tformat:"%s" > rebased4 && |
| 82 | test_cmp expect rebased4 |
| 83 | ' |
| 84 | |
| 85 | test_expect_success 'pre-rebase got correct input (4)' ' |
| 86 | test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work4 |
| 87 | ' |
| 88 | |
| 89 | test_expect_success 'set up merge history' ' |
| 90 | git checkout other^ && |
| 91 | git checkout -b side && |
| 92 | test_commit 5 C && |
| 93 | git checkout other && |
| 94 | git merge side |
| 95 | ' |
| 96 | |
| 97 | cat > expect-side <<'EOF' |
| 98 | commit work6 work6~1 work6^2 |
| 99 | Merge branch 'side' into other |
| 100 | commit work6^2 work6~2 |
| 101 | 5 |
| 102 | commit work6~1 work6~2 |
| 103 | 4 |
| 104 | commit work6~2 work6~3 |
| 105 | 3 |
| 106 | commit work6~3 work6~4 |
| 107 | 2 |
| 108 | commit work6~4 |
| 109 | 1 |
| 110 | EOF |
| 111 | |
| 112 | test_expect_success 'set up second root and merge' ' |
| 113 | git symbolic-ref HEAD refs/heads/third && |
| 114 | rm .git/index && |
| 115 | rm A B C && |
| 116 | test_commit 6 D && |
| 117 | git checkout other && |
| 118 | git merge --allow-unrelated-histories third |
| 119 | ' |
| 120 | |
| 121 | cat > expect-third <<'EOF' |
| 122 | commit work7 work7~1 work7^2 |
| 123 | Merge branch 'third' into other |
| 124 | commit work7^2 work7~4 |
| 125 | 6 |
| 126 | commit work7~1 work7~2 work7~1^2 |
| 127 | Merge branch 'side' into other |
| 128 | commit work7~1^2 work7~3 |
| 129 | 5 |
| 130 | commit work7~2 work7~3 |
| 131 | 4 |
| 132 | commit work7~3 work7~4 |
| 133 | 3 |
| 134 | commit work7~4 work7~5 |
| 135 | 2 |
| 136 | commit work7~5 |
| 137 | 1 |
| 138 | EOF |
| 139 | |
| 140 | test_expect_success 'setup pre-rebase hook that fails' ' |
| 141 | test_hook --setup --clobber pre-rebase <<-\EOF |
| 142 | false |
| 143 | EOF |
| 144 | ' |
| 145 | |
| 146 | test_expect_success 'pre-rebase hook stops rebase' ' |
| 147 | git checkout -b stops1 other && |
| 148 | test_must_fail git rebase --root --onto main && |
| 149 | test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops1 && |
| 150 | test 0 = $(git rev-list other...stops1 | wc -l) |
| 151 | ' |
| 152 | |
| 153 | test_expect_success 'pre-rebase hook stops rebase -i' ' |
| 154 | git checkout -b stops2 other && |
| 155 | test_must_fail git rebase --root --onto main && |
| 156 | test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops2 && |
| 157 | test 0 = $(git rev-list other...stops2 | wc -l) |
| 158 | ' |
| 159 | |
| 160 | test_expect_success 'remove pre-rebase hook' ' |
| 161 | rm -f .git/hooks/pre-rebase |
| 162 | ' |
| 163 | |
| 164 | test_expect_success 'set up a conflict' ' |
| 165 | git checkout main && |
| 166 | echo conflict > B && |
| 167 | git add B && |
| 168 | git commit -m conflict |
| 169 | ' |
| 170 | |
| 171 | test_expect_success 'rebase --root with conflict (first part)' ' |
| 172 | git checkout -b conflict1 other && |
| 173 | test_must_fail git rebase --root --onto main && |
| 174 | git ls-files -u | grep "B$" |
| 175 | ' |
| 176 | |
| 177 | test_expect_success 'fix the conflict' ' |
| 178 | echo 3 > B && |
| 179 | git add B |
| 180 | ' |
| 181 | |
| 182 | cat > expect-conflict <<EOF |
| 183 | 6 |
| 184 | 5 |
| 185 | 4 |
| 186 | 3 |
| 187 | conflict |
| 188 | 2 |
| 189 | 1 |
| 190 | EOF |
| 191 | |
| 192 | test_expect_success 'rebase --root with conflict (second part)' ' |
| 193 | git rebase --continue && |
| 194 | git log --pretty=tformat:"%s" > conflict1 && |
| 195 | test_cmp expect-conflict conflict1 |
| 196 | ' |
| 197 | |
| 198 | test_expect_success 'rebase -i --root with conflict (first part)' ' |
| 199 | git checkout -b conflict2 other && |
| 200 | test_must_fail git rebase -i --root --onto main && |
| 201 | git ls-files -u | grep "B$" |
| 202 | ' |
| 203 | |
| 204 | test_expect_success 'fix the conflict' ' |
| 205 | echo 3 > B && |
| 206 | git add B |
| 207 | ' |
| 208 | |
| 209 | test_expect_success 'rebase -i --root with conflict (second part)' ' |
| 210 | git rebase --continue && |
| 211 | git log --pretty=tformat:"%s" > conflict2 && |
| 212 | test_cmp expect-conflict conflict2 |
| 213 | ' |
| 214 | |
| 215 | cat >expect-conflict-p <<\EOF |
| 216 | commit conflict3 conflict3~1 conflict3^2 |
| 217 | Merge branch 'third' into other |
| 218 | commit conflict3^2 conflict3~4 |
| 219 | 6 |
| 220 | commit conflict3~1 conflict3~2 conflict3~1^2 |
| 221 | Merge branch 'side' into other |
| 222 | commit conflict3~1^2 conflict3~3 |
| 223 | 5 |
| 224 | commit conflict3~2 conflict3~3 |
| 225 | 4 |
| 226 | commit conflict3~3 conflict3~4 |
| 227 | 3 |
| 228 | commit conflict3~4 conflict3~5 |
| 229 | conflict |
| 230 | commit conflict3~5 conflict3~6 |
| 231 | 2 |
| 232 | commit conflict3~6 |
| 233 | 1 |
| 234 | EOF |
| 235 | |
| 236 | test_expect_success 'fix the conflict' ' |
| 237 | echo 3 > B && |
| 238 | git add B |
| 239 | ' |
| 240 | |
| 241 | test_done |