def test_create_feature_changes_active_branch(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) self.assertEquals('feat/recursion', self.repo.active_branch.name) mgr.create('foo') self.assertEquals('feat/foo', self.repo.active_branch.name)
def test_finish_feature_keep(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) mgr.finish('even', keep=True) # feature branch still exists self.assertIn('feat/even', [b.name for b in self.repo.branches])
def test_create_new_feature_from_alt_base(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) new_branch = mgr.create('foo', 'feat/even') self.assertEqual(new_branch.commit, gitflow.repo.branches['feat/even'].commit)
def test_feature_branch_origin(self): repo = create_git_repo(self) gitflow = GitFlow(repo).init() mgr = FeatureBranchManager(gitflow) new_branch = mgr.create('foobar') self.assertEqual(new_branch.commit, gitflow.repo.branches['develop'].commit)
def test_merge_conflict(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) mgr.merge('recursion', 'devel') self.assertRaises(MergeError, mgr.merge, 'even', 'devel') gitflow.git.rm('odd.py') gitflow.git.commit('-F.git/MERGE_MSG')
def test_delete_current_feature_raises_error(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) mgr.create('foo').checkout() self.assertRaisesRegexp(GitCommandError, 'Cannot delete the branch .* which you are currently on', mgr.delete, 'foo')
def test_finish_feature_unresolved_merge_conflict(self): gitflow = GitFlow(self.repo).init() mgr = FeatureBranchManager(gitflow) mgr.finish('recursion') self.assertRaises(MergeError, mgr.finish, 'even') # do not resolve, but finish again self.assertRaises(GitCommandError, mgr.finish, 'even')
def test_create_new_feature_branch_non_default_prefix(self): gitflow = GitFlow(self.repo).init() mgr = FeatureBranchManager(gitflow) new_branch = mgr.create('foo') self.assertEqual(new_branch.name, 'feat/foo') self.assertIn('feat/foo', [b.name for b in mgr.list()]) self.assertEqual(new_branch.commit, gitflow.repo.branches['devel'].commit)
def test_finish_release_unresolved_merge_conflict(self): gitflow = GitFlow(self.repo).init() fmgr = FeatureBranchManager(gitflow) fmgr.finish('even') fake_commit(self.repo, 'Overwrite version', filename='VERSION') mgr = ReleaseBranchManager(gitflow) self.assertRaises(MergeError, mgr.finish, '1.0') # do not resolve, but finish again self.assertRaises(GitCommandError, mgr.finish, '1.0')
def test_create_new_feature_branch(self): repo = create_git_repo(self) gitflow = GitFlow(repo).init() mgr = FeatureBranchManager(gitflow) self.assertEqual(0, len(mgr.list())) new_branch = mgr.create('foo') self.assertEqual(1, len(mgr.list())) self.assertEqual('feature/foo', mgr.list()[0].name) self.assertEqual(new_branch.commit, gitflow.repo.branches['develop'].commit)
def test_finish_feature_push_keep(self): gitflow = GitFlow(self.repo).init() mgr = FeatureBranchManager(gitflow) mgr.create('even') mgr.finish('even', push=True, keep=True) # Finishing removes the local and the remote feature branch self.assertIn('feat/even', [b.name for b in self.repo.branches]) self.assertIn('feat/even', [b.name for b in self.remote.branches])
def test_create_feature_from_remote_branch(self): remote_branch = self.remote.refs['feat/even'] rfc0 = remote_branch.commit gitflow = GitFlow(self.repo).init() mgr = FeatureBranchManager(gitflow) mgr.create('even') branch = self.repo.active_branch self.assertEqual(branch.name, 'feat/even') self.assertEqual(branch.commit, rfc0) # must be a tracking branch self.assertTrue(branch.tracking_branch()) self.assertEqual(branch.tracking_branch().name, 'my-remote/feat/even')
def test_create_feature_changes_active_branch_even_if_dirty_but_without_conflicts(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) # In this fixture, odd.py contains changes that would be overwritten. # Since we don't want to test this here, we revert all local changes in # odd.py, but leave the local changes in README.txt. These changes # won't be overwritten by the merge, so git-flow should be able to # create a new feature branch if Git can do this self.repo.index.reset(index=True, working_tree=True, paths=['odd.py']) mgr.create('foo') self.assertIn('feature/foo', [b.name for b in mgr.iter()])
def test_delete_feature_with_commits_raises_error(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) self.assertEquals(2, len(mgr.list())) mgr.create('foo') fake_commit(self.repo, 'A commit on the feature branch.', append=False) gitflow.develop().checkout() self.assertEquals(3, len(mgr.list())) self.assertRaisesRegexp(GitCommandError, 'The branch .* is not fully merged', mgr.delete, 'foo')
def test_create_feature_fetch_from_remote_branch_behind_really_fetches(self): rfc0 = self.remote.refs['feat/even'].commit # add a commit to remote feat/even branch self.remote.refs['feat/even'].checkout() change = fake_commit(self.remote, "Yet another even commit.") gitflow = GitFlow(self.repo).init() mgr = FeatureBranchManager(gitflow) mgr.create('even', fetch=True) # must not advance feat/even self.assertEqual(self.repo.refs['feat/even'].commit, rfc0) # change must nor be in local repo self.assertNotIn(change, all_commits(self.repo))
def test_merge_feature_without_commits(self): repo = create_git_repo(self) gitflow = GitFlow(repo).init() mgr = FeatureBranchManager(gitflow) dc0 = gitflow.develop().commit mgr.create('newstuff') mgr.merge('newstuff', 'develop') dc1 = gitflow.develop().commit # Assert the develop tip is unchanged by the merge self.assertEqual(dc0, dc1) # Assert the target-branch is active self.assertEqual(gitflow.repo.active_branch.name, 'develop')
def test_delete_feature_without_commits(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) self.assertEquals(2, len(mgr.list())) mgr.create('foo') gitflow.develop().checkout() self.assertEquals(3, len(mgr.list())) mgr.delete('foo') self.assertEquals(2, len(mgr.list())) self.assertNotIn('feat/foo', [b.name for b in self.repo.branches])
def test_create_feature_from_remote_branch_behind(self): # If BranchManager.create() uses `update`, this test-case has # to be adopted, since since `update` change the cloned repo. rfc0 = self.remote.refs['feat/even'].commit # add a commit to remote feat/even branch self.remote.refs['feat/even'].checkout() change = fake_commit(self.remote, "Yet another even commit.") gitflow = GitFlow(self.repo).init() mgr = FeatureBranchManager(gitflow) mgr.create('even') # does not advance feat/even, since create() uses `fetch`, not `update` self.assertEqual(self.repo.refs['feat/even'].commit, rfc0) # change must not be in local repo, since create() uses `fetch`, not `update` self.assertNotIn(change, all_commits(self.repo))
def test_delete_feature_with_commits_forcefully(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) self.assertEquals(2, len(mgr.list())) mgr.create('foo') fake_commit(self.repo, 'A commit on the feature branch.', append=False) gitflow.develop().checkout() self.assertEquals(3, len(mgr.list())) mgr.delete('foo', force=True) self.assertEquals(2, len(mgr.list())) self.assertNotIn('feat/foo', [b.name for b in self.repo.branches])
def test_merge_feature_with_multiple_commits(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) dc0 = gitflow.develop().commit mgr.merge('even', 'devel') dc1 = gitflow.develop().commit # Assert merge commit has been made self.assertEqual(2, len(dc1.parents)) self.assertTrue(dc1.message.startswith("Merge branch 'feat/even' into devel\n")) # Assert develop branch advanced self.assertNotEqual(dc0, dc1) # Assert the target-branch is active self.assertEqual(gitflow.repo.active_branch.name, 'devel')
def test_finish_release_merge_conflict(self): gitflow = GitFlow(self.repo).init() fmgr = FeatureBranchManager(gitflow) fmgr.finish('even') fake_commit(self.repo, 'Overwrite version', filename='VERSION') mgr = ReleaseBranchManager(gitflow) self.assertRaises(MergeError, mgr.finish, '1.0') # resolve the conflict gitflow.git.rm('VERSION') gitflow.git.commit('-F.git/MERGE_MSG') # the release branch is still here self.assertIn('rel/1.0', [b.name for b in self.repo.branches]) mgr.finish('1.0') # now the release branch is gone self.assertNotIn('rel/1.0', [b.name for b in self.repo.branches])
def test_finish_feature_merge_conflict(self): gitflow = GitFlow(self.repo).init() mgr = FeatureBranchManager(gitflow) mgr.finish('recursion') self.assertRaises(MergeError, mgr.finish, 'even') # resolve the conflict gitflow.git.rm('odd.py') gitflow.git.commit('-F.git/MERGE_MSG') # the feature branch is still here self.assertIn('feat/even', [b.name for b in self.repo.branches]) mgr.finish('even') # now the feature branch is gone self.assertNotIn('feat/even', [b.name for b in self.repo.branches])
def test_merge_feature_with_multiple_commits(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) dc0 = gitflow.develop().commit mgr.merge('even', 'devel') dc1 = gitflow.develop().commit # Assert merge commit has been made self.assertEqual(2, len(dc1.parents)) self.assertEqual("Merge branch 'feat/even' into devel\n", dc1.message) # Assert develop branch advanced self.assertNotEqual(dc0, dc1) # Assert the target-branch is active self.assertEqual(gitflow.repo.active_branch.name, 'devel')
def test_finish_release_merge_conflict_tag(self): """ finish + tag with merge-conflicts on develop """ version_filename = 'VERSION' new_version = '1.1\n' gitflow = GitFlow(self.repo).init() fmgr = FeatureBranchManager(gitflow) fmgr.finish('even') fake_commit(self.repo, 'Overwrite version', filename=version_filename, change=new_version) # verify that the tag does not yet exist # "v" comes form "versiontag" prefix in the gitflow config for the "release" fixture self.assertNotIn('v1.0', self.repo.tags) mgr = ReleaseBranchManager(gitflow) taginfo = dict( message='Tagging version 1.0', ) self.assertRaises(MergeError, mgr.finish, '1.0', tagging_info=taginfo) # verify that the tag exists, even though there was a failed merge self.assertIn('v1.0', self.repo.tags) # resolve the conflict # this is in favor of the change on develop write_file(filename=version_filename, append=False, change=new_version) gitflow.git.add(version_filename) gitflow.git.commit('-F.git/MERGE_MSG') # the release branch is still here self.assertIn('rel/1.0', [b.name for b in self.repo.branches]) # finish the release again # this should skip the tagging, since that part previously succeeded mgr.finish('1.0', tagging_info=taginfo) # now the release branch is gone self.assertNotIn('rel/1.0', [b.name for b in self.repo.branches]) # verify that the tag still exists self.assertIn('v1.0', self.repo.tags)
def test_merge_feature_with_single_commit(self): gitflow = GitFlow(self.repo).init() mgr = FeatureBranchManager(gitflow) dc0 = gitflow.develop().commit mgr.merge('recursion', 'devel') dc1 = gitflow.develop().commit # Assert no merge commit has been made self.assertEqual(1, len(dc1.parents)) self.assertEqual('Made the definition of odd recursive.\n', dc1.message) # Assert develop branch advanced self.assertNotEqual(dc0, dc1) # Assert the target-branch is active self.assertEqual(gitflow.repo.active_branch.name, 'devel')
def test_finish_feature(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) mc0 = gitflow.master().commit dc0 = gitflow.develop().commit mgr.finish('even') mc1 = gitflow.master().commit dc1 = gitflow.develop().commit # Feature finishes don't advance master, but develop self.assertEqual(mc0, mc1) self.assertNotEqual(dc0, dc1) # Finishing removes the feature branch self.assertNotIn('feat/even', [b.name for b in self.repo.branches]) # Merge commit message self.assertEquals('Finished feature even.\n', dc1.message)
def test_finish_release_merge_conflict_tag(self): """ finish + tag with merge-conflicts on develop """ version_filename = 'VERSION' new_version = '1.1\n' gitflow = GitFlow(self.repo).init() fmgr = FeatureBranchManager(gitflow) fmgr.finish('even') fake_commit(self.repo, 'Overwrite version', filename=version_filename, change=new_version) # verify that the tag does not yet exist # "v" comes form "versiontag" prefix in the gitflow config for the "release" fixture self.assertNotIn('v1.0', self.repo.tags) mgr = ReleaseBranchManager(gitflow) taginfo = dict(message='Tagging version 1.0', ) self.assertRaises(MergeError, mgr.finish, '1.0', tagging_info=taginfo) # verify that the tag exists, even though there was a failed merge self.assertIn('v1.0', self.repo.tags) # resolve the conflict # this is in favor of the change on develop write_file(filename=version_filename, append=False, change=new_version) gitflow.git.add(version_filename) gitflow.git.commit('-F.git/MERGE_MSG') # the release branch is still here self.assertIn('rel/1.0', [b.name for b in self.repo.branches]) # finish the release again # this should skip the tagging, since that part previously succeeded mgr.finish('1.0', tagging_info=taginfo) # now the release branch is gone self.assertNotIn('rel/1.0', [b.name for b in self.repo.branches]) # verify that the tag still exists self.assertIn('v1.0', self.repo.tags)
def test_finish_feature_push(self): remote = GitFlow(self.remote).init() gitflow = GitFlow(self.repo).init() rmc0 = remote.master().commit rdc0 = remote.develop().commit mc0 = gitflow.master().commit dc0 = gitflow.develop().commit mgr = FeatureBranchManager(gitflow) mgr.create('even') mgr.finish('even', push=True) rmc1 = remote.master().commit rdc1 = remote.develop().commit mc1 = gitflow.master().commit dc1 = gitflow.develop().commit # Feature finishes don't advance remote master, but remote develop self.assertEqual(rmc0, rmc1) self.assertNotEqual(rdc0, rdc1) self.assertEqual(mc0, mc1) self.assertNotEqual(dc0, dc1) # local and remote heads must be the same again self.assertEqual(rmc1, mc1) self.assertEqual(rdc1, dc1) # Finishing removes the local and the remote feature branch self.assertNotIn('feat/even', [b.name for b in self.repo.branches]) self.assertNotIn('feat/even', [b.name for b in self.remote.branches]) # Merge commit message self.assertEquals('Finished feature even.\n', rdc1.message)
def test_delete_already_merged_feature(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) self.assertEquals(2, len(mgr.list())) mgr.create('foo') fake_commit(self.repo, 'Dummy commit #1') fake_commit(self.repo, 'Dummy commit #2') mgr.merge('foo', 'devel') self.assertEquals(3, len(mgr.list())) mgr.delete('foo') self.assertEquals(2, len(mgr.list())) self.assertNotIn('feat/foo', [b.name for b in mgr.list()])
def test_by_nameprefix_not_unique_enough(self): gitflow = GitFlow() mgr = FeatureBranchManager(gitflow) mgr.create('rescue') self.assertRaises(PrefixNotUniqueError, mgr.by_name_prefix, 're') self.assertRaises(NoSuchBranchError, mgr.by_name_prefix, 'nonexisting')
def test_create_feature_raises_error_if_local_changes_would_be_overwritten( self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) self.assertRaisesRegexp(WorkdirIsDirtyError, 'checked in.*not committed', mgr.create, 'foo')
def test_finish_feature_on_unpulled_branch_raises_error(self): # branch exists on remote but was not pulled prior to finish gitflow = GitFlow(self.repo).init() mgr = FeatureBranchManager(gitflow) self.assertRaises(NoSuchBranchError, mgr.finish, 'even', push=True)
def test_by_nameprefix(self): gitflow = GitFlow() mgr = FeatureBranchManager(gitflow) self.assertEquals('feat/even', mgr.by_name_prefix('e').name) self.assertEquals('feat/recursion', mgr.by_name_prefix('re').name)
def test_delete_non_existing_feature_raises_error(self): gitflow = GitFlow(self.repo) mgr = FeatureBranchManager(gitflow) self.assertRaisesRegexp(GitCommandError, 'branch .* not found', mgr.delete, 'nonexisting')
def test_create_existing_feature_branch_raises_error(self): repo = create_git_repo(self) gitflow = GitFlow(repo).init() mgr = FeatureBranchManager(gitflow) mgr.create('foo') self.assertRaises(BranchExistsError, mgr.create, 'foo')