From 9efed57e86557369842d8b921c0b0515e197239d Mon Sep 17 00:00:00 2001
From: Gonzalo Peci <pecigonzalo@users.noreply.github.com>
Date: Thu, 14 Dec 2023 15:22:00 +0100
Subject: [PATCH] Add fetch.parallel option

---
 README.md                        | 8 +++++++-
 __test__/git-auth-helper.test.ts | 1 +
 action.yml                       | 7 ++++++-
 dist/index.js                    | 7 +++++++
 src/git-source-provider.ts       | 1 +
 src/git-source-settings.ts       | 5 +++++
 src/input-helper.ts              | 9 +++++++++
 7 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index c4c618e..1c0b8d0 100644
--- a/README.md
+++ b/README.md
@@ -94,6 +94,12 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
     # Default: false
     fetch-tags: ''
 
+    # Specifies the maximal number of fetch operations to be run in parallel at a time
+    # (submodules, or remotes when the --multiple option of git-fetch is in effect). A
+    # value of 0 will give some reasonable default. If unset, it defaults to 1.
+    # Default: 1
+    fetch-parallel: ''
+
     # Whether to show progress status output when fetching.
     # Default: true
     show-progress: ''
@@ -115,7 +121,7 @@ Please refer to the [release page](https://github.com/actions/checkout/releases/
     # integer allows up to that number of submodules fetched in parallel. A value of 0
     # will give some reasonable default. If unset, it defaults to 1.
     # Default: 1
-    submodulesFetchJobs: ''
+    submodules-fetch-jobs: ''
 
     # Add repository path as safe.directory for Git global config by running `git
     # config --global --add safe.directory <path>`
diff --git a/__test__/git-auth-helper.test.ts b/__test__/git-auth-helper.test.ts
index 94924f1..bb51821 100644
--- a/__test__/git-auth-helper.test.ts
+++ b/__test__/git-auth-helper.test.ts
@@ -807,6 +807,7 @@ async function setup(testName: string): Promise<void> {
     sparseCheckoutConeMode: true,
     fetchDepth: 1,
     fetchTags: false,
+    fetchParallel: '1',
     showProgress: true,
     lfs: false,
     submodules: false,
diff --git a/action.yml b/action.yml
index 4e27f10..fbe73d8 100644
--- a/action.yml
+++ b/action.yml
@@ -73,6 +73,11 @@ inputs:
   fetch-tags:
     description: 'Whether to fetch tags, even if fetch-depth > 0.'
     default: false
+  fetch-parallel:
+    description: >
+      Specifies the maximal number of fetch operations to be run in parallel at a time (submodules, or remotes when the --multiple option of git-fetch is in effect).
+      A value of 0 will give some reasonable default. If unset, it defaults to 1.
+    default: 1
   show-progress:
     description: 'Whether to show progress status output when fetching.'
     default: true
@@ -88,7 +93,7 @@ inputs:
       When the `ssh-key` input is not provided, SSH URLs beginning with `git@github.com:` are
       converted to HTTPS.
     default: false
-  submodulesFetchJobs:
+  submodules-fetch-jobs:
     description: >
       Specifies how many submodules are fetched/cloned at the same time. A positive integer allows up to that number of submodules fetched in parallel. A value of 0 will give some reasonable default. If unset, it defaults to 1.
     default: 1
diff --git a/dist/index.js b/dist/index.js
index b27e94a..e5408e8 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1243,6 +1243,7 @@ function getSource(settings) {
             }
             // Fetch
             core.startGroup('Fetching the repository');
+            yield git.config('fetch.parallel', settings.fetchParallel.toString());
             const fetchOptions = {};
             if (settings.filter) {
                 fetchOptions.filter = settings.filter;
@@ -1753,6 +1754,12 @@ function getInputs() {
         result.fetchTags =
             (core.getInput('fetch-tags') || 'false').toUpperCase() === 'TRUE';
         core.debug(`fetch tags = ${result.fetchTags}`);
+        // Fetch tags
+        result.fetchParallel = Math.floor(Number(core.getInput('fetch-parallel') || '1'));
+        if (isNaN(result.fetchParallel) || result.fetchParallel < 0) {
+            result.fetchParallel = 0;
+        }
+        core.debug(`fetch parallel = ${result.fetchTags}`);
         // Show fetch progress
         result.showProgress =
             (core.getInput('show-progress') || 'true').toUpperCase() === 'TRUE';
diff --git a/src/git-source-provider.ts b/src/git-source-provider.ts
index 58d4292..d95f688 100644
--- a/src/git-source-provider.ts
+++ b/src/git-source-provider.ts
@@ -153,6 +153,7 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
 
     // Fetch
     core.startGroup('Fetching the repository')
+    await git.config('fetch.parallel', settings.fetchParallel.toString())
     const fetchOptions: {
       filter?: string
       fetchDepth?: number
diff --git a/src/git-source-settings.ts b/src/git-source-settings.ts
index ae6bb74..99fd355 100644
--- a/src/git-source-settings.ts
+++ b/src/git-source-settings.ts
@@ -54,6 +54,11 @@ export interface IGitSourceSettings {
    */
   fetchTags: boolean
 
+  /**
+   * Indicates the maximal number of fetch operations to be run in parallel at a time
+   */
+  fetchParallel: number
+
   /**
    * Indicates whether to use the --progress option when fetching
    */
diff --git a/src/input-helper.ts b/src/input-helper.ts
index b2e76a9..3cc9221 100644
--- a/src/input-helper.ts
+++ b/src/input-helper.ts
@@ -113,6 +113,15 @@ export async function getInputs(): Promise<IGitSourceSettings> {
     (core.getInput('fetch-tags') || 'false').toUpperCase() === 'TRUE'
   core.debug(`fetch tags = ${result.fetchTags}`)
 
+  // Fetch tags
+  result.fetchParallel = Math.floor(
+    Number(core.getInput('fetch-parallel') || '1')
+  )
+  if (isNaN(result.fetchParallel) || result.fetchParallel < 0) {
+    result.fetchParallel = 0
+  }
+  core.debug(`fetch parallel = ${result.fetchTags}`)
+
   // Show fetch progress
   result.showProgress =
     (core.getInput('show-progress') || 'true').toUpperCase() === 'TRUE'