def test_iter_revs( tmp_dir, scm, ): """ new other │ │ old (tag) ────┘ │ root """ old = scm.active_branch() tmp_dir.scm_gen("foo", "init", commit="init") rev_root = scm.get_rev() tmp_dir.scm_gen("foo", "old", commit="old") rev_old = scm.get_rev() scm.checkout("new", create_new=True) tmp_dir.scm_gen("foo", "new", commit="new") rev_new = scm.get_rev() scm.checkout(old) scm.tag("tag") scm.checkout("other", create_new=True) tmp_dir.scm_gen("foo", "other", commit="new") rev_other = scm.get_rev() ref = ExpRefInfo(rev_root, "exp1") scm.set_ref(str(ref), rev_new) ref = ExpRefInfo(rev_root, "exp2") scm.set_ref(str(ref), rev_old) gen = iter_revs(scm, [rev_root, "new"], 1) assert gen == {rev_root: [rev_root], rev_new: ["new"]} gen = iter_revs(scm, ["new"], 2) assert gen == {rev_new: ["new"], rev_old: [rev_old]} gen = iter_revs(scm, ["other"], -1) assert gen == { rev_other: ["other"], rev_old: [rev_old], rev_root: [rev_root], } gen = iter_revs(scm, ["tag"]) assert gen == {rev_old: ["tag"]} gen = iter_revs(scm, all_branches=True) assert gen == {rev_old: [old], rev_new: ["new"], rev_other: ["other"]} gen = iter_revs(scm, all_tags=True) assert gen == {rev_old: ["tag"]} gen = iter_revs(scm, all_commits=True) assert gen == { rev_old: [rev_old], rev_new: [rev_new], rev_other: [rev_other], rev_root: [rev_root], } gen = iter_revs(scm, all_experiments=True) assert gen == { rev_new: [rev_new], rev_old: [rev_old], rev_root: [rev_root], }
def push( repo, git_remote: str, exp_names: Union[Iterable[str], str], all_commits=False, rev: Optional[str] = None, num=1, force: bool = False, push_cache: bool = False, **kwargs, ) -> Iterable[str]: exp_ref_set: Set["ExpRefInfo"] = set() if all_commits: exp_ref_set.update(exp_refs(repo.scm)) else: if exp_names: if isinstance(exp_names, str): exp_names = [exp_names] exp_ref_dict = resolve_name(repo.scm, exp_names) unresolved_exp_names = [] for exp_name, exp_ref in exp_ref_dict.items(): if exp_ref is None: unresolved_exp_names.append(exp_name) else: exp_ref_set.add(exp_ref) if unresolved_exp_names: raise UnresolvedExpNamesError(unresolved_exp_names) if rev: rev_dict = iter_revs(repo.scm, [rev], num) rev_set = set(rev_dict.keys()) ref_info_dict = exp_refs_by_baseline(repo.scm, rev_set) for _, ref_info_list in ref_info_dict.items(): exp_ref_set.update(ref_info_list) push_result = _push(repo, git_remote, exp_ref_set, force) if push_result[SyncStatus.DIVERGED]: diverged_refs = [ref.name for ref in push_result[SyncStatus.DIVERGED]] ui.warn( f"Local experiment '{diverged_refs}' has diverged from remote " "experiment with the same name. To override the remote experiment " "re-run with '--force'." ) if push_cache: push_cache_ref = ( push_result[SyncStatus.UP_TO_DATE] + push_result[SyncStatus.SUCCESS] ) _push_cache(repo, push_cache_ref, **kwargs) return [ref.name for ref in push_result[SyncStatus.SUCCESS]]
def _resolve_exp_by_baseline( repo, rev: str, num: int, commit_ref_dict: Dict["ExpRefInfo", str], git_remote: Optional[str] = None, ): rev_dict = iter_revs(repo.scm, [rev], num) rev_set = set(rev_dict.keys()) ref_info_dict = exp_refs_by_baseline(repo.scm, rev_set, git_remote) for _, ref_info_list in ref_info_dict.items(): for ref_info in ref_info_list: if ref_info not in commit_ref_dict: commit_ref_dict[ref_info] = ref_info.name
def push( repo, git_remote: str, exp_names: Union[Iterable[str], str], all_commits=False, rev: Optional[str] = None, num=1, force: bool = False, push_cache: bool = False, **kwargs, ) -> Iterable[str]: exp_ref_set: Set["ExpRefInfo"] = set() if all_commits: exp_ref_set.update(exp_refs(repo.scm)) else: if exp_names: if isinstance(exp_names, str): exp_names = [exp_names] exp_ref_dict = resolve_name(repo.scm, exp_names) unresolved_exp_names = [] for exp_name, exp_ref in exp_ref_dict.items(): if exp_ref is None: unresolved_exp_names.append(exp_name) else: exp_ref_set.add(exp_ref) if unresolved_exp_names: raise UnresolvedExpNamesError(unresolved_exp_names) if rev: rev_dict = iter_revs(repo.scm, [rev], num) rev_set = set(rev_dict.keys()) ref_info_dict = exp_refs_by_baseline(repo.scm, rev_set) for _, ref_info_list in ref_info_dict.items(): exp_ref_set.update(ref_info_list) _push(repo, git_remote, exp_ref_set, force) if push_cache: _push_cache(repo, exp_ref_set, **kwargs) return [ref.name for ref in exp_ref_set]
def ls( repo, rev: Optional[str] = None, all_commits: bool = False, num: int = 1, git_remote: Optional[str] = None, ): results = defaultdict(list) if all_commits: gen = exp_refs(repo.scm, git_remote) for info in gen: results[info.baseline_sha].append(info.name) return results rev = rev or "HEAD" revs = iter_revs(repo.scm, [rev], num) rev_set = set(revs.keys()) ref_info_dict = exp_refs_by_baseline(repo.scm, rev_set, git_remote) for rev, ref_info_list in ref_info_dict.items(): results[rev] = [ref_info.name for ref_info in ref_info_list] return results
def show( repo: "Repo", all_branches=False, all_tags=False, revs: Union[List[str], str, None] = None, all_commits=False, sha_only=False, num=1, param_deps=False, onerror: Optional[Callable] = None, fetch_running: bool = True, ): if onerror is None: onerror = onerror_collect res: Dict[str, Dict] = defaultdict(OrderedDict) if not any([revs, all_branches, all_tags, all_commits]): revs = ["HEAD"] if isinstance(revs, str): revs = [revs] found_revs: Dict[str, List[str]] = {"workspace": []} found_revs.update( iter_revs(repo.scm, revs, num, all_branches, all_tags, all_commits)) running = repo.experiments.get_running_exps(fetch_refs=fetch_running) for rev in found_revs: res[rev]["baseline"] = _collect_experiment_commit( repo, rev, sha_only=sha_only, param_deps=param_deps, running=running, onerror=onerror, is_baseline=True, ) if rev == "workspace": continue ref_info = ExpRefInfo(baseline_sha=rev) commits = [(ref, repo.scm.resolve_commit(ref)) for ref in repo.scm.iter_refs(base=str(ref_info))] for exp_ref, _ in sorted(commits, key=lambda x: x[1].commit_time, reverse=True): ref_info = ExpRefInfo.from_ref(exp_ref) assert ref_info.baseline_sha == rev _collect_experiment_branch( res[rev], repo, exp_ref, rev, sha_only=sha_only, param_deps=param_deps, running=running, onerror=onerror, ) # collect queued (not yet reproduced) experiments for stash_rev, entry in repo.experiments.stash_revs.items(): if entry.baseline_rev in found_revs: if stash_rev not in running or not running[stash_rev].get( "last"): experiment = _collect_experiment_commit( repo, stash_rev, sha_only=sha_only, stash=stash_rev not in running, param_deps=param_deps, running=running, onerror=onerror, ) res[entry.baseline_rev][stash_rev] = experiment return res