summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--manifest_xml.py16
-rw-r--r--project.py49
-rwxr-xr-xrepo8
3 files changed, 59 insertions, 14 deletions
diff --git a/manifest_xml.py b/manifest_xml.py
index 3c8fadd6..e2f58e62 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -261,6 +261,12 @@ class XmlManifest(object):
261 ce.setAttribute('dest', c.dest) 261 ce.setAttribute('dest', c.dest)
262 e.appendChild(ce) 262 e.appendChild(ce)
263 263
264 for l in p.linkfiles:
265 le = doc.createElement('linkfile')
266 le.setAttribute('src', l.src)
267 le.setAttribute('dest', l.dest)
268 e.appendChild(le)
269
264 default_groups = ['all', 'name:%s' % p.name, 'path:%s' % p.relpath] 270 default_groups = ['all', 'name:%s' % p.name, 'path:%s' % p.relpath]
265 egroups = [g for g in p.groups if g not in default_groups] 271 egroups = [g for g in p.groups if g not in default_groups]
266 if egroups: 272 if egroups:
@@ -765,6 +771,8 @@ class XmlManifest(object):
765 for n in node.childNodes: 771 for n in node.childNodes:
766 if n.nodeName == 'copyfile': 772 if n.nodeName == 'copyfile':
767 self._ParseCopyFile(project, n) 773 self._ParseCopyFile(project, n)
774 if n.nodeName == 'linkfile':
775 self._ParseLinkFile(project, n)
768 if n.nodeName == 'annotation': 776 if n.nodeName == 'annotation':
769 self._ParseAnnotation(project, n) 777 self._ParseAnnotation(project, n)
770 if n.nodeName == 'project': 778 if n.nodeName == 'project':
@@ -814,6 +822,14 @@ class XmlManifest(object):
814 # dest is relative to the top of the tree 822 # dest is relative to the top of the tree
815 project.AddCopyFile(src, dest, os.path.join(self.topdir, dest)) 823 project.AddCopyFile(src, dest, os.path.join(self.topdir, dest))
816 824
825 def _ParseLinkFile(self, project, node):
826 src = self._reqatt(node, 'src')
827 dest = self._reqatt(node, 'dest')
828 if not self.IsMirror:
829 # src is project relative;
830 # dest is relative to the top of the tree
831 project.AddLinkFile(src, dest, os.path.join(self.topdir, dest))
832
817 def _ParseAnnotation(self, project, node): 833 def _ParseAnnotation(self, project, node):
818 name = self._reqatt(node, 'name') 834 name = self._reqatt(node, 'name')
819 value = self._reqatt(node, 'value') 835 value = self._reqatt(node, 'value')
diff --git a/project.py b/project.py
index 876b86ac..0f110961 100644
--- a/project.py
+++ b/project.py
@@ -231,6 +231,30 @@ class _CopyFile:
231 except IOError: 231 except IOError:
232 _error('Cannot copy file %s to %s', src, dest) 232 _error('Cannot copy file %s to %s', src, dest)
233 233
234class _LinkFile:
235 def __init__(self, src, dest, abssrc, absdest):
236 self.src = src
237 self.dest = dest
238 self.abs_src = abssrc
239 self.abs_dest = absdest
240
241 def _Link(self):
242 src = self.abs_src
243 dest = self.abs_dest
244 # link file if it does not exist or is out of date
245 if not os.path.islink(dest) or os.readlink(dest) != src:
246 try:
247 # remove existing file first, since it might be read-only
248 if os.path.exists(dest):
249 os.remove(dest)
250 else:
251 dest_dir = os.path.dirname(dest)
252 if not os.path.isdir(dest_dir):
253 os.makedirs(dest_dir)
254 os.symlink(src, dest)
255 except IOError:
256 _error('Cannot link file %s to %s', src, dest)
257
234class RemoteSpec(object): 258class RemoteSpec(object):
235 def __init__(self, 259 def __init__(self,
236 name, 260 name,
@@ -555,6 +579,7 @@ class Project(object):
555 579
556 self.snapshots = {} 580 self.snapshots = {}
557 self.copyfiles = [] 581 self.copyfiles = []
582 self.linkfiles = []
558 self.annotations = [] 583 self.annotations = []
559 self.config = GitConfig.ForRepository( 584 self.config = GitConfig.ForRepository(
560 gitdir = self.gitdir, 585 gitdir = self.gitdir,
@@ -1040,7 +1065,7 @@ class Project(object):
1040 except OSError as e: 1065 except OSError as e:
1041 print("warn: Cannot remove archive %s: " 1066 print("warn: Cannot remove archive %s: "
1042 "%s" % (tarpath, str(e)), file=sys.stderr) 1067 "%s" % (tarpath, str(e)), file=sys.stderr)
1043 self._CopyFiles() 1068 self._CopyAndLinkFiles()
1044 return True 1069 return True
1045 1070
1046 if is_new is None: 1071 if is_new is None:
@@ -1103,9 +1128,11 @@ class Project(object):
1103 def PostRepoUpgrade(self): 1128 def PostRepoUpgrade(self):
1104 self._InitHooks() 1129 self._InitHooks()
1105 1130
1106 def _CopyFiles(self): 1131 def _CopyAndLinkFiles(self):
1107 for copyfile in self.copyfiles: 1132 for copyfile in self.copyfiles:
1108 copyfile._Copy() 1133 copyfile._Copy()
1134 for linkfile in self.linkfiles:
1135 linkfile._Link()
1109 1136
1110 def GetCommitRevisionId(self): 1137 def GetCommitRevisionId(self):
1111 """Get revisionId of a commit. 1138 """Get revisionId of a commit.
@@ -1152,7 +1179,7 @@ class Project(object):
1152 1179
1153 def _doff(): 1180 def _doff():
1154 self._FastForward(revid) 1181 self._FastForward(revid)
1155 self._CopyFiles() 1182 self._CopyAndLinkFiles()
1156 1183
1157 head = self.work_git.GetHead() 1184 head = self.work_git.GetHead()
1158 if head.startswith(R_HEADS): 1185 if head.startswith(R_HEADS):
@@ -1188,7 +1215,7 @@ class Project(object):
1188 except GitError as e: 1215 except GitError as e:
1189 syncbuf.fail(self, e) 1216 syncbuf.fail(self, e)
1190 return 1217 return
1191 self._CopyFiles() 1218 self._CopyAndLinkFiles()
1192 return 1219 return
1193 1220
1194 if head == revid: 1221 if head == revid:
@@ -1210,7 +1237,7 @@ class Project(object):
1210 except GitError as e: 1237 except GitError as e:
1211 syncbuf.fail(self, e) 1238 syncbuf.fail(self, e)
1212 return 1239 return
1213 self._CopyFiles() 1240 self._CopyAndLinkFiles()
1214 return 1241 return
1215 1242
1216 upstream_gain = self._revlist(not_rev(HEAD), revid) 1243 upstream_gain = self._revlist(not_rev(HEAD), revid)
@@ -1283,12 +1310,12 @@ class Project(object):
1283 if cnt_mine > 0 and self.rebase: 1310 if cnt_mine > 0 and self.rebase:
1284 def _dorebase(): 1311 def _dorebase():
1285 self._Rebase(upstream = '%s^1' % last_mine, onto = revid) 1312 self._Rebase(upstream = '%s^1' % last_mine, onto = revid)
1286 self._CopyFiles() 1313 self._CopyAndLinkFiles()
1287 syncbuf.later2(self, _dorebase) 1314 syncbuf.later2(self, _dorebase)
1288 elif local_changes: 1315 elif local_changes:
1289 try: 1316 try:
1290 self._ResetHard(revid) 1317 self._ResetHard(revid)
1291 self._CopyFiles() 1318 self._CopyAndLinkFiles()
1292 except GitError as e: 1319 except GitError as e:
1293 syncbuf.fail(self, e) 1320 syncbuf.fail(self, e)
1294 return 1321 return
@@ -1301,6 +1328,12 @@ class Project(object):
1301 abssrc = os.path.join(self.worktree, src) 1328 abssrc = os.path.join(self.worktree, src)
1302 self.copyfiles.append(_CopyFile(src, dest, abssrc, absdest)) 1329 self.copyfiles.append(_CopyFile(src, dest, abssrc, absdest))
1303 1330
1331 def AddLinkFile(self, src, dest, absdest):
1332 # dest should already be an absolute path, but src is project relative
1333 # make src an absolute path
1334 abssrc = os.path.join(self.worktree, src)
1335 self.linkfiles.append(_LinkFile(src, dest, abssrc, absdest))
1336
1304 def AddAnnotation(self, name, value, keep): 1337 def AddAnnotation(self, name, value, keep):
1305 self.annotations.append(_Annotation(name, value, keep)) 1338 self.annotations.append(_Annotation(name, value, keep))
1306 1339
@@ -2201,7 +2234,7 @@ class Project(object):
2201 if GitCommand(self, cmd).Wait() != 0: 2234 if GitCommand(self, cmd).Wait() != 0:
2202 raise GitError("cannot initialize work tree") 2235 raise GitError("cannot initialize work tree")
2203 2236
2204 self._CopyFiles() 2237 self._CopyAndLinkFiles()
2205 2238
2206 def _gitdir_path(self, path): 2239 def _gitdir_path(self, path):
2207 return os.path.realpath(os.path.join(self.gitdir, path)) 2240 return os.path.realpath(os.path.join(self.gitdir, path))
diff --git a/repo b/repo
index 768f11f8..b8c414be 100755
--- a/repo
+++ b/repo
@@ -114,6 +114,7 @@ import errno
114import optparse 114import optparse
115import os 115import os
116import re 116import re
117import shutil
117import stat 118import stat
118import subprocess 119import subprocess
119import sys 120import sys
@@ -741,12 +742,7 @@ def main(orig_args):
741 try: 742 try:
742 _Init(args) 743 _Init(args)
743 except CloneFailure: 744 except CloneFailure:
744 for root, dirs, files in os.walk(repodir, topdown=False): 745 shutil.rmtree(repodir, ignore_errors=True)
745 for name in files:
746 os.remove(os.path.join(root, name))
747 for name in dirs:
748 os.rmdir(os.path.join(root, name))
749 os.rmdir(repodir)
750 sys.exit(1) 746 sys.exit(1)
751 repo_main, rel_repo_dir = _FindRepo() 747 repo_main, rel_repo_dir = _FindRepo()
752 else: 748 else: