diff --git a/mpsd-software-environment.py b/mpsd-software-environment.py
index e3283fbd5c759ea335f235b4e8b930cb05f087e4..579f076952031aac74b650a95d26df57833aa0e0 100755
--- a/mpsd-software-environment.py
+++ b/mpsd-software-environment.py
@@ -520,50 +520,51 @@ def setup_log_cmd(
                 )
 
 
-def create_dir_structure(mpsd_release: str, script_dir: Path) -> None:
-    """
-    Create the directory structure and clone spack environments repo.
-
-    The create_dir_structure function creates the directory structure for
-    the specified release and clones the Spack environments repository if it
-    doesn't exist.
+def clone_repo(
+    target_path: Path, repo_url: str, branch=None, skip_if_exists=True
+) -> None:
+    """Clone repo locally. Optionally checkout a branch.
 
     Parameters
     ----------
-    - mpsd_release: A string representing the MPSD release version.
-    - script_dir: A Path object representing the path to the scripts directory.
-
-    Returns
-    -------
-    - None
+    target_path : Path
+      Where to check the repository out to
+    repo_url: str
+      where to clone the git repository from
+    branch: str (defaults to None)
+      if provided, checkout this branch after cloning
     """
-    # Create the directory structure for the release
-    release_base_dir = script_dir / mpsd_release
-    release_base_dir.mkdir(parents=True, exist_ok=True)
+    if not target_path.exists():
+        target_path.mkdir()
 
-    with os_chdir(release_base_dir):
-        # Clone the spack-environments repo if it doesn't exist
-        if not os.path.exists("spack-environments"):
-            run(
-                [
-                    "git",
-                    "clone",
-                    config_vars["spack_environments_repo"],
-                ],
-                check=True,
-            )
-        with os_chdir("spack-environments"):
+    with os_chdir(target_path):
+        run(
+            ["git", "clone", repo_url, "."],
+            check=True,
+        )
+    if branch:
+        with os_chdir(target_path):
             # Git fetch and checkout the release branch and git pull
             # to be sure that the resulting repo is up to date
             run(["git", "fetch", "--all"], check=True)
-            checkout_result = run(["git", "checkout", mpsd_release], check=True)
+            checkout_result = run(["git", "checkout", branch])
 
             if checkout_result.returncode != 0:
-                raise Exception(
-                    "Release branch does not exist in spack-environment repo \n."
-                    "Check for typos."
+                msg = f"Couldn't find {branch=}\n"
+
+                branches_result = run(
+                    ["git", "branch", "-a"], check=True, capture_output=True
                 )
-            run(["git", "pull"], check=True)
+                branches_list = branches_result.stdout.decode().split("\n")
+                # strip off 'remotes/origin' (needs Python 3.9):
+                branches_list = [
+                    b.strip().removeprefix("remotes/origin/") for b in branches_list
+                ]
+                msg += f"Available branches are {branches_list}"
+                logging.error(msg)
+                raise Exception(msg, branches_result)
+            else:
+                run(["git", "pull"], check=True)
 
 
 def get_release_info(mpsd_release: str, script_dir: Path) -> Tuple[str, str, List[str]]:
@@ -592,13 +593,15 @@ def get_release_info(mpsd_release: str, script_dir: Path) -> Tuple[str, str, Lis
     Raises
     ------
     FileNotFoundError
-        If the release directory does not exist. Run `create_dir_structure()` first.
+        If the release directory does not exist.
     """
     # Get the info for release
     release_base_dir = script_dir / mpsd_release
     if not os.path.exists(release_base_dir):
+        logging.debug(f"get_release_info({mpsd_release=}, {script_dir=}")
         raise FileNotFoundError(
-            "Release directory does not exist. Run create_dir_structure() first."
+            f"{release_base_dir} does not exist.\n"
+            "Hint: `prepare {mpsd_release}` may fix this."
         )
     with os_chdir(release_base_dir):
         with os_chdir("spack-environments"):
@@ -644,7 +647,20 @@ def prepare_environment(mpsd_release: str, script_dir: Path) -> List[str]:
     available_toolchains : list
         A list of available toolchains for the given MPSD release.
     """
-    create_dir_structure(mpsd_release, script_dir)
+    # Creates the directory structure for the specified release and clone the
+    # Spack environments repository if it doesn't exist:
+
+    # Create the directory structure for the release
+    release_base_dir = script_dir / mpsd_release
+    release_base_dir.mkdir(parents=True, exist_ok=True)
+    repo_path = release_base_dir / "spack-environments"
+    if repo_path.exists():
+        logging.debug(f"directory {repo_path} exists already, not touching")
+    else:
+        repo_url = config_vars["spack_environments_repo"]
+        logging.info(f"cloning repository {repo_path} from {repo_url}")
+        clone_repo(repo_path, repo_url, branch=mpsd_release)
+
     spe_branch, spe_commit_hash, available_toolchains = get_release_info(
         mpsd_release, script_dir
     )