Merge "Ignore clone-depth attribute when fetching to a mirror"
diff --git a/manifest_xml.py b/manifest_xml.py
index 3c8fadd..e2f58e6 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -261,6 +261,12 @@
ce.setAttribute('dest', c.dest)
e.appendChild(ce)
+ for l in p.linkfiles:
+ le = doc.createElement('linkfile')
+ le.setAttribute('src', l.src)
+ le.setAttribute('dest', l.dest)
+ e.appendChild(le)
+
default_groups = ['all', 'name:%s' % p.name, 'path:%s' % p.relpath]
egroups = [g for g in p.groups if g not in default_groups]
if egroups:
@@ -765,6 +771,8 @@
for n in node.childNodes:
if n.nodeName == 'copyfile':
self._ParseCopyFile(project, n)
+ if n.nodeName == 'linkfile':
+ self._ParseLinkFile(project, n)
if n.nodeName == 'annotation':
self._ParseAnnotation(project, n)
if n.nodeName == 'project':
@@ -814,6 +822,14 @@
# dest is relative to the top of the tree
project.AddCopyFile(src, dest, os.path.join(self.topdir, dest))
+ def _ParseLinkFile(self, project, node):
+ src = self._reqatt(node, 'src')
+ dest = self._reqatt(node, 'dest')
+ if not self.IsMirror:
+ # src is project relative;
+ # dest is relative to the top of the tree
+ project.AddLinkFile(src, dest, os.path.join(self.topdir, dest))
+
def _ParseAnnotation(self, project, node):
name = self._reqatt(node, 'name')
value = self._reqatt(node, 'value')
diff --git a/project.py b/project.py
index 876b86a..0f11096 100644
--- a/project.py
+++ b/project.py
@@ -231,6 +231,30 @@
except IOError:
_error('Cannot copy file %s to %s', src, dest)
+class _LinkFile:
+ def __init__(self, src, dest, abssrc, absdest):
+ self.src = src
+ self.dest = dest
+ self.abs_src = abssrc
+ self.abs_dest = absdest
+
+ def _Link(self):
+ src = self.abs_src
+ dest = self.abs_dest
+ # link file if it does not exist or is out of date
+ if not os.path.islink(dest) or os.readlink(dest) != src:
+ try:
+ # remove existing file first, since it might be read-only
+ if os.path.exists(dest):
+ os.remove(dest)
+ else:
+ dest_dir = os.path.dirname(dest)
+ if not os.path.isdir(dest_dir):
+ os.makedirs(dest_dir)
+ os.symlink(src, dest)
+ except IOError:
+ _error('Cannot link file %s to %s', src, dest)
+
class RemoteSpec(object):
def __init__(self,
name,
@@ -555,6 +579,7 @@
self.snapshots = {}
self.copyfiles = []
+ self.linkfiles = []
self.annotations = []
self.config = GitConfig.ForRepository(
gitdir = self.gitdir,
@@ -1040,7 +1065,7 @@
except OSError as e:
print("warn: Cannot remove archive %s: "
"%s" % (tarpath, str(e)), file=sys.stderr)
- self._CopyFiles()
+ self._CopyAndLinkFiles()
return True
if is_new is None:
@@ -1103,9 +1128,11 @@
def PostRepoUpgrade(self):
self._InitHooks()
- def _CopyFiles(self):
+ def _CopyAndLinkFiles(self):
for copyfile in self.copyfiles:
copyfile._Copy()
+ for linkfile in self.linkfiles:
+ linkfile._Link()
def GetCommitRevisionId(self):
"""Get revisionId of a commit.
@@ -1152,7 +1179,7 @@
def _doff():
self._FastForward(revid)
- self._CopyFiles()
+ self._CopyAndLinkFiles()
head = self.work_git.GetHead()
if head.startswith(R_HEADS):
@@ -1188,7 +1215,7 @@
except GitError as e:
syncbuf.fail(self, e)
return
- self._CopyFiles()
+ self._CopyAndLinkFiles()
return
if head == revid:
@@ -1210,7 +1237,7 @@
except GitError as e:
syncbuf.fail(self, e)
return
- self._CopyFiles()
+ self._CopyAndLinkFiles()
return
upstream_gain = self._revlist(not_rev(HEAD), revid)
@@ -1283,12 +1310,12 @@
if cnt_mine > 0 and self.rebase:
def _dorebase():
self._Rebase(upstream = '%s^1' % last_mine, onto = revid)
- self._CopyFiles()
+ self._CopyAndLinkFiles()
syncbuf.later2(self, _dorebase)
elif local_changes:
try:
self._ResetHard(revid)
- self._CopyFiles()
+ self._CopyAndLinkFiles()
except GitError as e:
syncbuf.fail(self, e)
return
@@ -1301,6 +1328,12 @@
abssrc = os.path.join(self.worktree, src)
self.copyfiles.append(_CopyFile(src, dest, abssrc, absdest))
+ def AddLinkFile(self, src, dest, absdest):
+ # dest should already be an absolute path, but src is project relative
+ # make src an absolute path
+ abssrc = os.path.join(self.worktree, src)
+ self.linkfiles.append(_LinkFile(src, dest, abssrc, absdest))
+
def AddAnnotation(self, name, value, keep):
self.annotations.append(_Annotation(name, value, keep))
@@ -2201,7 +2234,7 @@
if GitCommand(self, cmd).Wait() != 0:
raise GitError("cannot initialize work tree")
- self._CopyFiles()
+ self._CopyAndLinkFiles()
def _gitdir_path(self, path):
return os.path.realpath(os.path.join(self.gitdir, path))
diff --git a/repo b/repo
index 768f11f..b8c414b 100755
--- a/repo
+++ b/repo
@@ -114,6 +114,7 @@
import optparse
import os
import re
+import shutil
import stat
import subprocess
import sys
@@ -741,12 +742,7 @@
try:
_Init(args)
except CloneFailure:
- for root, dirs, files in os.walk(repodir, topdown=False):
- for name in files:
- os.remove(os.path.join(root, name))
- for name in dirs:
- os.rmdir(os.path.join(root, name))
- os.rmdir(repodir)
+ shutil.rmtree(repodir, ignore_errors=True)
sys.exit(1)
repo_main, rel_repo_dir = _FindRepo()
else: