OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # Copyright 2013 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. |
| 5 |
| 6 """Unit tests for git_rebase_update.py""" |
| 7 |
| 8 import os |
| 9 import sys |
| 10 |
| 11 DEPOT_TOOLS_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| 12 sys.path.insert(0, DEPOT_TOOLS_ROOT) |
| 13 |
| 14 from testing_support import coverage_utils |
| 15 from testing_support import git_test_utils |
| 16 |
| 17 class GitRebaseUpdateTest(git_test_utils.GitRepoReadWriteTestBase): |
| 18 REPO_SCHEMA = """ |
| 19 A B C D E F G |
| 20 B H I J K |
| 21 J L |
| 22 """ |
| 23 |
| 24 @classmethod |
| 25 def getRepoContent(cls, commit): |
| 26 # Every commit X gets a file X with the content X |
| 27 return {commit: {'data': commit}} |
| 28 |
| 29 @classmethod |
| 30 def setUpClass(cls): |
| 31 super(GitRebaseUpdateTest, cls).setUpClass() |
| 32 import git_rebase_update, git_new_branch, git_reparent_branch, git_common |
| 33 cls.reup = git_rebase_update |
| 34 cls.rp = git_reparent_branch |
| 35 cls.nb = git_new_branch |
| 36 cls.gc = git_common |
| 37 cls.gc.TEST_MODE = True |
| 38 |
| 39 def setUp(self): |
| 40 super(GitRebaseUpdateTest, self).setUp() |
| 41 # Include branch_K, branch_L to make sure that ABCDEFG all get the |
| 42 # same commit hashes as self.repo. Otherwise they get committed with the |
| 43 # wrong timestamps, due to commit ordering. |
| 44 # TODO(iannucci): Make commit timestamps deterministic in left to right, top |
| 45 # to bottom order, not in lexi-topographical order. |
| 46 origin_schema = git_test_utils.GitRepoSchema(""" |
| 47 A B C D E F G M N O |
| 48 B H I J K |
| 49 J L |
| 50 """, self.getRepoContent) |
| 51 self.origin = origin_schema.reify() |
| 52 self.origin.git('checkout', 'master') |
| 53 self.origin.git('branch', '-d', *['branch_'+l for l in 'KLG']) |
| 54 |
| 55 self.repo.git('remote', 'add', 'origin', self.origin.repo_path) |
| 56 self.repo.git('update-ref', 'refs/remotes/origin/master', 'tag_E') |
| 57 self.repo.git('branch', '--set-upstream-to', 'branch_G', 'branch_K') |
| 58 self.repo.git('branch', '--set-upstream-to', 'branch_K', 'branch_L') |
| 59 self.repo.git('branch', '--set-upstream-to', 'origin/master', 'branch_G') |
| 60 |
| 61 def tearDown(self): |
| 62 self.origin.nuke() |
| 63 super(GitRebaseUpdateTest, self).tearDown() |
| 64 |
| 65 def testRebaseUpdate(self): |
| 66 graphlines = lambda: [ |
| 67 l.strip() for l in self.repo.git( |
| 68 'log', '--graph', '--format=%s', '--branches').stdout.splitlines() |
| 69 ] |
| 70 |
| 71 self.repo.git('checkout', 'branch_K') |
| 72 |
| 73 self.repo.run(self.nb.main, ['foobar']) |
| 74 self.assertEqual(self.repo.git('rev-parse', 'HEAD').stdout, |
| 75 self.repo.git('rev-parse', 'origin/master').stdout) |
| 76 |
| 77 with self.repo.open('foobar', 'w') as f: |
| 78 f.write('this is the foobar file') |
| 79 self.repo.git('add', 'foobar') |
| 80 self.repo.git_commit('foobar1') |
| 81 |
| 82 with self.repo.open('foobar', 'w') as f: |
| 83 f.write('totes the Foobar file') |
| 84 self.repo.git_commit('foobar2') |
| 85 |
| 86 self.repo.git('checkout', 'branch_K') |
| 87 self.repo.run(self.nb.main, ['--upstream_current', 'sub_K']) |
| 88 with self.repo.open('K', 'w') as f: |
| 89 f.write('This depends on K') |
| 90 self.repo.git_commit('sub_K') |
| 91 |
| 92 self.repo.run(self.nb.main, ['old_branch']) |
| 93 self.repo.git('reset', '--hard', self.repo['A']) |
| 94 with self.repo.open('old_file', 'w') as f: |
| 95 f.write('old_files we want to keep around') |
| 96 self.repo.git('add', 'old_file') |
| 97 self.repo.git_commit('old_file') |
| 98 self.repo.git('config', 'branch.old_branch.dormant', 'true') |
| 99 |
| 100 self.repo.git('checkout', 'origin/master') |
| 101 |
| 102 self.assertEqual( |
| 103 graphlines(), [ |
| 104 '* old_file', |
| 105 '| * sub_K', |
| 106 '| * K', |
| 107 '| | * foobar2', |
| 108 '| | * foobar1', |
| 109 '| | | * G', |
| 110 '| | | * F', |
| 111 '| | |/', |
| 112 '| | * E', |
| 113 '| | * D', |
| 114 '| | * C', |
| 115 '| | | * L', |
| 116 '| | |/', |
| 117 '| |/|', |
| 118 '| * | J', |
| 119 '| * | I', |
| 120 '| * | H', |
| 121 '| |/', |
| 122 '| * B', |
| 123 '|/', |
| 124 '* A' |
| 125 ] |
| 126 ) |
| 127 self.assertEquals(self.repo['A'], self.origin['A']) |
| 128 self.assertEquals(self.repo['E'], self.origin['E']) |
| 129 |
| 130 with self.repo.open('bob', 'wb') as f: |
| 131 f.write('testing auto-freeze/thaw') |
| 132 |
| 133 output, _ = self.repo.capture_stdio(self.reup.main) |
| 134 self.assertIn('Cannot rebase-update', output) |
| 135 |
| 136 self.repo.git('checkout', 'branch_K') |
| 137 |
| 138 output, _ = self.repo.capture_stdio(self.reup.main) |
| 139 |
| 140 self.assertIn('Rebasing: branch_G', output) |
| 141 self.assertIn('Rebasing: branch_K', output) |
| 142 self.assertIn('Rebasing: branch_L', output) |
| 143 self.assertIn('Rebasing: foobar', output) |
| 144 self.assertIn('Rebasing: sub_K', output) |
| 145 self.assertIn('Deleted branch branch_G', output) |
| 146 self.assertIn('Reparented branch_K to track origin/master', output) |
| 147 |
| 148 self.assertEqual( |
| 149 graphlines(), [ |
| 150 '* old_file', |
| 151 '| * sub_K', |
| 152 '| | * foobar2', |
| 153 '| | * foobar1', |
| 154 '| | | * L', |
| 155 '| | |/', |
| 156 '| |/|', |
| 157 '| * | K', |
| 158 '| * | J', |
| 159 '| * | I', |
| 160 '| * | H', |
| 161 '| |/', |
| 162 '| * O', |
| 163 '| * N', |
| 164 '| * M', |
| 165 '| * G', |
| 166 '| * F', |
| 167 '| * E', |
| 168 '| * D', |
| 169 '| * C', |
| 170 '| * B', |
| 171 '|/', |
| 172 '* A' |
| 173 ] |
| 174 ) |
| 175 |
| 176 output, _ = self.repo.capture_stdio(self.reup.main) |
| 177 self.assertIn('branch_K up-to-date', output) |
| 178 self.assertIn('branch_L up-to-date', output) |
| 179 self.assertIn('foobar up-to-date', output) |
| 180 self.assertIn('sub_K up-to-date', output) |
| 181 |
| 182 with self.repo.open('bob') as f: |
| 183 self.assertEquals('testing auto-freeze/thaw', f.read()) |
| 184 |
| 185 self.assertEqual(self.repo.git('status', '--porcelain').stdout, '?? bob\n') |
| 186 |
| 187 self.repo.git('checkout', 'origin/master') |
| 188 _, err = self.repo.capture_stdio(self.rp.main, ['foobar']) |
| 189 self.assertIn('Must be on the branch', err) |
| 190 |
| 191 self.repo.git('checkout', 'branch_K') |
| 192 _, err = self.repo.capture_stdio(self.rp.main, ['origin/master']) |
| 193 self.assertIn('Cannot reparent a branch to its existing parent', err) |
| 194 output, _ = self.repo.capture_stdio(self.rp.main, ['foobar']) |
| 195 self.assertIn('Rebasing: branch_K', output) |
| 196 self.assertIn('Rebasing: sub_K', output) |
| 197 self.assertIn('Rebasing: branch_L', output) |
| 198 |
| 199 self.assertEqual( |
| 200 graphlines(), [ |
| 201 '* old_file', |
| 202 '| * sub_K', |
| 203 '| | * L', |
| 204 '| |/', |
| 205 '| * K', |
| 206 '| * J', |
| 207 '| * I', |
| 208 '| * H', |
| 209 '| * foobar2', |
| 210 '| * foobar1', |
| 211 '| * O', |
| 212 '| * N', |
| 213 '| * M', |
| 214 '| * G', |
| 215 '| * F', |
| 216 '| * E', |
| 217 '| * D', |
| 218 '| * C', |
| 219 '| * B', |
| 220 '|/', |
| 221 '* A' |
| 222 ] |
| 223 ) |
| 224 |
| 225 self.repo.git('checkout', 'sub_K') |
| 226 output, _ = self.repo.capture_stdio(self.rp.main, ['foobar']) |
| 227 self.assertIn('Squashing failed', output) |
| 228 |
| 229 self.assertTrue(self.repo.run(self.gc.in_rebase)) |
| 230 |
| 231 self.repo.git('rebase', '--abort') |
| 232 self.repo.git('thaw') |
| 233 |
| 234 self.assertEqual( |
| 235 graphlines(), [ |
| 236 '* old_file', |
| 237 '| * sub_K', |
| 238 '| | * L', |
| 239 '| |/', |
| 240 '| * K', |
| 241 '| * J', |
| 242 '| * I', |
| 243 '| * H', |
| 244 '| * foobar2', |
| 245 '| * foobar1', |
| 246 '| * O', |
| 247 '| * N', |
| 248 '| * M', |
| 249 '| * G', |
| 250 '| * F', |
| 251 '| * E', |
| 252 '| * D', |
| 253 '| * C', |
| 254 '| * B', |
| 255 '|/', |
| 256 '* A' |
| 257 ] |
| 258 ) |
| 259 |
| 260 self.assertEqual(self.repo.git('status', '--porcelain').stdout, '?? bob\n') |
| 261 |
| 262 |
| 263 def testRebaseConflicts(self): |
| 264 # Pretend that branch_L landed |
| 265 self.origin.git('checkout', 'master') |
| 266 with self.origin.open('L', 'w') as f: |
| 267 f.write('L') |
| 268 self.origin.git('add', 'L') |
| 269 self.origin.git_commit('L') |
| 270 |
| 271 # Add a commit to branch_K so that things fail |
| 272 self.repo.git('checkout', 'branch_K') |
| 273 with self.repo.open('M', 'w') as f: |
| 274 f.write('NOPE') |
| 275 self.repo.git('add', 'M') |
| 276 self.repo.git_commit('K NOPE') |
| 277 |
| 278 # Add a commits to branch_L which will work when squashed |
| 279 self.repo.git('checkout', 'branch_L') |
| 280 self.repo.git('reset', 'branch_L~') |
| 281 with self.repo.open('L', 'w') as f: |
| 282 f.write('NOPE') |
| 283 self.repo.git('add', 'L') |
| 284 self.repo.git_commit('L NOPE') |
| 285 with self.repo.open('L', 'w') as f: |
| 286 f.write('L') |
| 287 self.repo.git('add', 'L') |
| 288 self.repo.git_commit('L YUP') |
| 289 |
| 290 # start on a branch which will be deleted |
| 291 self.repo.git('checkout', 'branch_G') |
| 292 |
| 293 output, _ = self.repo.capture_stdio(self.reup.main) |
| 294 self.assertIn('branch.branch_K.dormant true', output) |
| 295 |
| 296 output, _ = self.repo.capture_stdio(self.reup.main) |
| 297 self.assertIn('Rebase in progress', output) |
| 298 |
| 299 self.repo.git('checkout', '--theirs', 'M') |
| 300 self.repo.git('rebase', '--skip') |
| 301 |
| 302 output, _ = self.repo.capture_stdio(self.reup.main) |
| 303 self.assertIn('Failed! Attempting to squash', output) |
| 304 self.assertIn('Deleted branch branch_G', output) |
| 305 self.assertIn('Deleted branch branch_L', output) |
| 306 self.assertIn('\'branch_G\' was merged', output) |
| 307 self.assertIn('checking out \'origin/master\'', output) |
| 308 |
| 309 |
| 310 def testTrackTag(self): |
| 311 self.origin.git('tag', 'lkgr', self.origin['M']) |
| 312 self.repo.git('tag', 'lkgr', self.repo['D']) |
| 313 |
| 314 self.repo.git('config', 'branch.branch_G.remote', '.') |
| 315 self.repo.git('config', 'branch.branch_G.merge', 'refs/tags/lkgr') |
| 316 |
| 317 self.assertIn( |
| 318 'fatal: \'foo bar\' is not a valid branch name', |
| 319 self.repo.capture_stdio(self.nb.main, ['--lkgr', 'foo bar'])[1]) |
| 320 |
| 321 self.repo.run(self.nb.main, ['--lkgr', 'foobar']) |
| 322 |
| 323 with self.repo.open('foobar', 'w') as f: |
| 324 f.write('this is the foobar file') |
| 325 self.repo.git('add', 'foobar') |
| 326 self.repo.git_commit('foobar1') |
| 327 |
| 328 with self.repo.open('foobar', 'w') as f: |
| 329 f.write('totes the Foobar file') |
| 330 self.repo.git_commit('foobar2') |
| 331 |
| 332 graphlines = lambda: [ |
| 333 l.strip() for l in self.repo.git( |
| 334 'log', '--graph', '--format=%s', '--branches', 'origin/master' |
| 335 ).stdout.splitlines() |
| 336 ] |
| 337 self.assertEqual( |
| 338 graphlines(), [ |
| 339 '* foobar2', |
| 340 '* foobar1', |
| 341 '| * G', |
| 342 '| * F', |
| 343 '| * E', |
| 344 '|/', |
| 345 '* D', |
| 346 '* C', |
| 347 '| * L', |
| 348 '| | * K', |
| 349 '| |/', |
| 350 '| * J', |
| 351 '| * I', |
| 352 '| * H', |
| 353 '|/', |
| 354 '* B', |
| 355 '* A', |
| 356 ] |
| 357 ) |
| 358 self.assertEquals(self.repo['A'], self.origin['A']) |
| 359 self.assertEquals(self.repo['G'], self.origin['G']) |
| 360 |
| 361 output, _ = self.repo.capture_stdio(self.reup.main) |
| 362 self.assertIn('Rebasing: branch_G', output) |
| 363 self.assertIn('Rebasing: branch_K', output) |
| 364 self.assertIn('Rebasing: branch_L', output) |
| 365 self.assertIn('Rebasing: foobar', output) |
| 366 self.assertEquals(self.repo.git('rev-parse', 'lkgr').stdout.strip(), |
| 367 self.origin['M']) |
| 368 |
| 369 self.assertEqual( |
| 370 graphlines(), [ |
| 371 '* O', |
| 372 '* N', |
| 373 '| * foobar2', |
| 374 '| * foobar1', |
| 375 '|/', |
| 376 '| * L', |
| 377 '| * K', |
| 378 '| * J', |
| 379 '| * I', |
| 380 '| * H', |
| 381 '|/', |
| 382 '* M', |
| 383 '* G', |
| 384 '* F', |
| 385 '* E', |
| 386 '* D', |
| 387 '* C', |
| 388 '* B', |
| 389 '* A' |
| 390 ] |
| 391 ) |
| 392 |
| 393 _, err = self.repo.capture_stdio(self.rp.main, ['tag F']) |
| 394 self.assertIn('fatal: invalid reference', err) |
| 395 |
| 396 output, _ = self.repo.capture_stdio(self.rp.main, ['tag_F']) |
| 397 self.assertIn('to track tag_F [tag] (was lkgr [tag])', output) |
| 398 |
| 399 self.assertEqual( |
| 400 graphlines(), [ |
| 401 '* O', |
| 402 '* N', |
| 403 '| * foobar2', |
| 404 '| * foobar1', |
| 405 '| | * L', |
| 406 '| | * K', |
| 407 '| | * J', |
| 408 '| | * I', |
| 409 '| | * H', |
| 410 '| |/', |
| 411 '|/|', |
| 412 '* | M', |
| 413 '* | G', |
| 414 '|/', |
| 415 '* F', |
| 416 '* E', |
| 417 '* D', |
| 418 '* C', |
| 419 '* B', |
| 420 '* A' |
| 421 ] |
| 422 ) |
| 423 |
| 424 |
| 425 |
| 426 if __name__ == '__main__': |
| 427 sys.exit(coverage_utils.covered_main(( |
| 428 os.path.join(DEPOT_TOOLS_ROOT, 'git_rebase_update.py'), |
| 429 os.path.join(DEPOT_TOOLS_ROOT, 'git_new_branch.py'), |
| 430 os.path.join(DEPOT_TOOLS_ROOT, 'git_reparent_branch.py') |
| 431 ))) |
OLD | NEW |