diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 8913a005..8da40770 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -3,3 +3,4 @@ | GitHub user | Real Name | Affiliation | Date | | ----------- | --------------- | ----------- | ---------- | | yaswant | Yaswant Pradhan | Met Office | 2026-07-17 | +| jfrost-mo | James Frost | Met Office | 2026-09-04 | diff --git a/github_scripts/get_git_sources.py b/github_scripts/get_git_sources.py index 313313ac..883fd635 100644 --- a/github_scripts/get_git_sources.py +++ b/github_scripts/get_git_sources.py @@ -280,10 +280,10 @@ def get_unmerged(loc: Path) -> list[str]: return files.stdout.split() -def check_existing(loc: Path) -> None: +def check_existing(loc: Path) -> bool: """ - If the repository exists and isn't a git repo, exit now as we don't want to - overwrite it + Return whether the repository already exists. If it does but isn't a git + repo, exit now as we don't want to overwrite it. """ if loc.exists(): @@ -292,6 +292,8 @@ def check_existing(loc: Path) -> None: f"The destination, '{loc}', already exists but isn't a git directory. " "Exiting so as to not overwrite it." ) + return True + return False def clone_repo_mirror( @@ -309,25 +311,30 @@ def clone_repo_mirror( - loc: path to clone the repository to """ - if loc.exists(): - check_existing(loc) - # Clone if the repo doesn't exist + fetch = determine_mirror_fetch(repo_source, repo_ref) if repo_ref else "HEAD" + if check_existing(loc): + # If not provided a ref, pull the latest version of the current branch. + if not repo_ref: + run_command(f"git -C {loc} pull") + return + # Update existing repository. + run_command(f"git -C {loc} fetch origin {fetch}") + run_command(f"git -C {loc} checkout FETCH_HEAD") else: - command = f"git clone {mirror_loc} {loc}" - run_command(command) - - # If not provided a ref, pull the latest repository and return - if not repo_ref: - run_command(f"git -C {loc} pull") - return - - fetch = determine_mirror_fetch(repo_source, repo_ref) - commands = ( - f"git -C {loc} fetch origin {fetch}", - f"git -C {loc} checkout FETCH_HEAD", - ) - for command in commands: - run_command(command) + # Clone if the repo doesn't exist. If the mirror is local we don't copy + # the objects to make it much faster. + try: + # Adding `--revision {fetch}` to the clone would be more efficient + # due to avoiding an unnecessary checkout, however we need to + # support versions of git older than v2.49. + run_command(f"git clone --shared {mirror_loc} {loc}") + run_command(f"git -C {loc} checkout {fetch}") + except SubprocessRunError: + logger.error( + "Cloning from local mirror failed. " + "Check your local guidance on how to set up mirror access." + ) + raise def determine_mirror_fetch(repo_source: str, repo_ref: str) -> str: @@ -361,7 +368,7 @@ def clone_repo(repo_source: str, repo_ref: str, loc: Path) -> None: - loc: path to clone the repository to """ - if not loc.exists(): + if not check_existing(loc): # Create a clean clone location loc.mkdir(parents=True) @@ -377,7 +384,6 @@ def clone_repo(repo_source: str, repo_ref: str, loc: Path) -> None: for command in commands: run_command(command) else: - check_existing(loc) commands = ( f"git -C {loc} fetch origin {repo_ref}", f"git -C {loc} checkout FETCH_HEAD", diff --git a/github_scripts/tests/test_get_git_sources.py b/github_scripts/tests/test_get_git_sources.py index 081281fd..66112be3 100644 --- a/github_scripts/tests/test_get_git_sources.py +++ b/github_scripts/tests/test_get_git_sources.py @@ -147,7 +147,8 @@ def test_check_exists(setup_sources): Test check_existing """ - assert check_existing(setup_sources / "SimSys_Scripts") is None + assert check_existing(setup_sources / "SimSys_Scripts") is True + assert check_existing(setup_sources / "does_not_exist") is False with pytest.raises(FileExistsError): check_existing(setup_sources / "empty_dir")