project: disable auto-gc for depth=1 in git config

During sync, `git checkout` can trigger fetch for missing objects in
partial clones. This internal fetch can trigger `git maintenance` or
`git gc` and cause delays during the local checkout phase. Set
maintenance.auto to false and gc.auto to 0 in during `_InitRemote` if
`depth=1` to ensure that implicit fetches spawned by git skip GC.

Bug: 379111283
Change-Id: I6b22a4867f29b6e9598746cb752820a84dc2aeb6
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/540681
Reviewed-by: Mike Frysinger <vapier@google.com>
Tested-by: Gavin Mak <gavinmak@google.com>
Commit-Queue: Gavin Mak <gavinmak@google.com>
diff --git a/git_config.py b/git_config.py
index 14c4c11..5559657 100644
--- a/git_config.py
+++ b/git_config.py
@@ -222,6 +222,12 @@
             value = "true" if value else "false"
         self.SetString(name, value)
 
+    def SetInt(self, name: str, value: int) -> None:
+        """Set an integer value for a key."""
+        if value is not None:
+            value = str(value)
+        self.SetString(name, value)
+
     def GetString(self, name: str, all_keys: bool = False) -> Union[str, None]:
         """Get the first value for a key, or None if it is not defined.
 
diff --git a/project.py b/project.py
index 8da2efc..f3ae9ab 100644
--- a/project.py
+++ b/project.py
@@ -3316,6 +3316,15 @@
                 remote.ResetFetch(mirror=True)
             remote.Save()
 
+        # Disable auto-gc for depth=1 to prevent hangs during lazy fetches
+        # inside git checkout for partial clones.
+        effective_depth = (
+            self.clone_depth or self.manifest.manifestProject.depth
+        )
+        if effective_depth == 1:
+            self.config.SetBoolean("maintenance.auto", False)
+            self.config.SetInt("gc.auto", 0)
+
     def _InitMRef(self):
         """Initialize the pseudo m/<manifest branch> ref."""
         if self.manifest.branch:
diff --git a/tests/test_git_config.py b/tests/test_git_config.py
index cf6e779..e1604bd 100644
--- a/tests/test_git_config.py
+++ b/tests/test_git_config.py
@@ -166,6 +166,30 @@
         config = self.get_config()
         self.assertIsNone(config.GetBoolean("foo.bar"))
 
+    def test_SetInt(self):
+        """Test SetInt behavior."""
+        # Set a value.
+        self.assertIsNone(self.config.GetInt("foo.bar"))
+        self.config.SetInt("foo.bar", 10)
+        self.assertEqual(10, self.config.GetInt("foo.bar"))
+
+        # Make sure the value was actually written out.
+        config = self.get_config()
+        self.assertEqual(10, config.GetInt("foo.bar"))
+        self.assertEqual("10", config.GetString("foo.bar"))
+
+        # Update the value.
+        self.config.SetInt("foo.bar", 20)
+        self.assertEqual(20, self.config.GetInt("foo.bar"))
+        config = self.get_config()
+        self.assertEqual(20, config.GetInt("foo.bar"))
+
+        # Delete the value.
+        self.config.SetInt("foo.bar", None)
+        self.assertIsNone(self.config.GetInt("foo.bar"))
+        config = self.get_config()
+        self.assertIsNone(config.GetInt("foo.bar"))
+
     def test_GetSyncAnalysisStateData(self):
         """Test config entries with a sync state analysis data."""
         superproject_logging_data = {}