Browse Source

git: Switch from shallow clones to "git archive" to support arbitrary commits

Jan Holthuis 5 years ago
parent
commit
54112368be
2 changed files with 11 additions and 6 deletions
  1. 9 4
      sphinx_multiversion/git.py
  2. 2 2
      sphinx_multiversion/main.py

+ 9 - 4
sphinx_multiversion/git.py

@@ -1,7 +1,9 @@
 # -*- coding: utf-8 -*-
 import collections
+import tempfile
 import subprocess
 import re
+import tarfile
 
 from . import sphinx
 
@@ -65,7 +67,10 @@ def find_versions(gitroot, confpath, tag_whitelist, branch_whitelist, remote_whi
         yield VersionRef(name, commit, source, is_remote, refname, version, release)
 
 
-def shallow_clone(src, dst, branch):
-    cmd = ("git", "clone", "--no-hardlinks", "--single-branch", "--depth", "1",
-           "--branch", branch, src, dst)
-    subprocess.check_call(cmd)
+def copy_tree(src, dst, reference, sourcepath='.'):
+    with tempfile.SpooledTemporaryFile() as fp:
+        cmd = ("git", "archive", "--format", "tar", reference.commit, "--", sourcepath)
+        subprocess.check_call(cmd, stdout=fp)
+        fp.seek(0)
+        with tarfile.TarFile(fileobj=fp) as tarfp:
+            tarfp.extractall(dst)

+ 2 - 2
sphinx_multiversion/main.py

@@ -81,8 +81,8 @@ def main(argv=None):
             repopath = os.path.join(tmp, str(hash(versionref)))
             srcdir = os.path.join(repopath, sourcedir)
             try:
-                git.shallow_clone(gitroot.as_uri(), repopath, versionref.name)
-            except subprocess.CalledProcessError:
+                git.copy_tree(gitroot.as_uri(), repopath, versionref)
+            except (OSError, subprocess.CalledProcessError):
                 outputdirs.remove(outputdir)
                 continue