Merge "GITC: Fix 'repo start <branch> <repo>/<subdir>'"
diff --git a/git_command.py b/git_command.py
index 0893bff..63b7b6f 100644
--- a/git_command.py
+++ b/git_command.py
@@ -168,6 +168,9 @@
       if p is not None:
         s = p + ' ' + s
       _setenv(env, 'GIT_CONFIG_PARAMETERS', s)
+    if 'GIT_ALLOW_PROTOCOL' not in env:
+      _setenv(env, 'GIT_ALLOW_PROTOCOL',
+              'file:git:http:https:ssh:persistent-http:persistent-https:sso')
 
     if project:
       if not cwd:
diff --git a/project.py b/project.py
index 5d8f61e..5058088 100644
--- a/project.py
+++ b/project.py
@@ -249,7 +249,7 @@
     if not os.path.islink(absDest) or (os.readlink(absDest) != relSrc):
       try:
         # remove existing file first, since it might be read-only
-        if os.path.exists(absDest):
+        if os.path.lexists(absDest):
           os.remove(absDest)
         else:
           dest_dir = os.path.dirname(absDest)
@@ -1110,7 +1110,8 @@
       clone_bundle=True,
       no_tags=False,
       archive=False,
-      optimized_fetch=False):
+      optimized_fetch=False,
+      prune=False):
     """Perform only the network IO portion of the sync process.
        Local working directory/branch state is not affected.
     """
@@ -1181,7 +1182,7 @@
     if (need_to_fetch
         and not self._RemoteFetch(initial=is_new, quiet=quiet, alt_dir=alt_dir,
                                   current_branch_only=current_branch_only,
-                                  no_tags=no_tags)):
+                                  no_tags=no_tags, prune=prune)):
       return False
 
     if self.worktree:
@@ -1795,7 +1796,8 @@
                    initial=False,
                    quiet=False,
                    alt_dir=None,
-                   no_tags=False):
+                   no_tags=False,
+                   prune=False):
 
     is_sha1 = False
     tag_name = None
@@ -1908,6 +1910,9 @@
     else:
       cmd.append('--tags')
 
+    if prune:
+      cmd.append('--prune')
+
     spec = []
     if not current_branch_only:
       # Fetch whole repo
diff --git a/subcmds/init.py b/subcmds/init.py
index dbb6ddd..b8e3de5 100644
--- a/subcmds/init.py
+++ b/subcmds/init.py
@@ -179,7 +179,7 @@
       r.Save()
 
     groups = re.split(r'[,\s]+', opt.groups)
-    all_platforms = ['linux', 'darwin']
+    all_platforms = ['linux', 'darwin', 'windows']
     platformize = lambda x: 'platform-' + x
     if opt.platform == 'auto':
       if (not opt.mirror and
@@ -188,7 +188,7 @@
     elif opt.platform == 'all':
       groups.extend(map(platformize, all_platforms))
     elif opt.platform in all_platforms:
-      groups.extend(platformize(opt.platform))
+      groups.append(platformize(opt.platform))
     elif opt.platform != 'none':
       print('fatal: invalid platform flag', file=sys.stderr)
       sys.exit(1)
diff --git a/subcmds/rebase.py b/subcmds/rebase.py
index 1bdc1f0..7479697 100644
--- a/subcmds/rebase.py
+++ b/subcmds/rebase.py
@@ -54,6 +54,11 @@
     p.add_option('--auto-stash',
                  dest='auto_stash', action='store_true',
                  help='Stash local modifications before starting')
+    p.add_option('-m', '--onto-manifest',
+                 dest='onto_manifest', action='store_true',
+                 help='Rebase onto the manifest version instead of upstream '
+                      'HEAD.  This helps to make sure the local tree stays '
+                      'consistent if you previously synced to a manifest.')
 
   def Execute(self, opt, args):
     all_projects = self.GetProjects(args)
@@ -106,6 +111,10 @@
       if opt.interactive:
         args.append("-i")
 
+      if opt.onto_manifest:
+        args.append('--onto')
+        args.append(project.revisionExpr)
+
       args.append(upbranch.LocalMerge)
 
       print('# %s: rebasing %s -> %s'
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 2a77065..4af411c 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -151,6 +151,9 @@
 are fixed to a sha1 revision if the sha1 revision does not already
 exist locally.
 
+The --prune option can be used to remove any refs that no longer
+exist on the remote.
+
 SSH Connections
 ---------------
 
@@ -234,6 +237,8 @@
     p.add_option('--optimized-fetch',
                  dest='optimized_fetch', action='store_true',
                  help='only fetch projects fixed to sha1 if revision does not exist locally')
+    p.add_option('--prune', dest='prune', action='store_true',
+                 help='delete refs that no longer exist on the remote')
     if show_smart:
       p.add_option('-s', '--smart-sync',
                    dest='smart_sync', action='store_true',
@@ -305,7 +310,8 @@
           force_sync=opt.force_sync,
           clone_bundle=not opt.no_clone_bundle,
           no_tags=opt.no_tags, archive=self.manifest.IsArchive,
-          optimized_fetch=opt.optimized_fetch)
+          optimized_fetch=opt.optimized_fetch,
+          prune=opt.prune)
         self._fetch_times.Set(project, time.time() - start)
 
         # Lock around all the rest of the code, since printing, updating a set
@@ -314,6 +320,7 @@
         did_lock = True
 
         if not success:
+          err_event.set()
           print('error: Cannot fetch %s' % project.name, file=sys.stderr)
           if opt.force_broken:
             print('warn: --force-broken, continuing to sync',
@@ -324,7 +331,7 @@
         fetched.add(project.gitdir)
         pm.update()
       except _FetchError:
-        err_event.set()
+        pass
       except Exception as e:
         print('error: Cannot fetch %s (%s: %s)' \
             % (project.name, type(e).__name__, str(e)), file=sys.stderr)