Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for cloning configuration using a commit hash #515

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions docs/source/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,21 @@ For example::
Where ``${REPOSITORY}`` is the git URL or path of the repository to clone from,
for example, https://github.com/payu-org/mom-example.git.

To clone and checkout an existing git branch, use the ``--branch`` flag and
To clone and checkout an existing git branch, use the ``-B/--branch`` flag and
specify the branch name::

payu clone --branch ${EXISTING_BRANCH} ${REPOSITORY} my_expt

To create and checkout a new git branch use ``--new-branch`` and specify a
new branch name:
To create and checkout a new git branch use ``-b/--new-branch`` and specify a
new branch name::

payu clone --new-branch ${NEW_BRANCH} ${REPOSITORY} my_expt

To create a new git branch starting from a tag or commit, use ``-s/--start-point``
flag::

payu clone -b ${NEW_BRANCH} -s {COMMIT_HASH|TAG} ${REPOSITORY} my_expt

To see more configuration options for ``payu clone``,
run::

Expand Down
16 changes: 11 additions & 5 deletions payu/branch.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ def switch_symlink(lab_dir_path: Path, control_path: Path,
def clone(repository: str,
directory: Path,
branch: Optional[str] = None,
start_point: Optional[str] = None,
new_branch_name: Optional[str] = None,
keep_uuid: bool = False,
model_type: Optional[str] = None,
Expand All @@ -227,11 +228,11 @@ def clone(repository: str,
directory: Path
The control directory where the repository will be cloned
branch: Optional[str]
Name of branch to clone and checkout
Name of branch to checkout during the git clone
start_point: Optional[str]
Branch-name/commit/tag to start new branch from
new_branch_name: Optional[str]
Name of new branch to create and checkout.
If branch is also defined, the new branch will start from the
latest commit of the branch.
Name of new branch to create and checkout
keep_uuid: bool, default False
Keep UUID unchanged, if it exists
config_path: Optional[Path]
Expand All @@ -248,6 +249,10 @@ def clone(repository: str,
Parent experiment UUID to add to generated metadata

Returns: None

Note: branch, if defined, can be set to avoid initially checking out the
default branch during git clone - this is useful for repositories where
the default branch is not a payu configuration.
"""
# Resolve directory to an absolute path
control_path = directory.resolve()
Expand Down Expand Up @@ -278,7 +283,8 @@ def clone(repository: str,
control_path=control_path,
model_type=model_type,
lab_path=lab_path,
parent_experiment=parent_experiment)
parent_experiment=parent_experiment,
start_point=start_point)
else:
# Checkout branch
if branch is None:
Expand Down
11 changes: 11 additions & 0 deletions payu/subcommands/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,17 @@
}
}

# Clone branch
clone_start_point = {
'flags': ('--start-point', '-s'),
'parameters': {
'action': 'store',
'dest': 'start_point',
'default': None,
'help': 'New branch will start from this commit or tag'
}
}
aidanheerdegen marked this conversation as resolved.
Show resolved Hide resolved

# Clone create branch
new_branch_name = {
'flags': ('--new-branch', '-b'),
Expand Down
7 changes: 4 additions & 3 deletions payu/subcommands/clone_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
args.keep_uuid, args.clone_branch,
args.repository, args.local_directory,
args.new_branch_name, args.restart_path,
args.parent_experiment]
args.parent_experiment, args.clone_start_point]


def transform_strings_to_path(path_str=None):
Expand All @@ -27,7 +27,7 @@ def transform_strings_to_path(path_str=None):

def runcmd(model_type, config_path, lab_path, keep_uuid,
branch, repository, local_directory, new_branch_name, restart_path,
parent_experiment):
parent_experiment, start_point):
"""Execute the command."""
config_path = transform_strings_to_path(config_path)
restart_path = transform_strings_to_path(restart_path)
Expand All @@ -43,7 +43,8 @@ def runcmd(model_type, config_path, lab_path, keep_uuid,
lab_path=lab_path,
new_branch_name=new_branch_name,
restart_path=restart_path,
parent_experiment=parent_experiment)
parent_experiment=parent_experiment,
start_point=start_point)


runscript = runcmd
47 changes: 47 additions & 0 deletions test/test_branch.py
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,53 @@ def test_clone(mock_uuid):
assert [head.name for head in cloned_repo2.heads] == ["Branch1", "Branch2"]


@pytest.mark.parametrize(
"start_point_type", ["commit", "tag"]
)
def test_clone_startpoint(start_point_type):
# Create a repo to clone
source_repo_path = tmpdir / "sourceRepo"
source_repo_path.mkdir()
source_repo = setup_control_repository(path=source_repo_path)

# Create branch1
branch1 = source_repo.create_head("Branch1")
branch1_commit = branch1.object.hexsha
if start_point_type == "tag":
source_repo.create_tag('v1.0', ref=branch1.commit)
start_point = 'v1.0'
elif start_point_type == "commit":
start_point = branch1_commit

# Add another commit on main branch so the commit is different to branch1
(source_repo_path / "mock_file.txt").touch()
source_repo.index.add("mock_file.txt")
source_repo.index.commit("Another commit with a mock file")

source_repo_commit = source_repo.active_branch.object.hexsha
assert source_repo_commit != branch1_commit

# Run Clone
cloned_repo_path = tmpdir / "clonedRepo"
with cd(tmpdir):
clone(
repository=str(source_repo_path),
directory=cloned_repo_path,
lab_path=labdir,
new_branch_name="Branch3",
start_point=start_point
)

cloned_repo = git.Repo(cloned_repo_path)

# Check branched starting from start point
second_latest_commit = list(cloned_repo.iter_commits(max_count=2))[1]
assert second_latest_commit.hexsha == branch1_commit

# Latest commit is different (new commit from metadata)
assert source_repo_commit != cloned_repo.active_branch.object.hexsha


def add_and_commit_metadata(repo, metadata):
"""Helper function to create/update metadata file and commit"""
metadata_path = ctrldir / "metadata.yaml"
Expand Down
Loading