Mercurial > hgsubversion
annotate svnexternals.py @ 313:942f198b8ff5
hg_delta_editor: detect new branches issued from non-branch directories
This fix solves the following case: let's /dumb/layout/project be an existing
project. To normalize the trunk/branches/tags layout, people may do:
$ mkdir /project
$ mv /dumb/layout/project /project/project
# Oups, should have been trunk!
$ mv /project/project /project/trunk
trunk creation was ignore because:
- update_branch_map() sees it come from a non-branch copy source and ignores it
(case #3).
- since it is not in self.branches, add_directory() ignores the non-existing path.
Then trunk is left uninitialized.
To solve this, we allow update_branch_map() to detect branches copied from
non-canonical locations.
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Sun, 03 May 2009 21:42:42 -0500 |
parents | ba8e91a7c077 |
children | 963d27a0b1c2 |
rev | line source |
---|---|
174
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
1 import cStringIO |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
2 |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
3 import os, re, shutil, stat, subprocess |
250
79349fd04836
utils: standardizing imported name to hgutil, our_util to util
Daniel Tang <dytang@cs.purdue.edu>
parents:
175
diff
changeset
|
4 from mercurial import util as hgutil |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
5 from mercurial.i18n import _ |
174
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
6 |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
7 class externalsfile(dict): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
8 """Map svn directories to lists of externals entries. |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
9 """ |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
10 def __init__(self): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
11 super(externalsfile, self).__init__() |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
12 self.encoding = 'utf-8' |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
13 |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
14 def __setitem__(self, key, value): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
15 if value is None: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
16 value = [] |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
17 elif isinstance(value, basestring): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
18 value = value.splitlines() |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
19 if key == '.': |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
20 key = '' |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
21 if not value: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
22 if key in self: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
23 del self[key] |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
24 else: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
25 super(externalsfile, self).__setitem__(key, value) |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
26 |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
27 def write(self): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
28 fp = cStringIO.StringIO() |
286
552deb1351ce
Replace mercurial.util.sort with sorted buildin (after mercurial a1a5a57efe90)
Martijn Pieters <mj@zopatista.com>
parents:
250
diff
changeset
|
29 for target in sorted(self): |
174
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
30 lines = self[target] |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
31 if not lines: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
32 continue |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
33 if not target: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
34 target = '.' |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
35 fp.write('[%s]\n' % target) |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
36 for l in lines: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
37 l = ' ' + l + '\n' |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
38 fp.write(l) |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
39 return fp.getvalue() |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
40 |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
41 def read(self, data): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
42 self.clear() |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
43 fp = cStringIO.StringIO(data) |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
44 dirs = {} |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
45 target = None |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
46 for line in fp.readlines(): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
47 if not line.strip(): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
48 continue |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
49 if line.startswith('['): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
50 line = line.strip() |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
51 if line[-1] != ']': |
250
79349fd04836
utils: standardizing imported name to hgutil, our_util to util
Daniel Tang <dytang@cs.purdue.edu>
parents:
175
diff
changeset
|
52 raise hgutil.Abort('invalid externals section name: %s' % line) |
174
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
53 target = line[1:-1] |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
54 if target == '.': |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
55 target = '' |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
56 elif line.startswith(' '): |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
57 line = line.rstrip('\n') |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
58 if target is None or not line: |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
59 continue |
f80132c5fea5
Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents:
diff
changeset
|
60 self.setdefault(target, []).append(line[1:]) |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
61 |
175
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
62 def diff(ext1, ext2): |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
63 """Compare 2 externalsfile and yield tuples like (dir, value1, value2) |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
64 where value1 is the external value in ext1 for dir or None, and |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
65 value2 the same in ext2. |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
66 """ |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
67 for d in ext1: |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
68 if d not in ext2: |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
69 yield d, '\n'.join(ext1[d]), None |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
70 elif ext1[d] != ext2[d]: |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
71 yield d, '\n'.join(ext1[d]), '\n'.join(ext2[d]) |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
72 for d in ext2: |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
73 if d not in ext1: |
2412800b1258
Support svn:externals changes via .hgsvnexternals updates
Patrick Mezard <pmezard@gmail.com>
parents:
174
diff
changeset
|
74 yield d, None, '\n'.join(ext2[d]) |
291
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
75 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
76 class BadDefinition(Exception): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
77 pass |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
78 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
79 re_defold = re.compile(r'^(.*?)\s+(?:-r\s*(\d+)\s+)?([a-zA-Z]+://.*)$') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
80 re_defnew = re.compile(r'^(?:-r\s*(\d+)\s+)?((?:[a-zA-Z]+://|\^/).*)\s+(.*)$') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
81 re_pegrev = re.compile(r'^(.*)@(\d+)$') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
82 re_scheme = re.compile(r'^[a-zA-Z]+://') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
83 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
84 def parsedefinition(line): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
85 """Parse an external definition line, return a tuple (path, rev, source) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
86 or raise BadDefinition. |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
87 """ |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
88 # The parsing is probably not correct wrt path with whitespaces or |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
89 # potential quotes. svn documentation is not really talkative about |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
90 # these either. |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
91 line = line.strip() |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
92 m = re_defnew.search(line) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
93 if m: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
94 rev, source, path = m.group(1, 2, 3) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
95 else: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
96 m = re_defold.search(line) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
97 if not m: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
98 raise BadDefinition() |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
99 path, rev, source = m.group(1, 2, 3) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
100 # Look for peg revisions |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
101 m = re_pegrev.search(source) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
102 if m: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
103 source, rev = m.group(1, 2) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
104 return (path, rev, source) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
105 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
106 def parsedefinitions(ui, repo, svnroot, exts): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
107 """Return (targetdir, revision, source) tuples. Fail if nested |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
108 targetdirs are detected. source is an svn project URL. |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
109 """ |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
110 defs = [] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
111 for base in sorted(exts): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
112 for line in exts[base]: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
113 try: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
114 path, rev, source = parsedefinition(line) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
115 except BadDefinition: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
116 ui.warn(_('ignoring invalid external definition: %r' % line)) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
117 continue |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
118 if re_scheme.search(source): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
119 pass |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
120 elif source.startswith('^/'): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
121 source = svnroot + source[1:] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
122 else: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
123 ui.warn(_('ignoring unsupported non-fully qualified external: %r' % source)) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
124 continue |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
125 wpath = hgutil.pconvert(os.path.join(base, path)) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
126 wpath = hgutil.canonpath(repo.root, '', wpath) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
127 defs.append((wpath, rev, source)) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
128 # Check target dirs are not nested |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
129 defs.sort() |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
130 for i, d in enumerate(defs): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
131 for d2 in defs[i+1:]: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
132 if d2[0].startswith(d[0] + '/'): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
133 raise hgutil.Abort(_('external directories cannot nest:\n%s\n%s') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
134 % (d[0], d2[0])) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
135 return defs |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
136 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
137 def computeactions(ui, repo, svnroot, ext1, ext2): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
138 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
139 def listdefs(data): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
140 defs = {} |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
141 exts = externalsfile() |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
142 exts.read(data) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
143 for d in parsedefinitions(ui, repo, svnroot, exts): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
144 defs[d[0]] = d |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
145 return defs |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
146 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
147 ext1 = listdefs(ext1) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
148 ext2 = listdefs(ext2) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
149 for wp1 in ext1: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
150 if wp1 in ext2: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
151 yield 'u', ext2[wp1] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
152 else: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
153 yield 'd', ext1[wp1] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
154 for wp2 in ext2: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
155 if wp2 not in ext1: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
156 yield 'u', ext2[wp2] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
157 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
158 def getsvninfo(svnurl): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
159 """Return a tuple (url, root) for supplied svn URL or working |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
160 directory path. |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
161 """ |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
162 # Yes, this is ugly, but good enough for now |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
163 args = ['svn', 'info', '--xml', svnurl] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
164 shell = os.name == 'nt' |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
165 p = subprocess.Popen(args, stdout=subprocess.PIPE, shell=shell) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
166 stdout = p.communicate()[0] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
167 if p.returncode: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
168 raise hgutil.Abort(_('cannot get information about %s') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
169 % svnurl) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
170 m = re.search(r'<root>(.*)</root>', stdout, re.S) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
171 if not m: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
172 raise hgutil.Abort(_('cannot find SVN repository root from %s') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
173 % svnurl) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
174 root = m.group(1).rstrip('/') |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
175 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
176 m = re.search(r'<url>(.*)</url>', stdout, re.S) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
177 if not m: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
178 raise hgutil.Abort(_('cannot find SVN repository URL from %s') % svnurl) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
179 url = m.group(1) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
180 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
181 m = re.search(r'<entry[^>]+revision="([^"]+)"', stdout, re.S) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
182 if not m: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
183 raise hgutil.Abort(_('cannot find SVN revision from %s') % svnurl) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
184 rev = m.group(1) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
185 return url, root, rev |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
186 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
187 class externalsupdater: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
188 def __init__(self, ui, repo): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
189 self.repo = repo |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
190 self.ui = ui |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
191 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
192 def update(self, wpath, rev, source): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
193 path = self.repo.wjoin(wpath) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
194 revspec = [] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
195 if rev: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
196 revspec = ['-r', rev] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
197 if os.path.isdir(path): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
198 exturl, extroot, extrev = getsvninfo(path) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
199 if source == exturl: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
200 if extrev != rev: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
201 self.ui.status(_('updating external on %s@%s\n') % |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
202 (wpath, rev or 'HEAD')) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
203 cwd = os.path.join(self.repo.root, path) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
204 self.svn(['update'] + revspec, cwd) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
205 return |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
206 self.delete(wpath) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
207 cwd, dest = os.path.split(path) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
208 cwd = os.path.join(self.repo.root, cwd) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
209 if not os.path.isdir(cwd): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
210 os.makedirs(cwd) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
211 self.ui.status(_('fetching external %s@%s\n') % (wpath, rev or 'HEAD')) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
212 self.svn(['co'] + revspec + [source, dest], cwd) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
213 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
214 def delete(self, wpath): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
215 path = self.repo.wjoin(wpath) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
216 if os.path.isdir(path): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
217 self.ui.status(_('removing external %s\n') % wpath) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
218 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
219 def onerror(function, path, excinfo): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
220 if function is not os.remove: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
221 raise |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
222 # read-only files cannot be unlinked under Windows |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
223 s = os.stat(path) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
224 if (s.st_mode & stat.S_IWRITE) != 0: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
225 raise |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
226 os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
227 os.remove(path) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
228 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
229 shutil.rmtree(path, onerror=onerror) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
230 return 1 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
231 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
232 def svn(self, args, cwd): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
233 args = ['svn'] + args |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
234 self.ui.debug(_('updating externals: %r, cwd=%s\n') % (args, cwd)) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
235 shell = os.name == 'nt' |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
236 subprocess.check_call(args, cwd=cwd, shell=shell) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
237 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
238 def updateexternals(ui, args, repo, **opts): |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
239 """update repository externals |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
240 """ |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
241 if len(args) > 1: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
242 raise hgutil.Abort(_('updateexternals expects at most one changeset')) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
243 node = None |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
244 if args: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
245 node = args[0] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
246 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
247 try: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
248 svnurl = file(repo.join('svn/url'), 'rb').read() |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
249 except: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
250 raise hgutil.Abort(_('failed to retrieve original svn URL')) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
251 svnroot = getsvninfo(svnurl)[1] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
252 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
253 # Retrieve current externals status |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
254 try: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
255 oldext = file(repo.join('svn/externals'), 'rb').read() |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
256 except IOError: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
257 oldext = '' |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
258 newext = '' |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
259 ctx = repo[node] |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
260 if '.hgsvnexternals' in ctx: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
261 newext = ctx['.hgsvnexternals'].data() |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
262 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
263 updater = externalsupdater(ui, repo) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
264 actions = computeactions(ui, repo, svnroot, oldext, newext) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
265 for action, ext in actions: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
266 if action == 'u': |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
267 updater.update(ext[0], ext[1], ext[2]) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
268 elif action == 'd': |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
269 updater.delete(ext[0]) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
270 else: |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
271 raise hgutil.Abort(_('unknown update actions: %r') % action) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
272 |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
273 file(repo.join('svn/externals'), 'wb').write(newext) |
ba8e91a7c077
Add 'updateexternals' to synchronize externals with remote repo.
Patrick Mezard <pmezard@gmail.com>
parents:
286
diff
changeset
|
274 |