Omit local_manifest groups from superproject override.

When we create superproject_override.xml, do not include projects that
are present from local_manifests/*.  Such projects are fully under the
control of the local_manifests/ file.

Bug: b/238934278
Test: manual, ./run_tests
Change-Id: I40382ceb82d9cf7b8dc7b5f2abed3f6d4d80017e
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/340877
Tested-by: Xin Li <delphij@google.com>
Reviewed-by: Xin Li <delphij@google.com>
Reviewed-by: Sam Saccone 🐐 <samccone@google.com>
diff --git a/git_superproject.py b/git_superproject.py
index 5d00bd7..8b6bbcf 100644
--- a/git_superproject.py
+++ b/git_superproject.py
@@ -295,7 +295,8 @@
     if not os.path.exists(self._superproject_path):
       self._LogWarning(f'missing superproject directory: {self._superproject_path}')
       return None
-    manifest_str = self._manifest.ToXml(groups=self._manifest.GetGroupsStr()).toxml()
+    manifest_str = self._manifest.ToXml(groups=self._manifest.GetGroupsStr(),
+                                        omit_local=True).toxml()
     manifest_path = self._manifest_path
     try:
       with open(manifest_path, 'w', encoding='utf-8') as fp:
diff --git a/manifest_xml.py b/manifest_xml.py
index 32f6b68..12614c6 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -502,7 +502,8 @@
     """
     return [x for x in re.split(r'[,\s]+', field) if x]
 
-  def ToXml(self, peg_rev=False, peg_rev_upstream=True, peg_rev_dest_branch=True, groups=None):
+  def ToXml(self, peg_rev=False, peg_rev_upstream=True,
+            peg_rev_dest_branch=True, groups=None, omit_local=False):
     """Return the current manifest XML."""
     mp = self.manifestProject
 
@@ -583,6 +584,9 @@
       if not p.MatchesGroups(groups):
         return
 
+      if omit_local and self.IsFromLocalManifest(p):
+        return
+
       name = p.name
       relpath = p.relpath
       if parent:
diff --git a/tests/test_git_superproject.py b/tests/test_git_superproject.py
index 603694d..0ad9b01 100644
--- a/tests/test_git_superproject.py
+++ b/tests/test_git_superproject.py
@@ -312,9 +312,6 @@
               '<project groups="notdefault,platform-' + self.platform + '" '
               'name="platform/art" path="art" '
               'revision="2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea" upstream="refs/heads/main"/>'
-              '<project clone-depth="1" groups="' + local_group + '" '
-              'name="platform/vendor/x" path="vendor/x" remote="goog" '
-              'revision="master-with-vendor"/>'
               '<superproject name="superproject"/>'
               '</manifest>')
 
diff --git a/tests/test_manifest_xml.py b/tests/test_manifest_xml.py
index 85c2073..48403c0 100644
--- a/tests/test_manifest_xml.py
+++ b/tests/test_manifest_xml.py
@@ -252,6 +252,37 @@
         '<manifest></manifest>')
     self.assertEqual(manifest.ToDict(), {})
 
+  def test_toxml_omit_local(self):
+    """Does not include local_manifests projects when omit_local=True."""
+    manifest = self.getXmlManifest(
+        '<?xml version="1.0" encoding="UTF-8"?><manifest>'
+        '<remote name="a" fetch=".."/><default remote="a" revision="r"/>'
+        '<project name="p" groups="local::me"/>'
+        '<project name="q"/>'
+        '<project name="r" groups="keep"/>'
+        '</manifest>')
+    self.assertEqual(
+        manifest.ToXml(omit_local=True).toxml(),
+        '<?xml version="1.0" ?><manifest>'
+        '<remote name="a" fetch=".."/><default remote="a" revision="r"/>'
+        '<project name="q"/><project name="r" groups="keep"/></manifest>')
+
+  def test_toxml_with_local(self):
+    """Does include local_manifests projects when omit_local=False."""
+    manifest = self.getXmlManifest(
+        '<?xml version="1.0" encoding="UTF-8"?><manifest>'
+        '<remote name="a" fetch=".."/><default remote="a" revision="r"/>'
+        '<project name="p" groups="local::me"/>'
+        '<project name="q"/>'
+        '<project name="r" groups="keep"/>'
+        '</manifest>')
+    self.assertEqual(
+        manifest.ToXml(omit_local=False).toxml(),
+        '<?xml version="1.0" ?><manifest>'
+        '<remote name="a" fetch=".."/><default remote="a" revision="r"/>'
+        '<project name="p" groups="local::me"/>'
+        '<project name="q"/><project name="r" groups="keep"/></manifest>')
+
   def test_repo_hooks(self):
     """Check repo-hooks settings."""
     manifest = self.getXmlManifest("""