Merge changes I9c1ab65f,I7b2027ae

* changes:
  init: Remove string concat in no-op os.path.join
  Support relative paths in --reference
diff --git a/docs/manifest-format.txt b/docs/manifest-format.txt
index 7778409..56bdf14 100644
--- a/docs/manifest-format.txt
+++ b/docs/manifest-format.txt
@@ -47,6 +47,7 @@
     <!ATTLIST default sync-j      CDATA #IMPLIED>
     <!ATTLIST default sync-c      CDATA #IMPLIED>
     <!ATTLIST default sync-s      CDATA #IMPLIED>
+    <!ATTLIST default sync-tags   CDATA #IMPLIED>
 
     <!ELEMENT manifest-server EMPTY>
     <!ATTLIST manifest-server url CDATA #REQUIRED>
@@ -63,6 +64,7 @@
     <!ATTLIST project groups      CDATA #IMPLIED>
     <!ATTLIST project sync-c      CDATA #IMPLIED>
     <!ATTLIST project sync-s      CDATA #IMPLIED>
+    <!ATTLIST default sync-tags   CDATA #IMPLIED>
     <!ATTLIST project upstream CDATA #IMPLIED>
     <!ATTLIST project clone-depth CDATA #IMPLIED>
     <!ATTLIST project force-path CDATA #IMPLIED>
@@ -84,6 +86,7 @@
     <!ATTLIST extend-project name CDATA #REQUIRED>
     <!ATTLIST extend-project path CDATA #IMPLIED>
     <!ATTLIST extend-project groups CDATA #IMPLIED>
+    <!ATTLIST extend-project revision CDATA #IMPLIED>
 
     <!ELEMENT remove-project EMPTY>
     <!ATTLIST remove-project name  CDATA #REQUIRED>
@@ -170,6 +173,10 @@
 
 Attribute `sync-s`: Set to true to also sync sub-projects.
 
+Attribute `sync-tags`: Set to false to only sync the given Git
+branch (specified in the `revision` attribute) rather than
+the other ref tags.
+
 
 Element manifest-server
 -----------------------
@@ -294,6 +301,9 @@
 Attribute `groups`: List of additional groups to which this project
 belongs.  Same syntax as the corresponding element of `project`.
 
+Attribute `revision`: If specified, overrides the revision of the original
+project.  Same syntax as the corresponding element of `project`.
+
 Element annotation
 ------------------
 
diff --git a/git_config.py b/git_config.py
index 3ba9dbd..854b238 100644
--- a/git_config.py
+++ b/git_config.py
@@ -534,7 +534,7 @@
         for line in p.stdout:
           line = line.strip()
           if line.startswith(cookieprefix):
-            cookiefile = line[len(cookieprefix):]
+            cookiefile = os.path.expanduser(line[len(cookieprefix):])
           if line.startswith(proxyprefix):
             proxy = line[len(proxyprefix):]
         # Leave subprocess open, as cookie file may be transient.
@@ -553,7 +553,10 @@
       if e.errno == errno.ENOENT:
         pass  # No persistent proxy.
       raise
-  yield GitConfig.ForUser().GetString('http.cookiefile'), None
+  cookiefile = GitConfig.ForUser().GetString('http.cookiefile')
+  if cookiefile:
+    cookiefile = os.path.expanduser(cookiefile)
+  yield cookiefile, None
 
 def _preconnect(url):
   m = URI_ALL.match(url)
diff --git a/manifest_xml.py b/manifest_xml.py
index 9b5d784..60d6116 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -63,6 +63,7 @@
   sync_j = 1
   sync_c = False
   sync_s = False
+  sync_tags = True
 
   def __eq__(self, other):
     return self.__dict__ == other.__dict__
@@ -238,6 +239,9 @@
     if d.sync_s:
       have_default = True
       e.setAttribute('sync-s', 'true')
+    if not d.sync_tags:
+      have_default = True
+      e.setAttribute('sync-tags', 'false')
     if have_default:
       root.appendChild(e)
       root.appendChild(doc.createTextNode(''))
@@ -327,6 +331,9 @@
       if p.sync_s:
         e.setAttribute('sync-s', 'true')
 
+      if not p.sync_tags:
+        e.setAttribute('sync-tags', 'false')
+
       if p.clone_depth:
         e.setAttribute('clone-depth', str(p.clone_depth))
 
@@ -564,12 +571,15 @@
         groups = node.getAttribute('groups')
         if groups:
           groups = self._ParseGroups(groups)
+        revision = node.getAttribute('revision')
 
         for p in self._projects[name]:
           if path and p.relpath != path:
             continue
           if groups:
             p.groups.extend(groups)
+          if revision:
+            p.revisionExpr = revision
       if node.nodeName == 'repo-hooks':
         # Get the name of the project and the (space-separated) list of enabled.
         repo_hooks_project = self._reqatt(node, 'in-project')
@@ -702,6 +712,12 @@
       d.sync_s = False
     else:
       d.sync_s = sync_s.lower() in ("yes", "true", "1")
+
+    sync_tags = node.getAttribute('sync-tags')
+    if not sync_tags:
+      d.sync_tags = True
+    else:
+      d.sync_tags = sync_tags.lower() in ("yes", "true", "1")
     return d
 
   def _ParseNotice(self, node):
@@ -796,6 +812,12 @@
     else:
       sync_s = sync_s.lower() in ("yes", "true", "1")
 
+    sync_tags = node.getAttribute('sync-tags')
+    if not sync_tags:
+      sync_tags = self._default.sync_tags
+    else:
+      sync_tags = sync_tags.lower() in ("yes", "true", "1")
+
     clone_depth = node.getAttribute('clone-depth')
     if clone_depth:
       try:
@@ -841,6 +863,7 @@
                       groups = groups,
                       sync_c = sync_c,
                       sync_s = sync_s,
+                      sync_tags = sync_tags,
                       clone_depth = clone_depth,
                       upstream = upstream,
                       parent = parent,
diff --git a/project.py b/project.py
index 3ba8a07..e4682e6 100644
--- a/project.py
+++ b/project.py
@@ -660,6 +660,7 @@
                groups=None,
                sync_c=False,
                sync_s=False,
+               sync_tags=True,
                clone_depth=None,
                upstream=None,
                parent=None,
@@ -683,6 +684,7 @@
       groups: The `groups` attribute of manifest.xml's project element.
       sync_c: The `sync-c` attribute of manifest.xml's project element.
       sync_s: The `sync-s` attribute of manifest.xml's project element.
+      sync_tags: The `sync-tags` attribute of manifest.xml's project element.
       upstream: The `upstream` attribute of manifest.xml's project element.
       parent: The parent Project object.
       is_derived: False if the project was explicitly defined in the manifest;
@@ -715,6 +717,7 @@
     self.groups = groups
     self.sync_c = sync_c
     self.sync_s = sync_s
+    self.sync_tags = sync_tags
     self.clone_depth = clone_depth
     self.upstream = upstream
     self.parent = parent
@@ -1290,6 +1293,10 @@
       elif self.manifest.default.sync_c:
         current_branch_only = True
 
+    if not no_tags:
+      if not self.sync_tags:
+        no_tags = True
+
     if self.clone_depth:
       depth = self.clone_depth
     else:
@@ -1901,6 +1908,7 @@
                            groups=self.groups,
                            sync_c=self.sync_c,
                            sync_s=self.sync_s,
+                           sync_tags=self.sync_tags,
                            parent=self,
                            is_derived=True)
       result.append(subproject)