summaryrefslogtreecommitdiffstats
path: root/project.py
diff options
context:
space:
mode:
authorJulien Campergue <julien.campergue@parrot.com>2013-10-16 11:02:35 +0200
committerDavid Pursehouse <david.pursehouse@sonymobile.com>2013-12-10 08:27:07 +0000
commit335f5ef4ad25a85c69fe6d8c848c5d1d447e22c8 (patch)
tree6a64a34ce5063d8d255c7840e167db2484e68c9a /project.py
parent61df418c599a0359b33b8a65a12660023fc37a2a (diff)
downloadgit-repo-335f5ef4ad25a85c69fe6d8c848c5d1d447e22c8.tar.gz
Add --archive option to init to sync using git archive
This significantly reduces sync time and used brandwidth as only a tar of each project's revision is checked out, but git is not accessible from projects anymore. This is relevant when git is not needed in projects but sync speed/brandwidth may be important like on CI servers when building several versions from scratch regularly for example. Archive is not supported over http/https. Change-Id: I48c3c7de2cd5a1faec33e295fcdafbc7807d0e4d Signed-off-by: Julien Campergue <julien.campergue@parrot.com>
Diffstat (limited to 'project.py')
-rw-r--r--project.py63
1 files changed, 62 insertions, 1 deletions
diff --git a/project.py b/project.py
index b01a52ba..0d491119 100644
--- a/project.py
+++ b/project.py
@@ -23,6 +23,7 @@ import shutil
23import stat 23import stat
24import subprocess 24import subprocess
25import sys 25import sys
26import tarfile
26import tempfile 27import tempfile
27import time 28import time
28 29
@@ -982,15 +983,62 @@ class Project(object):
982 983
983## Sync ## 984## Sync ##
984 985
986 def _ExtractArchive(self, tarpath, path=None):
987 """Extract the given tar on its current location
988
989 Args:
990 - tarpath: The path to the actual tar file
991
992 """
993 try:
994 with tarfile.open(tarpath, 'r') as tar:
995 tar.extractall(path=path)
996 return True
997 except (IOError, tarfile.TarError) as e:
998 print("error: Cannot extract archive %s: "
999 "%s" % (tarpath, str(e)), file=sys.stderr)
1000 return False
1001
985 def Sync_NetworkHalf(self, 1002 def Sync_NetworkHalf(self,
986 quiet=False, 1003 quiet=False,
987 is_new=None, 1004 is_new=None,
988 current_branch_only=False, 1005 current_branch_only=False,
989 clone_bundle=True, 1006 clone_bundle=True,
990 no_tags=False): 1007 no_tags=False,
1008 archive=False):
991 """Perform only the network IO portion of the sync process. 1009 """Perform only the network IO portion of the sync process.
992 Local working directory/branch state is not affected. 1010 Local working directory/branch state is not affected.
993 """ 1011 """
1012 if archive and not isinstance(self, MetaProject):
1013 if self.remote.url.startswith(('http://', 'https://')):
1014 print("error: %s: Cannot fetch archives from http/https "
1015 "remotes." % self.name, file=sys.stderr)
1016 return False
1017
1018 name = self.relpath.replace('\\', '/')
1019 name = name.replace('/', '_')
1020 tarpath = '%s.tar' % name
1021 topdir = self.manifest.topdir
1022
1023 try:
1024 self._FetchArchive(tarpath, cwd=topdir)
1025 except GitError as e:
1026 print('error: %s' % str(e), file=sys.stderr)
1027 return False
1028
1029 # From now on, we only need absolute tarpath
1030 tarpath = os.path.join(topdir, tarpath)
1031
1032 if not self._ExtractArchive(tarpath, path=topdir):
1033 return False
1034 try:
1035 os.remove(tarpath)
1036 except OSError as e:
1037 print("warn: Cannot remove archive %s: "
1038 "%s" % (tarpath, str(e)), file=sys.stderr)
1039 self._CopyFiles()
1040 return True
1041
994 if is_new is None: 1042 if is_new is None:
995 is_new = not self.Exists 1043 is_new = not self.Exists
996 if is_new: 1044 if is_new:
@@ -1573,6 +1621,19 @@ class Project(object):
1573 1621
1574## Direct Git Commands ## 1622## Direct Git Commands ##
1575 1623
1624 def _FetchArchive(self, tarpath, cwd=None):
1625 cmd = ['archive', '-v', '-o', tarpath]
1626 cmd.append('--remote=%s' % self.remote.url)
1627 cmd.append('--prefix=%s/' % self.relpath)
1628 cmd.append(self.revisionExpr)
1629
1630 command = GitCommand(self, cmd, cwd=cwd,
1631 capture_stdout=True,
1632 capture_stderr=True)
1633
1634 if command.Wait() != 0:
1635 raise GitError('git archive %s: %s' % (self.name, command.stderr))
1636
1576 def _RemoteFetch(self, name=None, 1637 def _RemoteFetch(self, name=None,
1577 current_branch_only=False, 1638 current_branch_only=False,
1578 initial=False, 1639 initial=False,