manifest_xml: change .repo/manifest.xml to a plain file

Changing this to a file instead of using a symlink serves two purposes:
* We can insert some comments & doc links to help users learn what this
  is for, discover relevant documentation, and to discourage them from
  modifying things.
* Windows requires Administrator access to use symlinks.  With this
  last change, Windows users can get repo client checkouts with the new
  --worktree option and not need symlinks anywhere at all.  Which means
  they no longer need to be an Administrator in order to `repo sync`.

Change-Id: I9bc46824fd8d4b0f446ba84bd764994ca1e597e2
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/256313
Tested-by: Mike Frysinger <vapier@google.com>
Reviewed-by: David Pursehouse <dpursehouse@collab.net>
diff --git a/docs/internal-fs-layout.md b/docs/internal-fs-layout.md
index 0b6c470..8050e4f 100644
--- a/docs/internal-fs-layout.md
+++ b/docs/internal-fs-layout.md
@@ -68,13 +68,20 @@
     If you want to switch the tracking settings, re-run `repo init` with the
     new settings.
 
+*   `manifest.xml`: The manifest that repo uses.  It is generated at `repo init`
+    and uses the `--manifest-name` to determine what manifest file to load next
+    out of `manifests/`.
+
+    Do not try to modify this to load other manifests as it will confuse repo.
+    If you want to switch manifest files, re-run `repo init` with the new
+    setting.
+
+    Older versions of repo managed this with symlinks.
+
 *   `manifest.xml -> manifests/<manifest-name>.xml`: A symlink to the manifest
     that the user wishes to sync.  It is specified at `repo init` time via
     `--manifest-name`.
 
-    Do not try to repoint this symlink to other files as it will confuse repo.
-    If you want to switch manifest files, re-run `repo init` with the new
-    setting.
 
 *   `manifests.git/.repo_config.json`: JSON cache of the `manifests.git/config`
     file for repo to read/process quickly.
diff --git a/manifest_xml.py b/manifest_xml.py
index fe0735a..a3effd1 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -191,12 +191,27 @@
     """
     self.Override(name)
 
-    try:
-      if os.path.lexists(self.manifestFile):
-        platform_utils.remove(self.manifestFile)
-      platform_utils.symlink(os.path.join('manifests', name), self.manifestFile)
-    except OSError as e:
-      raise ManifestParseError('cannot link manifest %s: %s' % (name, str(e)))
+    # Old versions of repo would generate symlinks we need to clean up.
+    if os.path.lexists(self.manifestFile):
+      platform_utils.remove(self.manifestFile)
+    # This file is interpreted as if it existed inside the manifest repo.
+    # That allows us to use <include> with the relative file name.
+    with open(self.manifestFile, 'w') as fp:
+      fp.write("""<?xml version="1.0" encoding="UTF-8"?>
+<!--
+DO NOT EDIT THIS FILE!  It is generated by repo and changes will be discarded.
+If you want to use a different manifest, use `repo init -m <file>` instead.
+
+If you want to customize your checkout by overriding manifest settings, use
+the local_manifests/ directory instead.
+
+For more information on repo manifests, check out:
+https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
+-->
+<manifest>
+  <include name="%s" />
+</manifest>
+""" % (name,))
 
   def _RemoteToXml(self, r, doc, root):
     e = doc.createElement('remote')