experiments: support cloning parent in detached-head state (#4611)

* experiments: account for cloning detached-head parent repo

* add test for detached-head parent
This commit is contained in:
Peter Rowlands (변기호)
2020-09-24 18:36:51 +03:00
committed by GitHub
parent 2cbd46ba75
commit 32bb46f34f
2 changed files with 44 additions and 1 deletions
+16 -1
View File
@@ -178,11 +178,26 @@ class Experiments:
self.scm.checkout(rev)
def _checkout_default_branch(self):
from git.refs.symbolic import SymbolicReference
# switch to default branch
git_repo = self.scm.repo
origin_refs = git_repo.remotes["origin"].refs
ref = origin_refs["HEAD"].reference
# origin/HEAD will point to tip of the default branch unless we
# initially cloned a repo that was in a detached-HEAD state.
#
# If we are currently detached because we cloned a detached
# repo, we can't actually tell what branch should be considered
# default, so we just fall back to the first available reference.
if "HEAD" in origin_refs:
ref = origin_refs["HEAD"].reference
else:
ref = origin_refs[0]
if not isinstance(ref, SymbolicReference):
ref = ref.reference
branch_name = ref.name.split("/")[-1]
if branch_name in git_repo.heads:
branch = git_repo.heads[branch_name]
else:
@@ -208,3 +208,31 @@ def test_extend_branch(tmp_dir, scm, dvc):
dvc.experiments.checkout(exp_b)
assert (tmp_dir / "params.yaml").read_text().strip() == "foo: 3"
assert (tmp_dir / "metrics.yaml").read_text().strip() == "foo: 3"
def test_detached_parent(tmp_dir, scm, dvc, mocker):
tmp_dir.gen("copy.py", COPY_SCRIPT)
tmp_dir.gen("params.yaml", "foo: 1")
stage = dvc.run(
cmd="python copy.py params.yaml metrics.yaml",
metrics_no_cache=["metrics.yaml"],
params=["foo"],
name="copy-file",
)
scm.add(["dvc.yaml", "dvc.lock", "copy.py", "params.yaml", "metrics.yaml"])
scm.commit("v1")
detached_rev = scm.get_rev()
tmp_dir.gen("params.yaml", "foo: 2")
dvc.reproduce(stage.addressing)
scm.add(["dvc.yaml", "dvc.lock", "copy.py", "params.yaml", "metrics.yaml"])
scm.commit("v2")
scm.checkout(detached_rev)
assert scm.repo.head.is_detached
dvc.reproduce(stage.addressing, experiment=True, params=["foo=3"])
exp_rev = dvc.experiments.scm.get_rev()
assert dvc.experiments.get_baseline(exp_rev) == detached_rev
assert (tmp_dir / "params.yaml").read_text().strip() == "foo: 3"
assert (tmp_dir / "metrics.yaml").read_text().strip() == "foo: 3"