Allow clone depth to be specified per project

If the clone-depth attribute is set on a project, its value will
be used to set the depth when fetching the git.  The value, if
given, must be a positive integer.

The value in the clone-depth attribute overrides any value given to
repo init via the --depth command line option.

Change-Id: I273015b3724213600b63e40cca4cafaa9f782ddf
diff --git a/docs/manifest-format.txt b/docs/manifest-format.txt
index 0bf09f6..f4629a5 100644
--- a/docs/manifest-format.txt
+++ b/docs/manifest-format.txt
@@ -56,6 +56,7 @@
     <!ATTLIST project sync-c   CDATA #IMPLIED>
     <!ATTLIST project sync-s   CDATA #IMPLIED>
     <!ATTLIST project upstream CDATA #IMPLIED>
+    <!ATTLIST project clone-depth CDATA #IMPLIED>
 
     <!ELEMENT annotation (EMPTY)>
     <!ATTLIST annotation name  CDATA #REQUIRED>
@@ -222,6 +223,10 @@
 can be found.  Used when syncing a revision locked manifest in
 -c mode to avoid having to sync the entire ref space.
 
+Attribute `clone-depth`: Set the depth to use when fetching this
+project.  If specified, this value will override any value given
+to repo init with the --depth option on the command line.
+
 Element annotation
 ------------------
 
diff --git a/manifest_xml.py b/manifest_xml.py
index 92ef785..4eef748 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -665,6 +665,16 @@
     else:
       sync_s = sync_s.lower() in ("yes", "true", "1")
 
+    clone_depth = node.getAttribute('clone-depth')
+    if clone_depth:
+      try:
+        clone_depth = int(clone_depth)
+        if  clone_depth <= 0:
+          raise ValueError()
+      except ValueError:
+        raise ManifestParseError('invalid clone-depth %s in %s' %
+                                 (clone_depth, self.manifestFile))
+
     upstream = node.getAttribute('upstream')
 
     groups = ''
@@ -692,6 +702,7 @@
                       groups = groups,
                       sync_c = sync_c,
                       sync_s = sync_s,
+                      clone_depth = clone_depth,
                       upstream = upstream,
                       parent = parent)
 
diff --git a/project.py b/project.py
index 901a283..20bf866 100644
--- a/project.py
+++ b/project.py
@@ -488,6 +488,7 @@
                groups = None,
                sync_c = False,
                sync_s = False,
+               clone_depth = None,
                upstream = None,
                parent = None,
                is_derived = False):
@@ -533,6 +534,7 @@
     self.groups = groups
     self.sync_c = sync_c
     self.sync_s = sync_s
+    self.clone_depth = clone_depth
     self.upstream = upstream
     self.parent = parent
     self.is_derived = is_derived
@@ -1645,7 +1647,10 @@
 
     # The --depth option only affects the initial fetch; after that we'll do
     # full fetches of changes.
-    depth = self.manifest.manifestProject.config.GetString('repo.depth')
+    if self.clone_depth:
+      depth = self.clone_depth
+    else:
+      depth = self.manifest.manifestProject.config.GetString('repo.depth')
     if depth and initial:
       cmd.append('--depth=%s' % depth)
 
@@ -1705,7 +1710,7 @@
     return ok
 
   def _ApplyCloneBundle(self, initial=False, quiet=False):
-    if initial and self.manifest.manifestProject.config.GetString('repo.depth'):
+    if initial and (self.manifest.manifestProject.config.GetString('repo.depth') or self.clone_depth):
       return False
 
     remote = self.GetRemote(self.remote.name)