| 1 | #!/bin/sh |
| 2 | |
| 3 | test_description='messages from rebase operation' |
| 4 | |
| 5 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
| 6 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
| 7 | |
| 8 | . ./test-lib.sh |
| 9 | |
| 10 | test_expect_success 'setup' ' |
| 11 | # Commit dates are hardcoded to 2005, and the reflog entries will have |
| 12 | # a matching timestamp. Maintenance may thus immediately expire |
| 13 | # reflogs if it was running. |
| 14 | git config set gc.reflogExpire never && |
| 15 | git config set gc.reflogExpireUnreachable never && |
| 16 | |
| 17 | test_commit O fileO && |
| 18 | test_commit X fileX && |
| 19 | git branch fast-forward && |
| 20 | test_commit A fileA && |
| 21 | test_commit B fileB && |
| 22 | test_commit Y fileY && |
| 23 | |
| 24 | git checkout -b conflicts O && |
| 25 | test_commit P && |
| 26 | test_commit conflict-X fileX && |
| 27 | test_commit Q && |
| 28 | |
| 29 | git checkout -b topic O && |
| 30 | git cherry-pick A B && |
| 31 | test_commit Z fileZ && |
| 32 | git tag start |
| 33 | ' |
| 34 | |
| 35 | test_expect_success 'rebase -m' ' |
| 36 | git rebase -m main >actual && |
| 37 | test_must_be_empty actual |
| 38 | ' |
| 39 | |
| 40 | test_expect_success 'rebase against main twice' ' |
| 41 | git rebase --apply main >out && |
| 42 | test_grep "Current branch topic is up to date" out |
| 43 | ' |
| 44 | |
| 45 | test_expect_success 'rebase against main twice with --force' ' |
| 46 | git rebase --force-rebase --apply main >out && |
| 47 | test_grep "Current branch topic is up to date, rebase forced" out |
| 48 | ' |
| 49 | |
| 50 | test_expect_success 'rebase against main twice from another branch' ' |
| 51 | git checkout topic^ && |
| 52 | git rebase --apply main topic >out && |
| 53 | test_grep "Current branch topic is up to date" out |
| 54 | ' |
| 55 | |
| 56 | test_expect_success 'rebase fast-forward to main' ' |
| 57 | git checkout topic^ && |
| 58 | git rebase --apply topic >out && |
| 59 | test_grep "Fast-forwarded HEAD to topic" out |
| 60 | ' |
| 61 | |
| 62 | test_expect_success 'rebase --stat' ' |
| 63 | git reset --hard start && |
| 64 | git rebase --stat main >diffstat.txt && |
| 65 | grep "^ fileX | *1 +$" diffstat.txt |
| 66 | ' |
| 67 | |
| 68 | test_expect_success 'rebase w/config rebase.stat' ' |
| 69 | git reset --hard start && |
| 70 | git config rebase.stat true && |
| 71 | git rebase main >diffstat.txt && |
| 72 | grep "^ fileX | *1 +$" diffstat.txt |
| 73 | ' |
| 74 | |
| 75 | test_expect_success 'rebase -n overrides config rebase.stat config' ' |
| 76 | git reset --hard start && |
| 77 | git config rebase.stat true && |
| 78 | git rebase -n main >diffstat.txt && |
| 79 | ! grep "^ fileX | *1 +$" diffstat.txt |
| 80 | ' |
| 81 | |
| 82 | test_expect_success 'rebase --onto outputs the invalid ref' ' |
| 83 | test_must_fail git rebase --onto invalid-ref HEAD HEAD 2>err && |
| 84 | test_grep "invalid-ref" err |
| 85 | ' |
| 86 | |
| 87 | test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' ' |
| 88 | test_must_fail git rebase -Cnot-a-number HEAD 2>err && |
| 89 | test_grep "numerical value" err && |
| 90 | test_must_fail git rebase --whitespace=bad HEAD 2>err && |
| 91 | test_grep "Invalid whitespace option" err |
| 92 | ' |
| 93 | |
| 94 | write_reflog_expect () { |
| 95 | if test $mode = --apply |
| 96 | then |
| 97 | sed 's/(continue)/(pick)/' |
| 98 | else |
| 99 | cat |
| 100 | fi >expect |
| 101 | } |
| 102 | |
| 103 | test_reflog () { |
| 104 | mode=$1 |
| 105 | reflog_action="$2" |
| 106 | |
| 107 | test_expect_success "rebase $mode reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" ' |
| 108 | git checkout conflicts && |
| 109 | test_when_finished "git reset --hard Q" && |
| 110 | |
| 111 | ( |
| 112 | if test -n "$reflog_action" |
| 113 | then |
| 114 | GIT_REFLOG_ACTION="$reflog_action" && |
| 115 | export GIT_REFLOG_ACTION |
| 116 | fi && |
| 117 | test_must_fail git rebase $mode main && |
| 118 | echo resolved >fileX && |
| 119 | git add fileX && |
| 120 | git rebase --continue |
| 121 | ) && |
| 122 | |
| 123 | git log -g --format=%gs -5 >actual && |
| 124 | write_reflog_expect <<-EOF && |
| 125 | ${reflog_action:-rebase} (finish): returning to refs/heads/conflicts |
| 126 | ${reflog_action:-rebase} (pick): Q |
| 127 | ${reflog_action:-rebase} (continue): conflict-X |
| 128 | ${reflog_action:-rebase} (pick): P |
| 129 | ${reflog_action:-rebase} (start): checkout main |
| 130 | EOF |
| 131 | test_cmp expect actual && |
| 132 | |
| 133 | git log -g --format=%gs -1 conflicts >actual && |
| 134 | write_reflog_expect <<-EOF && |
| 135 | ${reflog_action:-rebase} (finish): refs/heads/conflicts onto $(git rev-parse main) |
| 136 | EOF |
| 137 | test_cmp expect actual && |
| 138 | |
| 139 | # check there is only one new entry in the branch reflog |
| 140 | test_cmp_rev conflicts@{1} Q |
| 141 | ' |
| 142 | |
| 143 | test_expect_success "rebase $mode fast-forward reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" ' |
| 144 | git checkout fast-forward && |
| 145 | test_when_finished "git reset --hard X" && |
| 146 | |
| 147 | ( |
| 148 | if test -n "$reflog_action" |
| 149 | then |
| 150 | GIT_REFLOG_ACTION="$reflog_action" && |
| 151 | export GIT_REFLOG_ACTION |
| 152 | fi && |
| 153 | git rebase $mode main |
| 154 | ) && |
| 155 | |
| 156 | git log -g --format=%gs -2 >actual && |
| 157 | write_reflog_expect <<-EOF && |
| 158 | ${reflog_action:-rebase} (finish): returning to refs/heads/fast-forward |
| 159 | ${reflog_action:-rebase} (start): checkout main |
| 160 | EOF |
| 161 | test_cmp expect actual && |
| 162 | |
| 163 | git log -g --format=%gs -1 fast-forward >actual && |
| 164 | write_reflog_expect <<-EOF && |
| 165 | ${reflog_action:-rebase} (finish): refs/heads/fast-forward onto $(git rev-parse main) |
| 166 | EOF |
| 167 | test_cmp expect actual && |
| 168 | |
| 169 | # check there is only one new entry in the branch reflog |
| 170 | test_cmp_rev fast-forward@{1} X |
| 171 | ' |
| 172 | |
| 173 | test_expect_success "rebase $mode --skip reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" ' |
| 174 | git checkout conflicts && |
| 175 | test_when_finished "git reset --hard Q" && |
| 176 | |
| 177 | ( |
| 178 | if test -n "$reflog_action" |
| 179 | then |
| 180 | GIT_REFLOG_ACTION="$reflog_action" && |
| 181 | export GIT_REFLOG_ACTION |
| 182 | fi && |
| 183 | test_must_fail git rebase $mode main && |
| 184 | git rebase --skip |
| 185 | ) && |
| 186 | |
| 187 | git log -g --format=%gs -4 >actual && |
| 188 | write_reflog_expect <<-EOF && |
| 189 | ${reflog_action:-rebase} (finish): returning to refs/heads/conflicts |
| 190 | ${reflog_action:-rebase} (pick): Q |
| 191 | ${reflog_action:-rebase} (pick): P |
| 192 | ${reflog_action:-rebase} (start): checkout main |
| 193 | EOF |
| 194 | test_cmp expect actual |
| 195 | ' |
| 196 | |
| 197 | test_expect_success "rebase $mode --abort reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" ' |
| 198 | git checkout conflicts && |
| 199 | test_when_finished "git reset --hard Q" && |
| 200 | |
| 201 | git log -g -1 conflicts >branch-expect && |
| 202 | ( |
| 203 | if test -n "$reflog_action" |
| 204 | then |
| 205 | GIT_REFLOG_ACTION="$reflog_action" && |
| 206 | export GIT_REFLOG_ACTION |
| 207 | fi && |
| 208 | test_must_fail git rebase $mode main && |
| 209 | git rebase --abort |
| 210 | ) && |
| 211 | |
| 212 | git log -g --format=%gs -3 >actual && |
| 213 | write_reflog_expect <<-EOF && |
| 214 | ${reflog_action:-rebase} (abort): returning to refs/heads/conflicts |
| 215 | ${reflog_action:-rebase} (pick): P |
| 216 | ${reflog_action:-rebase} (start): checkout main |
| 217 | EOF |
| 218 | test_cmp expect actual && |
| 219 | |
| 220 | # check branch reflog is unchanged |
| 221 | git log -g -1 conflicts >branch-actual && |
| 222 | test_cmp branch-expect branch-actual |
| 223 | ' |
| 224 | |
| 225 | test_expect_success "rebase $mode --abort detached HEAD reflog${reflog_action:+ GIT_REFLOG_ACTION=$reflog_action}" ' |
| 226 | git checkout Q && |
| 227 | test_when_finished "git reset --hard Q" && |
| 228 | |
| 229 | ( |
| 230 | if test -n "$reflog_action" |
| 231 | then |
| 232 | GIT_REFLOG_ACTION="$reflog_action" && |
| 233 | export GIT_REFLOG_ACTION |
| 234 | fi && |
| 235 | test_must_fail git rebase $mode main && |
| 236 | git rebase --abort |
| 237 | ) && |
| 238 | |
| 239 | git log -g --format=%gs -3 >actual && |
| 240 | write_reflog_expect <<-EOF && |
| 241 | ${reflog_action:-rebase} (abort): returning to $(git rev-parse Q) |
| 242 | ${reflog_action:-rebase} (pick): P |
| 243 | ${reflog_action:-rebase} (start): checkout main |
| 244 | EOF |
| 245 | test_cmp expect actual |
| 246 | ' |
| 247 | } |
| 248 | |
| 249 | test_reflog --merge |
| 250 | test_reflog --merge my-reflog-action |
| 251 | test_reflog --apply |
| 252 | test_reflog --apply my-reflog-action |
| 253 | |
| 254 | test_expect_success 'rebase -i onto unrelated history' ' |
| 255 | git init unrelated && |
| 256 | test_commit -C unrelated 1 && |
| 257 | git -C unrelated remote add -f origin "$PWD" && |
| 258 | git -C unrelated branch --set-upstream-to=origin/main && |
| 259 | git -C unrelated -c core.editor=true rebase -i -v --stat >actual && |
| 260 | test_grep "Changes to " actual && |
| 261 | test_grep "5 files changed" actual |
| 262 | ' |
| 263 | |
| 264 | test_done |