def test_upstream(self): Fixture.from_scheme("""1:-a1 s:-a1 d:-a1 a:-1a 2:-a2 s:-a2 d:-a2 a:-2a""").actualize() misc.checkout('1/staging') self.assert_aflow_dies_with( 'Error: 1/a_v1 is merged in master. In git-aflow you cannot revert ' 'a topic until it is reverted from the upstream branch.', 'revert', 'a') misc.checkout('1/develop') self.assert_aflow_dies_with( 'Error: 1/a_v1 is merged in 1/staging. In git-aflow you cannot ' 'revert a topic until it is reverted from the upstream branch.', 'revert', 'a') misc.checkout('2/staging') self.assert_aflow_dies_with( 'Error: 2/a_v2 is merged in master. In git-aflow you cannot revert ' 'a topic until it is reverted from the upstream branch.', 'revert', 'a') self.assert_aflow_returns_0(None, 'start', 'integration') self.assert_aflow_returns_0(None, 'merge', 'a') self.assert_aflow_returns_0('2/a_v2 reverted successfully.', 'revert', 'a')
def test_unfinish(self): Fixture.from_scheme("""1: s:-a1 d:-a1-e1-b1-c1-B1-b1-B1-b1 a:-1a b:-a1-e1-1b c:----------1c e:----1e""").actualize() self.assert_aflow_dies_with( "1/a_v1 was previously merged in 1/staging, so it's impossible to " "unfinish it.", 'continue', '-u', 'a') dev_head = misc.rev_parse('1/develop') self.assert_aflow_dies_with( 'Failed to continue 1/e_v1. It is merged in 1/b_v1 which was later ' 'merged in 1/develop. 1/develop reset back to ' + dev_head + '.', 'continue', '-u', 'e') self.assert_aflow_returns_0( '1/b_v1 created and checked out. Use "git af topic finish" to ' 'merge new revision of topic into develop', 'continue', '-u', 'b') self.assert_aflow_returns_0( """Using "End User Feature" as default topic type. 1/b_v1 merged into 1/develop successfully. Branch 1/b_v1 deleted.""", 'finish') self.assertEqual(Fixture.from_repo(), Fixture.from_scheme(""" 1:- s:-a1 d:-a1-e1-c1-b1 c:-1c e:-1e a:-1a b:-a1-e1-1b"""))
def test_dependents(self): Fixture.from_scheme("""1: d:-a1-b1-c1 a:-1a b:-a1-1b c:-a1-b1-1c""").actualize() misc.checkout('1/develop') self.assert_aflow_dies_with( 'Unable to revert 1/a_v1 since 1/c_v1 depends on it. ' 'Revert it first or use "git af revert -d" revert dependent ' 'topics automatically.', 'revert', 'a') self.assert_aflow_returns_0("""1/c_v1 reverted successfully. 1/b_v1 reverted successfully. 1/a_v1 reverted successfully.""", 'revert', 'a', '-d') self.assertEqual(Fixture.from_repo(), Fixture.from_scheme(""" 1:- d:-a1-b1-c1-C1-B1-A1 b:-a1-1b a:-1a c:-a1-b1-1c""")) branch.reset('HEAD^^^') self.assert_aflow_returns_0("""1/c_v1 reverted successfully. 1/b_v1 reverted successfully.""", 'revert', 'b', 'c') self.assertEqual(Fixture.from_repo(), Fixture.from_scheme(""" 1:- d:-a1-b1-c1-C1-B1 b:-a1-1b a:-1a c:-a1-b1-1c"""))
def test_auto_name(self): Fixture.from_scheme("""1: d:-a1 a:-1a""").actualize() misc.checkout('1/develop^2') self.assert_aflow_returns_0( '1/a_v2 created and checked out. Use "git af topic finish" to ' 'merge new revision of topic into develop', 'continue')
def test_unexpected_conflict(self): Fixture.from_scheme("""1: d:-a1 a:-1a""").actualize() misc.checkout('1/develop') with open('a', 'w') as b: b.write('Does not matter') misc.add('a') commit.commit('No matter') self.assert_aflow_dies_with('Revert failed unexpectedly, aborting..', 'revert', 'a')
def test_checks(self): Fixture.from_scheme("""1: d:-a1 a:-1a""").actualize() misc.checkout('1/develop') self.assert_aflow_dies_with('Error: topic a specified more than once', 'revert', 'a', 'a_v1') self.assert_aflow_dies_with("Didn't found non-reverted merges of a_v2 " "in 1/develop", 'revert', 'a_v2') self.assert_aflow_dies_with("Didn't found non-reverted merges of b in " "1/develop", 'revert', 'b')
def test_unexpected_conflict(self): Fixture.from_scheme("""1: a:-1a""").actualize() misc.checkout('1/develop') with open('a', 'w') as b: b.write('Does not matter') misc.add('a') commit.commit('No matter') misc.checkout('1/a_v1') self.assert_aflow_dies_with( 'Using "End User Feature" as default topic type.' + os.linesep + 'Merge of 1/a_v1 conflicted unexpectedly. Conflict detector gave ' 'false negative result. 1/develop reset.', 'finish')
def test_exclude_current(self): Fixture.from_scheme('''1: d:-a1-------b1 b:----a1-1- a:-1a''').actualize() # branch c is based on a, so a_v1 should be excluded from merge misc.checkout('1/a') branch.create('c') misc.checkout('c') self.assert_aflow_returns_0( 'Using default topic source(s): develop' + os.linesep + '1/b_v1 merged successfully', 'merge', '-d', 'b')
def test_update_for_prev_iter_topic(self): Fixture.from_scheme("""1:-a1 s:-a1 d:-a1 a:-1a 2: d:-b1 b:-1b""").actualize() branch.create('2/a_v2', '2') misc.checkout('2/a_v2') commit.commit('No matter', allow_empty=True) self.assert_aflow_returns_0( """Taking topic type from previous merge of 1/a_v1. 2/a_v2 merged into 2/develop successfully. Branch 2/a_v2 deleted.""", 'finish')
def test_cross_iteration(self): Fixture.from_scheme("""1:-a1 s:-a1 d:-a1 a:-1a 2:""").actualize() misc.checkout('2/develop') self.assert_aflow_returns_0( '2/a_v2 created and checked out. Use "git af topic finish" to ' 'merge new revision of topic into develop', 'continue', 'a') commit.commit('No matter', allow_empty=True) self.assert_aflow_returns_0(None, 'finish') self.assert_aflow_dies_with( 'Failed to find merges of b in 2 and previous iterations.', 'continue', 'b') self.assert_aflow_returns_0( 'Please, note that a_v2' ' is already present in other iteration(s), so changes you will ' 'make for this revision in current iteration should correspond to ' 'changes made for same revision in other iterations. You may ' 'also use "git af port" to bring commits of some revision from ' 'one iteration to another.' + os.linesep + '1/a_v2 created and checked out. Use "git af topic finish" to ' 'merge new revision of topic into develop', 'continue', '1/a') misc.checkout('2/staging') self.assert_aflow_returns_0(None, 'merge', 'a') misc.checkout('master') self.assert_aflow_returns_0(None, 'merge', 'a') self.assert_aflow_returns_0(None, 'rebase', '-n', '3') self.assert_aflow_returns_0( '3/a_v3 created and checked out. Use "git af topic finish" to ' 'merge new revision of topic into develop', 'continue', 'a') commit.commit('No matter', allow_empty=True) self.assert_aflow_returns_0(None, 'finish') self.assertEqual(Fixture.from_repo(), Fixture.from_scheme(""" 1:-a1 s:-a1 d:-a1 a:-1a 2:-a2 s:-a2 d:-a2 a:-2- 3: d:-a3 a:-3-"""))
def test_complex(self): Fixture.from_scheme("""1: d:-a1-b1-a2-b2-c1 a:-1a-a--2A b:-1b-a1-a2-2--c1 c:-a1-a2-b1-b2-1c""").actualize() self.assert_aflow_returns_0(None, 'checkout', 'b') commit.commit('No matter', allow_empty=True) self.assert_aflow_returns_0(None, 'finish') self.assertEqual(Fixture.from_repo(), Fixture.from_scheme(""" 1:- s:- d:-a1-b1-a2-b2-c1-b3 a:-1a-a--2A b:-1b-a1-a2-2--c1-3- c:-a1-a2-b1-b2-1c"""))
def test_fake_merge(self): Fixture.from_scheme("""1: s:-a1 d:-a1 a:-1a""").actualize() misc.checkout('1/staging') self.assert_aflow_returns_0('1/a_v1 reverted successfully.', 'revert', 'a') self.assert_aflow_returns_0("""Using default topic source(s): develop 1/a_v1 merged successfully""", 'merge', 'a') self.assert_aflow_returns_0('1/a_v1 reverted successfully.', 'revert', 'a') self.assertEqual(Fixture.from_repo(), Fixture.from_scheme(""" 1:- s:-a1-A1-a1-A1 d:-a1 a:-1a"""))
def test_reverts(self): Fixture.from_scheme("""1: d:-a1 a:-1a b:-a1""").actualize() misc.checkout('1/b') self.assert_aflow_returns_0(None, 'revert', 'a') self.assert_aflow_dies_with( "Current topic contains reverts of topics from current iteration " "which is forbidden. Please rebase your topic excluding merges you " "don't like and try to finish it again.", 'finish') self.assert_aflow_returns_0(None, 'merge', 'a') self.assert_aflow_returns_0(None, 'revert', 'a') self.assert_aflow_dies_with( "Current topic contains reverts of topics from current iteration " "which is forbidden. Please rebase your topic excluding merges you " "don't like and try to finish it again.", 'finish')
def test_checks(self): Fixture.from_scheme("""1: d:-a1 a:-1a""").actualize() misc.checkout('1/develop') self.assert_aflow_dies_with( 'No topic name was specified, neither HEAD is pointing to ' 'last commit of some topic. Nothing to continue.', 'continue') self.assert_aflow_returns_0( 'Version suffix ignored.' + os.linesep + '1/a_v2 created and checked out. Use "git af topic finish" to ' + 'merge new revision of topic into develop', 'continue', 'a_v1') self.assert_aflow_dies_with( '1/a_v2 already exists. Use "git af checkout 1/a_v2" to continue ' 'your work on topic', 'continue', 'a')
def test_versions(self): Fixture.from_scheme("""1: d:-a1-b1-a2-c1-b2-a3 a:-1a-b1-2a-c1-b2-3a b:-a1-1b-a2-c1-2b c:-a1-b1-a2-1c""").actualize() misc.checkout('1/develop') self.assert_aflow_returns_0("""1/a_v3 reverted successfully. 1/b_v2 reverted successfully. 1/c_v1 reverted successfully. 1/a_v2 reverted successfully.""", 'revert', 'a_v2', '-d') self.assertEqual(Fixture.from_repo(), Fixture.from_scheme(""" 1:- s:- d:-a1-b1-a2-c1-b2-a3-A3-B2-C1-A2 b:-a1-1b-a2-c1-2b a:-1a-b1-2a-c1-b2-3a c:-a1-b1-a2-1c"""))
def test_dependencies(self): Fixture.from_scheme('''1: d:----a1-b1-a2-c1 a:-1a----b1-2c b:-1b--------- c:----b1-a1-a2-1-''').actualize() misc.checkout('1/staging') self.assert_aflow_returns_0(None, 'merge', '-a') misc.checkout('master') self.assert_aflow_returns_0(None, 'merge', '-d', 'c') self.assertEqual(Fixture.from_repo(), Fixture.from_scheme( '''1:----b1-a1-a2-c1 s:----a1-b1-a2-c1 d:----a1-b1-a2-c1 a:-1a----b1-2c b:-1b--------- c:----b1-a1-a2-1-'''))
def test_refinish(self): Fixture.from_scheme("""1: d:-a1 a:-1a""").actualize() misc.checkout('1/develop') commit.revert('HEAD', parent=1) branch.delete('1/a') self.assert_aflow_returns_0(None, 'checkout', 'a') self.assert_aflow_returns_0( 'Assuming topic you are finishing is 1/a_v1.' + os.linesep + 'Taking topic type from previous merge of 1/a_v1.' + os.linesep + '1/a_v1 merged into 1/develop successfully.', 'finish') self.assertEqual(Fixture.from_repo(), Fixture.from_scheme(""" 1: d:-a1-A1-a1 a:-1a"""))
def test_auto_version(self): Fixture.from_scheme("""1: d:-a1 a:-1a-a-""").actualize() misc.checkout('1/a') self.assert_aflow_returns_0( """Using topic version 2 as default. Taking topic type from previous merge of 1/a_v1. 1/a_v2 merged into 1/develop successfully. Branch 1/a deleted.""", 'finish') commit.revert('HEAD', 1) self.assert_aflow_returns_0(None, 'checkout', 'a') self.assert_aflow_returns_0( """Using version 2 of already merged revision with same head SHA. Taking topic type from previous merge of 1/a_v2. 1/a_v2 merged into 1/develop successfully.""", 'finish', '-n', 'a')
def test_conflict_with_deps_first(self): Fixture.from_scheme("""1: d:-a1-b1-c1-e1 a:-1a b:-a1-1b c:-a1----1c e:-a1-------1e """).actualize() self.assert_aflow_returns_0(None, 'start', 'f') with open('a', 'w') as a: a.write('Does not matter') misc.add('a') commit.commit('No matter') # bug isn't reproduced stably, but probably it fails on the first try for i in range(0, 5): self.assert_aflow_dies_with( 'Finish failed because of conflicts between current ' 'topic and 1/a_v1 in file a', 'finish')
def test_subdirectory_conflict(self): Fixture.from_scheme("""1: a: b:""").actualize() misc.checkout('1/a') os.mkdir('subdir') with open('subdir/a', 'w') as a: a.write('A content') misc.add('subdir/a') commit.commit('No matter a') self.assert_aflow_returns_0(None, 'finish') misc.checkout('1/b') os.mkdir('subdir') with open('subdir/a', 'w') as a: a.write('B content') misc.add('subdir/a') commit.commit('No matter b') os.chdir('subdir') self.assert_aflow_dies_with( 'Finish failed because of conflicts between current ' 'topic and 1/a_v1 in file subdir/a', 'finish') os.chdir(misc.get_root_dir()) misc.checkout('1/staging') self.assert_aflow_returns_0(None, 'merge', 'a') misc.checkout('master') self.assert_aflow_returns_0(None, 'merge', 'a') self.assert_aflow_returns_0(None, 'rebase', '-n', '2') self.assert_aflow_returns_0(None, 'continue', 'a') with open('subdir/a', 'w') as a: a.write('A new content') misc.add('subdir/a') commit.commit('No matter a2') self.assert_aflow_returns_0(None, 'finish') self.assert_aflow_returns_0(None, 'start', 'b') misc.rm('subdir', recursively=True) commit.commit('delete a') self.assert_aflow_dies_with( 'Finish failed because of conflicts between current ' 'topic and 2/a_v2 in file subdir/a', 'finish')
def test_conflict(self): Fixture.from_scheme('''1: d:----b1-c1 b:-1b a:-b- c:-1c''').actualize() misc.checkout('1/a') self.assert_aflow_dies_with( 'Using default topic source(s): develop' + os.linesep + 'Merge of 1/b_v1 failed. See conflicted files via "git status", ' 'resolve conflicts, add files to index ("git add") and do ' '"git commit --no-edit" to finish the merge.' + os.linesep + 'Alternatively, you may abort failed merge via "git merge --abort"', 'merge', 'b') commit.abort_merge() self.assert_aflow_dies_with( 'Using default topic source(s): develop' + os.linesep + 'Merge of 1/b_v1 failed. See conflicted files via "git status", ' 'resolve conflicts, add files to index ("git add") and do ' '"git commit --no-edit" to finish the merge.' + os.linesep + 'Then call "git af merge [topics]" again to merge remaining ' 'topics. Topics remaining to merge: 1/c_v1' + os.linesep + 'Alternatively, you may abort failed merge via "git merge --abort"', 'merge', 'b', 'c') commit.abort_merge() misc.checkout('1/develop') commit.merge('1/a') misc.add('b') commit.commit() misc.checkout('1/staging') self.assert_aflow_returns_0(None, 'merge', 'b') self.assert_aflow_dies_with( 'Using default topic source(s): develop' + os.linesep + 'Merge of 1/a_v1 failed. Something went wrong, did not ' 'expect conflict there (1/staging). Please check carefully what ' 'you are doing. Merge aborted.', 'merge', 'a')
def test_description_type(self): Fixture.from_scheme('''1: d:-a1 a:-1a''').actualize() # edit description/type misc.checkout('1/staging') self.assert_aflow_returns_0( None, 'merge', '-e', 'No matter.', '-D', 'a') self.assertEqual(commit.get_full_message('HEAD'), """Merge branch '1/a_v1' into 1/staging DEV No matter.""") # use description/type from sources misc.checkout('master') self.assert_aflow_returns_0(None, 'merge', 'a') self.assertEqual(commit.get_full_message('HEAD'), """Merge branch '1/a_v1' DEV No matter.""")
def test_already_merged(self): Fixture.from_scheme('''1: d:-a1-a2 a:-1a-2a b:-a1-a2''').actualize() misc.checkout('1/b') self.assert_aflow_dies_with( 'Using default topic source(s): develop' + os.linesep + 'Latest revision of a in sources is 1/a_v2. We already have it ' 'merged in 1/b. Skipping..' + os.linesep + 'There is nothing to merge.', 'merge', 'a') self.assert_aflow_dies_with( 'Using default topic source(s): develop' + os.linesep + 'We already have this version of a_v2 in 1/b. Skipping..' + os.linesep + 'There is nothing to merge.', 'merge', 'a_v2') self.assert_aflow_dies_with( 'Using default topic source(s): develop' + os.linesep + 'There is nothing to merge.', 'merge', '-a')
def test_filter(self): Fixture.from_scheme("""1: d:-a1 a:-1a""").actualize() self.assert_aflow_returns_0(None, 'start', 'refactoring') commit.commit('No matter1', allow_empty=True) self.assert_aflow_returns_0(None, 'finish', '-D', 'Blah blah.') self.assert_aflow_returns_0(None, 'start', 'fix') commit.commit('No matter2', allow_empty=True) self.assert_aflow_returns_0( None, 'finish', '-F', 'Very long description very long description very long description') self.assert_aflow_returns_0("""\ Using default topic source(s): develop 1/develop-----------Type |Ver| Description-------------------------------------- fix FIX | 1 | Very long description very long description ve... refactoring DEV | 1 | Blah blah.""", 'list', '-FD') self.assert_aflow_returns_0("""\ Using default topic source(s): develop 1/develop-----------Type |Ver| Description-------------------------------------- refactoring DEV | 1 | Blah blah. a EUF | 1 | N/A""", 'list', '-D', '--EUF')
def test_update(self): Fixture.from_scheme('''1: s:----a1-b1 d:----a1-b1-c1-a2-b2-c2-a3 a:-1a----2a-------b2-c2-3a b:-1b----------a2-2b c:-1c----------a2-b2-2c''').actualize() misc.checkout('1/staging') self.assert_aflow_dies_with( 'Using default topic source(s): develop' + os.linesep + 'Merge failed. Topic 1/a_v3 depends on 1/c_v1. Try merge it first ' 'or use "git af merge -d" to merge dependencies automatically', 'merge', '-u') self.assert_aflow_returns_0(None, 'merge', '-d', '-u') self.assertEqual( Fixture.from_repo(), Fixture.from_scheme("""1:- s:-a1-b1-a2-b2-c1-c2-a3 d:-a1-b1-c1-a2-b2-c2-a3 b:-1b-a1-a2-2b c:-1c-a1-a2-b1-b2-2c a:-1a-2a-b1-b2-c1-c2-3a"""))
def test_sources(self): Fixture.from_scheme("""1:-a1 s:-a1 d:-a1 a:-1a 2: d:-a2 a:-2a""").actualize() self.assert_aflow_returns_0("""\ master--------------Type |Ver| Description-------------------------------------- 2/staging-----------Type |Ver| Description-------------------------------------- 2/develop-----------Type |Ver| Description-------------------------------------- a EUF | 2 | N/A""", 'list', '-a') misc.checkout('2/staging') self.assert_aflow_returns_0(None, 'merge', 'a') self.assert_aflow_returns_0("""\ Using default topic source(s): develop 2/develop-----------Type |Ver| Description-------------------------------------- a EUF | 2 | N/A""", 'list') self.assert_aflow_returns_0("""\ master--------------Type |Ver| Description-------------------------------------- 1/develop-----------Type |Ver| Description-------------------------------------- a EUF | 1 | N/A""", 'list', 'master', '1/develop')
def test_preserve_description(self): Fixture.from_scheme("""1:-a1 s:-a1 d:-a1 a:-1a 2:""").actualize() branch.create('2/a_v2', '2') misc.checkout('2/a_v2') commit.commit('No matter', allow_empty=True) self.assert_aflow_returns_0( """Taking topic type from previous merge of 1/a_v1. 2/a_v2 merged into 2/develop successfully. Branch 2/a_v2 deleted.""", 'finish', 'Some description') misc.checkout('2/staging') self.assert_aflow_returns_0(None, 'merge', 'a') misc.checkout('master') self.assert_aflow_returns_0(None, 'merge', 'a') self.assert_aflow_returns_0(None, 'continue', 'a') commit.commit('No matter', allow_empty=True) self.assert_aflow_returns_0(None, 'finish', '-D', 'Other description') self.assert_aflow_returns_0(None, 'rebase', '-n', '3') self.assert_aflow_returns_0(None, 'continue', '3/a') commit.commit('No matter', allow_empty=True) self.assert_aflow_returns_0( """Taking topic description from previous merge of 2/a_v3. Taking topic type from previous merge of 2/a_v3. 3/a_v3 merged into 3/develop successfully. Branch 3/a_v3 deleted.""", 'finish') self.assertEqual( commit.get_full_message('HEAD'), """Merge branch '3/a_v3' into 3/develop DEV Other description""")
def test_checks(self): Fixture.from_scheme('''1: a:-a--a- b:-b-''').actualize() # detached head misc.checkout('1/a^') self.assert_aflow_dies_with( 'Error: detached head state. Please checkout some branch before ' 'proceed', 'merge', 'no_matter') # topic description applicable misc.checkout('1/a') self.assert_aflow_returns_0(None, 'finish') misc.checkout('1/b') self.assert_aflow_returns_0(None, 'finish') misc.checkout('1/staging') expected = 'If you are going to specify topic description and/or ' \ 'type, you should merge one single topic' self.assert_aflow_dies_with(expected, 'merge', '-a', '-e', 'no matter') self.assert_aflow_dies_with(expected, 'merge', 'a', 'b', '-D') # working tree self.assert_aflow_returns_0(None, 'continue', 'a') os.remove('a') self.assert_aflow_dies_with( 'Error: your working tree is dirty. Please, stash or reset your ' 'changes before proceeding.', 'merge', 'no_matter') branch.reset('HEAD') # topic present in sources misc.checkout('master') self.assert_aflow_dies_with( 'Using default topic source(s): staging' + os.linesep + 'Merge failed. No topic a in sources 1/staging', 'merge', 'a') self.assert_aflow_dies_with( 'Merge failed. No topic a_v2 in sources 1/develop', 'merge', '-s', 'develop', 'a_v2') # is there anything to merge self.assert_aflow_dies_with( 'Using default topic source(s): staging' + os.linesep + 'There is nothing to merge.', 'merge', '-a') # dependency check self.assert_aflow_returns_0(None, 'start', 'c') self.assert_aflow_returns_0(None, 'merge', 'a') self.assert_aflow_returns_0(None, 'finish') misc.checkout('1/staging') self.assert_aflow_dies_with( 'Using default topic source(s): develop' + os.linesep + 'Merge failed. Topic 1/c_v1 depends on 1/a_v1. Try merge it first ' 'or use "git af merge -d" to merge dependencies automatically', 'merge', 'c') commit.merge('1/a_v2', "Merge branch '1/a_v2' into 1/staging") misc.checkout('master') self.assert_aflow_dies_with( 'Using default topic source(s): staging' + os.linesep + 'Merge failed. We should merge 1/a_v2 along with 1/a_v1, but ' '1/a_v1 is absent in sources.', 'merge', 'a') misc.checkout('1/staging') branch.reset('HEAD^') # source exists and belongs to ci self.assert_aflow_dies_with( 'Cannot find branch 1/wrong_source or wrong_source.', 'merge', '-a', '-s', 'wrong_source') misc.checkout('1/staging') self.assert_aflow_returns_0(None, 'merge', 'a') misc.checkout('master') self.assert_aflow_returns_0(None, 'merge', 'a') self.assert_aflow_returns_0(None, 'rebase', '-n', '2') self.assert_aflow_returns_0(None, 'start', 'wrong_source') misc.checkout('1/staging') self.assert_aflow_dies_with( "Merge sources should belong to current iteration. 2/wrong_source" " doesn't.", 'merge', '-a', '-s', '2/wrong_source') # consistency check branch.create('1/b_v2') misc.checkout('1/b_v2') commit.commit('no matter', allow_empty=True) misc.checkout('1/develop') commit.merge('1/b_v2') misc.checkout('1/staging') self.assert_aflow_dies_with(None, 'merge', 'no_matter') # merge into develop misc.checkout('1/develop') self.assert_aflow_dies_with( 'You cannot merge into develop, use git af topic finish instead', 'merge', 'a') # not valid aflow repo misc.checkout('1/staging') branch.delete('1/develop') self.assert_aflow_dies_with( 'Error: could not get current iteration, we are probably not in ' 'git-aflow repo.', 'merge', 'no_matter')
def test_checks(self): Fixture.from_scheme('''1:-b1 s:-b1 d:-b1 a:-a--1a b:-1b 2:''').actualize() # no finish for develop, master and staging for branch_ in 'master', '1/develop', '1/staging': misc.checkout(branch_) self.assert_aflow_dies_with( 'Finish failed for branch ' + branch_ + '. Cannot finish ' 'develop, master, staging or release/* branches.', 'finish') # one topic is based on another branch.create('1/no_matter', '1/b') misc.checkout('1/no_matter') commit.commit('No matter', allow_empty=True) self.assert_aflow_dies_with( 'TB of current topic is based on another topic, which is illegal. ' 'You should either merge other topic instead of basing on it or ' 'name topic you are finishing appropriately.', 'finish') misc.checkout('1/develop') branch.delete('1/no_matter') # unable to determine topic name misc.checkout('1/a^') self.assert_aflow_dies_with( 'You are in detached head state now. Please check out topic you ' 'want to finish, e.g. "git af checkout topicA" or specify name ' '(like git af topic finish -n TopicName if you are going to merge ' 'a commit, not branch', 'finish') # name format misc.checkout('1/a') self.assert_aflow_dies_with( 'Error: invalid topic name 1/\_v1. "..", "~", "^", ":", "?", "*", ' '"[", "@", "", spaces and ASCII control characters are not allowed.' ' */release/*, */develop, */staging and master are not allowed too.' ' Input something like "fix_issue18" or "do_api_refactoring"', 'finish', '-n', '\\') # may lose untracked files with open('b', 'w') as b: b.write('Does not matter') self.assert_aflow_dies_with( 'Error: you have some untracked files which you may loose when ' 'switching to 1/develop. Please, delete or commit them. ' 'Here they are: b.', 'finish') # conflict misc.add('b') commit.commit('no matter') self.assert_aflow_dies_with( 'Finish failed because of conflicts between current topic and ' '1/b_v1 in file b', 'finish') os.remove('b') branch.reset('HEAD^') # working tree os.remove('a') self.assert_aflow_dies_with( 'Error: your working tree is dirty. Please, stash or reset your ' 'changes before proceeding.', 'finish') branch.reset('HEAD') # use topic name corresponding to some other iteration self.assert_aflow_dies_with( 'It is not possible to finish in current iteration topic from ' 'other one. Finish failed.', 'finish', '-n', '2/a_v1') # topic based on current one exists self.assert_aflow_returns_0(None, 'finish') misc.checkout('1/a_v1^') self.assert_aflow_dies_with( 'Finish failed. There is another topic (1/a_v1) in 1/develop which ' 'is based on one you are trying to finish.', 'finish', '-n', 'no_matter') # already finished self.assert_aflow_returns_0(None, 'checkout', 'a') self.assert_aflow_dies_with( '1/develop already contains this revision of a', 'finish') # dependency not merged branch.create('dependency', '1') misc.checkout('dependency') commit.commit('No matter', allow_empty=True) self.assert_aflow_returns_0(None, 'continue', 'b') commit.merge('dependency') self.assert_aflow_dies_with( 'Finish failed. Your topic depends on 1/dependency_v1 which is ' 'absent in 1/develop', 'finish') # topic isn't based on its iteration branch.create('2/a') misc.checkout('2/a') self.assert_aflow_dies_with( 'Finish failed. Current topic branch is not based on iteration ' 'start which is not allowed in git-aflow', 'finish') # topic is based on later iteration branch.create('1/c', '2') misc.checkout('1/c') commit.commit('No matter', allow_empty=True) self.assert_aflow_dies_with( 'Current topic branch is based on 2. Use "git af topic port" to ' 'bring it to current iteration and then call ' '"git af topic finish"', 'finish') # not based on previous revision branch.create('1/a_v2', '1') misc.checkout('1/a_v2') commit.commit('no matter', allow_empty=True) self.assert_aflow_dies_with( 'Cannot finish. There is elder revision of this topic in 1/develop ' 'and SHA you are trying to finish is not based on it. Please ' 'rebase your work on 1/a_v1', 'finish') # empty topic self.assert_aflow_returns_0(None, 'start', 'No_matter') self.assert_aflow_dies_with( 'Finish failed. Topic must contain at least one commit.', 'finish') # there already is a later revision of this topic and it isn't based on # one being finished now misc.checkout('1/develop') backup_sha = commit.get_current_sha() commit.merge('1/a_v2') commit.revert('HEAD', 1, True) commit.commit(allow_empty=True) commit.revert('HEAD^^', 1, True) commit.commit(allow_empty=True) branch.delete('1/a_v2') self.assert_aflow_returns_0(None, 'checkout', 'a_v1') self.assert_aflow_dies_with( 'Cannot finish. Newer revision 1/a_v2 was merged into 1/develop ' 'and it is not based on revision you are trying to finish.', 'finish') misc.checkout('1/develop') branch.reset(backup_sha) # same revision in develop has different SHA commit.revert('HEAD', 1, True) commit.commit(allow_empty=True) self.assert_aflow_returns_0(None, 'checkout', 'No_matter') commit.commit('No matter', allow_empty=True) self.assert_aflow_dies_with( '1/a_v1 was already merged in 1/develop with different head SHA. ' 'Finish failed.', 'finish', '-n', 'a_v1') branch.reset(backup_sha) # finish _vN while there is no _v(N-1) self.assert_aflow_returns_0(None, 'continue', 'a') commit.commit('no matter', True) self.assert_aflow_dies_with( 'Wrong topic version specified. Latest revision has version == 1. ' 'Increment version by 1', 'finish', '-n', 'a_v3') # finish _vN while there is no _v(N-1) in current iteration misc.checkout('2/develop') self.assert_aflow_returns_0(None, 'start', 'No_matter') commit.commit('no matter', True) self.assert_aflow_dies_with( 'You should finish version 1 before finishing 2/a_v2', 'finish', '-n', 'a_v2')