Răsfoiți Sursa

Add a sync flag that fetches only current branch

There is also shortcuts in case if the "current branch" is
a persistent revision such as tag or sha1. We check if the
persistent revision is present locally and if it does - do
no fetch anything from the server.

This greately reduces sync time and size of the on-disk repo

Change-Id: I23c6d95185474ed6e1a03c836a47f489953b99be
Anatol Pomazau 14 ani în urmă
părinte
comite
53d6f4d17e
2 a modificat fișierele cu 46 adăugiri și 21 ștergeri
  1. 37 18
      project.py
  2. 9 3
      subcmds/sync.py

+ 37 - 18
project.py

@@ -36,7 +36,7 @@ except ImportError:
 
 
 from color import Coloring
 from color import Coloring
 from git_command import GitCommand
 from git_command import GitCommand
-from git_config import GitConfig, IsId, GetSchemeFromUrl
+from git_config import GitConfig, IsId, GetSchemeFromUrl, ID_RE
 from error import DownloadError
 from error import DownloadError
 from error import GitError, HookError, ImportError, UploadError
 from error import GitError, HookError, ImportError, UploadError
 from error import ManifestInvalidRevisionError
 from error import ManifestInvalidRevisionError
@@ -900,7 +900,7 @@ class Project(object):
 
 
 ## Sync ##
 ## Sync ##
 
 
-  def Sync_NetworkHalf(self, quiet=False, is_new=None):
+  def Sync_NetworkHalf(self, quiet=False, is_new=None, current_branch_only=False):
     """Perform only the network IO portion of the sync process.
     """Perform only the network IO portion of the sync process.
        Local working directory/branch state is not affected.
        Local working directory/branch state is not affected.
     """
     """
@@ -926,21 +926,10 @@ class Project(object):
     if alt_dir is None and self._ApplyCloneBundle(initial=is_new, quiet=quiet):
     if alt_dir is None and self._ApplyCloneBundle(initial=is_new, quiet=quiet):
       is_new = False
       is_new = False
 
 
-    if not self._RemoteFetch(initial=is_new, quiet=quiet, alt_dir=alt_dir):
+    if not self._RemoteFetch(initial=is_new, quiet=quiet, alt_dir=alt_dir,
+                             current_branch_only=current_branch_only):
       return False
       return False
 
 
-    #Check that the requested ref was found after fetch
-    #
-    try:
-      self.GetRevisionId()
-    except ManifestInvalidRevisionError:
-      # if the ref is a tag. We can try fetching
-      # the tag manually as a last resort
-      #
-      rev = self.revisionExpr
-      if rev.startswith(R_TAGS):
-        self._RemoteFetch(None, rev[len(R_TAGS):], quiet=quiet)
-
     if self.worktree:
     if self.worktree:
       self._InitMRef()
       self._InitMRef()
     else:
     else:
@@ -1335,10 +1324,30 @@ class Project(object):
 
 
 ## Direct Git Commands ##
 ## Direct Git Commands ##
 
 
-  def _RemoteFetch(self, name=None, tag=None,
+  def _RemoteFetch(self, name=None,
+                   current_branch_only=False,
                    initial=False,
                    initial=False,
                    quiet=False,
                    quiet=False,
                    alt_dir=None):
                    alt_dir=None):
+
+    is_sha1 = False
+    tag_name = None
+
+    if current_branch_only:
+      if ID_RE.match(self.revisionExpr) is not None:
+        is_sha1 = True
+      elif self.revisionExpr.startswith(R_TAGS):
+        # this is a tag and its sha1 value should never change
+        tag_name = self.revisionExpr[len(R_TAGS):]
+
+      if is_sha1 or tag_name is not None:
+        try:
+          self.GetRevisionId()
+          return True
+        except ManifestInvalidRevisionError:
+          # There is no such persistent revision. We have to fetch it.
+          pass
+
     if not name:
     if not name:
       name = self.remote.name
       name = self.remote.name
 
 
@@ -1401,9 +1410,19 @@ class Project(object):
     if not self.worktree:
     if not self.worktree:
       cmd.append('--update-head-ok')
       cmd.append('--update-head-ok')
     cmd.append(name)
     cmd.append(name)
-    if tag is not None:
+
+    if not current_branch_only or is_sha1:
+      # Fetch whole repo
+      cmd.append('--tags')
+      cmd.append((u'+refs/heads/*:') + remote.ToLocal('refs/heads/*'))
+    elif tag_name is not None:
       cmd.append('tag')
       cmd.append('tag')
-      cmd.append(tag)
+      cmd.append(tag_name)
+    else:
+      branch = self.revisionExpr
+      if branch.startswith(R_HEADS):
+        branch = branch[len(R_HEADS):]
+      cmd.append((u'+refs/heads/%s:' % branch) + remote.ToLocal('refs/heads/%s' % branch))
 
 
     ok = False
     ok = False
     for i in range(2):
     for i in range(2):

+ 9 - 3
subcmds/sync.py

@@ -131,6 +131,9 @@ later is required to fix a server side protocol bug.
     p.add_option('-d','--detach',
     p.add_option('-d','--detach',
                  dest='detach_head', action='store_true',
                  dest='detach_head', action='store_true',
                  help='detach projects back to manifest revision')
                  help='detach projects back to manifest revision')
+    p.add_option('-c','--current-branch',
+                 dest='current_branch_only', action='store_true',
+                 help='fetch only current branch from server')
     p.add_option('-q','--quiet',
     p.add_option('-q','--quiet',
                  dest='quiet', action='store_true',
                  dest='quiet', action='store_true',
                  help='be more quiet')
                  help='be more quiet')
@@ -179,7 +182,8 @@ later is required to fix a server side protocol bug.
       # - We always make sure we unlock the lock if we locked it.
       # - We always make sure we unlock the lock if we locked it.
       try:
       try:
         try:
         try:
-          success = project.Sync_NetworkHalf(quiet=opt.quiet)
+          success = project.Sync_NetworkHalf(quiet=opt.quiet,
+                                             current_branch_only=opt.current_branch_only)
 
 
           # Lock around all the rest of the code, since printing, updating a set
           # Lock around all the rest of the code, since printing, updating a set
           # and Progress.update() are not thread safe.
           # and Progress.update() are not thread safe.
@@ -212,7 +216,8 @@ later is required to fix a server side protocol bug.
     if self.jobs == 1:
     if self.jobs == 1:
       for project in projects:
       for project in projects:
         pm.update()
         pm.update()
-        if project.Sync_NetworkHalf(quiet=opt.quiet):
+        if project.Sync_NetworkHalf(quiet=opt.quiet,
+                                    current_branch_only=opt.current_branch_only):
           fetched.add(project.gitdir)
           fetched.add(project.gitdir)
         else:
         else:
           print >>sys.stderr, 'error: Cannot fetch %s' % project.name
           print >>sys.stderr, 'error: Cannot fetch %s' % project.name
@@ -388,7 +393,8 @@ uncommitted changes are present' % project.relpath
       _PostRepoUpgrade(self.manifest)
       _PostRepoUpgrade(self.manifest)
 
 
     if not opt.local_only:
     if not opt.local_only:
-      mp.Sync_NetworkHalf(quiet=opt.quiet)
+      mp.Sync_NetworkHalf(quiet=opt.quiet,
+                          current_branch_only=opt.current_branch_only)
 
 
     if mp.HasChanges:
     if mp.HasChanges:
       syncbuf = SyncBuffer(mp.config)
       syncbuf = SyncBuffer(mp.config)