Mercurial > public > mercurial-scm > hg
annotate mercurial/hg.py @ 726:809a870a0e73
Add a source designator to the walk methods.
If the source is 'f' (the filesystem), the file definitely exists in
the filesystem. If 'm' (a rev or dirstate manifest), the file may not
still exist with the given name.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Tue, 19 Jul 2005 07:15:59 -0800 |
parents | c6b912f8b5b2 |
children | d2dc7663d512 |
rev | line source |
---|---|
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1 # hg.py - repository classes for mercurial |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
2 # |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
3 # Copyright 2005 Matt Mackall <mpm@selenic.com> |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
4 # |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
6 # of the GNU General Public License, incorporated herein by reference. |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
7 |
249 | 8 import sys, struct, os |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
418
diff
changeset
|
9 import util |
262 | 10 from revlog import * |
11 from demandload import * | |
12 demandload(globals(), "re lock urllib urllib2 transaction time socket") | |
434 | 13 demandload(globals(), "tempfile httprangereader bdiff") |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
14 demandload(globals(), "bisect select") |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
15 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
16 class filelog(revlog): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
17 def __init__(self, opener, path): |
144
ea9188538222
Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents:
140
diff
changeset
|
18 revlog.__init__(self, opener, |
ea9188538222
Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents:
140
diff
changeset
|
19 os.path.join("data", path + ".i"), |
ea9188538222
Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents:
140
diff
changeset
|
20 os.path.join("data", path + ".d")) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
21 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
22 def read(self, node): |
360 | 23 t = self.revision(node) |
686
d7d68d27ebe5
Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents:
681
diff
changeset
|
24 if not t.startswith('\1\n'): |
360 | 25 return t |
26 s = t.find('\1\n', 2) | |
27 return t[s+2:] | |
28 | |
29 def readmeta(self, node): | |
30 t = self.revision(node) | |
686
d7d68d27ebe5
Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents:
681
diff
changeset
|
31 if not t.startswith('\1\n'): |
360 | 32 return t |
33 s = t.find('\1\n', 2) | |
34 mt = t[2:s] | |
35 for l in mt.splitlines(): | |
36 k, v = l.split(": ", 1) | |
37 m[k] = v | |
38 return m | |
39 | |
40 def add(self, text, meta, transaction, link, p1=None, p2=None): | |
686
d7d68d27ebe5
Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents:
681
diff
changeset
|
41 if meta or text.startswith('\1\n'): |
360 | 42 mt = "" |
43 if meta: | |
44 mt = [ "%s: %s\n" % (k, v) for k,v in meta.items() ] | |
45 text = "\1\n" + "".join(mt) + "\1\n" + text | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
46 return self.addrevision(text, transaction, link, p1, p2) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
47 |
79 | 48 def annotate(self, node): |
199 | 49 |
50 def decorate(text, rev): | |
436 | 51 return ([rev] * len(text.splitlines()), text) |
199 | 52 |
53 def pair(parent, child): | |
436 | 54 for a1, a2, b1, b2 in bdiff.blocks(parent[1], child[1]): |
471 | 55 child[0][b1:b2] = parent[0][a1:a2] |
56 return child | |
199 | 57 |
200 | 58 # find all ancestors |
216
201115f2859b
hg annotate: actually annotate the given version
mpm@selenic.com
parents:
210
diff
changeset
|
59 needed = {node:1} |
199 | 60 visit = [node] |
61 while visit: | |
62 n = visit.pop(0) | |
63 for p in self.parents(n): | |
64 if p not in needed: | |
65 needed[p] = 1 | |
66 visit.append(p) | |
200 | 67 else: |
68 # count how many times we'll use this | |
69 needed[p] += 1 | |
199 | 70 |
200 | 71 # sort by revision which is a topological order |
471 | 72 visit = [ (self.rev(n), n) for n in needed.keys() ] |
199 | 73 visit.sort() |
74 hist = {} | |
75 | |
471 | 76 for r,n in visit: |
199 | 77 curr = decorate(self.read(n), self.linkrev(n)) |
78 for p in self.parents(n): | |
79 if p != nullid: | |
80 curr = pair(hist[p], curr) | |
200 | 81 # trim the history of unneeded revs |
82 needed[p] -= 1 | |
83 if not needed[p]: | |
84 del hist[p] | |
199 | 85 hist[n] = curr |
86 | |
436 | 87 return zip(hist[n][0], hist[n][1].splitlines(1)) |
79 | 88 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
89 class manifest(revlog): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
90 def __init__(self, opener): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
91 self.mapcache = None |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
92 self.listcache = None |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
93 self.addlist = None |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
94 revlog.__init__(self, opener, "00manifest.i", "00manifest.d") |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
95 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
96 def read(self, node): |
313 | 97 if node == nullid: return {} # don't upset local cache |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
98 if self.mapcache and self.mapcache[0] == node: |
561 | 99 return self.mapcache[1] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
100 text = self.revision(node) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
101 map = {} |
276 | 102 flag = {} |
25
daa724b27300
Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents:
20
diff
changeset
|
103 self.listcache = (text, text.splitlines(1)) |
daa724b27300
Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents:
20
diff
changeset
|
104 for l in self.listcache[1]: |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
105 (f, n) = l.split('\0') |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
106 map[f] = bin(n[:40]) |
276 | 107 flag[f] = (n[40:-1] == "x") |
108 self.mapcache = (node, map, flag) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
109 return map |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
110 |
276 | 111 def readflags(self, node): |
313 | 112 if node == nullid: return {} # don't upset local cache |
358
9f4077d7ef6f
[PATCH] manifest.readflags performance buglet
mpm@selenic.com
parents:
350
diff
changeset
|
113 if not self.mapcache or self.mapcache[0] != node: |
276 | 114 self.read(node) |
115 return self.mapcache[2] | |
116 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
117 def diff(self, a, b): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
118 # this is sneaky, as we're not actually using a and b |
140 | 119 if self.listcache and self.addlist and self.listcache[0] == a: |
98 | 120 d = mdiff.diff(self.listcache[1], self.addlist, 1) |
121 if mdiff.patch(a, d) != b: | |
122 sys.stderr.write("*** sortdiff failed, falling back ***\n") | |
123 return mdiff.textdiff(a, b) | |
124 return d | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
125 else: |
44 | 126 return mdiff.textdiff(a, b) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
127 |
644 | 128 def add(self, map, flags, transaction, link, p1=None, p2=None,changed=None): |
129 # directly generate the mdiff delta from the data collected during | |
130 # the bisect loop below | |
131 def gendelta(delta): | |
132 i = 0 | |
133 result = [] | |
134 while i < len(delta): | |
135 start = delta[i][2] | |
136 end = delta[i][3] | |
137 l = delta[i][4] | |
138 if l == None: | |
139 l = "" | |
140 while i < len(delta) - 1 and start <= delta[i+1][2] and end >= delta[i+1][2]: | |
141 if delta[i+1][3] > end: | |
142 end = delta[i+1][3] | |
143 if delta[i+1][4]: | |
144 l += delta[i+1][4] | |
145 i += 1 | |
146 result.append(struct.pack(">lll", start, end, len(l)) + l) | |
147 i += 1 | |
148 return result | |
149 | |
150 # apply the changes collected during the bisect loop to our addlist | |
151 def addlistdelta(addlist, delta): | |
152 # apply the deltas to the addlist. start from the bottom up | |
153 # so changes to the offsets don't mess things up. | |
154 i = len(delta) | |
155 while i > 0: | |
156 i -= 1 | |
157 start = delta[i][0] | |
158 end = delta[i][1] | |
159 if delta[i][4]: | |
160 addlist[start:end] = [delta[i][4]] | |
161 else: | |
162 del addlist[start:end] | |
163 return addlist | |
164 | |
165 # calculate the byte offset of the start of each line in the | |
166 # manifest | |
167 def calcoffsets(addlist): | |
168 offsets = [0] * (len(addlist) + 1) | |
169 offset = 0 | |
170 i = 0 | |
171 while i < len(addlist): | |
172 offsets[i] = offset | |
173 offset += len(addlist[i]) | |
174 i += 1 | |
175 offsets[i] = offset | |
176 return offsets | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
177 |
644 | 178 # if we're using the listcache, make sure it is valid and |
179 # parented by the same node we're diffing against | |
180 if not changed or not self.listcache or not p1 or self.mapcache[0] != p1: | |
181 files = map.keys() | |
182 files.sort() | |
183 | |
184 self.addlist = ["%s\000%s%s\n" % | |
185 (f, hex(map[f]), flags[f] and "x" or '') | |
186 for f in files] | |
187 cachedelta = None | |
188 else: | |
189 addlist = self.listcache[1] | |
190 | |
191 # find the starting offset for each line in the add list | |
192 offsets = calcoffsets(addlist) | |
193 | |
194 # combine the changed lists into one list for sorting | |
195 work = [[x, 0] for x in changed[0]] | |
196 work[len(work):] = [[x, 1] for x in changed[1]] | |
197 work.sort() | |
198 | |
199 delta = [] | |
200 bs = 0 | |
201 | |
202 for w in work: | |
203 f = w[0] | |
204 # bs will either be the index of the item or the insertion point | |
205 bs = bisect.bisect(addlist, f, bs) | |
206 if bs < len(addlist): | |
207 fn = addlist[bs][:addlist[bs].index('\0')] | |
208 else: | |
209 fn = None | |
210 if w[1] == 0: | |
211 l = "%s\000%s%s\n" % (f, hex(map[f]), flags[f] and "x" or '') | |
212 else: | |
213 l = None | |
214 start = bs | |
215 if fn != f: | |
216 # item not found, insert a new one | |
659 | 217 end = bs |
644 | 218 if w[1] == 1: |
713
7c385bd5f993
Added missing newline after two error messages.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
705
diff
changeset
|
219 sys.stderr.write("failed to remove %s from manifest\n" |
7c385bd5f993
Added missing newline after two error messages.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
705
diff
changeset
|
220 % f) |
644 | 221 sys.exit(1) |
222 else: | |
223 # item is found, replace/delete the existing line | |
224 end = bs + 1 | |
225 delta.append([start, end, offsets[start], offsets[end], l]) | |
226 | |
227 self.addlist = addlistdelta(addlist, delta) | |
228 if self.mapcache[0] == self.tip(): | |
229 cachedelta = "".join(gendelta(delta)) | |
230 else: | |
231 cachedelta = None | |
232 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
233 text = "".join(self.addlist) |
644 | 234 if cachedelta and mdiff.patch(self.listcache[0], cachedelta) != text: |
713
7c385bd5f993
Added missing newline after two error messages.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
705
diff
changeset
|
235 sys.stderr.write("manifest delta failure\n") |
644 | 236 sys.exit(1) |
237 n = self.addrevision(text, transaction, link, p1, p2, cachedelta) | |
302 | 238 self.mapcache = (n, map, flags) |
25
daa724b27300
Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents:
20
diff
changeset
|
239 self.listcache = (text, self.addlist) |
140 | 240 self.addlist = None |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
241 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
242 return n |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
243 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
244 class changelog(revlog): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
245 def __init__(self, opener): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
246 revlog.__init__(self, opener, "00changelog.i", "00changelog.d") |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
247 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
248 def extract(self, text): |
37 | 249 if not text: |
40 | 250 return (nullid, "", "0", [], "") |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
251 last = text.index("\n\n") |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
252 desc = text[last + 2:] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
253 l = text[:last].splitlines() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
254 manifest = bin(l[0]) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
255 user = l[1] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
256 date = l[2] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
257 files = l[3:] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
258 return (manifest, user, date, files, desc) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
259 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
260 def read(self, node): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
261 return self.extract(self.revision(node)) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
262 |
203 | 263 def add(self, manifest, list, desc, transaction, p1=None, p2=None, |
264 user=None, date=None): | |
265 date = date or "%d %d" % (time.time(), time.timezone) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
266 list.sort() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
267 l = [hex(manifest), user, date] + list + ["", desc] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
268 text = "\n".join(l) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
269 return self.addrevision(text, transaction, self.count(), p1, p2) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
270 |
220 | 271 class dirstate: |
244 | 272 def __init__(self, opener, ui, root): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
273 self.opener = opener |
244 | 274 self.root = root |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
275 self.dirty = 0 |
20 | 276 self.ui = ui |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
277 self.map = None |
227 | 278 self.pl = None |
363 | 279 self.copies = {} |
723 | 280 self.ignorefunc = None |
281 | |
282 def wjoin(self, f): | |
283 return os.path.join(self.root, f) | |
284 | |
285 def ignore(self, f): | |
286 if not self.ignorefunc: | |
287 bigpat = [] | |
288 try: | |
289 l = file(self.wjoin(".hgignore")) | |
290 for pat in l: | |
291 if pat != "\n": | |
292 p = util.pconvert(pat[:-1]) | |
293 try: | |
294 r = re.compile(p) | |
295 except: | |
296 self.ui.warn("ignoring invalid ignore" | |
297 + " regular expression '%s'\n" % p) | |
298 else: | |
299 bigpat.append(util.pconvert(pat[:-1])) | |
300 except IOError: pass | |
301 | |
302 s = "(?:%s)" % (")|(?:".join(bigpat)) | |
303 r = re.compile(s) | |
304 self.ignorefunc = r.search | |
305 | |
306 return self.ignorefunc(f) | |
220 | 307 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
308 def __del__(self): |
220 | 309 if self.dirty: |
310 self.write() | |
311 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
312 def __getitem__(self, key): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
313 try: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
314 return self.map[key] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
315 except TypeError: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
316 self.read() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
317 return self[key] |
220 | 318 |
319 def __contains__(self, key): | |
320 if not self.map: self.read() | |
321 return key in self.map | |
322 | |
227 | 323 def parents(self): |
324 if not self.pl: | |
325 self.read() | |
326 return self.pl | |
327 | |
723 | 328 def markdirty(self): |
329 if not self.dirty: | |
330 self.dirty = 1 | |
331 | |
227 | 332 def setparents(self, p1, p2 = nullid): |
723 | 333 self.markdirty() |
227 | 334 self.pl = p1, p2 |
335 | |
220 | 336 def state(self, key): |
337 try: | |
338 return self[key][0] | |
339 except KeyError: | |
340 return "?" | |
341 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
342 def read(self): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
343 if self.map is not None: return self.map |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
344 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
345 self.map = {} |
227 | 346 self.pl = [nullid, nullid] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
347 try: |
220 | 348 st = self.opener("dirstate").read() |
311 | 349 if not st: return |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
350 except: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
351 |
227 | 352 self.pl = [st[:20], st[20: 40]] |
353 | |
354 pos = 40 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
355 while pos < len(st): |
220 | 356 e = struct.unpack(">cllll", st[pos:pos+17]) |
357 l = e[4] | |
358 pos += 17 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
359 f = st[pos:pos + l] |
515 | 360 if '\0' in f: |
363 | 361 f, c = f.split('\0') |
362 self.copies[f] = c | |
220 | 363 self.map[f] = e[:4] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
364 pos += l |
363 | 365 |
366 def copy(self, source, dest): | |
367 self.read() | |
723 | 368 self.markdirty() |
363 | 369 self.copies[dest] = source |
370 | |
371 def copied(self, file): | |
372 return self.copies.get(file, None) | |
515 | 373 |
220 | 374 def update(self, files, state): |
375 ''' current states: | |
376 n normal | |
231 | 377 m needs merging |
220 | 378 r marked for removal |
379 a marked for addition''' | |
380 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
381 if not files: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
382 self.read() |
723 | 383 self.markdirty() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
384 for f in files: |
220 | 385 if state == "r": |
386 self.map[f] = ('r', 0, 0, 0) | |
387 else: | |
253 | 388 s = os.stat(os.path.join(self.root, f)) |
389 self.map[f] = (state, s.st_mode, s.st_size, s.st_mtime) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
390 |
220 | 391 def forget(self, files): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
392 if not files: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
393 self.read() |
723 | 394 self.markdirty() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
395 for f in files: |
20 | 396 try: |
397 del self.map[f] | |
398 except KeyError: | |
220 | 399 self.ui.warn("not in dirstate: %s!\n" % f) |
20 | 400 pass |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
401 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
402 def clear(self): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
403 self.map = {} |
723 | 404 self.markdirty() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
405 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
406 def write(self): |
220 | 407 st = self.opener("dirstate", "w") |
227 | 408 st.write("".join(self.pl)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
409 for f, e in self.map.items(): |
363 | 410 c = self.copied(f) |
411 if c: | |
412 f = f + "\0" + c | |
220 | 413 e = struct.pack(">cllll", e[0], e[1], e[2], e[3], len(f)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
414 st.write(e + f) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
415 self.dirty = 0 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
416 |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
723
diff
changeset
|
417 def walk(self, files = None, match = util.always): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
418 self.read() |
536 | 419 dc = self.map.copy() |
723 | 420 # walk all files by default |
536 | 421 if not files: files = [self.root] |
723 | 422 def traverse(): |
556 | 423 for f in util.unique(files): |
537 | 424 f = os.path.join(self.root, f) |
536 | 425 if os.path.isdir(f): |
426 for dir, subdirs, fl in os.walk(f): | |
427 d = dir[len(self.root) + 1:] | |
723 | 428 if d == '.hg': |
429 subdirs[:] = [] | |
430 continue | |
669
8aa2a282eda4
.hgignore speedups patch incorporating Matt's feedback.
mwilli2@localhost.localdomain
parents:
667
diff
changeset
|
431 for sd in subdirs: |
723 | 432 ds = os.path.join(d, sd +'/') |
433 if self.ignore(ds) or not match(ds): | |
669
8aa2a282eda4
.hgignore speedups patch incorporating Matt's feedback.
mwilli2@localhost.localdomain
parents:
667
diff
changeset
|
434 subdirs.remove(sd) |
536 | 435 for fn in fl: |
436 fn = util.pconvert(os.path.join(d, fn)) | |
726
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
437 yield 'f', fn |
536 | 438 else: |
726
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
439 yield 'f', f[len(self.root) + 1:] |
536 | 440 |
669
8aa2a282eda4
.hgignore speedups patch incorporating Matt's feedback.
mwilli2@localhost.localdomain
parents:
667
diff
changeset
|
441 for k in dc.keys(): |
726
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
442 yield 'm', k |
669
8aa2a282eda4
.hgignore speedups patch incorporating Matt's feedback.
mwilli2@localhost.localdomain
parents:
667
diff
changeset
|
443 |
723 | 444 # yield only files that match: all in dirstate, others only if |
445 # not in .hgignore | |
446 | |
726
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
447 for src, fn in util.unique(traverse()): |
723 | 448 if fn in dc: |
449 del dc[fn] | |
450 elif self.ignore(fn): | |
451 continue | |
452 if match(fn): | |
726
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
453 yield src, fn |
723 | 454 |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
723
diff
changeset
|
455 def changes(self, files = None, match = util.always): |
723 | 456 self.read() |
457 dc = self.map.copy() | |
458 lookup, changed, added, unknown = [], [], [], [] | |
459 | |
726
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
460 for src, fn in self.walk(files, match): |
536 | 461 try: s = os.stat(os.path.join(self.root, fn)) |
462 except: continue | |
463 | |
464 if fn in dc: | |
465 c = dc[fn] | |
466 del dc[fn] | |
467 | |
468 if c[0] == 'm': | |
469 changed.append(fn) | |
470 elif c[0] == 'a': | |
471 added.append(fn) | |
472 elif c[0] == 'r': | |
473 unknown.append(fn) | |
474 elif c[2] != s.st_size or (c[1] ^ s.st_mode) & 0100: | |
475 changed.append(fn) | |
476 elif c[1] != s.st_mode or c[3] != s.st_mtime: | |
477 lookup.append(fn) | |
478 else: | |
723 | 479 if match(fn): unknown.append(fn) |
536 | 480 |
481 return (lookup, changed, added, dc.keys(), unknown) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
482 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
483 # used to avoid circular references so destructors work |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
484 def opener(base): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
485 p = base |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
486 def o(path, mode="r"): |
686
d7d68d27ebe5
Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents:
681
diff
changeset
|
487 if p.startswith("http://"): |
15
6daf7757e92b
Fix network pull of repo files with "%" in their base64 encoding.
mpm@selenic.com
parents:
10
diff
changeset
|
488 f = os.path.join(p, urllib.quote(path)) |
372 | 489 return httprangereader.httprangereader(f) |
15
6daf7757e92b
Fix network pull of repo files with "%" in their base64 encoding.
mpm@selenic.com
parents:
10
diff
changeset
|
490 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
491 f = os.path.join(p, path) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
492 |
292 | 493 mode += "b" # for that other OS |
494 | |
495 if mode[0] != "r": | |
110
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
496 try: |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
497 s = os.stat(f) |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
498 except OSError: |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
499 d = os.path.dirname(f) |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
500 if not os.path.isdir(d): |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
501 os.makedirs(d) |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
502 else: |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
503 if s.st_nlink > 1: |
417 | 504 file(f + ".tmp", "wb").write(file(f, "rb").read()) |
421 | 505 util.rename(f+".tmp", f) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
506 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
507 return file(f, mode) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
508 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
509 return o |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
510 |
499 | 511 class RepoError(Exception): pass |
512 | |
60 | 513 class localrepository: |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
514 def __init__(self, ui, path=None, create=0): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
515 self.remote = 0 |
686
d7d68d27ebe5
Reapply startswith() changes that got lost with stale edit
Matt Mackall <mpm@selenic.com>
parents:
681
diff
changeset
|
516 if path and path.startswith("http://"): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
517 self.remote = 1 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
518 self.path = path |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
519 else: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
520 if not path: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
521 p = os.getcwd() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
522 while not os.path.isdir(os.path.join(p, ".hg")): |
420
dbe86d465e09
[PATCH] Repo locator fix for the other `OS'
mpm@selenic.com
parents:
419
diff
changeset
|
523 oldp = p |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
524 p = os.path.dirname(p) |
499 | 525 if p == oldp: raise RepoError("no repo found") |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
526 path = p |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
527 self.path = os.path.join(path, ".hg") |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
528 |
405 | 529 if not create and not os.path.isdir(self.path): |
499 | 530 raise RepoError("repository %s not found" % self.path) |
405 | 531 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
532 self.root = path |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
533 self.ui = ui |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
534 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
535 if create: |
515 | 536 os.mkdir(self.path) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
537 os.mkdir(self.join("data")) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
538 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
539 self.opener = opener(self.path) |
291
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
540 self.wopener = opener(self.root) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
541 self.manifest = manifest(self.opener) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
542 self.changelog = changelog(self.opener) |
343 | 543 self.tagscache = None |
544 self.nodetagscache = None | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
545 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
546 if not self.remote: |
244 | 547 self.dirstate = dirstate(self.opener, ui, self.root) |
337 | 548 try: |
549 self.ui.readconfig(self.opener("hgrc")) | |
550 except IOError: pass | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
551 |
487 | 552 def hook(self, name, **args): |
553 s = self.ui.config("hooks", name) | |
554 if s: | |
555 self.ui.note("running hook %s: %s\n" % (name, s)) | |
556 old = {} | |
557 for k, v in args.items(): | |
558 k = k.upper() | |
559 old[k] = os.environ.get(k, None) | |
560 os.environ[k] = v | |
561 | |
562 r = os.system(s) | |
563 | |
564 for k, v in old.items(): | |
565 if v != None: | |
566 os.environ[k] = v | |
567 else: | |
568 del os.environ[k] | |
569 | |
570 if r: | |
571 self.ui.warn("abort: %s hook failed with status %d!\n" % | |
572 (name, r)) | |
573 return False | |
574 return True | |
575 | |
343 | 576 def tags(self): |
577 '''return a mapping of tag to node''' | |
477
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
578 if not self.tagscache: |
343 | 579 self.tagscache = {} |
609
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
580 def addtag(self, k, n): |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
581 try: |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
582 bin_n = bin(n) |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
583 except TypeError: |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
584 bin_n = '' |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
585 self.tagscache[k.strip()] = bin_n |
659 | 586 |
67 | 587 try: |
254 | 588 # read each head of the tags file, ending with the tip |
589 # and add each tag found to the map, with "newer" ones | |
590 # taking precedence | |
67 | 591 fl = self.file(".hgtags") |
254 | 592 h = fl.heads() |
593 h.reverse() | |
594 for r in h: | |
595 for l in fl.revision(r).splitlines(): | |
596 if l: | |
385
e9e1efd5291c
Fixed problems with extra spaces around tags in .hgtags
Thomas Arendsen Hein <thomas@intevation.de>
parents:
383
diff
changeset
|
597 n, k = l.split(" ", 1) |
609
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
598 addtag(self, k, n) |
477
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
599 except KeyError: |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
600 pass |
659 | 601 |
609
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
602 try: |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
603 f = self.opener("localtags") |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
604 for l in f: |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
605 n, k = l.split(" ", 1) |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
606 addtag(self, k, n) |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
607 except IOError: |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
608 pass |
659 | 609 |
343 | 610 self.tagscache['tip'] = self.changelog.tip() |
659 | 611 |
343 | 612 return self.tagscache |
613 | |
614 def tagslist(self): | |
615 '''return a list of tags ordered by revision''' | |
616 l = [] | |
477
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
617 for t, n in self.tags().items(): |
343 | 618 try: |
619 r = self.changelog.rev(n) | |
620 except: | |
621 r = -2 # sort to the beginning of the list if unknown | |
622 l.append((r,t,n)) | |
623 l.sort() | |
624 return [(t,n) for r,t,n in l] | |
625 | |
626 def nodetags(self, node): | |
627 '''return the tags associated with a node''' | |
628 if not self.nodetagscache: | |
629 self.nodetagscache = {} | |
630 for t,n in self.tags().items(): | |
631 self.nodetagscache.setdefault(n,[]).append(t) | |
632 return self.nodetagscache.get(node, []) | |
633 | |
634 def lookup(self, key): | |
67 | 635 try: |
343 | 636 return self.tags()[key] |
67 | 637 except KeyError: |
658
f8098ae9f5b6
Generate a friendlier except for failed lookups
Matt Mackall <mpm@selenic.com>
parents:
657
diff
changeset
|
638 try: |
f8098ae9f5b6
Generate a friendlier except for failed lookups
Matt Mackall <mpm@selenic.com>
parents:
657
diff
changeset
|
639 return self.changelog.lookup(key) |
f8098ae9f5b6
Generate a friendlier except for failed lookups
Matt Mackall <mpm@selenic.com>
parents:
657
diff
changeset
|
640 except: |
f8098ae9f5b6
Generate a friendlier except for failed lookups
Matt Mackall <mpm@selenic.com>
parents:
657
diff
changeset
|
641 raise RepoError("unknown revision '%s'" % key) |
67 | 642 |
634
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
643 def dev(self): |
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
644 if self.remote: return -1 |
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
645 return os.stat(self.path).st_dev |
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
646 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
647 def join(self, f): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
648 return os.path.join(self.path, f) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
649 |
244 | 650 def wjoin(self, f): |
651 return os.path.join(self.root, f) | |
652 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
653 def file(self, f): |
192 | 654 if f[0] == '/': f = f[1:] |
144
ea9188538222
Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents:
140
diff
changeset
|
655 return filelog(self.opener, f) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
656 |
627 | 657 def getcwd(self): |
658 cwd = os.getcwd() | |
659 if cwd == self.root: return '' | |
660 return cwd[len(self.root) + 1:] | |
661 | |
291
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
662 def wfile(self, f, mode='r'): |
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
663 return self.wopener(f, mode) |
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
664 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
665 def transaction(self): |
251 | 666 # save dirstate for undo |
263 | 667 try: |
668 ds = self.opener("dirstate").read() | |
669 except IOError: | |
670 ds = "" | |
251 | 671 self.opener("undo.dirstate", "w").write(ds) |
515 | 672 |
582 | 673 return transaction.transaction(self.ui.warn, |
674 self.opener, self.join("journal"), | |
262 | 675 self.join("undo")) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
676 |
210 | 677 def recover(self): |
225 | 678 lock = self.lock() |
557 | 679 if os.path.exists(self.join("journal")): |
501 | 680 self.ui.status("rolling back interrupted transaction\n") |
557 | 681 return transaction.rollback(self.opener, self.join("journal")) |
210 | 682 else: |
683 self.ui.warn("no interrupted transaction available\n") | |
684 | |
685 def undo(self): | |
225 | 686 lock = self.lock() |
210 | 687 if os.path.exists(self.join("undo")): |
501 | 688 self.ui.status("rolling back last transaction\n") |
262 | 689 transaction.rollback(self.opener, self.join("undo")) |
251 | 690 self.dirstate = None |
421 | 691 util.rename(self.join("undo.dirstate"), self.join("dirstate")) |
251 | 692 self.dirstate = dirstate(self.opener, self.ui, self.root) |
163 | 693 else: |
210 | 694 self.ui.warn("no undo information available\n") |
162 | 695 |
161 | 696 def lock(self, wait = 1): |
697 try: | |
698 return lock.lock(self.join("lock"), 0) | |
699 except lock.LockHeld, inst: | |
700 if wait: | |
701 self.ui.warn("waiting for lock held by %s\n" % inst.args[0]) | |
702 return lock.lock(self.join("lock"), wait) | |
703 raise inst | |
704 | |
203 | 705 def rawcommit(self, files, text, user, date, p1=None, p2=None): |
442 | 706 orig_parent = self.dirstate.parents()[0] or nullid |
452
a1e91c24dab5
rawcommit: do lookup of parents at the appropriate layer
mpm@selenic.com
parents:
442
diff
changeset
|
707 p1 = p1 or self.dirstate.parents()[0] or nullid |
a1e91c24dab5
rawcommit: do lookup of parents at the appropriate layer
mpm@selenic.com
parents:
442
diff
changeset
|
708 p2 = p2 or self.dirstate.parents()[1] or nullid |
302 | 709 c1 = self.changelog.read(p1) |
710 c2 = self.changelog.read(p2) | |
711 m1 = self.manifest.read(c1[0]) | |
712 mf1 = self.manifest.readflags(c1[0]) | |
713 m2 = self.manifest.read(c2[0]) | |
714 | |
442 | 715 if orig_parent == p1: |
716 update_dirstate = 1 | |
717 else: | |
718 update_dirstate = 0 | |
719 | |
203 | 720 tr = self.transaction() |
302 | 721 mm = m1.copy() |
722 mfm = mf1.copy() | |
203 | 723 linkrev = self.changelog.count() |
724 for f in files: | |
725 try: | |
302 | 726 t = self.wfile(f).read() |
441 | 727 tm = util.is_exec(self.wjoin(f), mfm.get(f, False)) |
302 | 728 r = self.file(f) |
729 mfm[f] = tm | |
360 | 730 mm[f] = r.add(t, {}, tr, linkrev, |
302 | 731 m1.get(f, nullid), m2.get(f, nullid)) |
442 | 732 if update_dirstate: |
733 self.dirstate.update([f], "n") | |
203 | 734 except IOError: |
314
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
735 try: |
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
736 del mm[f] |
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
737 del mfm[f] |
442 | 738 if update_dirstate: |
739 self.dirstate.forget([f]) | |
314
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
740 except: |
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
741 # deleted from p2? |
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
742 pass |
203 | 743 |
302 | 744 mnode = self.manifest.add(mm, mfm, tr, linkrev, c1[0], c2[0]) |
608
d2994b5298fb
Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents:
588
diff
changeset
|
745 user = user or self.ui.username() |
302 | 746 n = self.changelog.add(mnode, files, text, tr, p1, p2, user, date) |
203 | 747 tr.close() |
442 | 748 if update_dirstate: |
749 self.dirstate.setparents(n, nullid) | |
203 | 750 |
317 | 751 def commit(self, files = None, text = "", user = None, date = None): |
220 | 752 commit = [] |
753 remove = [] | |
754 if files: | |
755 for f in files: | |
756 s = self.dirstate.state(f) | |
244 | 757 if s in 'nmai': |
220 | 758 commit.append(f) |
759 elif s == 'r': | |
760 remove.append(f) | |
761 else: | |
244 | 762 self.ui.warn("%s not tracked!\n" % f) |
220 | 763 else: |
723 | 764 (c, a, d, u) = self.changes() |
220 | 765 commit = c + a |
766 remove = d | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
767 |
220 | 768 if not commit and not remove: |
151 | 769 self.ui.status("nothing changed\n") |
770 return | |
771 | |
487 | 772 if not self.hook("precommit"): |
773 return 1 | |
774 | |
229 | 775 p1, p2 = self.dirstate.parents() |
776 c1 = self.changelog.read(p1) | |
777 c2 = self.changelog.read(p2) | |
778 m1 = self.manifest.read(c1[0]) | |
276 | 779 mf1 = self.manifest.readflags(c1[0]) |
229 | 780 m2 = self.manifest.read(c2[0]) |
225 | 781 lock = self.lock() |
151 | 782 tr = self.transaction() |
783 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
784 # check in files |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
785 new = {} |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
786 linkrev = self.changelog.count() |
220 | 787 commit.sort() |
788 for f in commit: | |
83 | 789 self.ui.note(f + "\n") |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
790 try: |
441 | 791 mf1[f] = util.is_exec(self.wjoin(f), mf1.get(f, False)) |
418 | 792 t = self.wfile(f).read() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
793 except IOError: |
667
31a9aa890016
A number of minor fixes to problems that pychecker found.
mark.williamson@cl.cam.ac.uk
parents:
660
diff
changeset
|
794 self.ui.warn("trouble committing %s!\n" % f) |
220 | 795 raise |
796 | |
363 | 797 meta = {} |
798 cp = self.dirstate.copied(f) | |
799 if cp: | |
800 meta["copy"] = cp | |
801 meta["copyrev"] = hex(m1.get(cp, m2.get(cp, nullid))) | |
575 | 802 self.ui.debug(" %s: copy %s:%s\n" % (f, cp, meta["copyrev"])) |
363 | 803 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
804 r = self.file(f) |
229 | 805 fp1 = m1.get(f, nullid) |
806 fp2 = m2.get(f, nullid) | |
363 | 807 new[f] = r.add(t, meta, tr, linkrev, fp1, fp2) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
808 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
809 # update manifest |
229 | 810 m1.update(new) |
416
5e9e8b8d2629
[PATCH] Removal of a file added by merging branches
mpm@selenic.com
parents:
415
diff
changeset
|
811 for f in remove: |
5e9e8b8d2629
[PATCH] Removal of a file added by merging branches
mpm@selenic.com
parents:
415
diff
changeset
|
812 if f in m1: |
5e9e8b8d2629
[PATCH] Removal of a file added by merging branches
mpm@selenic.com
parents:
415
diff
changeset
|
813 del m1[f] |
644 | 814 mn = self.manifest.add(m1, mf1, tr, linkrev, c1[0], c2[0], (new,remove)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
815 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
816 # add changeset |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
817 new = new.keys() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
818 new.sort() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
819 |
288 | 820 if not text: |
821 edittext = "\n" + "HG: manifest hash %s\n" % hex(mn) | |
822 edittext += "".join(["HG: changed %s\n" % f for f in new]) | |
823 edittext += "".join(["HG: removed %s\n" % f for f in remove]) | |
824 edittext = self.ui.edit(edittext) | |
825 if not edittext.rstrip(): | |
826 return 1 | |
827 text = edittext | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
828 |
608
d2994b5298fb
Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents:
588
diff
changeset
|
829 user = user or self.ui.username() |
317 | 830 n = self.changelog.add(mn, new, text, tr, p1, p2, user, date) |
487 | 831 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
832 tr.close() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
833 |
229 | 834 self.dirstate.setparents(n) |
220 | 835 self.dirstate.update(new, "n") |
836 self.dirstate.forget(remove) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
837 |
660
2c83350784c3
Move commit hook after commit completes
Matt Mackall <mpm@selenic.com>
parents:
659
diff
changeset
|
838 if not self.hook("commit", node=hex(n)): |
2c83350784c3
Move commit hook after commit completes
Matt Mackall <mpm@selenic.com>
parents:
659
diff
changeset
|
839 return 1 |
2c83350784c3
Move commit hook after commit completes
Matt Mackall <mpm@selenic.com>
parents:
659
diff
changeset
|
840 |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
723
diff
changeset
|
841 def walk(self, node = None, files = [], match = util.always): |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
723
diff
changeset
|
842 if node: |
726
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
843 for fn in self.manifest.read(self.changelog.read(node)[0]): |
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
844 yield 'm', fn |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
723
diff
changeset
|
845 else: |
726
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
846 for src, fn in self.dirstate.walk(files, match): |
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
847 yield src, fn |
723 | 848 |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
723
diff
changeset
|
849 def changes(self, node1 = None, node2 = None, files = [], |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
723
diff
changeset
|
850 match = util.always): |
566 | 851 mf2, u = None, [] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
852 |
536 | 853 def fcmp(fn, mf): |
291
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
854 t1 = self.wfile(fn).read() |
29 | 855 t2 = self.file(fn).revision(mf[fn]) |
856 return cmp(t1, t2) | |
857 | |
723 | 858 def mfmatches(node): |
859 mf = dict(self.manifest.read(node)) | |
860 for fn in mf.keys(): | |
861 if not match(fn): | |
862 del mf[fn] | |
863 return mf | |
864 | |
536 | 865 # are we comparing the working directory? |
561 | 866 if not node2: |
723 | 867 l, c, a, d, u = self.dirstate.changes(files, match) |
536 | 868 |
869 # are we comparing working dir against its parent? | |
561 | 870 if not node1: |
536 | 871 if l: |
872 # do a full compare of any files that might have changed | |
873 change = self.changelog.read(self.dirstate.parents()[0]) | |
723 | 874 mf2 = mfmatches(change[0]) |
548 | 875 for f in l: |
561 | 876 if fcmp(f, mf2): |
536 | 877 c.append(f) |
561 | 878 |
879 for l in c, a, d, u: | |
880 l.sort() | |
881 | |
536 | 882 return (c, a, d, u) |
515 | 883 |
536 | 884 # are we comparing working dir against non-tip? |
885 # generate a pseudo-manifest for the working dir | |
561 | 886 if not node2: |
887 if not mf2: | |
536 | 888 change = self.changelog.read(self.dirstate.parents()[0]) |
723 | 889 mf2 = mfmatches(change[0]) |
536 | 890 for f in a + c + l: |
561 | 891 mf2[f] = "" |
536 | 892 for f in d: |
561 | 893 if f in mf2: del mf2[f] |
536 | 894 else: |
561 | 895 change = self.changelog.read(node2) |
723 | 896 mf2 = mfmatches(change[0]) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
897 |
566 | 898 # flush lists from dirstate before comparing manifests |
899 c, a = [], [] | |
900 | |
561 | 901 change = self.changelog.read(node1) |
723 | 902 mf1 = mfmatches(change[0]) |
32 | 903 |
904 for fn in mf2: | |
905 if mf1.has_key(fn): | |
906 if mf1[fn] != mf2[fn]: | |
561 | 907 if mf2[fn] != "" or fcmp(fn, mf1): |
536 | 908 c.append(fn) |
32 | 909 del mf1[fn] |
910 else: | |
536 | 911 a.append(fn) |
515 | 912 |
536 | 913 d = mf1.keys() |
561 | 914 |
915 for l in c, a, d, u: | |
916 l.sort() | |
515 | 917 |
536 | 918 return (c, a, d, u) |
32 | 919 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
920 def add(self, list): |
220 | 921 for f in list: |
244 | 922 p = self.wjoin(f) |
611
48c3eb2bf844
* clean up error handling when user requests to use a non file object
shaleh@speakeasy.net
parents:
609
diff
changeset
|
923 if not os.path.exists(p): |
659 | 924 self.ui.warn("%s does not exist!\n" % f) |
611
48c3eb2bf844
* clean up error handling when user requests to use a non file object
shaleh@speakeasy.net
parents:
609
diff
changeset
|
925 elif not os.path.isfile(p): |
48c3eb2bf844
* clean up error handling when user requests to use a non file object
shaleh@speakeasy.net
parents:
609
diff
changeset
|
926 self.ui.warn("%s not added: mercurial only supports files currently\n" % f) |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
723
diff
changeset
|
927 elif self.dirstate.state(f) in 'an': |
220 | 928 self.ui.warn("%s already tracked!\n" % f) |
929 else: | |
930 self.dirstate.update([f], "a") | |
931 | |
932 def forget(self, list): | |
933 for f in list: | |
934 if self.dirstate.state(f) not in 'ai': | |
935 self.ui.warn("%s not added!\n" % f) | |
936 else: | |
937 self.dirstate.forget([f]) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
938 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
939 def remove(self, list): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
940 for f in list: |
244 | 941 p = self.wjoin(f) |
611
48c3eb2bf844
* clean up error handling when user requests to use a non file object
shaleh@speakeasy.net
parents:
609
diff
changeset
|
942 if os.path.exists(p): |
220 | 943 self.ui.warn("%s still exists!\n" % f) |
402 | 944 elif self.dirstate.state(f) == 'a': |
945 self.ui.warn("%s never committed!\n" % f) | |
657
22bc6fb9aefc
dirstate.forget() takes a list
Matt Mackall <mpm@selenic.com>
parents:
656
diff
changeset
|
946 self.dirstate.forget([f]) |
220 | 947 elif f not in self.dirstate: |
948 self.ui.warn("%s not tracked!\n" % f) | |
949 else: | |
950 self.dirstate.update([f], "r") | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
951 |
363 | 952 def copy(self, source, dest): |
953 p = self.wjoin(dest) | |
611
48c3eb2bf844
* clean up error handling when user requests to use a non file object
shaleh@speakeasy.net
parents:
609
diff
changeset
|
954 if not os.path.exists(dest): |
363 | 955 self.ui.warn("%s does not exist!\n" % dest) |
611
48c3eb2bf844
* clean up error handling when user requests to use a non file object
shaleh@speakeasy.net
parents:
609
diff
changeset
|
956 elif not os.path.isfile(dest): |
659 | 957 self.ui.warn("copy failed: %s is not a file\n" % dest) |
363 | 958 else: |
959 if self.dirstate.state(dest) == '?': | |
960 self.dirstate.update([dest], "a") | |
961 self.dirstate.copy(source, dest) | |
962 | |
222 | 963 def heads(self): |
964 return self.changelog.heads() | |
965 | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
966 def branches(self, nodes): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
967 if not nodes: nodes = [self.changelog.tip()] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
968 b = [] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
969 for n in nodes: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
970 t = n |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
971 while n: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
972 p = self.changelog.parents(n) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
973 if p[1] != nullid or p[0] == nullid: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
974 b.append((t, n, p[0], p[1])) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
975 break |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
976 n = p[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
977 return b |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
978 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
979 def between(self, pairs): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
980 r = [] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
981 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
982 for top, bottom in pairs: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
983 n, l, i = top, [], 0 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
984 f = 1 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
985 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
986 while n != bottom: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
987 p = self.changelog.parents(n)[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
988 if i == f: |
575 | 989 l.append(n) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
990 f = f * 2 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
991 n = p |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
992 i += 1 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
993 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
994 r.append(l) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
995 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
996 return r |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
997 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
998 def newer(self, nodes): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
999 m = {} |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1000 nl = [] |
94 | 1001 pm = {} |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1002 cl = self.changelog |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1003 t = l = cl.count() |
94 | 1004 |
1005 # find the lowest numbered node | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1006 for n in nodes: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1007 l = min(l, cl.rev(n)) |
94 | 1008 m[n] = 1 |
46 | 1009 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1010 for i in xrange(l, t): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1011 n = cl.node(i) |
94 | 1012 if n in m: # explicitly listed |
1013 pm[n] = 1 | |
1014 nl.append(n) | |
1015 continue | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1016 for p in cl.parents(n): |
94 | 1017 if p in pm: # parent listed |
1018 pm[n] = 1 | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1019 nl.append(n) |
94 | 1020 break |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1021 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1022 return nl |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1023 |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1024 def findincoming(self, remote, base={}): |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1025 m = self.changelog.nodemap |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1026 search = [] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1027 fetch = [] |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
1028 seen = {} |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
1029 seenbranch = {} |
192 | 1030 |
636
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
1031 # assume we're closer to the tip than the root |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
1032 # and start by examining the heads |
222 | 1033 self.ui.status("searching for changes\n") |
1034 heads = remote.heads() | |
1035 unknown = [] | |
1036 for h in heads: | |
1037 if h not in m: | |
1038 unknown.append(h) | |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1039 else: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1040 base[h] = 1 |
46 | 1041 |
222 | 1042 if not unknown: |
60 | 1043 return None |
324 | 1044 |
1045 rep = {} | |
1046 reqcnt = 0 | |
515 | 1047 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
1048 # search through remote branches |
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
1049 # a 'branch' here is a linear segment of history, with four parts: |
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
1050 # head, root, first parent, second parent |
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
1051 # (a branch always has two parents (or none) by definition) |
222 | 1052 unknown = remote.branches(unknown) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1053 while unknown: |
324 | 1054 r = [] |
1055 while unknown: | |
1056 n = unknown.pop(0) | |
1057 if n[0] in seen: | |
1058 continue | |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
1059 |
324 | 1060 self.ui.debug("examining %s:%s\n" % (short(n[0]), short(n[1]))) |
1061 if n[0] == nullid: | |
1062 break | |
328 | 1063 if n in seenbranch: |
324 | 1064 self.ui.debug("branch already found\n") |
1065 continue | |
1066 if n[1] and n[1] in m: # do we know the base? | |
1067 self.ui.debug("found incomplete branch %s:%s\n" | |
1068 % (short(n[0]), short(n[1]))) | |
1069 search.append(n) # schedule branch range for scanning | |
328 | 1070 seenbranch[n] = 1 |
324 | 1071 else: |
1072 if n[1] not in seen and n[1] not in fetch: | |
1073 if n[2] in m and n[3] in m: | |
1074 self.ui.debug("found new changeset %s\n" % | |
1075 short(n[1])) | |
1076 fetch.append(n[1]) # earliest unknown | |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
1077 base[n[2]] = 1 # latest known |
324 | 1078 continue |
1079 | |
1080 for a in n[2:4]: | |
1081 if a not in rep: | |
1082 r.append(a) | |
1083 rep[a] = 1 | |
1084 | |
328 | 1085 seen[n[0]] = 1 |
1086 | |
324 | 1087 if r: |
1088 reqcnt += 1 | |
1089 self.ui.debug("request %d: %s\n" % | |
1090 (reqcnt, " ".join(map(short, r)))) | |
1091 for p in range(0, len(r), 10): | |
1092 for b in remote.branches(r[p:p+10]): | |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
1093 self.ui.debug("received %s:%s\n" % |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
1094 (short(b[0]), short(b[1]))) |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
1095 if b[0] not in m and b[0] not in seen: |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
1096 unknown.append(b) |
515 | 1097 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
1098 # do binary search on the branches we found |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1099 while search: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1100 n = search.pop(0) |
324 | 1101 reqcnt += 1 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1102 l = remote.between([(n[0], n[1])])[0] |
328 | 1103 l.append(n[1]) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1104 p = n[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1105 f = 1 |
328 | 1106 for i in l: |
1107 self.ui.debug("narrowing %d:%d %s\n" % (f, len(l), short(i))) | |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1108 if i in m: |
85 | 1109 if f <= 2: |
83 | 1110 self.ui.debug("found new branch changeset %s\n" % |
1111 short(p)) | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1112 fetch.append(p) |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
1113 base[i] = 1 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1114 else: |
83 | 1115 self.ui.debug("narrowed branch search to %s:%s\n" |
1116 % (short(p), short(i))) | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1117 search.append((p, i)) |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1118 break |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1119 p, f = i, f * 2 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1120 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
1121 # sanity check our fetch list |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1122 for f in fetch: |
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1123 if f in m: |
499 | 1124 raise RepoError("already have changeset " + short(f[:4])) |
83 | 1125 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
1126 if base.keys() == [nullid]: |
514
874e577e332e
change unrelated repository error to a warning
mpm@selenic.com
parents:
511
diff
changeset
|
1127 self.ui.warn("warning: pulling from an unrelated repository!\n") |
511 | 1128 |
94 | 1129 self.ui.note("adding new changesets starting at " + |
83 | 1130 " ".join([short(f) for f in fetch]) + "\n") |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1131 |
324 | 1132 self.ui.debug("%d total queries\n" % reqcnt) |
1133 | |
516 | 1134 return fetch |
1135 | |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1136 def findoutgoing(self, remote): |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1137 base = {} |
637
31e090c34d3b
Fix up the broken bits in findoutgoing
Matt Mackall <mpm@selenic.com>
parents:
636
diff
changeset
|
1138 self.findincoming(remote, base) |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1139 remain = dict.fromkeys(self.changelog.nodemap) |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1140 |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1141 # prune everything remote has from the tree |
637
31e090c34d3b
Fix up the broken bits in findoutgoing
Matt Mackall <mpm@selenic.com>
parents:
636
diff
changeset
|
1142 del remain[nullid] |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1143 remove = base.keys() |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1144 while remove: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1145 n = remove.pop(0) |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1146 if n in remain: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1147 del remain[n] |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1148 for p in self.changelog.parents(n): |
637
31e090c34d3b
Fix up the broken bits in findoutgoing
Matt Mackall <mpm@selenic.com>
parents:
636
diff
changeset
|
1149 remove.append(p) |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1150 |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1151 # find every node whose parents have been pruned |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1152 subset = [] |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1153 for n in remain: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1154 p1, p2 = self.changelog.parents(n) |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1155 if p1 not in remain and p2 not in remain: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1156 subset.append(n) |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1157 |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1158 # this is the set of all roots we have to push |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1159 return subset |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
1160 |
622
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1161 def pull(self, remote): |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1162 lock = self.lock() |
636
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
1163 |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
1164 # if we have an empty repo, fetch everything |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
1165 if self.changelog.tip() == nullid: |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
1166 self.ui.status("requesting all changes\n") |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
1167 fetch = [nullid] |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
1168 else: |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
1169 fetch = self.findincoming(remote) |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
1170 |
622
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1171 if not fetch: |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1172 self.ui.status("no changes found\n") |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1173 return 1 |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1174 |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1175 cg = remote.changegroup(fetch) |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1176 return self.addchangegroup(cg) |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1177 |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1178 def push(self, remote): |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1179 lock = remote.lock() |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1180 update = self.findoutgoing(remote) |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1181 if not update: |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1182 self.ui.status("no changes found\n") |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1183 return 1 |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1184 |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1185 cg = self.changegroup(update) |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1186 return remote.addchangegroup(cg) |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
1187 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
1188 def changegroup(self, basenodes): |
222 | 1189 class genread: |
1190 def __init__(self, generator): | |
1191 self.g = generator | |
1192 self.buf = "" | |
1193 def read(self, l): | |
1194 while l > len(self.buf): | |
1195 try: | |
1196 self.buf += self.g.next() | |
1197 except StopIteration: | |
1198 break | |
1199 d, self.buf = self.buf[:l], self.buf[l:] | |
1200 return d | |
515 | 1201 |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1202 def gengroup(): |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1203 nodes = self.newer(basenodes) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1204 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1205 # construct the link map |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1206 linkmap = {} |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1207 for n in nodes: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1208 linkmap[self.changelog.rev(n)] = n |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1209 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1210 # construct a list of all changed files |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1211 changed = {} |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1212 for n in nodes: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1213 c = self.changelog.read(n) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1214 for f in c[3]: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1215 changed[f] = 1 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1216 changed = changed.keys() |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1217 changed.sort() |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1218 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1219 # the changegroup is changesets + manifests + all file revs |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1220 revs = [ self.changelog.rev(n) for n in nodes ] |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1221 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1222 for y in self.changelog.group(linkmap): yield y |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1223 for y in self.manifest.group(linkmap): yield y |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1224 for f in changed: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1225 yield struct.pack(">l", len(f) + 4) + f |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1226 g = self.file(f).group(linkmap) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1227 for y in g: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1228 yield y |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1229 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1230 yield struct.pack(">l", 0) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1231 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1232 return genread(gengroup()) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1233 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1234 def addchangegroup(self, source): |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1235 |
222 | 1236 def getchunk(): |
1237 d = source.read(4) | |
1238 if not d: return "" | |
1239 l = struct.unpack(">l", d)[0] | |
1240 if l <= 4: return "" | |
1241 return source.read(l - 4) | |
1242 | |
1243 def getgroup(): | |
1244 while 1: | |
1245 c = getchunk() | |
1246 if not c: break | |
1247 yield c | |
1248 | |
1249 def csmap(x): | |
1250 self.ui.debug("add changeset %s\n" % short(x)) | |
1251 return self.changelog.count() | |
1252 | |
1253 def revmap(x): | |
1254 return self.changelog.rev(x) | |
1255 | |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1256 if not source: return |
222 | 1257 changesets = files = revisions = 0 |
225 | 1258 |
222 | 1259 tr = self.transaction() |
1260 | |
1261 # pull off the changeset group | |
1262 self.ui.status("adding changesets\n") | |
1263 co = self.changelog.tip() | |
224
ccbcc4d76f81
fix bad assumption about uniqueness of file versions
mpm@selenic.com
parents:
223
diff
changeset
|
1264 cn = self.changelog.addgroup(getgroup(), csmap, tr, 1) # unique |
222 | 1265 changesets = self.changelog.rev(cn) - self.changelog.rev(co) |
1266 | |
1267 # pull off the manifest group | |
1268 self.ui.status("adding manifests\n") | |
1269 mm = self.manifest.tip() | |
1270 mo = self.manifest.addgroup(getgroup(), revmap, tr) | |
1271 | |
1272 # process the files | |
1273 self.ui.status("adding file revisions\n") | |
1274 while 1: | |
1275 f = getchunk() | |
1276 if not f: break | |
1277 self.ui.debug("adding %s revisions\n" % f) | |
1278 fl = self.file(f) | |
529
aace5b681fe9
Attempt to fix negative revision count from pull
mpm@selenic.com
parents:
522
diff
changeset
|
1279 o = fl.count() |
222 | 1280 n = fl.addgroup(getgroup(), revmap, tr) |
529
aace5b681fe9
Attempt to fix negative revision count from pull
mpm@selenic.com
parents:
522
diff
changeset
|
1281 revisions += fl.count() - o |
222 | 1282 files += 1 |
1283 | |
1284 self.ui.status(("modified %d files, added %d changesets" + | |
1285 " and %d new revisions\n") | |
1286 % (files, changesets, revisions)) | |
1287 | |
1288 tr.close() | |
1289 return | |
1290 | |
588 | 1291 def update(self, node, allow=False, force=False, choose=None, |
1292 moddirstate=True): | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1293 pl = self.dirstate.parents() |
275 | 1294 if not force and pl[1] != nullid: |
254 | 1295 self.ui.warn("aborting: outstanding uncommitted merges\n") |
690 | 1296 return 1 |
46 | 1297 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1298 p1, p2 = pl[0], node |
305 | 1299 pa = self.changelog.ancestor(p1, p2) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1300 m1n = self.changelog.read(p1)[0] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1301 m2n = self.changelog.read(p2)[0] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1302 man = self.manifest.ancestor(m1n, m2n) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1303 m1 = self.manifest.read(m1n) |
276 | 1304 mf1 = self.manifest.readflags(m1n) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1305 m2 = self.manifest.read(m2n) |
276 | 1306 mf2 = self.manifest.readflags(m2n) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1307 ma = self.manifest.read(man) |
412 | 1308 mfa = self.manifest.readflags(man) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1309 |
723 | 1310 (c, a, d, u) = self.changes() |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1311 |
408
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1312 # is this a jump, or a merge? i.e. is there a linear path |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1313 # from p1 to p2? |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1314 linear_path = (pa == p1 or pa == p2) |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1315 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1316 # resolve the manifest to determine which files |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1317 # we care about merging |
254 | 1318 self.ui.note("resolving manifests\n") |
650
2c934c7b79dc
Fix bug in reverting deleted files
Matt Mackall <mpm@selenic.com>
parents:
649
diff
changeset
|
1319 self.ui.debug(" force %s allow %s moddirstate %s linear %s\n" % |
2c934c7b79dc
Fix bug in reverting deleted files
Matt Mackall <mpm@selenic.com>
parents:
649
diff
changeset
|
1320 (force, allow, moddirstate, linear_path)) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1321 self.ui.debug(" ancestor %s local %s remote %s\n" % |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1322 (short(man), short(m1n), short(m2n))) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1323 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1324 merge = {} |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1325 get = {} |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1326 remove = [] |
305 | 1327 mark = {} |
46 | 1328 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1329 # construct a working dir manifest |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1330 mw = m1.copy() |
276 | 1331 mfw = mf1.copy() |
576 | 1332 umap = dict.fromkeys(u) |
1333 | |
254 | 1334 for f in a + c + u: |
1335 mw[f] = "" | |
441 | 1336 mfw[f] = util.is_exec(self.wjoin(f), mfw.get(f, False)) |
576 | 1337 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1338 for f in d: |
254 | 1339 if f in mw: del mw[f] |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1340 |
408
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1341 # If we're jumping between revisions (as opposed to merging), |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1342 # and if neither the working directory nor the target rev has |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1343 # the file, then we need to remove it from the dirstate, to |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1344 # prevent the dirstate from listing the file when it is no |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1345 # longer in the manifest. |
588 | 1346 if moddirstate and linear_path and f not in m2: |
408
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1347 self.dirstate.forget((f,)) |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1348 |
576 | 1349 # Compare manifests |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1350 for f, n in mw.iteritems(): |
588 | 1351 if choose and not choose(f): continue |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1352 if f in m2: |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1353 s = 0 |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1354 |
407
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1355 # is the wfile new since m1, and match m2? |
428 | 1356 if f not in m1: |
407
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1357 t1 = self.wfile(f).read() |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1358 t2 = self.file(f).revision(m2[f]) |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1359 if cmp(t1, t2) == 0: |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1360 mark[f] = 1 |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1361 n = m2[f] |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1362 del t1, t2 |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1363 |
296
a3d83bf86755
hg update: fix clobbering files when going backwards
mpm@selenic.com
parents:
292
diff
changeset
|
1364 # are files different? |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1365 if n != m2[f]: |
254 | 1366 a = ma.get(f, nullid) |
296
a3d83bf86755
hg update: fix clobbering files when going backwards
mpm@selenic.com
parents:
292
diff
changeset
|
1367 # are both different from the ancestor? |
254 | 1368 if n != a and m2[f] != a: |
273
4f8174389001
merge: Fix bug where we overwrote local when local was newer
mpm@selenic.com
parents:
263
diff
changeset
|
1369 self.ui.debug(" %s versions differ, resolve\n" % f) |
276 | 1370 # merge executable bits |
1371 # "if we changed or they changed, change in merge" | |
1372 a, b, c = mfa.get(f, 0), mfw[f], mf2[f] | |
1373 mode = ((a^b) | (a^c)) ^ a | |
1374 merge[f] = (m1.get(f, nullid), m2[f], mode) | |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1375 s = 1 |
305 | 1376 # are we clobbering? |
1377 # is remote's version newer? | |
1378 # or are we going back in time? | |
1379 elif force or m2[f] != a or (p2 == pa and mw[f] == m1[f]): | |
273
4f8174389001
merge: Fix bug where we overwrote local when local was newer
mpm@selenic.com
parents:
263
diff
changeset
|
1380 self.ui.debug(" remote %s is newer, get\n" % f) |
254 | 1381 get[f] = m2[f] |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1382 s = 1 |
305 | 1383 else: |
1384 mark[f] = 1 | |
576 | 1385 elif f in umap: |
1386 # this unknown file is the same as the checkout | |
1387 get[f] = m2[f] | |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1388 |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1389 if not s and mfw[f] != mf2[f]: |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1390 if force: |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1391 self.ui.debug(" updating permissions for %s\n" % f) |
441 | 1392 util.set_exec(self.wjoin(f), mf2[f]) |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1393 else: |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1394 a, b, c = mfa.get(f, 0), mfw[f], mf2[f] |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1395 mode = ((a^b) | (a^c)) ^ a |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1396 if mode != b: |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1397 self.ui.debug(" updating permissions for %s\n" % f) |
441 | 1398 util.set_exec(self.wjoin(f), mode) |
305 | 1399 mark[f] = 1 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1400 del m2[f] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1401 elif f in ma: |
616 | 1402 if n != ma[f]: |
1403 r = "d" | |
1404 if not force and (linear_path or allow): | |
415
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1405 r = self.ui.prompt( |
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1406 (" local changed %s which remote deleted\n" % f) + |
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1407 "(k)eep or (d)elete?", "[kd]", "k") |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1408 if r == "d": |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1409 remove.append(f) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1410 else: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1411 self.ui.debug("other deleted %s\n" % f) |
254 | 1412 remove.append(f) # other deleted it |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1413 else: |
254 | 1414 if n == m1.get(f, nullid): # same as parent |
383
4862a134e2c2
hg merge: fix time asymmetry bug with deleting files on update to past
mpm@selenic.com
parents:
377
diff
changeset
|
1415 if p2 == pa: # going backwards? |
4862a134e2c2
hg merge: fix time asymmetry bug with deleting files on update to past
mpm@selenic.com
parents:
377
diff
changeset
|
1416 self.ui.debug("remote deleted %s\n" % f) |
4862a134e2c2
hg merge: fix time asymmetry bug with deleting files on update to past
mpm@selenic.com
parents:
377
diff
changeset
|
1417 remove.append(f) |
4862a134e2c2
hg merge: fix time asymmetry bug with deleting files on update to past
mpm@selenic.com
parents:
377
diff
changeset
|
1418 else: |
4862a134e2c2
hg merge: fix time asymmetry bug with deleting files on update to past
mpm@selenic.com
parents:
377
diff
changeset
|
1419 self.ui.debug("local created %s, keeping\n" % f) |
254 | 1420 else: |
1421 self.ui.debug("working dir created %s, keeping\n" % f) | |
46 | 1422 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1423 for f, n in m2.iteritems(): |
588 | 1424 if choose and not choose(f): continue |
256 | 1425 if f[0] == "/": continue |
616 | 1426 if f in ma and n != ma[f]: |
1427 r = "k" | |
1428 if not force and (linear_path or allow): | |
415
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1429 r = self.ui.prompt( |
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1430 ("remote changed %s which local deleted\n" % f) + |
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1431 "(k)eep or (d)elete?", "[kd]", "k") |
616 | 1432 if r == "k": get[f] = n |
1433 elif f not in ma: | |
254 | 1434 self.ui.debug("remote created %s\n" % f) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1435 get[f] = n |
616 | 1436 else: |
680
4b7b79d2db2c
Handle undeletion of files when checking out old revisions
Matt Mackall <mpm@selenic.com>
parents:
679
diff
changeset
|
1437 if force or p2 == pa: # going backwards? |
4b7b79d2db2c
Handle undeletion of files when checking out old revisions
Matt Mackall <mpm@selenic.com>
parents:
679
diff
changeset
|
1438 self.ui.debug("local deleted %s, recreating\n" % f) |
650
2c934c7b79dc
Fix bug in reverting deleted files
Matt Mackall <mpm@selenic.com>
parents:
649
diff
changeset
|
1439 get[f] = n |
680
4b7b79d2db2c
Handle undeletion of files when checking out old revisions
Matt Mackall <mpm@selenic.com>
parents:
679
diff
changeset
|
1440 else: |
4b7b79d2db2c
Handle undeletion of files when checking out old revisions
Matt Mackall <mpm@selenic.com>
parents:
679
diff
changeset
|
1441 self.ui.debug("local deleted %s\n" % f) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1442 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1443 del mw, m1, m2, ma |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1444 |
275 | 1445 if force: |
1446 for f in merge: | |
1447 get[f] = merge[f][1] | |
1448 merge = {} | |
1449 | |
690 | 1450 if linear_path or force: |
254 | 1451 # we don't need to do any magic, just jump to the new rev |
1452 mode = 'n' | |
1453 p1, p2 = p2, nullid | |
1454 else: | |
275 | 1455 if not allow: |
305 | 1456 self.ui.status("this update spans a branch" + |
1457 " affecting the following files:\n") | |
1458 fl = merge.keys() + get.keys() | |
1459 fl.sort() | |
1460 for f in fl: | |
1461 cf = "" | |
1462 if f in merge: cf = " (resolve)" | |
1463 self.ui.status(" %s%s\n" % (f, cf)) | |
1464 self.ui.warn("aborting update spanning branches!\n") | |
1465 self.ui.status("(use update -m to perform a branch merge)\n") | |
275 | 1466 return 1 |
254 | 1467 # we have to remember what files we needed to get/change |
1468 # because any file that's different from either one of its | |
1469 # parents must be in the changeset | |
1470 mode = 'm' | |
588 | 1471 if moddirstate: |
1472 self.dirstate.update(mark.keys(), "m") | |
254 | 1473 |
588 | 1474 if moddirstate: |
1475 self.dirstate.setparents(p1, p2) | |
191
d7e859cf2f1b
merge: add count of new manifests, files, and revisions
mpm@selenic.com
parents:
190
diff
changeset
|
1476 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1477 # get the files we don't need to change |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1478 files = get.keys() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1479 files.sort() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1480 for f in files: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1481 if f[0] == "/": continue |
273
4f8174389001
merge: Fix bug where we overwrote local when local was newer
mpm@selenic.com
parents:
263
diff
changeset
|
1482 self.ui.note("getting %s\n" % f) |
276 | 1483 t = self.file(f).read(get[f]) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1484 try: |
291
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
1485 self.wfile(f, "w").write(t) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1486 except IOError: |
297
0dbcf3c9ff20
Fixed usage of removed variable 'wp'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
292
diff
changeset
|
1487 os.makedirs(os.path.dirname(self.wjoin(f))) |
291
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
1488 self.wfile(f, "w").write(t) |
441 | 1489 util.set_exec(self.wjoin(f), mf2[f]) |
588 | 1490 if moddirstate: |
1491 self.dirstate.update([f], mode) | |
46 | 1492 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1493 # merge the tricky bits |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1494 files = merge.keys() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1495 files.sort() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1496 for f in files: |
256 | 1497 self.ui.status("merging %s\n" % f) |
276 | 1498 m, o, flag = merge[f] |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1499 self.merge3(f, m, o) |
441 | 1500 util.set_exec(self.wjoin(f), flag) |
588 | 1501 if moddirstate: |
1502 self.dirstate.update([f], 'm') | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1503 |
681 | 1504 remove.sort() |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1505 for f in remove: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1506 self.ui.note("removing %s\n" % f) |
690 | 1507 try: |
1508 os.unlink(f) | |
1509 except OSError, inst: | |
1510 self.ui.warn("update failed to remove %s: %s!\n" % (f, inst)) | |
578 | 1511 # try removing directories that might now be empty |
1512 try: os.removedirs(os.path.dirname(f)) | |
1513 except: pass | |
588 | 1514 if moddirstate: |
1515 if mode == 'n': | |
1516 self.dirstate.forget(remove) | |
1517 else: | |
1518 self.dirstate.update(remove, 'r') | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1519 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1520 def merge3(self, fn, my, other): |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1521 """perform a 3-way merge in the working directory""" |
249 | 1522 |
96 | 1523 def temp(prefix, node): |
1524 pre = "%s~%s." % (os.path.basename(fn), prefix) | |
1525 (fd, name) = tempfile.mkstemp("", pre) | |
417 | 1526 f = os.fdopen(fd, "wb") |
96 | 1527 f.write(fl.revision(node)) |
1528 f.close() | |
1529 return name | |
1530 | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1531 fl = self.file(fn) |
96 | 1532 base = fl.ancestor(my, other) |
244 | 1533 a = self.wjoin(fn) |
346 | 1534 b = temp("base", base) |
1535 c = temp("other", other) | |
96 | 1536 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1537 self.ui.note("resolving %s\n" % fn) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1538 self.ui.debug("file %s: other %s ancestor %s\n" % |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1539 (fn, short(other), short(base))) |
96 | 1540 |
703
fb6f85ecc863
merge program setting from hgrc wasn't used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
691
diff
changeset
|
1541 cmd = (os.environ.get("HGMERGE") or self.ui.config("ui", "merge") |
fb6f85ecc863
merge program setting from hgrc wasn't used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
691
diff
changeset
|
1542 or "hgmerge") |
240 | 1543 r = os.system("%s %s %s %s" % (cmd, a, b, c)) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1544 if r: |
275 | 1545 self.ui.warn("merging %s failed!\n" % fn) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1546 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1547 os.unlink(b) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1548 os.unlink(c) |
96 | 1549 |
247 | 1550 def verify(self): |
1551 filelinkrevs = {} | |
1552 filenodes = {} | |
1553 changesets = revisions = files = 0 | |
1554 errors = 0 | |
1555 | |
302 | 1556 seen = {} |
247 | 1557 self.ui.status("checking changesets\n") |
1558 for i in range(self.changelog.count()): | |
1559 changesets += 1 | |
1560 n = self.changelog.node(i) | |
302 | 1561 if n in seen: |
1562 self.ui.warn("duplicate changeset at revision %d\n" % i) | |
1563 errors += 1 | |
1564 seen[n] = 1 | |
515 | 1565 |
247 | 1566 for p in self.changelog.parents(n): |
1567 if p not in self.changelog.nodemap: | |
1568 self.ui.warn("changeset %s has unknown parent %s\n" % | |
1569 (short(n), short(p))) | |
1570 errors += 1 | |
1571 try: | |
1572 changes = self.changelog.read(n) | |
1573 except Exception, inst: | |
1574 self.ui.warn("unpacking changeset %s: %s\n" % (short(n), inst)) | |
1575 errors += 1 | |
1576 | |
1577 for f in changes[3]: | |
1578 filelinkrevs.setdefault(f, []).append(i) | |
1579 | |
302 | 1580 seen = {} |
247 | 1581 self.ui.status("checking manifests\n") |
1582 for i in range(self.manifest.count()): | |
1583 n = self.manifest.node(i) | |
302 | 1584 if n in seen: |
1585 self.ui.warn("duplicate manifest at revision %d\n" % i) | |
1586 errors += 1 | |
1587 seen[n] = 1 | |
515 | 1588 |
247 | 1589 for p in self.manifest.parents(n): |
1590 if p not in self.manifest.nodemap: | |
1591 self.ui.warn("manifest %s has unknown parent %s\n" % | |
1592 (short(n), short(p))) | |
1593 errors += 1 | |
1594 | |
1595 try: | |
1596 delta = mdiff.patchtext(self.manifest.delta(n)) | |
1597 except KeyboardInterrupt: | |
582 | 1598 self.ui.warn("aborted") |
247 | 1599 sys.exit(0) |
1600 except Exception, inst: | |
1601 self.ui.warn("unpacking manifest %s: %s\n" | |
1602 % (short(n), inst)) | |
1603 errors += 1 | |
1604 | |
1605 ff = [ l.split('\0') for l in delta.splitlines() ] | |
1606 for f, fn in ff: | |
284 | 1607 filenodes.setdefault(f, {})[bin(fn[:40])] = 1 |
247 | 1608 |
1609 self.ui.status("crosschecking files in changesets and manifests\n") | |
1610 for f in filenodes: | |
1611 if f not in filelinkrevs: | |
1612 self.ui.warn("file %s in manifest but not in changesets\n" % f) | |
1613 errors += 1 | |
1614 | |
1615 for f in filelinkrevs: | |
1616 if f not in filenodes: | |
1617 self.ui.warn("file %s in changeset but not in manifest\n" % f) | |
1618 errors += 1 | |
1619 | |
1620 self.ui.status("checking files\n") | |
1621 ff = filenodes.keys() | |
1622 ff.sort() | |
1623 for f in ff: | |
1624 if f == "/dev/null": continue | |
1625 files += 1 | |
1626 fl = self.file(f) | |
1627 nodes = { nullid: 1 } | |
302 | 1628 seen = {} |
247 | 1629 for i in range(fl.count()): |
1630 revisions += 1 | |
1631 n = fl.node(i) | |
1632 | |
302 | 1633 if n in seen: |
1634 self.ui.warn("%s: duplicate revision %d\n" % (f, i)) | |
1635 errors += 1 | |
1636 | |
247 | 1637 if n not in filenodes[f]: |
1638 self.ui.warn("%s: %d:%s not in manifests\n" | |
1639 % (f, i, short(n))) | |
1640 errors += 1 | |
1641 else: | |
1642 del filenodes[f][n] | |
1643 | |
1644 flr = fl.linkrev(n) | |
1645 if flr not in filelinkrevs[f]: | |
1646 self.ui.warn("%s:%s points to unexpected changeset %d\n" | |
1647 % (f, short(n), fl.linkrev(n))) | |
1648 errors += 1 | |
1649 else: | |
1650 filelinkrevs[f].remove(flr) | |
1651 | |
1652 # verify contents | |
1653 try: | |
1654 t = fl.read(n) | |
1655 except Exception, inst: | |
1656 self.ui.warn("unpacking file %s %s: %s\n" | |
1657 % (f, short(n), inst)) | |
1658 errors += 1 | |
1659 | |
1660 # verify parents | |
1661 (p1, p2) = fl.parents(n) | |
1662 if p1 not in nodes: | |
1663 self.ui.warn("file %s:%s unknown parent 1 %s" % | |
1664 (f, short(n), short(p1))) | |
1665 errors += 1 | |
1666 if p2 not in nodes: | |
1667 self.ui.warn("file %s:%s unknown parent 2 %s" % | |
1668 (f, short(n), short(p1))) | |
1669 errors += 1 | |
1670 nodes[n] = 1 | |
1671 | |
1672 # cross-check | |
1673 for node in filenodes[f]: | |
1674 self.ui.warn("node %s in manifests not in %s\n" | |
1675 % (hex(n), f)) | |
1676 errors += 1 | |
1677 | |
1678 self.ui.status("%d files, %d changesets, %d total revisions\n" % | |
1679 (files, changesets, revisions)) | |
1680 | |
1681 if errors: | |
1682 self.ui.warn("%d integrity errors encountered!\n" % errors) | |
1683 return 1 | |
1684 | |
623
314867960a4a
Change remote repository to httprepository
Matt Mackall <mpm@selenic.com>
parents:
622
diff
changeset
|
1685 class httprepository: |
60 | 1686 def __init__(self, ui, path): |
176
1d8e9637a0a4
Change hg: protocol name to http: and http: to old-http:
mpm@selenic.com
parents:
171
diff
changeset
|
1687 self.url = path |
60 | 1688 self.ui = ui |
321 | 1689 no_list = [ "localhost", "127.0.0.1" ] |
1690 host = ui.config("http_proxy", "host") | |
424
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1691 if host is None: |
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1692 host = os.environ.get("http_proxy") |
426
8c90ab5644c9
Allow hgrc's proxy host and $http_proxy env var to start with http://
Thomas Arendsen Hein <thomas@intevation.de>
parents:
424
diff
changeset
|
1693 if host and host.startswith('http://'): |
8c90ab5644c9
Allow hgrc's proxy host and $http_proxy env var to start with http://
Thomas Arendsen Hein <thomas@intevation.de>
parents:
424
diff
changeset
|
1694 host = host[7:] |
321 | 1695 user = ui.config("http_proxy", "user") |
1696 passwd = ui.config("http_proxy", "passwd") | |
1697 no = ui.config("http_proxy", "no") | |
424
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1698 if no is None: |
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1699 no = os.environ.get("no_proxy") |
321 | 1700 if no: |
1701 no_list = no_list + no.split(",") | |
515 | 1702 |
321 | 1703 no_proxy = 0 |
1704 for h in no_list: | |
1705 if (path.startswith("http://" + h + "/") or | |
1706 path.startswith("http://" + h + ":") or | |
1707 path == "http://" + h): | |
1708 no_proxy = 1 | |
1709 | |
1710 # Note: urllib2 takes proxy values from the environment and those will | |
1711 # take precedence | |
424
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1712 for env in ["HTTP_PROXY", "http_proxy", "no_proxy"]: |
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1713 if os.environ.has_key(env): |
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1714 del os.environ[env] |
321 | 1715 |
1716 proxy_handler = urllib2.BaseHandler() | |
1717 if host and not no_proxy: | |
1718 proxy_handler = urllib2.ProxyHandler({"http" : "http://" + host}) | |
1719 | |
1720 authinfo = None | |
1721 if user and passwd: | |
1722 passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm() | |
1723 passmgr.add_password(None, host, user, passwd) | |
1724 authinfo = urllib2.ProxyBasicAuthHandler(passmgr) | |
1725 | |
1726 opener = urllib2.build_opener(proxy_handler, authinfo) | |
1727 urllib2.install_opener(opener) | |
60 | 1728 |
634
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
1729 def dev(self): |
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
1730 return -1 |
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
1731 |
60 | 1732 def do_cmd(self, cmd, **args): |
83 | 1733 self.ui.debug("sending %s command\n" % cmd) |
60 | 1734 q = {"cmd": cmd} |
1735 q.update(args) | |
1736 qs = urllib.urlencode(q) | |
1737 cu = "%s?%s" % (self.url, qs) | |
321 | 1738 return urllib2.urlopen(cu) |
60 | 1739 |
222 | 1740 def heads(self): |
1741 d = self.do_cmd("heads").read() | |
1742 try: | |
1743 return map(bin, d[:-1].split(" ")) | |
1744 except: | |
1745 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |
1746 raise | |
1747 | |
60 | 1748 def branches(self, nodes): |
1749 n = " ".join(map(hex, nodes)) | |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1750 d = self.do_cmd("branches", nodes=n).read() |
217 | 1751 try: |
1752 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ] | |
1753 return br | |
1754 except: | |
1755 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |
1756 raise | |
60 | 1757 |
1758 def between(self, pairs): | |
1759 n = "\n".join(["-".join(map(hex, p)) for p in pairs]) | |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1760 d = self.do_cmd("between", pairs=n).read() |
217 | 1761 try: |
1762 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ] | |
1763 return p | |
1764 except: | |
1765 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |
1766 raise | |
60 | 1767 |
1768 def changegroup(self, nodes): | |
1769 n = " ".join(map(hex, nodes)) | |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1770 f = self.do_cmd("changegroup", roots=n) |
192 | 1771 bytes = 0 |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1772 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1773 class zread: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1774 def __init__(self, f): |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1775 self.zd = zlib.decompressobj() |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1776 self.f = f |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1777 self.buf = "" |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1778 def read(self, l): |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1779 while l > len(self.buf): |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1780 r = f.read(4096) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1781 if r: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1782 self.buf += self.zd.decompress(r) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1783 else: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1784 self.buf += self.zd.flush() |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1785 break |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1786 d, self.buf = self.buf[:l], self.buf[l:] |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1787 return d |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1788 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1789 return zread(f) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1790 |
638
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1791 class remotelock: |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1792 def __init__(self, repo): |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1793 self.repo = repo |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1794 def release(self): |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1795 self.repo.unlock() |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1796 self.repo = None |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1797 def __del__(self): |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1798 if self.repo: |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1799 self.release() |
60 | 1800 |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1801 class sshrepository: |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1802 def __init__(self, ui, path): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1803 self.url = path |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1804 self.ui = ui |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1805 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1806 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', path) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1807 if not m: |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1808 raise RepoError("couldn't parse destination %s\n" % path) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1809 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1810 self.user = m.group(2) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1811 self.host = m.group(3) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1812 self.port = m.group(5) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1813 self.path = m.group(7) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1814 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1815 args = self.user and ("%s@%s" % (self.user, self.host)) or self.host |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1816 args = self.port and ("%s -p %s") % (args, self.port) or args |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1817 path = self.path or "" |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1818 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1819 cmd = "ssh %s 'hg -R %s serve --stdio'" |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1820 cmd = cmd % (args, path) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1821 |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1822 self.pipeo, self.pipei, self.pipee = os.popen3(cmd) |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1823 |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1824 def readerr(self): |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1825 while 1: |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1826 r,w,x = select.select([self.pipee], [], [], 0) |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1827 if not r: break |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1828 l = self.pipee.readline() |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1829 if not l: break |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1830 self.ui.status("remote: ", l) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1831 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1832 def __del__(self): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1833 self.pipeo.close() |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1834 self.pipei.close() |
648
8c89408a7154
Attempt to read all remaining remote output at close
Matt Mackall <mpm@selenic.com>
parents:
646
diff
changeset
|
1835 for l in self.pipee: |
8c89408a7154
Attempt to read all remaining remote output at close
Matt Mackall <mpm@selenic.com>
parents:
646
diff
changeset
|
1836 self.ui.status("remote: ", l) |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1837 self.pipee.close() |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1838 |
634
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
1839 def dev(self): |
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
1840 return -1 |
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
1841 |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1842 def do_cmd(self, cmd, **args): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1843 self.ui.debug("sending %s command\n" % cmd) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1844 self.pipeo.write("%s\n" % cmd) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1845 for k, v in args.items(): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1846 self.pipeo.write("%s %d\n" % (k, len(v))) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1847 self.pipeo.write(v) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1848 self.pipeo.flush() |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1849 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1850 return self.pipei |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1851 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1852 def call(self, cmd, **args): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1853 r = self.do_cmd(cmd, **args) |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1854 l = r.readline() |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1855 self.readerr() |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1856 try: |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1857 l = int(l) |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1858 except: |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1859 raise RepoError("unexpected response '%s'" % l) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1860 return r.read(l) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1861 |
638
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1862 def lock(self): |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1863 self.call("lock") |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1864 return remotelock(self) |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1865 |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1866 def unlock(self): |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1867 self.call("unlock") |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
1868 |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1869 def heads(self): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1870 d = self.call("heads") |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1871 try: |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1872 return map(bin, d[:-1].split(" ")) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1873 except: |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1874 raise RepoError("unexpected response '%s'" % (d[:400] + "...")) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1875 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1876 def branches(self, nodes): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1877 n = " ".join(map(hex, nodes)) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1878 d = self.call("branches", nodes=n) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1879 try: |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1880 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ] |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1881 return br |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1882 except: |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1883 raise RepoError("unexpected response '%s'" % (d[:400] + "...")) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1884 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1885 def between(self, pairs): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1886 n = "\n".join(["-".join(map(hex, p)) for p in pairs]) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1887 d = self.call("between", pairs=n) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1888 try: |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1889 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ] |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1890 return p |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1891 except: |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1892 raise RepoError("unexpected response '%s'" % (d[:400] + "...")) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1893 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1894 def changegroup(self, nodes): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1895 n = " ".join(map(hex, nodes)) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1896 f = self.do_cmd("changegroup", roots=n) |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1897 return self.pipei |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1898 |
639
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1899 def addchangegroup(self, cg): |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1900 d = self.call("addchangegroup") |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1901 if d: |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1902 raise RepoError("push refused: %s", d) |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1903 |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1904 while 1: |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1905 d = cg.read(4096) |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1906 if not d: break |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1907 self.pipeo.write(d) |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1908 self.readerr() |
639
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1909 |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1910 self.pipeo.flush() |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1911 |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1912 self.readerr() |
639
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1913 l = int(self.pipei.readline()) |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
1914 return self.pipei.read(l) != "" |
639
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
1915 |
60 | 1916 def repository(ui, path=None, create=0): |
623
314867960a4a
Change remote repository to httprepository
Matt Mackall <mpm@selenic.com>
parents:
622
diff
changeset
|
1917 if path: |
314867960a4a
Change remote repository to httprepository
Matt Mackall <mpm@selenic.com>
parents:
622
diff
changeset
|
1918 if path.startswith("http://"): |
314867960a4a
Change remote repository to httprepository
Matt Mackall <mpm@selenic.com>
parents:
622
diff
changeset
|
1919 return httprepository(ui, path) |
314867960a4a
Change remote repository to httprepository
Matt Mackall <mpm@selenic.com>
parents:
622
diff
changeset
|
1920 if path.startswith("hg://"): |
314867960a4a
Change remote repository to httprepository
Matt Mackall <mpm@selenic.com>
parents:
622
diff
changeset
|
1921 return httprepository(ui, path.replace("hg://", "http://")) |
314867960a4a
Change remote repository to httprepository
Matt Mackall <mpm@selenic.com>
parents:
622
diff
changeset
|
1922 if path.startswith("old-http://"): |
314867960a4a
Change remote repository to httprepository
Matt Mackall <mpm@selenic.com>
parents:
622
diff
changeset
|
1923 return localrepository(ui, path.replace("old-http://", "http://")) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1924 if path.startswith("ssh://"): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
1925 return sshrepository(ui, path) |
60 | 1926 |
623
314867960a4a
Change remote repository to httprepository
Matt Mackall <mpm@selenic.com>
parents:
622
diff
changeset
|
1927 return localrepository(ui, path, create) |