Skip to content

Commit

Permalink
fix(cli): do not start a session when in detached HEAD state (#3636)
Browse files Browse the repository at this point in the history
  • Loading branch information
m-alisafaee committed Oct 11, 2023
1 parent f4b6480 commit 80f70f5
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 1 deletion.
3 changes: 3 additions & 0 deletions renku/core/session/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ def session_start(
"""
from renku.domain_model.project_context import project_context

if project_context.repository.head.detached:
raise errors.SessionStartError("Cannot start a session from a detached HEAD. Check out a branch first.")

# NOTE: The Docker client in Python requires the parameters below to be a list and will fail with a tuple.
# Click will convert parameters with the flag "many" set to True to tuples.
kwargs["security_opt"] = list(kwargs.get("security_opt", []))
Expand Down
10 changes: 9 additions & 1 deletion renku/infrastructure/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -1554,6 +1554,11 @@ def reference(self) -> Optional[Reference]:
except (git.GitError, TypeError):
return None

@property
def detached(self) -> bool:
"""True if the reference is to a commit and not a branch."""
return self._reference.is_detached


class RemoteReference(Reference):
"""A git remote reference."""
Expand Down Expand Up @@ -1681,8 +1686,11 @@ def set_url(self, url: str):
_run_git_command(self._repository, "remote", "set-url", self.name, url)

@property
def head(self) -> str:
def head(self) -> Optional[str]:
"""The head commit of the remote."""
if self._repository.head.is_detached:
return None

self._remote.fetch()
return _run_git_command(self._repository, "rev-parse", f"{self._remote.name}/{self._repository.active_branch}")

Expand Down
15 changes: 15 additions & 0 deletions tests/cli/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,18 @@ def test_session_list_format(runner, project, dummy_session_provider, format, ou
assert 0 == result.exit_code, format_result_exception(result)
assert length == len(result.output.splitlines())
assert output in result.output


def test_session_detached_start(runner, project, dummy_session_provider):
"""Test starting a session in a detached HEAD repository."""
# NOTE: Make a dummy commit for project to have two commits
(project.repository.path / "README.md").write_text("changes")
project.repository.add(all=True)
project.repository.commit("dummy commit")

project.repository.checkout("HEAD~")

result = runner.invoke(cli, ["session", "start", "-p", "dummy"])

assert 1 == result.exit_code, format_result_exception(result)
assert "Cannot start a session from a detached HEAD" in result.output
20 changes: 20 additions & 0 deletions tests/core/metadata/test_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,23 @@ def test_ignored_paths(paths, ignored, project):
from renku.domain_model.project_context import project_context

assert project_context.repository.get_ignored_paths(*paths) == ignored


def test_remote(git_repository):
"""Test get remote of a repository."""
assert 1 == len(git_repository.remotes)

remote = git_repository.remotes[0]

assert "origin" == remote.name
assert "8853e0c1112e512c36db9cc76faff560b655e5d5" == remote.head


def test_remote_detached(git_repository):
"""Test get remote of a repository with detached head."""
git_repository.checkout("HEAD~")

remote = git_repository.remotes[0]

assert "origin" == remote.name
assert remote.head is None

0 comments on commit 80f70f5

Please sign in to comment.