diff --git a/docs/manifest-format.md b/docs/manifest-format.md
index b45b91809..bf1a09337 100644
--- a/docs/manifest-format.md
+++ b/docs/manifest-format.md
@@ -579,7 +579,9 @@ This also applies to all extend-project elements in the included manifests.
Same syntax as the corresponding element of `project`.
Attribute `revision`: Name of a Git branch (e.g. `main` or `refs/heads/main`)
-default to which all projects in the included manifest belong.
+default to which all projects in the included manifest belong. This recurses,
+meaning it will apply to all projects in all manifests included as a result of
+this element.
## Local Manifests {#local-manifests}
diff --git a/man/repo-manifest.1 b/man/repo-manifest.1
index 38c728e6e..74e44efdd 100644
--- a/man/repo-manifest.1
+++ b/man/repo-manifest.1
@@ -641,7 +641,9 @@ extend\-project elements in the included manifests. Same syntax as the
corresponding element of `project`.
.PP
Attribute `revision`: Name of a Git branch (e.g. `main` or `refs/heads/main`)
-default to which all projects in the included manifest belong.
+default to which all projects in the included manifest belong. This recurses,
+meaning it will apply to all projects in all manifests included as a result of
+this element.
.PP
Local Manifests
.PP
diff --git a/manifest_xml.py b/manifest_xml.py
index 2d476748c..0e899e5ab 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -1305,6 +1305,14 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
nodes = []
for node in manifest.childNodes:
+ if (
+ parent_node
+ and node.nodeName in ("include", "project")
+ and not node.hasAttribute("revision")
+ ):
+ node.setAttribute(
+ "revision", parent_node.getAttribute("revision")
+ )
if node.nodeName == "include":
name = self._reqatt(node, "name")
if restrict_includes:
@@ -1349,14 +1357,6 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
node.getAttribute("groups")
)
node.setAttribute("groups", ",".join(sorted(nodeGroups)))
- if (
- parent_node
- and node.nodeName == "project"
- and not node.hasAttribute("revision")
- ):
- node.setAttribute(
- "revision", parent_node.getAttribute("revision")
- )
nodes.append(node)
return nodes
diff --git a/tests/test_manifest_xml.py b/tests/test_manifest_xml.py
index 960d0cd85..0cd84f081 100644
--- a/tests/test_manifest_xml.py
+++ b/tests/test_manifest_xml.py
@@ -422,9 +422,27 @@ class IncludeElementTests(ManifestParseTestCase):
(self.manifest_dir / "stable.xml").write_text(
"""
+
+
+"""
+ )
+ (self.manifest_dir / "man1.xml").write_text(
+ """
+
+
+
+
+"""
+ )
+ (self.manifest_dir / "man2.xml").write_text(
+ """
+
+
+
+
"""
)
include_m = manifest_xml.XmlManifest(str(self.repodir), str(root_m))
@@ -441,6 +459,14 @@ class IncludeElementTests(ManifestParseTestCase):
if proj.name == "stable-name2":
# Check stable proj revision can override include node.
self.assertEqual("stable-branch2", proj.revisionExpr)
+ if proj.name == "man1-name1":
+ self.assertEqual("stable-branch", proj.revisionExpr)
+ if proj.name == "man1-name2":
+ self.assertEqual("stable-branch3", proj.revisionExpr)
+ if proj.name == "man2-name1":
+ self.assertEqual("stable-branch2", proj.revisionExpr)
+ if proj.name == "man2-name2":
+ self.assertEqual("stable-branch3", proj.revisionExpr)
def test_group_levels(self):
root_m = self.manifest_dir / "root.xml"