From ad5dc193903d344f874145b3e00ff0c2b4820840 Mon Sep 17 00:00:00 2001
From: Frits Talbot <frits@metapathy.com>
Date: Sun, 9 Aug 2020 23:30:32 +0200
Subject: [PATCH 1/3] Add fetchJobs option to parallelize submodule updates

---
 README.md                        |  5 +++++
 __test__/git-auth-helper.test.ts |  1 +
 __test__/input-helper.test.ts    |  1 +
 action.yml                       |  3 +++
 dist/index.js                    | 13 +++++++++++--
 src/git-command-manager.ts       | 16 ++++++++++++++--
 src/git-source-provider.ts       |  3 ++-
 src/git-source-settings.ts       |  5 +++++
 src/input-helper.ts              |  7 +++++++
 9 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 9c56a6f..90eef49 100644
--- a/README.md
+++ b/README.md
@@ -93,6 +93,11 @@ Refer [here](https://github.com/actions/checkout/blob/v1/README.md) for previous
     # Default: 1
     fetch-depth: ''
 
+    # Number of fetches to perform simultaneously when updating submodules. 0
+    # indicates default (serial updates).
+    # Default: 0
+    fetch-jobs: ''
+
     # Whether to download Git-LFS files
     # Default: false
     lfs: ''
diff --git a/__test__/git-auth-helper.test.ts b/__test__/git-auth-helper.test.ts
index 2b4830c..889e2b6 100644
--- a/__test__/git-auth-helper.test.ts
+++ b/__test__/git-auth-helper.test.ts
@@ -760,6 +760,7 @@ async function setup(testName: string): Promise<void> {
     clean: true,
     commit: '',
     fetchDepth: 1,
+    fetchJobs: 0,
     lfs: false,
     submodules: false,
     nestedSubmodules: false,
diff --git a/__test__/input-helper.test.ts b/__test__/input-helper.test.ts
index 920bc8e..d9da8b9 100644
--- a/__test__/input-helper.test.ts
+++ b/__test__/input-helper.test.ts
@@ -75,6 +75,7 @@ describe('input-helper tests', () => {
     expect(settings.commit).toBeTruthy()
     expect(settings.commit).toBe('1234567890123456789012345678901234567890')
     expect(settings.fetchDepth).toBe(1)
+    expect(settings.fetchJobs).toBe(0)
     expect(settings.lfs).toBe(false)
     expect(settings.ref).toBe('refs/heads/some-ref')
     expect(settings.repositoryName).toBe('some-repo')
diff --git a/action.yml b/action.yml
index 91d3982..1abd5c8 100644
--- a/action.yml
+++ b/action.yml
@@ -56,6 +56,9 @@ inputs:
   fetch-depth:
     description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.'
     default: 1
+  fetch-jobs:
+    description: 'Number of fetches to perform simultaneously when updating submodules. 0 indicates default (serial updates).'
+    default: 0
   lfs:
     description: 'Whether to download Git-LFS files'
     default: false
diff --git a/dist/index.js b/dist/index.js
index ae64f3f..2faf9a2 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -5939,7 +5939,7 @@ class GitCommandManager {
             yield this.execGit(args);
         });
     }
-    submoduleUpdate(fetchDepth, recursive) {
+    submoduleUpdate(fetchDepth, recursive, fetchJobs) {
         return __awaiter(this, void 0, void 0, function* () {
             const args = ['-c', 'protocol.version=2'];
             args.push('submodule', 'update', '--init', '--force');
@@ -5949,6 +5949,9 @@ class GitCommandManager {
             if (recursive) {
                 args.push('--recursive');
             }
+            if (fetchJobs > 0) {
+                args.push(`--jobs=${fetchJobs}`);
+            }
             yield this.execGit(args);
         });
     }
@@ -6252,7 +6255,7 @@ function getSource(settings) {
                     // Checkout submodules
                     core.startGroup('Fetching submodules');
                     yield git.submoduleSync(settings.nestedSubmodules);
-                    yield git.submoduleUpdate(settings.fetchDepth, settings.nestedSubmodules);
+                    yield git.submoduleUpdate(settings.fetchDepth, settings.nestedSubmodules, settings.fetchJobs);
                     yield git.submoduleForeach('git config --local gc.auto 0', settings.nestedSubmodules);
                     core.endGroup();
                     // Persist credentials
@@ -14567,6 +14570,12 @@ function getInputs() {
         result.fetchDepth = 0;
     }
     core.debug(`fetch depth = ${result.fetchDepth}`);
+    // Fetch jobs
+    result.fetchJobs = Math.floor(Number(core.getInput('fetch-jobs') || '0'));
+    if (isNaN(result.fetchJobs) || result.fetchJobs < 0) {
+        result.fetchJobs = 0;
+    }
+    core.debug(`fetch jobs = ${result.fetchJobs}`);
     // LFS
     result.lfs = (core.getInput('lfs') || 'false').toUpperCase() === 'TRUE';
     core.debug(`lfs = ${result.lfs}`);
diff --git a/src/git-command-manager.ts b/src/git-command-manager.ts
index 059e3d8..92dc3f3 100644
--- a/src/git-command-manager.ts
+++ b/src/git-command-manager.ts
@@ -39,7 +39,11 @@ export interface IGitCommandManager {
   shaExists(sha: string): Promise<boolean>
   submoduleForeach(command: string, recursive: boolean): Promise<string>
   submoduleSync(recursive: boolean): Promise<void>
-  submoduleUpdate(fetchDepth: number, recursive: boolean): Promise<void>
+  submoduleUpdate(
+    fetchDepth: number,
+    recursive: boolean,
+    fetchJobs: number
+  ): Promise<void>
   tagExists(pattern: string): Promise<boolean>
   tryClean(): Promise<boolean>
   tryConfigUnset(configKey: string, globalConfig?: boolean): Promise<boolean>
@@ -308,7 +312,11 @@ class GitCommandManager {
     await this.execGit(args)
   }
 
-  async submoduleUpdate(fetchDepth: number, recursive: boolean): Promise<void> {
+  async submoduleUpdate(
+    fetchDepth: number,
+    recursive: boolean,
+    fetchJobs: number
+  ): Promise<void> {
     const args = ['-c', 'protocol.version=2']
     args.push('submodule', 'update', '--init', '--force')
     if (fetchDepth > 0) {
@@ -319,6 +327,10 @@ class GitCommandManager {
       args.push('--recursive')
     }
 
+    if (fetchJobs > 0) {
+      args.push(`--jobs=${fetchJobs}`)
+    }
+
     await this.execGit(args)
   }
 
diff --git a/src/git-source-provider.ts b/src/git-source-provider.ts
index 366ff33..eea6624 100644
--- a/src/git-source-provider.ts
+++ b/src/git-source-provider.ts
@@ -181,7 +181,8 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
         await git.submoduleSync(settings.nestedSubmodules)
         await git.submoduleUpdate(
           settings.fetchDepth,
-          settings.nestedSubmodules
+          settings.nestedSubmodules,
+          settings.fetchJobs
         )
         await git.submoduleForeach(
           'git config --local gc.auto 0',
diff --git a/src/git-source-settings.ts b/src/git-source-settings.ts
index 2786222..f5f529a 100644
--- a/src/git-source-settings.ts
+++ b/src/git-source-settings.ts
@@ -34,6 +34,11 @@ export interface IGitSourceSettings {
    */
   fetchDepth: number
 
+  /**
+   * The number of fetches to perform simultaneously when updating submodules
+   */
+  fetchJobs: number
+
   /**
    * Indicates whether to fetch LFS objects
    */
diff --git a/src/input-helper.ts b/src/input-helper.ts
index 4c05d6e..8767899 100644
--- a/src/input-helper.ts
+++ b/src/input-helper.ts
@@ -88,6 +88,13 @@ export function getInputs(): IGitSourceSettings {
   }
   core.debug(`fetch depth = ${result.fetchDepth}`)
 
+  // Fetch jobs
+  result.fetchJobs = Math.floor(Number(core.getInput('fetch-jobs') || '0'))
+  if (isNaN(result.fetchJobs) || result.fetchJobs < 0) {
+    result.fetchJobs = 0
+  }
+  core.debug(`fetch jobs = ${result.fetchJobs}`)
+
   // LFS
   result.lfs = (core.getInput('lfs') || 'false').toUpperCase() === 'TRUE'
   core.debug(`lfs = ${result.lfs}`)

From a5c1ce924a7a6ae521f5b4bc156c9f871d61824e Mon Sep 17 00:00:00 2001
From: Frits Talbot <frits@metapathy.com>
Date: Sat, 10 Oct 2020 10:02:44 +0200
Subject: [PATCH 2/3] Support fetch-jobs: 0 to use as many jobs as there are
 processors

The default is now fetch-jobs: -1, which is the new value for
reverting to normal git behavior (provide no --jobs argument).
---
 README.md                        | 7 ++++---
 __test__/git-auth-helper.test.ts | 2 +-
 __test__/input-helper.test.ts    | 2 +-
 action.yml                       | 7 +++++--
 dist/index.js                    | 8 ++++----
 src/git-command-manager.ts       | 2 +-
 src/input-helper.ts              | 6 +++---
 7 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/README.md b/README.md
index 90eef49..bc2552b 100644
--- a/README.md
+++ b/README.md
@@ -93,9 +93,10 @@ Refer [here](https://github.com/actions/checkout/blob/v1/README.md) for previous
     # Default: 1
     fetch-depth: ''
 
-    # Number of fetches to perform simultaneously when updating submodules. 0
-    # indicates default (serial updates).
-    # Default: 0
+    # Number of fetches to perform simultaneously when updating submodules: -1
+    # indicates to use git default (serial updates). 0 uses as many jobs as there are
+    # processors.
+    # Default: -1
     fetch-jobs: ''
 
     # Whether to download Git-LFS files
diff --git a/__test__/git-auth-helper.test.ts b/__test__/git-auth-helper.test.ts
index 889e2b6..6ac3f12 100644
--- a/__test__/git-auth-helper.test.ts
+++ b/__test__/git-auth-helper.test.ts
@@ -760,7 +760,7 @@ async function setup(testName: string): Promise<void> {
     clean: true,
     commit: '',
     fetchDepth: 1,
-    fetchJobs: 0,
+    fetchJobs: -1,
     lfs: false,
     submodules: false,
     nestedSubmodules: false,
diff --git a/__test__/input-helper.test.ts b/__test__/input-helper.test.ts
index d9da8b9..b6146f8 100644
--- a/__test__/input-helper.test.ts
+++ b/__test__/input-helper.test.ts
@@ -75,7 +75,7 @@ describe('input-helper tests', () => {
     expect(settings.commit).toBeTruthy()
     expect(settings.commit).toBe('1234567890123456789012345678901234567890')
     expect(settings.fetchDepth).toBe(1)
-    expect(settings.fetchJobs).toBe(0)
+    expect(settings.fetchJobs).toBe(-1)
     expect(settings.lfs).toBe(false)
     expect(settings.ref).toBe('refs/heads/some-ref')
     expect(settings.repositoryName).toBe('some-repo')
diff --git a/action.yml b/action.yml
index 1abd5c8..d4433d2 100644
--- a/action.yml
+++ b/action.yml
@@ -57,8 +57,11 @@ inputs:
     description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.'
     default: 1
   fetch-jobs:
-    description: 'Number of fetches to perform simultaneously when updating submodules. 0 indicates default (serial updates).'
-    default: 0
+    description: >
+      Number of fetches to perform simultaneously when updating submodules:
+      -1 indicates to use git default (serial updates). 0 uses as many jobs as
+      there are processors.
+    default: -1
   lfs:
     description: 'Whether to download Git-LFS files'
     default: false
diff --git a/dist/index.js b/dist/index.js
index 2faf9a2..d77981a 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -5949,7 +5949,7 @@ class GitCommandManager {
             if (recursive) {
                 args.push('--recursive');
             }
-            if (fetchJobs > 0) {
+            if (fetchJobs > -1) {
                 args.push(`--jobs=${fetchJobs}`);
             }
             yield this.execGit(args);
@@ -14571,9 +14571,9 @@ function getInputs() {
     }
     core.debug(`fetch depth = ${result.fetchDepth}`);
     // Fetch jobs
-    result.fetchJobs = Math.floor(Number(core.getInput('fetch-jobs') || '0'));
-    if (isNaN(result.fetchJobs) || result.fetchJobs < 0) {
-        result.fetchJobs = 0;
+    result.fetchJobs = Math.floor(Number(core.getInput('fetch-jobs') || '-1'));
+    if (isNaN(result.fetchJobs) || result.fetchJobs < -1) {
+        result.fetchJobs = -1;
     }
     core.debug(`fetch jobs = ${result.fetchJobs}`);
     // LFS
diff --git a/src/git-command-manager.ts b/src/git-command-manager.ts
index 92dc3f3..6ef3bec 100644
--- a/src/git-command-manager.ts
+++ b/src/git-command-manager.ts
@@ -327,7 +327,7 @@ class GitCommandManager {
       args.push('--recursive')
     }
 
-    if (fetchJobs > 0) {
+    if (fetchJobs > -1) {
       args.push(`--jobs=${fetchJobs}`)
     }
 
diff --git a/src/input-helper.ts b/src/input-helper.ts
index 8767899..8a3f79b 100644
--- a/src/input-helper.ts
+++ b/src/input-helper.ts
@@ -89,9 +89,9 @@ export function getInputs(): IGitSourceSettings {
   core.debug(`fetch depth = ${result.fetchDepth}`)
 
   // Fetch jobs
-  result.fetchJobs = Math.floor(Number(core.getInput('fetch-jobs') || '0'))
-  if (isNaN(result.fetchJobs) || result.fetchJobs < 0) {
-    result.fetchJobs = 0
+  result.fetchJobs = Math.floor(Number(core.getInput('fetch-jobs') || '-1'))
+  if (isNaN(result.fetchJobs) || result.fetchJobs < -1) {
+    result.fetchJobs = -1
   }
   core.debug(`fetch jobs = ${result.fetchJobs}`)
 

From d46e61f9c4e7f742cf33189aa2785d3188af4aef Mon Sep 17 00:00:00 2001
From: Frits Talbot <frits@metapathy.com>
Date: Sat, 31 Dec 2022 11:36:08 +0100
Subject: [PATCH 3/3] Only process fetch-jobs argument if submodules are
 enabled

---
 dist/index.js       | 15 +++++++++------
 src/input-helper.ts | 17 ++++++++++-------
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/dist/index.js b/dist/index.js
index cbb39f9..ac06948 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -17219,12 +17219,6 @@ function getInputs() {
             result.fetchDepth = 0;
         }
         core.debug(`fetch depth = ${result.fetchDepth}`);
-        // Fetch jobs
-        result.fetchJobs = Math.floor(Number(core.getInput('fetch-jobs') || '-1'));
-        if (isNaN(result.fetchJobs) || result.fetchJobs < -1) {
-            result.fetchJobs = -1;
-        }
-        core.debug(`fetch jobs = ${result.fetchJobs}`);
         // LFS
         result.lfs = (core.getInput('lfs') || 'false').toUpperCase() === 'TRUE';
         core.debug(`lfs = ${result.lfs}`);
@@ -17241,6 +17235,15 @@ function getInputs() {
         }
         core.debug(`submodules = ${result.submodules}`);
         core.debug(`recursive submodules = ${result.nestedSubmodules}`);
+        // Fetch jobs during submodule update
+        result.fetchJobs = -1;
+        if (result.submodules) {
+            result.fetchJobs = Math.floor(Number(core.getInput('fetch-jobs') || '-1'));
+            if (isNaN(result.fetchJobs) || result.fetchJobs < -1) {
+                result.fetchJobs = -1;
+            }
+            core.debug(`fetch jobs = ${result.fetchJobs}`);
+        }
         // Auth token
         result.authToken = core.getInput('token', { required: true });
         // SSH
diff --git a/src/input-helper.ts b/src/input-helper.ts
index ad26b7a..a06afe0 100644
--- a/src/input-helper.ts
+++ b/src/input-helper.ts
@@ -89,13 +89,6 @@ export async function getInputs(): Promise<IGitSourceSettings> {
   }
   core.debug(`fetch depth = ${result.fetchDepth}`)
 
-  // Fetch jobs
-  result.fetchJobs = Math.floor(Number(core.getInput('fetch-jobs') || '-1'))
-  if (isNaN(result.fetchJobs) || result.fetchJobs < -1) {
-    result.fetchJobs = -1
-  }
-  core.debug(`fetch jobs = ${result.fetchJobs}`)
-
   // LFS
   result.lfs = (core.getInput('lfs') || 'false').toUpperCase() === 'TRUE'
   core.debug(`lfs = ${result.lfs}`)
@@ -113,6 +106,16 @@ export async function getInputs(): Promise<IGitSourceSettings> {
   core.debug(`submodules = ${result.submodules}`)
   core.debug(`recursive submodules = ${result.nestedSubmodules}`)
 
+  // Fetch jobs during submodule update
+  result.fetchJobs = -1
+  if (result.submodules) {
+    result.fetchJobs = Math.floor(Number(core.getInput('fetch-jobs') || '-1'))
+    if (isNaN(result.fetchJobs) || result.fetchJobs < -1) {
+      result.fetchJobs = -1
+    }
+    core.debug(`fetch jobs = ${result.fetchJobs}`)
+  }
+
   // Auth token
   result.authToken = core.getInput('token', {required: true})