Merge pull request #10416 from bensze01/abicheck-worktree-submodules

Use submodule work trees during ABI check
diff --git a/scripts/abi_check.py b/scripts/abi_check.py
index 243e6fc..4fe7f54 100755
--- a/scripts/abi_check.py
+++ b/scripts/abi_check.py
@@ -197,11 +197,32 @@
         """If the crypto submodule is present, initialize it.
         if version.crypto_revision exists, update it to that revision,
         otherwise update it to the default revision"""
-        update_output = subprocess.check_output(
-            [self.git_command, "submodule", "update", "--init", '--recursive'],
-            cwd=git_worktree_path,
+        submodule_output = subprocess.check_output(
+            [self.git_command, "submodule", "foreach", "--recursive",
+             f'git worktree add --detach "{git_worktree_path}/$displaypath" HEAD'],
+            cwd=self.repo_path,
             stderr=subprocess.STDOUT
         )
+        self.log.debug(submodule_output.decode("utf-8"))
+
+        try:
+            # Try to update the submodules using local commits
+            # (Git will sometimes insist on fetching the remote without --no-fetch
+            # if the submodules are shallow clones)
+            update_output = subprocess.check_output(
+                [self.git_command, "submodule", "update", "--init", '--recursive', '--no-fetch'],
+                cwd=git_worktree_path,
+                stderr=subprocess.STDOUT
+            )
+        except subprocess.CalledProcessError as err:
+            self.log.debug(err.stdout.decode("utf-8"))
+
+            # Checkout with --no-fetch failed, falling back to fetching from origin
+            update_output = subprocess.check_output(
+                [self.git_command, "submodule", "update", "--init", '--recursive'],
+                cwd=git_worktree_path,
+                stderr=subprocess.STDOUT
+            )
         self.log.debug(update_output.decode("utf-8"))
         if not (os.path.exists(os.path.join(git_worktree_path, "crypto"))
                 and version.crypto_revision):
@@ -390,8 +411,15 @@
     def _cleanup_worktree(self, git_worktree_path):
         """Remove the specified git worktree."""
         shutil.rmtree(git_worktree_path)
+        submodule_output = subprocess.check_output(
+            [self.git_command, "submodule", "foreach", "--recursive",
+             f'git worktree remove "{git_worktree_path}/$displaypath"'],
+            cwd=self.repo_path,
+            stderr=subprocess.STDOUT
+        )
+        self.log.debug(submodule_output.decode("utf-8"))
         worktree_output = subprocess.check_output(
-            [self.git_command, "worktree", "prune"],
+            [self.git_command, "worktree", "remove", git_worktree_path],
             cwd=self.repo_path,
             stderr=subprocess.STDOUT
         )