| Index: tests/git_rebase_update_test.py
|
| diff --git a/tests/git_rebase_update_test.py b/tests/git_rebase_update_test.py
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..f73eefe07bbfc6ec99f1a6484be20c0547ecbd5b
|
| --- /dev/null
|
| +++ b/tests/git_rebase_update_test.py
|
| @@ -0,0 +1,431 @@
|
| +#!/usr/bin/env python
|
| +# Copyright 2013 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +"""Unit tests for git_rebase_update.py"""
|
| +
|
| +import os
|
| +import sys
|
| +
|
| +DEPOT_TOOLS_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
| +sys.path.insert(0, DEPOT_TOOLS_ROOT)
|
| +
|
| +from testing_support import coverage_utils
|
| +from testing_support import git_test_utils
|
| +
|
| +class GitRebaseUpdateTest(git_test_utils.GitRepoReadWriteTestBase):
|
| + REPO_SCHEMA = """
|
| + A B C D E F G
|
| + B H I J K
|
| + J L
|
| + """
|
| +
|
| + @classmethod
|
| + def getRepoContent(cls, commit):
|
| + # Every commit X gets a file X with the content X
|
| + return {commit: {'data': commit}}
|
| +
|
| + @classmethod
|
| + def setUpClass(cls):
|
| + super(GitRebaseUpdateTest, cls).setUpClass()
|
| + import git_rebase_update, git_new_branch, git_reparent_branch, git_common
|
| + cls.reup = git_rebase_update
|
| + cls.rp = git_reparent_branch
|
| + cls.nb = git_new_branch
|
| + cls.gc = git_common
|
| + cls.gc.TEST_MODE = True
|
| +
|
| + def setUp(self):
|
| + super(GitRebaseUpdateTest, self).setUp()
|
| + # Include branch_K, branch_L to make sure that ABCDEFG all get the
|
| + # same commit hashes as self.repo. Otherwise they get committed with the
|
| + # wrong timestamps, due to commit ordering.
|
| + # TODO(iannucci): Make commit timestamps deterministic in left to right, top
|
| + # to bottom order, not in lexi-topographical order.
|
| + origin_schema = git_test_utils.GitRepoSchema("""
|
| + A B C D E F G M N O
|
| + B H I J K
|
| + J L
|
| + """, self.getRepoContent)
|
| + self.origin = origin_schema.reify()
|
| + self.origin.git('checkout', 'master')
|
| + self.origin.git('branch', '-d', *['branch_'+l for l in 'KLG'])
|
| +
|
| + self.repo.git('remote', 'add', 'origin', self.origin.repo_path)
|
| + self.repo.git('update-ref', 'refs/remotes/origin/master', 'tag_E')
|
| + self.repo.git('branch', '--set-upstream-to', 'branch_G', 'branch_K')
|
| + self.repo.git('branch', '--set-upstream-to', 'branch_K', 'branch_L')
|
| + self.repo.git('branch', '--set-upstream-to', 'origin/master', 'branch_G')
|
| +
|
| + def tearDown(self):
|
| + self.origin.nuke()
|
| + super(GitRebaseUpdateTest, self).tearDown()
|
| +
|
| + def testRebaseUpdate(self):
|
| + graphlines = lambda: [
|
| + l.strip() for l in self.repo.git(
|
| + 'log', '--graph', '--format=%s', '--branches').stdout.splitlines()
|
| + ]
|
| +
|
| + self.repo.git('checkout', 'branch_K')
|
| +
|
| + self.repo.run(self.nb.main, ['foobar'])
|
| + self.assertEqual(self.repo.git('rev-parse', 'HEAD').stdout,
|
| + self.repo.git('rev-parse', 'origin/master').stdout)
|
| +
|
| + with self.repo.open('foobar', 'w') as f:
|
| + f.write('this is the foobar file')
|
| + self.repo.git('add', 'foobar')
|
| + self.repo.git_commit('foobar1')
|
| +
|
| + with self.repo.open('foobar', 'w') as f:
|
| + f.write('totes the Foobar file')
|
| + self.repo.git_commit('foobar2')
|
| +
|
| + self.repo.git('checkout', 'branch_K')
|
| + self.repo.run(self.nb.main, ['--upstream_current', 'sub_K'])
|
| + with self.repo.open('K', 'w') as f:
|
| + f.write('This depends on K')
|
| + self.repo.git_commit('sub_K')
|
| +
|
| + self.repo.run(self.nb.main, ['old_branch'])
|
| + self.repo.git('reset', '--hard', self.repo['A'])
|
| + with self.repo.open('old_file', 'w') as f:
|
| + f.write('old_files we want to keep around')
|
| + self.repo.git('add', 'old_file')
|
| + self.repo.git_commit('old_file')
|
| + self.repo.git('config', 'branch.old_branch.dormant', 'true')
|
| +
|
| + self.repo.git('checkout', 'origin/master')
|
| +
|
| + self.assertEqual(
|
| + graphlines(), [
|
| + '* old_file',
|
| + '| * sub_K',
|
| + '| * K',
|
| + '| | * foobar2',
|
| + '| | * foobar1',
|
| + '| | | * G',
|
| + '| | | * F',
|
| + '| | |/',
|
| + '| | * E',
|
| + '| | * D',
|
| + '| | * C',
|
| + '| | | * L',
|
| + '| | |/',
|
| + '| |/|',
|
| + '| * | J',
|
| + '| * | I',
|
| + '| * | H',
|
| + '| |/',
|
| + '| * B',
|
| + '|/',
|
| + '* A'
|
| + ]
|
| + )
|
| + self.assertEquals(self.repo['A'], self.origin['A'])
|
| + self.assertEquals(self.repo['E'], self.origin['E'])
|
| +
|
| + with self.repo.open('bob', 'wb') as f:
|
| + f.write('testing auto-freeze/thaw')
|
| +
|
| + output, _ = self.repo.capture_stdio(self.reup.main)
|
| + self.assertIn('Cannot rebase-update', output)
|
| +
|
| + self.repo.git('checkout', 'branch_K')
|
| +
|
| + output, _ = self.repo.capture_stdio(self.reup.main)
|
| +
|
| + self.assertIn('Rebasing: branch_G', output)
|
| + self.assertIn('Rebasing: branch_K', output)
|
| + self.assertIn('Rebasing: branch_L', output)
|
| + self.assertIn('Rebasing: foobar', output)
|
| + self.assertIn('Rebasing: sub_K', output)
|
| + self.assertIn('Deleted branch branch_G', output)
|
| + self.assertIn('Reparented branch_K to track origin/master', output)
|
| +
|
| + self.assertEqual(
|
| + graphlines(), [
|
| + '* old_file',
|
| + '| * sub_K',
|
| + '| | * foobar2',
|
| + '| | * foobar1',
|
| + '| | | * L',
|
| + '| | |/',
|
| + '| |/|',
|
| + '| * | K',
|
| + '| * | J',
|
| + '| * | I',
|
| + '| * | H',
|
| + '| |/',
|
| + '| * O',
|
| + '| * N',
|
| + '| * M',
|
| + '| * G',
|
| + '| * F',
|
| + '| * E',
|
| + '| * D',
|
| + '| * C',
|
| + '| * B',
|
| + '|/',
|
| + '* A'
|
| + ]
|
| + )
|
| +
|
| + output, _ = self.repo.capture_stdio(self.reup.main)
|
| + self.assertIn('branch_K up-to-date', output)
|
| + self.assertIn('branch_L up-to-date', output)
|
| + self.assertIn('foobar up-to-date', output)
|
| + self.assertIn('sub_K up-to-date', output)
|
| +
|
| + with self.repo.open('bob') as f:
|
| + self.assertEquals('testing auto-freeze/thaw', f.read())
|
| +
|
| + self.assertEqual(self.repo.git('status', '--porcelain').stdout, '?? bob\n')
|
| +
|
| + self.repo.git('checkout', 'origin/master')
|
| + _, err = self.repo.capture_stdio(self.rp.main, ['foobar'])
|
| + self.assertIn('Must be on the branch', err)
|
| +
|
| + self.repo.git('checkout', 'branch_K')
|
| + _, err = self.repo.capture_stdio(self.rp.main, ['origin/master'])
|
| + self.assertIn('Cannot reparent a branch to its existing parent', err)
|
| + output, _ = self.repo.capture_stdio(self.rp.main, ['foobar'])
|
| + self.assertIn('Rebasing: branch_K', output)
|
| + self.assertIn('Rebasing: sub_K', output)
|
| + self.assertIn('Rebasing: branch_L', output)
|
| +
|
| + self.assertEqual(
|
| + graphlines(), [
|
| + '* old_file',
|
| + '| * sub_K',
|
| + '| | * L',
|
| + '| |/',
|
| + '| * K',
|
| + '| * J',
|
| + '| * I',
|
| + '| * H',
|
| + '| * foobar2',
|
| + '| * foobar1',
|
| + '| * O',
|
| + '| * N',
|
| + '| * M',
|
| + '| * G',
|
| + '| * F',
|
| + '| * E',
|
| + '| * D',
|
| + '| * C',
|
| + '| * B',
|
| + '|/',
|
| + '* A'
|
| + ]
|
| + )
|
| +
|
| + self.repo.git('checkout', 'sub_K')
|
| + output, _ = self.repo.capture_stdio(self.rp.main, ['foobar'])
|
| + self.assertIn('Squashing failed', output)
|
| +
|
| + self.assertTrue(self.repo.run(self.gc.in_rebase))
|
| +
|
| + self.repo.git('rebase', '--abort')
|
| + self.repo.git('thaw')
|
| +
|
| + self.assertEqual(
|
| + graphlines(), [
|
| + '* old_file',
|
| + '| * sub_K',
|
| + '| | * L',
|
| + '| |/',
|
| + '| * K',
|
| + '| * J',
|
| + '| * I',
|
| + '| * H',
|
| + '| * foobar2',
|
| + '| * foobar1',
|
| + '| * O',
|
| + '| * N',
|
| + '| * M',
|
| + '| * G',
|
| + '| * F',
|
| + '| * E',
|
| + '| * D',
|
| + '| * C',
|
| + '| * B',
|
| + '|/',
|
| + '* A'
|
| + ]
|
| + )
|
| +
|
| + self.assertEqual(self.repo.git('status', '--porcelain').stdout, '?? bob\n')
|
| +
|
| +
|
| + def testRebaseConflicts(self):
|
| + # Pretend that branch_L landed
|
| + self.origin.git('checkout', 'master')
|
| + with self.origin.open('L', 'w') as f:
|
| + f.write('L')
|
| + self.origin.git('add', 'L')
|
| + self.origin.git_commit('L')
|
| +
|
| + # Add a commit to branch_K so that things fail
|
| + self.repo.git('checkout', 'branch_K')
|
| + with self.repo.open('M', 'w') as f:
|
| + f.write('NOPE')
|
| + self.repo.git('add', 'M')
|
| + self.repo.git_commit('K NOPE')
|
| +
|
| + # Add a commits to branch_L which will work when squashed
|
| + self.repo.git('checkout', 'branch_L')
|
| + self.repo.git('reset', 'branch_L~')
|
| + with self.repo.open('L', 'w') as f:
|
| + f.write('NOPE')
|
| + self.repo.git('add', 'L')
|
| + self.repo.git_commit('L NOPE')
|
| + with self.repo.open('L', 'w') as f:
|
| + f.write('L')
|
| + self.repo.git('add', 'L')
|
| + self.repo.git_commit('L YUP')
|
| +
|
| + # start on a branch which will be deleted
|
| + self.repo.git('checkout', 'branch_G')
|
| +
|
| + output, _ = self.repo.capture_stdio(self.reup.main)
|
| + self.assertIn('branch.branch_K.dormant true', output)
|
| +
|
| + output, _ = self.repo.capture_stdio(self.reup.main)
|
| + self.assertIn('Rebase in progress', output)
|
| +
|
| + self.repo.git('checkout', '--theirs', 'M')
|
| + self.repo.git('rebase', '--skip')
|
| +
|
| + output, _ = self.repo.capture_stdio(self.reup.main)
|
| + self.assertIn('Failed! Attempting to squash', output)
|
| + self.assertIn('Deleted branch branch_G', output)
|
| + self.assertIn('Deleted branch branch_L', output)
|
| + self.assertIn('\'branch_G\' was merged', output)
|
| + self.assertIn('checking out \'origin/master\'', output)
|
| +
|
| +
|
| + def testTrackTag(self):
|
| + self.origin.git('tag', 'lkgr', self.origin['M'])
|
| + self.repo.git('tag', 'lkgr', self.repo['D'])
|
| +
|
| + self.repo.git('config', 'branch.branch_G.remote', '.')
|
| + self.repo.git('config', 'branch.branch_G.merge', 'refs/tags/lkgr')
|
| +
|
| + self.assertIn(
|
| + 'fatal: \'foo bar\' is not a valid branch name',
|
| + self.repo.capture_stdio(self.nb.main, ['--lkgr', 'foo bar'])[1])
|
| +
|
| + self.repo.run(self.nb.main, ['--lkgr', 'foobar'])
|
| +
|
| + with self.repo.open('foobar', 'w') as f:
|
| + f.write('this is the foobar file')
|
| + self.repo.git('add', 'foobar')
|
| + self.repo.git_commit('foobar1')
|
| +
|
| + with self.repo.open('foobar', 'w') as f:
|
| + f.write('totes the Foobar file')
|
| + self.repo.git_commit('foobar2')
|
| +
|
| + graphlines = lambda: [
|
| + l.strip() for l in self.repo.git(
|
| + 'log', '--graph', '--format=%s', '--branches', 'origin/master'
|
| + ).stdout.splitlines()
|
| + ]
|
| + self.assertEqual(
|
| + graphlines(), [
|
| + '* foobar2',
|
| + '* foobar1',
|
| + '| * G',
|
| + '| * F',
|
| + '| * E',
|
| + '|/',
|
| + '* D',
|
| + '* C',
|
| + '| * L',
|
| + '| | * K',
|
| + '| |/',
|
| + '| * J',
|
| + '| * I',
|
| + '| * H',
|
| + '|/',
|
| + '* B',
|
| + '* A',
|
| + ]
|
| + )
|
| + self.assertEquals(self.repo['A'], self.origin['A'])
|
| + self.assertEquals(self.repo['G'], self.origin['G'])
|
| +
|
| + output, _ = self.repo.capture_stdio(self.reup.main)
|
| + self.assertIn('Rebasing: branch_G', output)
|
| + self.assertIn('Rebasing: branch_K', output)
|
| + self.assertIn('Rebasing: branch_L', output)
|
| + self.assertIn('Rebasing: foobar', output)
|
| + self.assertEquals(self.repo.git('rev-parse', 'lkgr').stdout.strip(),
|
| + self.origin['M'])
|
| +
|
| + self.assertEqual(
|
| + graphlines(), [
|
| + '* O',
|
| + '* N',
|
| + '| * foobar2',
|
| + '| * foobar1',
|
| + '|/',
|
| + '| * L',
|
| + '| * K',
|
| + '| * J',
|
| + '| * I',
|
| + '| * H',
|
| + '|/',
|
| + '* M',
|
| + '* G',
|
| + '* F',
|
| + '* E',
|
| + '* D',
|
| + '* C',
|
| + '* B',
|
| + '* A'
|
| + ]
|
| + )
|
| +
|
| + _, err = self.repo.capture_stdio(self.rp.main, ['tag F'])
|
| + self.assertIn('fatal: invalid reference', err)
|
| +
|
| + output, _ = self.repo.capture_stdio(self.rp.main, ['tag_F'])
|
| + self.assertIn('to track tag_F [tag] (was lkgr [tag])', output)
|
| +
|
| + self.assertEqual(
|
| + graphlines(), [
|
| + '* O',
|
| + '* N',
|
| + '| * foobar2',
|
| + '| * foobar1',
|
| + '| | * L',
|
| + '| | * K',
|
| + '| | * J',
|
| + '| | * I',
|
| + '| | * H',
|
| + '| |/',
|
| + '|/|',
|
| + '* | M',
|
| + '* | G',
|
| + '|/',
|
| + '* F',
|
| + '* E',
|
| + '* D',
|
| + '* C',
|
| + '* B',
|
| + '* A'
|
| + ]
|
| + )
|
| +
|
| +
|
| +
|
| +if __name__ == '__main__':
|
| + sys.exit(coverage_utils.covered_main((
|
| + os.path.join(DEPOT_TOOLS_ROOT, 'git_rebase_update.py'),
|
| + os.path.join(DEPOT_TOOLS_ROOT, 'git_new_branch.py'),
|
| + os.path.join(DEPOT_TOOLS_ROOT, 'git_reparent_branch.py')
|
| + )))
|
|
|