project: set core.repositoryFormatVersion=1 when using extensions

When using extensions, make sure we set the git repo format version
so git knows to check the extension compatibility.  We can add a
helper to the Project API to simplify this and make it foolproof.

Change-Id: I9ab6c32d92fe2b8e5df6e2b080ca71556332e909
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/256035
Tested-by: Mike Frysinger <vapier@google.com>
Reviewed-by: Jonathan Nieder <jrn@google.com>
diff --git a/project.py b/project.py
index 3a7ac9e..5bead64 100644
--- a/project.py
+++ b/project.py
@@ -2186,6 +2186,24 @@
     return result
 
 # Direct Git Commands ##
+  def EnableRepositoryExtension(self, key, value='true', version=1):
+    """Enable git repository extension |key| with |value|.
+
+    Args:
+      key: The extension to enabled.  Omit the "extensions." prefix.
+      value: The value to use for the extension.
+      version: The minimum git repository version needed.
+    """
+    # Make sure the git repo version is new enough already.
+    found_version = self.config.GetInt('core.repositoryFormatVersion')
+    if found_version is None:
+      found_version = 0
+    if found_version < version:
+      self.config.SetString('core.repositoryFormatVersion', str(version))
+
+    # Enable the extension!
+    self.config.SetString('extensions.%s' % (key,), value)
+
   def _CheckForImmutableRevision(self):
     try:
       # if revision (sha or tag) is not present then following function
@@ -2314,7 +2332,7 @@
     if clone_filter:
       git_require((2, 19, 0), fail=True, msg='partial clones')
       cmd.append('--filter=%s' % clone_filter)
-      self.config.SetString('extensions.partialclone', self.remote.name)
+      self.EnableRepositoryExtension('partialclone', self.remote.name)
 
     if depth:
       cmd.append('--depth=%s' % depth)
@@ -2630,7 +2648,7 @@
         # Enable per-worktree config file support if possible.  This is more a
         # nice-to-have feature for users rather than a hard requirement.
         if self.use_git_worktrees and git_require((2, 19, 0)):
-          self.config.SetString('extensions.worktreeConfig', 'true')
+          self.EnableRepositoryExtension('worktreeConfig')
 
       # If we have a separate directory to hold refs, initialize it as well.
       if self.objdir != self.gitdir:
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 49867a9..eada76a 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -576,8 +576,7 @@
         print('%s: Shared project %s found, disabling pruning.' %
               (project.relpath, project.name))
         if git_require((2, 7, 0)):
-          project.config.SetString('core.repositoryFormatVersion', '1')
-          project.config.SetString('extensions.preciousObjects', 'true')
+          project.EnableRepositoryExtension('preciousObjects')
         else:
           # This isn't perfect, but it's the best we can do with old git.
           print('%s: WARNING: shared projects are unreliable when using old '