def test_sync___override_merge_conflict_ours(self, mock_labbook_lfs_disabled, mock_config_file): """ test sync, with override in case of merge conflict. """ username = '******' lb = mock_labbook_lfs_disabled[2] wf = LabbookWorkflow(lb) wf.publish(username=username) bm = BranchManager(lb, username='******') bm.create_branch('test-conflict-branch') fpath = os.path.join(lb.root_dir, 'input', 'testfile') with open(fpath, 'w') as f: f.write('filedata') lb.sweep_uncommitted_changes() wf.sync('test') other_user = '******' wf_other = LabbookWorkflow.import_from_remote( wf.remote, username=other_user, config_file=mock_config_file[0]) bm_other = BranchManager(wf_other.labbook, username=other_user) bm_other.workon_branch('test-conflict-branch') with open(os.path.join(wf_other.labbook.root_dir, 'input', 'testfile'), 'w') as f: f.write('conflicting-change-other-user') wf_other.labbook.sweep_uncommitted_changes() wf_other.sync(username=username) fpath = os.path.join(wf.labbook.root_dir, 'input', 'testfile') with open(fpath, 'w') as f: f.write('conflicting-change-original-user') wf.labbook.sweep_uncommitted_changes() n = wf.sync(username=username, override=MergeOverride.OURS) flines = open(os.path.join(wf.labbook.root_dir, 'input', 'testfile')).read() assert 'conflicting-change-original-user' == flines
def resolve_is_mergeable(self, info): lb = InventoryManager().load_labbook(get_logged_in_username(), self.owner, self.name) mergeable = self.branch_name in BranchManager(lb).branches_local \ and self.branch_name != BranchManager(lb).active_branch return mergeable
def test_sync___detect_merge_conflict(self, mock_labbook_lfs_disabled, mock_config_file): """ test import_from_remote method """ username = '******' lb = mock_labbook_lfs_disabled[2] wf = LabbookWorkflow(lb) wf.publish(username=username) bm = BranchManager(lb, username='******') bm.create_branch('test-conflict-branch') fpath = os.path.join(lb.root_dir, 'input', 'testfile') with open(fpath, 'w') as f: f.write('filedata') lb.sweep_uncommitted_changes() wf.sync('test') other_user = '******' wf_other = LabbookWorkflow.import_from_remote( wf.remote, username=other_user, config_file=mock_config_file[0]) bm_other = BranchManager(wf_other.labbook, username=other_user) bm_other.workon_branch('test-conflict-branch') with open(os.path.join(wf_other.labbook.root_dir, 'input', 'testfile'), 'w') as f: f.write('conflicting-change-other-user') wf_other.labbook.sweep_uncommitted_changes() wf_other.sync(username=username) with open(fpath, 'w') as f: f.write('conflicting-change-original-user') wf.labbook.sweep_uncommitted_changes() h = wf.labbook.git.commit_hash with pytest.raises(MergeConflict): n = wf.sync(username=username) assert h == wf.labbook.git.commit_hash
def test_remove_remote_branch(self, mock_labbook_lfs_disabled): lb = mock_labbook_lfs_disabled[2] with tempfile.TemporaryDirectory() as tempdir: call_subprocess('git init .'.split(), tempdir) call_subprocess('touch FILE_A'.split(), tempdir) call_subprocess('git add FILE_A'.split(), tempdir) call_subprocess('git commit -am "message"'.split(), tempdir) call_subprocess('git checkout -b remote-branch'.split(), cwd=tempdir) call_subprocess('git checkout master'.split(), cwd=tempdir) lb.git.add_remote('origin', tempdir) bm = BranchManager(lb) bm.fetch() assert 'remote-branch' in bm.branches_remote # Get this remote branch locally, but go back to master bm.workon_branch('remote-branch') call_subprocess('git checkout master'.split(), cwd=bm.repository.root_dir) bm.remove_remote_branch('remote-branch') bm.fetch() # Confirm branch exists locally, but is gone on remote. assert 'remote-branch' in bm.branches_local assert 'remote-branch' not in bm.branches_remote
def test_success_merge_from(self, mock_labbook_lfs_disabled): """ Test merging with nonconflicting changes. """ lb = mock_labbook_lfs_disabled[2] bm = BranchManager(lb, username=TEST_USER) t = 'my-new-example-feature' feature_branch_name = bm.create_branch(title=t) assert bm.active_branch == feature_branch_name bm.workon_branch(bm.workspace_branch) FileOperations.makedir(lb, 'code/sillyfolder', create_activity_record=True) FileOperations.makedir(lb, 'input/newfolder', create_activity_record=True) bm.workon_branch(feature_branch_name) FileOperations.makedir(lb, 'output/otherdir', create_activity_record=True) bm.merge_from(bm.workspace_branch) # Assert repo state is as we expect assert os.path.isdir(os.path.join(lb.root_dir, 'code/sillyfolder')) assert os.path.isdir(os.path.join(lb.root_dir, 'input/newfolder')) assert os.path.isdir(os.path.join(lb.root_dir, 'output/otherdir')) assert lb.is_repo_clean # Return to original branch and check proper state bm.workon_branch(bm.workspace_branch) assert os.path.isdir(os.path.join(lb.root_dir, 'code/sillyfolder')) assert os.path.isdir(os.path.join(lb.root_dir, 'input/newfolder')) assert not os.path.isdir(os.path.join(lb.root_dir, 'output/otherdir')) assert lb.is_repo_clean
def test_fail_remove_branch_on_active_branch(self, mock_labbook_lfs_disabled): """ Test remove branch does raises exception when deleting current branch """ lb = mock_labbook_lfs_disabled[2] bm = BranchManager(lb, username=TEST_USER) with pytest.raises(BranchException): bm.remove_branch(bm.active_branch)
def sync_branch(repository: Repository, username: Optional[str], override: str, pull_only: bool, feedback_callback: Callable) -> int: """""" if not repository.has_remote: return 0 repository.sweep_uncommitted_changes() repository.git.fetch() bm = BranchManager(repository) branch_name = bm.active_branch if pull_only and branch_name not in bm.branches_remote: # Cannot pull when remote branch doesn't exist. feedback_callback("Pull complete - nothing to pull") return 0 if branch_name not in bm.branches_remote: # Branch does not exist, so push it to remote. _set_upstream_branch(repository, bm.active_branch, feedback_callback) return 0 else: pulled_updates_count = bm.get_commits_behind() _pull(repository, branch_name, override, feedback_callback) should_push = not pull_only if should_push: # Skip pushing back up if set to pull_only push_tokens = f'git push origin {branch_name}'.split() if branch_name not in bm.branches_remote: push_tokens.insert(2, "--set-upstream") call_subprocess(push_tokens, cwd=repository.root_dir) feedback_callback("Sync complete") else: feedback_callback("Pull complete") return pulled_updates_count
def _pull(repository: Repository, branch_name: str, override: str, feedback_cb: Callable) -> None: # TODO(billvb) Refactor to BranchManager feedback_cb(f"Pulling from remote branch \"{branch_name}\"...") cp = repository.git.commit_hash try: call_subprocess(f'git pull'.split(), cwd=repository.root_dir) call_subprocess(f'git submodule update --recursive'.split(), cwd=repository.root_dir) except subprocess.CalledProcessError as cp_error: if 'Automatic merge failed' in cp_error.stdout.decode(): feedback_cb( f"Detected merge conflict, resolution method = {override}") bm = BranchManager(repository, username='') conflicted_files = bm._infer_conflicted_files( cp_error.stdout.decode()) if 'abort' == override: call_subprocess(f'git reset --hard {cp}'.split(), cwd=repository.root_dir) raise MergeConflict('Merge conflict pulling upstream', conflicted_files) call_subprocess( f'git checkout --{override} {" ".join(conflicted_files)}'. split(), cwd=repository.root_dir) call_subprocess('git add .'.split(), cwd=repository.root_dir) call_subprocess('git commit -m "Merge"'.split(), cwd=repository.root_dir) feedback_cb("Resolved merge conflict") else: raise
def resolve_commits_ahead(self, info): lb = InventoryManager().load_labbook(get_logged_in_username(), self.owner, self.name) self._configure_git(lb, info) bm = BranchManager(lb) return bm.get_commits_ahead(branch_name=self.branch_name)
def test_sync_repository(self, mock_labbook_lfs_disabled): username = '******' lb = mock_labbook_lfs_disabled[2] bm = BranchManager(lb, username) assert bm.branches_remote == [] assert bm.branches_local == ['master'] jobs.publish_repository(lb, username=username, access_token='fake', id_token='fake-too') assert os.path.exists(lb.remote) # Assert that publish only pushes up the master branch. assert bm.branches_local == ['master'] assert bm.branches_remote == ['master'] assert bm.get_commits_ahead('master') == 0 assert bm.get_commits_behind('master') == 0 lb.write_readme("do a commit") assert bm.get_commits_ahead('master') == 1 assert bm.get_commits_behind('master') == 0 jobs.sync_repository(lb, username=username, override=MergeOverride.OURS, access_token='fake', id_token='fake-too') assert bm.get_commits_ahead('master') == 0 assert bm.get_commits_behind('master') == 0
def helper_resolve_branches(self, lb, kwargs): bm = BranchManager(lb) fetcher = FetchLoader() return [Branch(_fetch_loader=fetcher, owner=self.owner, name=self.name, branch_name=b) for b in sorted(set(bm.branches_local + bm.branches_remote))]
def test_success_rollback_basic(self, mock_labbook_lfs_disabled): """ Basic test of rollback feature - making a branch from """ test_user_lb = mock_labbook_lfs_disabled[2] # Create a directory and capture that Git revision (to be used as basis for rollback). FileOperations.makedir(test_user_lb, relative_path='code/folder1', create_activity_record=True) commit = test_user_lb.git.commit_hash # Make follow-up changes to be reverted (sort of). FileOperations.makedir(test_user_lb, relative_path='code/folder2', create_activity_record=True) FileOperations.makedir(test_user_lb, relative_path='code/folder3', create_activity_record=True) # Make rollback branch from Git revision captured above. bm = BranchManager(test_user_lb, username=TEST_USER) new_b = bm.create_branch('rollback-from-folder-1', revision=commit) FileOperations.makedir(test_user_lb, relative_path='input/branch-folder', create_activity_record=True) # Check state of repo is as exptected assert os.path.exists(os.path.join(test_user_lb.root_dir, 'code/folder1')) assert not os.path.exists(os.path.join(test_user_lb.root_dir, 'code/folder2')) assert not os.path.exists(os.path.join(test_user_lb.root_dir, 'code/folder3')) # Now, make chagnes to rollback branch FileOperations.makedir(test_user_lb, relative_path='input/branch-1', create_activity_record=True) FileOperations.makedir(test_user_lb, relative_path='input/branch-2', create_activity_record=True) FileOperations.makedir(test_user_lb, relative_path='input/branch-3', create_activity_record=True) # Now, try pulling upstream changes back into the rollback branch, then demonstrate state # is as expected. bm.merge_from(bm.workspace_branch) assert os.path.exists(os.path.join(test_user_lb.root_dir, 'code/folder2')) assert os.path.exists(os.path.join(test_user_lb.root_dir, 'code/folder3')) assert os.path.exists(os.path.join(test_user_lb.root_dir, 'input/branch-1')) assert os.path.exists(os.path.join(test_user_lb.root_dir, 'input/branch-2')) assert os.path.exists(os.path.join(test_user_lb.root_dir, 'input/branch-3')) assert test_user_lb.is_repo_clean
def test_fail_create_rollback_to_invalid_revision( self, mock_labbook_lfs_disabled): """ Fail when provided with an invalid Git revision """ test_user_lb = mock_labbook_lfs_disabled[2] bm = BranchManager(test_user_lb, username=TEST_USER) with pytest.raises(InvalidBranchName): bm.create_branch('should-fail', revision='invalidrevision')
def migrate(self) -> bool: """ Migrate the given LabBook to the most recent schema AND branch version. Returns: Boolean indicating whether a migration was performed (False if already up-to-date) """ if self.repository.schema == CURRENT_LABBOOK_SCHEMA: logger.info(f"{str(self.labbook)} already migrated.") return False if 'gm.workspace' not in BranchManager(self.labbook).active_branch: raise GitWorkflowException( 'Must be on a gm.workspace branch to migrate') im = InventoryManager(self.labbook.client_config.config_file) gitworkflows_utils.migrate_labbook_branches(self.labbook) self.repository = im.load_labbook_from_directory(self.labbook.root_dir) gitworkflows_utils.migrate_labbook_schema(self.labbook) self.repository = im.load_labbook_from_directory(self.labbook.root_dir) gitworkflows_utils.migrate_labbook_untracked_space(self.labbook) self.repository = im.load_labbook_from_directory(self.labbook.root_dir) # Pushes up the new master branch if self.repository.has_remote: self.sync(username='') return True
def mutate_and_get_payload(cls, root, info, owner, labbook_name, other_branch_name, override_method="abort", client_mutation_id=None): username = get_logged_in_username() lb = InventoryManager().load_labbook(username, owner, labbook_name, author=get_logged_in_author()) with lb.lock(): override = MergeOverride(override_method) bm = BranchManager(lb, username=username) if override == MergeOverride.ABORT: bm.merge_from(other_branch=other_branch_name) elif override == MergeOverride.OURS: bm.merge_use_ours(other_branch=other_branch_name) elif override == MergeOverride.THEIRS: bm.merge_use_theirs(other_branch=other_branch_name) else: raise ValueError(f"Unknown override method {override}") return MergeFromBranch( Labbook(id="{}&{}".format(owner, labbook_name), name=labbook_name, owner=owner))
def publish_to_remote(repository: Repository, username: str, remote: str, feedback_callback: Callable) -> None: # TODO(billvb) - Refactor all (or part) to BranchManager bm = BranchManager(repository, username=username) if bm.workspace_branch != bm.active_branch: raise ValueError(f'Must be on branch {bm.workspace_branch} to publish') feedback_callback(f"Preparing to publish {repository.name}") git_garbage_collect(repository) # Try five attempts to fetch - the remote repo could have been created just milliseconds # ago, so may need a few moments to settle before it supports all the git operations. for tr in range(5): try: repository.git.fetch(remote=remote) break except Exception as e: logger.warning( f"Fetch attempt {tr+1}/5 failed for {str(repository)}: {e}") time.sleep(1) else: raise ValueError( f"Timed out trying to fetch repo for {str(repository)}") feedback_callback("Pushing up regular objects...") call_subprocess( ['git', 'push', '--set-upstream', 'origin', bm.workspace_branch], cwd=repository.root_dir) feedback_callback(f"Publish complete.") repository.git.clear_checkout_context()
def test_conflicted_merge_from_no_force_fail(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] with open('/tmp/s1.txt', 'w') as s1: s1.write('original-file\ndata') FileOperations.insert_file(lb, section='code', src_file=s1.name) bm = BranchManager(lb, username=UT_USERNAME) nb = bm.create_branch(f'new-branch') with open('/tmp/s1.txt', 'w') as s1: s1.write('branch-conflict-data') FileOperations.insert_file(lb, section='code', src_file=s1.name) bm.workon_branch(bm.workspace_branch) with open('/tmp/s1.txt', 'w') as s1: s1.write('mainline-conflict-data') FileOperations.insert_file(lb, section='code', src_file=s1.name) merge_q = f""" mutation x {{ mergeFromBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", otherBranchName: "{nb}" }}) {{ labbook{{ name description activeBranchName }} }} }} """ r = client.execute(merge_q) assert 'errors' in r assert 'Merge conflict' in r['errors'][0]['message']
def remote_labbook_repo(): # TODO: Remove after integration tests with LFS support are available conf_file, working_dir = _create_temp_work_dir(lfs_enabled=False) im = InventoryManager(conf_file) lb = im.create_labbook('test', 'test', 'sample-repo-lb', description="my first labbook") bm = BranchManager(lb, username='******') bm.create_branch('testing-branch') #with tempfile.TemporaryDirectory() as tmpdirname: with open(os.path.join('/tmp', 'codefile.c'), 'wb') as codef: codef.write(b'// Cody McCodeface ...') FileOperations.insert_file(lb, "code", "/tmp/codefile.c") assert lb.is_repo_clean bm.workon_branch('master') # Location of the repo to push/pull from yield lb.root_dir shutil.rmtree(working_dir) try: os.remove('/tmp/codefile.c') except: pass
def test_delete_feature_branch_success(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) b1 = bm.create_branch(f"tester1") bm.workon_branch(bm.workspace_branch) q = f""" mutation makeFeatureBranch {{ deleteExperimentalBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", branchName: "{b1}", deleteLocal: true }}) {{ labbook {{ branches {{ branchName }} }} }} }} """ r = client.execute(q) pprint.pprint(r) # Cannot delete branch when it's the currently active branch assert 'errors' not in r assert bm.active_branch == bm.workspace_branch assert lb.is_repo_clean assert b1 not in bm.branches_local
def test_workon_feature_branch_success(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) b1 = bm.create_branch(f"tester1") bm.workon_branch(bm.workspace_branch) assert bm.active_branch == 'master' q = f""" mutation makeFeatureBranch {{ workonExperimentalBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", branchName: "{b1}" }}) {{ labbook{{ name description branches {{ branchName }} activeBranchName }} }} }} """ r = client.execute(q) assert 'errors' not in r assert r['data']['workonExperimentalBranch']['labbook']['activeBranchName'] \ == 'tester1' ab = r['data']['workonExperimentalBranch']['labbook']['branches'] assert set([n['branchName'] for n in ab]) \ == set(['master', 'tester1']) assert bm.active_branch == 'tester1' assert lb.is_repo_clean
def test_create_feature_branch_bad_name_fail(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) bad_branch_names = [ '', '_', 'Über-bad', 'xxx-xxx' * 40, 'cats_99', 'bad-', '-', '-bad', 'bad--bad', 'bad---bad--bad-bad', 'Nope', 'Nope99', 'Nope-99', 'N&PE', 'n*ope', 'no;way', 'no:way', '<nope>-not-a-branch', 'Robert") DROP TABLE Students; --', "no way not a branch", ''.join(chr(x) for x in range(0, 78)), ''.join(chr(x) for x in range(0, 255)), chr(0) * 10, chr(0) * 10000 ] for bad_name in bad_branch_names: q = f""" mutation makeFeatureBranch {{ createExperimentalBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", branchName: "{bad_name}" }}) {{ newBranchName }} }} """ r = client.execute(q) pprint.pprint(r) assert 'errors' in r assert bm.active_branch == bm.workspace_branch assert lb.is_repo_clean
def test_create_feature_branch_success(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) b1 = bm.create_branch(f"tester1") bm.workon_branch(bm.workspace_branch) q = f""" mutation makeFeatureBranch {{ createExperimentalBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", branchName: "valid-branch-name-working1" }}) {{ labbook{{ name activeBranchName branches {{ branchName }} }} }} }} """ r = client.execute(q) assert 'errors' not in r assert r['data']['createExperimentalBranch']['labbook']['activeBranchName'] \ == 'valid-branch-name-working1' assert set([n['branchName'] for n in r['data']['createExperimentalBranch']['labbook']['branches']]) \ == set(['tester1', 'master', 'valid-branch-name-working1']) assert lb.active_branch == 'valid-branch-name-working1' assert lb.is_repo_clean
def test_query_mergeable_branches_from_main(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) b1 = bm.create_branch(f"tester1") bm.workon_branch(bm.workspace_branch) b2 = bm.create_branch(f"tester2") bm.workon_branch(bm.workspace_branch) assert bm.active_branch == bm.workspace_branch q = f""" {{ labbook(name: "{UT_LBNAME}", owner: "{UT_USERNAME}") {{ branches {{ branchName isMergeable }} }} }} """ r = client.execute(q) assert 'errors' not in r assert len(r['data']['labbook']['branches']) == 3 assert r['data']['labbook']['branches'][0]['branchName'] == 'master' assert r['data']['labbook']['branches'][0]['isMergeable'] == False assert r['data']['labbook']['branches'][1]['branchName'] == 'tester1' assert r['data']['labbook']['branches'][1]['isMergeable'] == True assert r['data']['labbook']['branches'][2]['branchName'] == 'tester2' assert r['data']['labbook']['branches'][2]['isMergeable'] == True
def test_query_mergeable_branches_from_feature_branch( self, mock_create_labbooks): # Per current branch model, can only merge in workspace branch lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) b1 = bm.create_branch(f"tester1") bm.workon_branch(bm.workspace_branch) b2 = bm.create_branch(f"tester2") q = f""" {{ labbook(name: "{UT_LBNAME}", owner: "{UT_USERNAME}") {{ workspaceBranchName branches {{ branchName isMergeable }} }} }} """ r = client.execute(q) assert 'errors' not in r assert r['data']['labbook'][ 'workspaceBranchName'] == bm.workspace_branch branches = r['data']['labbook']['branches'] assert branches[0]['branchName'] == 'master' assert branches[0]['isMergeable'] is True assert branches[1]['branchName'] == 'tester1' assert branches[1]['isMergeable'] is True assert branches[2]['branchName'] == 'tester2' assert branches[2]['isMergeable'] is False
def test_available_branches(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] bm = BranchManager(lb, username=UT_USERNAME) q = f""" {{ labbook(name: "{UT_LBNAME}", owner: "{UT_USERNAME}") {{ branches {{ branchName isLocal isRemote isActive }} }} }} """ r = client.execute(q) pprint.pprint(r) assert 'errors' not in r assert len(r['data']['labbook']['branches']) == 1 assert r['data']['labbook']['branches'][0][ 'branchName'] == bm.workspace_branch assert r['data']['labbook']['branches'][0][ 'isLocal'] == True, "Should be local" assert r['data']['labbook']['branches'][0][ 'isRemote'] == False, "There should be no remote branches" assert r['data']['labbook']['branches'][0]['isActive'] == True
def test_reflect_deleted_files_on_merge_in(self, mock_create_labbooks): lb, client = mock_create_labbooks[0], mock_create_labbooks[1] with open('/tmp/s1.txt', 'w') as s1: s1.write('original-file\ndata') FileOperations.insert_file(lb, section='code', src_file=s1.name) bm = BranchManager(lb, username=UT_USERNAME) nb = bm.create_branch(f'new-branch') assert os.path.exists(os.path.join(lb.root_dir, 'code', 's1.txt')) FileOperations.delete_files(lb, 'code', ['s1.txt']) assert lb.is_repo_clean assert not os.path.exists(os.path.join(lb.root_dir, 'code', 's1.txt')) bm.workon_branch(bm.workspace_branch) assert os.path.exists(os.path.join(lb.root_dir, 'code', 's1.txt')) merge_q = f""" mutation x {{ mergeFromBranch(input: {{ owner: "{UT_USERNAME}", labbookName: "{UT_LBNAME}", otherBranchName: "{nb}" }}) {{ labbook{{ name description activeBranchName }} }} }} """ r = client.execute(merge_q) assert 'errors' not in r assert r['data']['mergeFromBranch']['labbook']['activeBranchName'] == 'master' assert not os.path.exists(os.path.join(lb.root_dir, 'code', 's1.txt'))
def mutate_and_get_payload(cls, root, info, owner, labbook_name, branch_name, revision=None, description=None, client_mutation_id=None): username = get_logged_in_username() lb = InventoryManager().load_labbook(username, owner, labbook_name, author=get_logged_in_author()) with lb.lock(): bm = BranchManager(lb, username=username) full_branch_title = bm.create_branch(title=branch_name, revision=revision) logger.info( f"In {str(lb)} created new experimental feature branch: " f"{full_branch_title}") if description: cls._update_branch_description(lb, description) return CreateExperimentalBranch( Labbook(id="{}&{}".format(owner, labbook_name), name=labbook_name, owner=owner))
def test_fail_create_branch_duplicate_name(self, mock_labbook_lfs_disabled): """ Ensure cannot create a new branch with name of existing branch """ t = "branch-to-be-made-twice" lb = mock_labbook_lfs_disabled[2] bm = BranchManager(lb, username=TEST_USER) bm.create_branch(title=t) with pytest.raises(InvalidBranchName): bm.create_branch(title=t)
def helper_resolve_active_branch(self, labbook): active_branch_name = BranchManager( labbook, username=get_logged_in_username()).active_branch return LabbookRef( id=f"{self.owner}&{self.name}&None&{active_branch_name}", owner=self.owner, name=self.name, prefix=None, ref_name=active_branch_name)
def test_success_create_branch_simple(self, mock_labbook_lfs_disabled): """ Test basic creation of a new branch""" t = "my-first-feature-branch" lb = mock_labbook_lfs_disabled[2] bm = BranchManager(lb, username=TEST_USER) assert bm.active_branch == 'master' bm.create_branch(title=t) assert bm.active_branch == t assert lb.is_repo_clean is True