Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/hg.py @ 276:10e325db7347
add tracking of execute permissions
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
add tracking of execute permissions
Changes to executable permissions are now tracked. We only track one
bit here as the others tends to be problematic. "hg manifest" now
shows file permissions.
manifest hash: b76b85d12a9550fdc9fbc4f9446a812f3a2bbe88
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCpzYBywK+sNU5EO8RAgkMAJ48l2ac12E20EFS24/i8ScwOtG4HwCgkbaE
ue6l1RJroqzNA7vNeqwCwK4=
=sEmJ
-----END PGP SIGNATURE-----
author | mpm@selenic.com |
---|---|
date | Wed, 08 Jun 2005 10:16:33 -0800 |
parents | 61d45b0ba8fb |
children | 79279550c8ff |
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 |
262 | 9 from revlog import * |
10 from demandload import * | |
11 demandload(globals(), "re lock urllib urllib2 transaction time socket") | |
12 demandload(globals(), "tempfile byterange difflib") | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
13 |
276 | 14 def is_exec(f): |
15 return (os.stat(f).st_mode & 0100 != 0) | |
16 | |
17 def set_exec(f, mode): | |
18 s = os.stat(f).st_mode | |
19 if (s & 0100 != 0) == mode: | |
20 return | |
21 os.chmod(f, s & 0666 | (mode * 0111)) | |
22 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
23 class filelog(revlog): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
24 def __init__(self, opener, path): |
144
ea9188538222
Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents:
140
diff
changeset
|
25 revlog.__init__(self, opener, |
ea9188538222
Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents:
140
diff
changeset
|
26 os.path.join("data", path + ".i"), |
ea9188538222
Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents:
140
diff
changeset
|
27 os.path.join("data", path + ".d")) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
28 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
29 def read(self, node): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
30 return self.revision(node) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
31 def add(self, text, transaction, link, p1=None, p2=None): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
32 return self.addrevision(text, transaction, link, p1, p2) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
33 |
79 | 34 def annotate(self, node): |
199 | 35 |
36 def decorate(text, rev): | |
37 return [(rev, l) for l in text.splitlines(1)] | |
38 | |
39 def strip(annotation): | |
40 return [e[1] for e in annotation] | |
41 | |
42 def pair(parent, child): | |
109
95699294f580
Annotate was being too clever trying to work in place, and triggering
mpm@selenic.com
parents:
107
diff
changeset
|
43 new = [] |
262 | 44 sm = difflib.SequenceMatcher(None, strip(parent), strip(child)) |
79 | 45 for o, m, n, s, t in sm.get_opcodes(): |
109
95699294f580
Annotate was being too clever trying to work in place, and triggering
mpm@selenic.com
parents:
107
diff
changeset
|
46 if o == 'equal': |
199 | 47 new += parent[m:n] |
109
95699294f580
Annotate was being too clever trying to work in place, and triggering
mpm@selenic.com
parents:
107
diff
changeset
|
48 else: |
199 | 49 new += child[s:t] |
50 return new | |
51 | |
200 | 52 # find all ancestors |
216
201115f2859b
hg annotate: actually annotate the given version
mpm@selenic.com
parents:
210
diff
changeset
|
53 needed = {node:1} |
199 | 54 visit = [node] |
55 while visit: | |
56 n = visit.pop(0) | |
57 for p in self.parents(n): | |
58 if p not in needed: | |
59 needed[p] = 1 | |
60 visit.append(p) | |
200 | 61 else: |
62 # count how many times we'll use this | |
63 needed[p] += 1 | |
199 | 64 |
200 | 65 # sort by revision which is a topological order |
199 | 66 visit = needed.keys() |
67 visit = [ (self.rev(n), n) for n in visit ] | |
68 visit.sort() | |
69 visit = [ p[1] for p in visit ] | |
70 hist = {} | |
71 | |
72 for n in visit: | |
73 curr = decorate(self.read(n), self.linkrev(n)) | |
74 for p in self.parents(n): | |
75 if p != nullid: | |
76 curr = pair(hist[p], curr) | |
200 | 77 # trim the history of unneeded revs |
78 needed[p] -= 1 | |
79 if not needed[p]: | |
80 del hist[p] | |
199 | 81 hist[n] = curr |
82 | |
83 return hist[n] | |
79 | 84 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
85 class manifest(revlog): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
86 def __init__(self, opener): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
87 self.mapcache = None |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
88 self.listcache = None |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
89 self.addlist = None |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
90 revlog.__init__(self, opener, "00manifest.i", "00manifest.d") |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
91 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
92 def read(self, node): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
93 if self.mapcache and self.mapcache[0] == node: |
90 | 94 return self.mapcache[1].copy() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
95 text = self.revision(node) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
96 map = {} |
276 | 97 flag = {} |
25
daa724b27300
Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents:
20
diff
changeset
|
98 self.listcache = (text, text.splitlines(1)) |
daa724b27300
Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents:
20
diff
changeset
|
99 for l in self.listcache[1]: |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
100 (f, n) = l.split('\0') |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
101 map[f] = bin(n[:40]) |
276 | 102 flag[f] = (n[40:-1] == "x") |
103 self.mapcache = (node, map, flag) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
104 return map |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
105 |
276 | 106 def readflags(self, node): |
107 if self.mapcache or self.mapcache[0] != node: | |
108 self.read(node) | |
109 return self.mapcache[2] | |
110 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
111 def diff(self, a, b): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
112 # this is sneaky, as we're not actually using a and b |
140 | 113 if self.listcache and self.addlist and self.listcache[0] == a: |
98 | 114 d = mdiff.diff(self.listcache[1], self.addlist, 1) |
115 if mdiff.patch(a, d) != b: | |
116 sys.stderr.write("*** sortdiff failed, falling back ***\n") | |
117 return mdiff.textdiff(a, b) | |
118 return d | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
119 else: |
44 | 120 return mdiff.textdiff(a, b) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
121 |
276 | 122 def add(self, map, flags, transaction, link, p1=None, p2=None): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
123 files = map.keys() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
124 files.sort() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
125 |
276 | 126 self.addlist = ["%s\000%s%s\n" % |
127 (f, hex(map[f]), flags[f] and "x" or '') | |
128 for f in files] | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
129 text = "".join(self.addlist) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
130 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
131 n = self.addrevision(text, transaction, link, p1, p2) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
132 self.mapcache = (n, map) |
25
daa724b27300
Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents:
20
diff
changeset
|
133 self.listcache = (text, self.addlist) |
140 | 134 self.addlist = None |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
135 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
136 return n |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
137 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
138 class changelog(revlog): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
139 def __init__(self, opener): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
140 revlog.__init__(self, opener, "00changelog.i", "00changelog.d") |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
141 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
142 def extract(self, text): |
37 | 143 if not text: |
40 | 144 return (nullid, "", "0", [], "") |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
145 last = text.index("\n\n") |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
146 desc = text[last + 2:] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
147 l = text[:last].splitlines() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
148 manifest = bin(l[0]) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
149 user = l[1] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
150 date = l[2] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
151 files = l[3:] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
152 return (manifest, user, date, files, desc) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
153 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
154 def read(self, node): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
155 return self.extract(self.revision(node)) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
156 |
203 | 157 def add(self, manifest, list, desc, transaction, p1=None, p2=None, |
158 user=None, date=None): | |
159 user = (user or | |
160 os.environ.get("HGUSER") or | |
55
2add70d51441
From: Thomas Arendsen Hein <thomas@intevation.de>
mpm@selenic.com
parents:
48
diff
changeset
|
161 os.environ.get("EMAIL") or |
2add70d51441
From: Thomas Arendsen Hein <thomas@intevation.de>
mpm@selenic.com
parents:
48
diff
changeset
|
162 os.environ.get("LOGNAME", "unknown") + '@' + socket.getfqdn()) |
203 | 163 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
|
164 list.sort() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
165 l = [hex(manifest), user, date] + list + ["", desc] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
166 text = "\n".join(l) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
167 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
|
168 |
220 | 169 class dirstate: |
244 | 170 def __init__(self, opener, ui, root): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
171 self.opener = opener |
244 | 172 self.root = root |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
173 self.dirty = 0 |
20 | 174 self.ui = ui |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
175 self.map = None |
227 | 176 self.pl = None |
220 | 177 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
178 def __del__(self): |
220 | 179 if self.dirty: |
180 self.write() | |
181 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
182 def __getitem__(self, key): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
183 try: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
184 return self.map[key] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
185 except TypeError: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
186 self.read() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
187 return self[key] |
220 | 188 |
189 def __contains__(self, key): | |
190 if not self.map: self.read() | |
191 return key in self.map | |
192 | |
227 | 193 def parents(self): |
194 if not self.pl: | |
195 self.read() | |
196 return self.pl | |
197 | |
198 def setparents(self, p1, p2 = nullid): | |
199 self.dirty = 1 | |
200 self.pl = p1, p2 | |
201 | |
220 | 202 def state(self, key): |
203 try: | |
204 return self[key][0] | |
205 except KeyError: | |
206 return "?" | |
207 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
208 def read(self): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
209 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
|
210 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
211 self.map = {} |
227 | 212 self.pl = [nullid, nullid] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
213 try: |
220 | 214 st = self.opener("dirstate").read() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
215 except: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
216 |
227 | 217 self.pl = [st[:20], st[20: 40]] |
218 | |
219 pos = 40 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
220 while pos < len(st): |
220 | 221 e = struct.unpack(">cllll", st[pos:pos+17]) |
222 l = e[4] | |
223 pos += 17 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
224 f = st[pos:pos + l] |
220 | 225 self.map[f] = e[:4] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
226 pos += l |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
227 |
220 | 228 def update(self, files, state): |
229 ''' current states: | |
230 n normal | |
231 | 231 m needs merging |
220 | 232 r marked for removal |
233 a marked for addition''' | |
234 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
235 if not files: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
236 self.read() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
237 self.dirty = 1 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
238 for f in files: |
220 | 239 if state == "r": |
240 self.map[f] = ('r', 0, 0, 0) | |
241 else: | |
253 | 242 s = os.stat(os.path.join(self.root, f)) |
243 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
|
244 |
220 | 245 def forget(self, files): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
246 if not files: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
247 self.read() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
248 self.dirty = 1 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
249 for f in files: |
20 | 250 try: |
251 del self.map[f] | |
252 except KeyError: | |
220 | 253 self.ui.warn("not in dirstate: %s!\n" % f) |
20 | 254 pass |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
255 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
256 def clear(self): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
257 self.map = {} |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
258 self.dirty = 1 |
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 write(self): |
220 | 261 st = self.opener("dirstate", "w") |
227 | 262 st.write("".join(self.pl)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
263 for f, e in self.map.items(): |
220 | 264 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
|
265 st.write(e + f) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
266 self.dirty = 0 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
267 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
268 def copy(self): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
269 self.read() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
270 return self.map.copy() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
271 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
272 # used to avoid circular references so destructors work |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
273 def opener(base): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
274 p = base |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
275 def o(path, mode="r"): |
15
6daf7757e92b
Fix network pull of repo files with "%" in their base64 encoding.
mpm@selenic.com
parents:
10
diff
changeset
|
276 if p[:7] == "http://": |
6daf7757e92b
Fix network pull of repo files with "%" in their base64 encoding.
mpm@selenic.com
parents:
10
diff
changeset
|
277 f = os.path.join(p, urllib.quote(path)) |
6daf7757e92b
Fix network pull of repo files with "%" in their base64 encoding.
mpm@selenic.com
parents:
10
diff
changeset
|
278 return httprangereader(f) |
6daf7757e92b
Fix network pull of repo files with "%" in their base64 encoding.
mpm@selenic.com
parents:
10
diff
changeset
|
279 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
280 f = os.path.join(p, path) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
281 |
110
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
282 if mode != "r": |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
283 try: |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
284 s = os.stat(f) |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
285 except OSError: |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
286 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
|
287 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
|
288 os.makedirs(d) |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
289 else: |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
290 if s.st_nlink > 1: |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
291 file(f + ".tmp", "w").write(file(f).read()) |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
292 os.rename(f+".tmp", f) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
293 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
294 return file(f, mode) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
295 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
296 return o |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
297 |
60 | 298 class localrepository: |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
299 def __init__(self, ui, path=None, create=0): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
300 self.remote = 0 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
301 if path and path[:7] == "http://": |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
302 self.remote = 1 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
303 self.path = path |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
304 else: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
305 if not path: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
306 p = os.getcwd() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
307 while not os.path.isdir(os.path.join(p, ".hg")): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
308 p = os.path.dirname(p) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
309 if p == "/": raise "No repo found" |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
310 path = p |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
311 self.path = os.path.join(path, ".hg") |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
312 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
313 self.root = path |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
314 self.ui = ui |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
315 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
316 if create: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
317 os.mkdir(self.path) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
318 os.mkdir(self.join("data")) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
319 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
320 self.opener = opener(self.path) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
321 self.manifest = manifest(self.opener) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
322 self.changelog = changelog(self.opener) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
323 self.ignorelist = None |
67 | 324 self.tags = None |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
325 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
326 if not self.remote: |
244 | 327 self.dirstate = dirstate(self.opener, ui, self.root) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
328 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
329 def ignore(self, f): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
330 if self.ignorelist is None: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
331 self.ignorelist = [] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
332 try: |
67 | 333 l = open(os.path.join(self.root, ".hgignore")) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
334 for pat in l: |
9 | 335 if pat != "\n": |
336 self.ignorelist.append(re.compile(pat[:-1])) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
337 except IOError: pass |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
338 for pat in self.ignorelist: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
339 if pat.search(f): return True |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
340 return False |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
341 |
67 | 342 def lookup(self, key): |
343 if self.tags is None: | |
344 self.tags = {} | |
345 try: | |
254 | 346 # read each head of the tags file, ending with the tip |
347 # and add each tag found to the map, with "newer" ones | |
348 # taking precedence | |
67 | 349 fl = self.file(".hgtags") |
254 | 350 h = fl.heads() |
351 h.reverse() | |
352 for r in h: | |
353 for l in fl.revision(r).splitlines(): | |
354 if l: | |
355 n, k = l.split(" ") | |
356 self.tags[k] = bin(n) | |
67 | 357 except KeyError: pass |
358 try: | |
359 return self.tags[key] | |
360 except KeyError: | |
361 return self.changelog.lookup(key) | |
362 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
363 def join(self, f): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
364 return os.path.join(self.path, f) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
365 |
244 | 366 def wjoin(self, f): |
367 return os.path.join(self.root, f) | |
368 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
369 def file(self, f): |
192 | 370 if f[0] == '/': f = f[1:] |
144
ea9188538222
Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents:
140
diff
changeset
|
371 return filelog(self.opener, f) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
372 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
373 def transaction(self): |
251 | 374 # save dirstate for undo |
263 | 375 try: |
376 ds = self.opener("dirstate").read() | |
377 except IOError: | |
378 ds = "" | |
251 | 379 self.opener("undo.dirstate", "w").write(ds) |
262 | 380 |
381 return transaction.transaction(self.opener, self.join("journal"), | |
382 self.join("undo")) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
383 |
210 | 384 def recover(self): |
225 | 385 lock = self.lock() |
210 | 386 if os.path.exists(self.join("recover")): |
387 self.ui.status("attempting to rollback interrupted transaction\n") | |
262 | 388 return transaction.rollback(self.opener, self.join("recover")) |
210 | 389 else: |
390 self.ui.warn("no interrupted transaction available\n") | |
391 | |
392 def undo(self): | |
225 | 393 lock = self.lock() |
210 | 394 if os.path.exists(self.join("undo")): |
395 self.ui.status("attempting to rollback last transaction\n") | |
262 | 396 transaction.rollback(self.opener, self.join("undo")) |
251 | 397 self.dirstate = None |
398 os.rename(self.join("undo.dirstate"), self.join("dirstate")) | |
399 self.dirstate = dirstate(self.opener, self.ui, self.root) | |
163 | 400 else: |
210 | 401 self.ui.warn("no undo information available\n") |
162 | 402 |
161 | 403 def lock(self, wait = 1): |
404 try: | |
405 return lock.lock(self.join("lock"), 0) | |
406 except lock.LockHeld, inst: | |
407 if wait: | |
408 self.ui.warn("waiting for lock held by %s\n" % inst.args[0]) | |
409 return lock.lock(self.join("lock"), wait) | |
410 raise inst | |
411 | |
203 | 412 def rawcommit(self, files, text, user, date, p1=None, p2=None): |
228 | 413 p1 = p1 or self.dirstate.parents()[0] or nullid |
414 p2 = p2 or self.dirstate.parents()[1] or nullid | |
203 | 415 pchange = self.changelog.read(p1) |
416 pmmap = self.manifest.read(pchange[0]) | |
417 tr = self.transaction() | |
418 mmap = {} | |
419 linkrev = self.changelog.count() | |
420 for f in files: | |
421 try: | |
422 t = file(f).read() | |
423 except IOError: | |
424 self.ui.warn("Read file %s error, skipped\n" % f) | |
425 continue | |
426 r = self.file(f) | |
228 | 427 # FIXME - need to find both parents properly |
203 | 428 prev = pmmap.get(f, nullid) |
429 mmap[f] = r.add(t, tr, linkrev, prev) | |
430 | |
431 mnode = self.manifest.add(mmap, tr, linkrev, pchange[0]) | |
432 n = self.changelog.add(mnode, files, text, tr, p1, p2, user ,date, ) | |
433 tr.close() | |
228 | 434 self.dirstate.setparents(p1, p2) |
220 | 435 self.dirstate.clear() |
436 self.dirstate.update(mmap.keys(), "n") | |
203 | 437 |
229 | 438 def commit(self, files = None, text = ""): |
220 | 439 commit = [] |
440 remove = [] | |
441 if files: | |
442 for f in files: | |
443 s = self.dirstate.state(f) | |
244 | 444 if s in 'nmai': |
220 | 445 commit.append(f) |
446 elif s == 'r': | |
447 remove.append(f) | |
448 else: | |
244 | 449 self.ui.warn("%s not tracked!\n" % f) |
220 | 450 else: |
230 | 451 (c, a, d, u) = self.diffdir(self.root) |
220 | 452 commit = c + a |
453 remove = d | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
454 |
220 | 455 if not commit and not remove: |
151 | 456 self.ui.status("nothing changed\n") |
457 return | |
458 | |
229 | 459 p1, p2 = self.dirstate.parents() |
460 c1 = self.changelog.read(p1) | |
461 c2 = self.changelog.read(p2) | |
462 m1 = self.manifest.read(c1[0]) | |
276 | 463 mf1 = self.manifest.readflags(c1[0]) |
229 | 464 m2 = self.manifest.read(c2[0]) |
225 | 465 lock = self.lock() |
151 | 466 tr = self.transaction() |
467 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
468 # check in files |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
469 new = {} |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
470 linkrev = self.changelog.count() |
220 | 471 commit.sort() |
472 for f in commit: | |
83 | 473 self.ui.note(f + "\n") |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
474 try: |
276 | 475 fp = self.wjoin(f) |
476 mf1[f] = is_exec(fp) | |
477 t = file(fp).read() | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
478 except IOError: |
220 | 479 self.warn("trouble committing %s!\n" % f) |
480 raise | |
481 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
482 r = self.file(f) |
229 | 483 fp1 = m1.get(f, nullid) |
484 fp2 = m2.get(f, nullid) | |
485 new[f] = r.add(t, tr, linkrev, fp1, fp2) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
486 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
487 # update manifest |
229 | 488 m1.update(new) |
489 for f in remove: del m1[f] | |
276 | 490 mn = self.manifest.add(m1, mf1, tr, linkrev, c1[0], c2[0]) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
491 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
492 # add changeset |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
493 new = new.keys() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
494 new.sort() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
495 |
229 | 496 edittext = text + "\n" + "HG: manifest hash %s\n" % hex(mn) |
185
db3aa85b9379
Add manifest hash to commit messages for easy signing
mpm@selenic.com
parents:
182
diff
changeset
|
497 edittext += "".join(["HG: changed %s\n" % f for f in new]) |
25
daa724b27300
Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents:
20
diff
changeset
|
498 edittext += "".join(["HG: removed %s\n" % f for f in remove]) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
499 edittext = self.ui.edit(edittext) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
500 |
229 | 501 n = self.changelog.add(mn, new, edittext, tr, p1, p2) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
502 tr.close() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
503 |
229 | 504 self.dirstate.setparents(n) |
220 | 505 self.dirstate.update(new, "n") |
506 self.dirstate.forget(remove) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
507 |
230 | 508 def diffdir(self, path, changeset = None): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
509 changed = [] |
220 | 510 added = [] |
511 unknown = [] | |
4
ce3bd728b858
Fix exception handling for reading current working version
mpm@selenic.com
parents:
0
diff
changeset
|
512 mf = {} |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
513 |
29 | 514 if changeset: |
515 change = self.changelog.read(changeset) | |
4
ce3bd728b858
Fix exception handling for reading current working version
mpm@selenic.com
parents:
0
diff
changeset
|
516 mf = self.manifest.read(change[0]) |
230 | 517 dc = dict.fromkeys(mf) |
518 else: | |
519 changeset = self.dirstate.parents()[0] | |
520 change = self.changelog.read(changeset) | |
521 mf = self.manifest.read(change[0]) | |
220 | 522 dc = self.dirstate.copy() |
29 | 523 |
524 def fcmp(fn): | |
244 | 525 t1 = file(self.wjoin(fn)).read() |
29 | 526 t2 = self.file(fn).revision(mf[fn]) |
527 return cmp(t1, t2) | |
528 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
529 for dir, subdirs, files in os.walk(self.root): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
530 d = dir[len(self.root)+1:] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
531 if ".hg" in subdirs: subdirs.remove(".hg") |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
532 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
533 for f in files: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
534 fn = os.path.join(d, f) |
64 | 535 try: s = os.stat(os.path.join(self.root, fn)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
536 except: continue |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
537 if fn in dc: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
538 c = dc[fn] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
539 del dc[fn] |
220 | 540 if not c: |
29 | 541 if fcmp(fn): |
542 changed.append(fn) | |
231 | 543 elif c[0] == 'm': |
544 changed.append(fn) | |
220 | 545 elif c[0] == 'a': |
546 added.append(fn) | |
547 elif c[0] == 'r': | |
548 unknown.append(fn) | |
276 | 549 elif c[2] != s.st_size or (c[1] ^ s.st_mode) & 0100: |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
550 changed.append(fn) |
220 | 551 elif c[1] != s.st_mode or c[3] != s.st_mtime: |
29 | 552 if fcmp(fn): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
553 changed.append(fn) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
554 else: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
555 if self.ignore(fn): continue |
220 | 556 unknown.append(fn) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
557 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
558 deleted = dc.keys() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
559 deleted.sort() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
560 |
220 | 561 return (changed, added, deleted, unknown) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
562 |
32 | 563 def diffrevs(self, node1, node2): |
33 | 564 changed, added = [], [] |
32 | 565 |
566 change = self.changelog.read(node1) | |
567 mf1 = self.manifest.read(change[0]) | |
33 | 568 change = self.changelog.read(node2) |
32 | 569 mf2 = self.manifest.read(change[0]) |
570 | |
571 for fn in mf2: | |
572 if mf1.has_key(fn): | |
573 if mf1[fn] != mf2[fn]: | |
574 changed.append(fn) | |
575 del mf1[fn] | |
576 else: | |
577 added.append(fn) | |
578 | |
579 deleted = mf1.keys() | |
580 deleted.sort() | |
581 | |
582 return (changed, added, deleted) | |
583 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
584 def add(self, list): |
220 | 585 for f in list: |
244 | 586 p = self.wjoin(f) |
220 | 587 if not os.path.isfile(p): |
588 self.ui.warn("%s does not exist!\n" % f) | |
589 elif self.dirstate.state(f) == 'n': | |
590 self.ui.warn("%s already tracked!\n" % f) | |
591 else: | |
592 self.dirstate.update([f], "a") | |
593 | |
594 def forget(self, list): | |
595 for f in list: | |
596 if self.dirstate.state(f) not in 'ai': | |
597 self.ui.warn("%s not added!\n" % f) | |
598 else: | |
599 self.dirstate.forget([f]) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
600 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
601 def remove(self, list): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
602 for f in list: |
244 | 603 p = self.wjoin(f) |
220 | 604 if os.path.isfile(p): |
605 self.ui.warn("%s still exists!\n" % f) | |
606 elif f not in self.dirstate: | |
607 self.ui.warn("%s not tracked!\n" % f) | |
608 else: | |
609 self.dirstate.update([f], "r") | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
610 |
222 | 611 def heads(self): |
612 return self.changelog.heads() | |
613 | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
614 def branches(self, nodes): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
615 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
|
616 b = [] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
617 for n in nodes: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
618 t = n |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
619 while n: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
620 p = self.changelog.parents(n) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
621 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
|
622 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
|
623 break |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
624 n = p[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
625 return b |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
626 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
627 def between(self, pairs): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
628 r = [] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
629 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
630 for top, bottom in pairs: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
631 n, l, i = top, [], 0 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
632 f = 1 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
633 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
634 while n != bottom: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
635 p = self.changelog.parents(n)[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
636 if i == f: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
637 l.append(n) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
638 f = f * 2 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
639 n = p |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
640 i += 1 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
641 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
642 r.append(l) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
643 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
644 return r |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
645 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
646 def newer(self, nodes): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
647 m = {} |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
648 nl = [] |
94 | 649 pm = {} |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
650 cl = self.changelog |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
651 t = l = cl.count() |
94 | 652 |
653 # find the lowest numbered node | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
654 for n in nodes: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
655 l = min(l, cl.rev(n)) |
94 | 656 m[n] = 1 |
46 | 657 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
658 for i in xrange(l, t): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
659 n = cl.node(i) |
94 | 660 if n in m: # explicitly listed |
661 pm[n] = 1 | |
662 nl.append(n) | |
663 continue | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
664 for p in cl.parents(n): |
94 | 665 if p in pm: # parent listed |
666 pm[n] = 1 | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
667 nl.append(n) |
94 | 668 break |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
669 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
670 return nl |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
671 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
672 def getchangegroup(self, remote): |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
673 m = self.changelog.nodemap |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
674 search = [] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
675 fetch = [] |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
676 seen = {} |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
677 seenbranch = {} |
192 | 678 |
190
3dd5ce2fddb6
merge: short-circuit search for merge into empty repo
mpm@selenic.com
parents:
187
diff
changeset
|
679 # if we have an empty repo, fetch everything |
3dd5ce2fddb6
merge: short-circuit search for merge into empty repo
mpm@selenic.com
parents:
187
diff
changeset
|
680 if self.changelog.tip() == nullid: |
222 | 681 self.ui.status("requesting all changes\n") |
190
3dd5ce2fddb6
merge: short-circuit search for merge into empty repo
mpm@selenic.com
parents:
187
diff
changeset
|
682 return remote.changegroup([nullid]) |
3dd5ce2fddb6
merge: short-circuit search for merge into empty repo
mpm@selenic.com
parents:
187
diff
changeset
|
683 |
3dd5ce2fddb6
merge: short-circuit search for merge into empty repo
mpm@selenic.com
parents:
187
diff
changeset
|
684 # otherwise, assume we're closer to the tip than the root |
222 | 685 self.ui.status("searching for changes\n") |
686 heads = remote.heads() | |
687 unknown = [] | |
688 for h in heads: | |
689 if h not in m: | |
690 unknown.append(h) | |
46 | 691 |
222 | 692 if not unknown: |
192 | 693 self.ui.status("nothing to do!\n") |
60 | 694 return None |
222 | 695 |
696 unknown = remote.branches(unknown) | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
697 while unknown: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
698 n = unknown.pop(0) |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
699 seen[n[0]] = 1 |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
700 |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
701 self.ui.debug("examining %s:%s\n" % (short(n[0]), short(n[1]))) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
702 if n == nullid: break |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
703 if n in seenbranch: |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
704 self.ui.debug("branch already found\n") |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
705 continue |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
706 if n[1] and n[1] in m: # do we know the base? |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
707 self.ui.debug("found incomplete branch %s:%s\n" |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
708 % (short(n[0]), short(n[1]))) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
709 search.append(n) # schedule branch range for scanning |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
710 seenbranch[n] = 1 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
711 else: |
94 | 712 if n[2] in m and n[3] in m: |
713 if n[1] not in fetch: | |
714 self.ui.debug("found new changeset %s\n" % | |
715 short(n[1])) | |
716 fetch.append(n[1]) # earliest unknown | |
717 continue | |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
718 |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
719 r = [] |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
720 for a in n[2:4]: |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
721 if a not in seen: r.append(a) |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
722 |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
723 if r: |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
724 self.ui.debug("requesting %s\n" % |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
725 " ".join(map(short, r))) |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
726 for b in remote.branches(r): |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
727 self.ui.debug("received %s:%s\n" % |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
728 (short(b[0]), short(b[1]))) |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
729 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
|
730 unknown.append(b) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
731 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
732 while search: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
733 n = search.pop(0) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
734 l = remote.between([(n[0], n[1])])[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
735 p = n[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
736 f = 1 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
737 for i in l + [n[1]]: |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
738 if i in m: |
85 | 739 if f <= 2: |
83 | 740 self.ui.debug("found new branch changeset %s\n" % |
741 short(p)) | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
742 fetch.append(p) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
743 else: |
83 | 744 self.ui.debug("narrowed branch search to %s:%s\n" |
745 % (short(p), short(i))) | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
746 search.append((p, i)) |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
747 break |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
748 p, f = i, f * 2 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
749 |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
750 for f in fetch: |
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
751 if f in m: |
83 | 752 raise "already have", short(f[:4]) |
753 | |
94 | 754 self.ui.note("adding new changesets starting at " + |
83 | 755 " ".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
|
756 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
757 return remote.changegroup(fetch) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
758 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
759 def changegroup(self, basenodes): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
760 nodes = self.newer(basenodes) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
761 |
46 | 762 # construct the link map |
763 linkmap = {} | |
764 for n in nodes: | |
765 linkmap[self.changelog.rev(n)] = n | |
766 | |
767 # construct a list of all changed files | |
768 changed = {} | |
769 for n in nodes: | |
770 c = self.changelog.read(n) | |
771 for f in c[3]: | |
772 changed[f] = 1 | |
773 changed = changed.keys() | |
774 changed.sort() | |
775 | |
776 # the changegroup is changesets + manifests + all file revs | |
777 revs = [ self.changelog.rev(n) for n in nodes ] | |
778 | |
192 | 779 for y in self.changelog.group(linkmap): yield y |
780 for y in self.manifest.group(linkmap): yield y | |
46 | 781 for f in changed: |
192 | 782 yield struct.pack(">l", len(f) + 4) + f |
46 | 783 g = self.file(f).group(linkmap) |
192 | 784 for y in g: |
785 yield y | |
46 | 786 |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
787 def addchangegroup(self, generator): |
222 | 788 |
789 class genread: | |
790 def __init__(self, generator): | |
791 self.g = generator | |
792 self.buf = "" | |
793 def read(self, l): | |
794 while l > len(self.buf): | |
795 try: | |
796 self.buf += self.g.next() | |
797 except StopIteration: | |
798 break | |
799 d, self.buf = self.buf[:l], self.buf[l:] | |
800 return d | |
801 | |
802 def getchunk(): | |
803 d = source.read(4) | |
804 if not d: return "" | |
805 l = struct.unpack(">l", d)[0] | |
806 if l <= 4: return "" | |
807 return source.read(l - 4) | |
808 | |
809 def getgroup(): | |
810 while 1: | |
811 c = getchunk() | |
812 if not c: break | |
813 yield c | |
814 | |
815 def csmap(x): | |
816 self.ui.debug("add changeset %s\n" % short(x)) | |
817 return self.changelog.count() | |
818 | |
819 def revmap(x): | |
820 return self.changelog.rev(x) | |
821 | |
822 if not generator: return | |
823 changesets = files = revisions = 0 | |
225 | 824 |
222 | 825 source = genread(generator) |
225 | 826 lock = self.lock() |
222 | 827 tr = self.transaction() |
828 | |
829 # pull off the changeset group | |
830 self.ui.status("adding changesets\n") | |
831 co = self.changelog.tip() | |
224
ccbcc4d76f81
fix bad assumption about uniqueness of file versions
mpm@selenic.com
parents:
223
diff
changeset
|
832 cn = self.changelog.addgroup(getgroup(), csmap, tr, 1) # unique |
222 | 833 changesets = self.changelog.rev(cn) - self.changelog.rev(co) |
834 | |
835 # pull off the manifest group | |
836 self.ui.status("adding manifests\n") | |
837 mm = self.manifest.tip() | |
838 mo = self.manifest.addgroup(getgroup(), revmap, tr) | |
839 | |
840 # process the files | |
841 self.ui.status("adding file revisions\n") | |
842 while 1: | |
843 f = getchunk() | |
844 if not f: break | |
845 self.ui.debug("adding %s revisions\n" % f) | |
846 fl = self.file(f) | |
847 o = fl.tip() | |
848 n = fl.addgroup(getgroup(), revmap, tr) | |
849 revisions += fl.rev(n) - fl.rev(o) | |
850 files += 1 | |
851 | |
852 self.ui.status(("modified %d files, added %d changesets" + | |
853 " and %d new revisions\n") | |
854 % (files, changesets, revisions)) | |
855 | |
856 tr.close() | |
857 return | |
858 | |
275 | 859 def update(self, node, allow=False, force=False): |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
860 pl = self.dirstate.parents() |
275 | 861 if not force and pl[1] != nullid: |
254 | 862 self.ui.warn("aborting: outstanding uncommitted merges\n") |
46 | 863 return |
864 | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
865 p1, p2 = pl[0], node |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
866 m1n = self.changelog.read(p1)[0] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
867 m2n = self.changelog.read(p2)[0] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
868 man = self.manifest.ancestor(m1n, m2n) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
869 m1 = self.manifest.read(m1n) |
276 | 870 mf1 = self.manifest.readflags(m1n) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
871 m2 = self.manifest.read(m2n) |
276 | 872 mf2 = self.manifest.readflags(m2n) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
873 ma = self.manifest.read(man) |
276 | 874 mfa = self.manifest.readflags(m2n) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
875 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
876 (c, a, d, u) = self.diffdir(self.root) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
877 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
878 # 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
|
879 # we care about merging |
254 | 880 self.ui.note("resolving manifests\n") |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
881 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
|
882 (short(man), short(m1n), short(m2n))) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
883 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
884 merge = {} |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
885 get = {} |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
886 remove = [] |
46 | 887 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
888 # construct a working dir manifest |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
889 mw = m1.copy() |
276 | 890 mfw = mf1.copy() |
254 | 891 for f in a + c + u: |
892 mw[f] = "" | |
276 | 893 mfw[f] = is_exec(self.wjoin(f)) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
894 for f in d: |
254 | 895 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
|
896 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
897 for f, n in mw.iteritems(): |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
898 if f in m2: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
899 if n != m2[f]: |
254 | 900 a = ma.get(f, nullid) |
901 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
|
902 self.ui.debug(" %s versions differ, resolve\n" % f) |
254 | 903 merge[f] = (m1.get(f, nullid), m2[f]) |
276 | 904 # merge executable bits |
905 # "if we changed or they changed, change in merge" | |
906 a, b, c = mfa.get(f, 0), mfw[f], mf2[f] | |
907 mode = ((a^b) | (a^c)) ^ a | |
908 merge[f] = (m1.get(f, nullid), m2[f], mode) | |
273
4f8174389001
merge: Fix bug where we overwrote local when local was newer
mpm@selenic.com
parents:
263
diff
changeset
|
909 elif m2[f] != a: |
4f8174389001
merge: Fix bug where we overwrote local when local was newer
mpm@selenic.com
parents:
263
diff
changeset
|
910 self.ui.debug(" remote %s is newer, get\n" % f) |
254 | 911 get[f] = m2[f] |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
912 del m2[f] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
913 elif f in ma: |
275 | 914 if not force and n != ma[f]: |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
915 r = self.ui.prompt( |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
916 (" local changed %s which remote deleted\n" % f) + |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
917 "(k)eep or (d)elete?", "[kd]", "k") |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
918 if r == "d": |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
919 remove.append(f) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
920 else: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
921 self.ui.debug("other deleted %s\n" % f) |
254 | 922 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
|
923 else: |
254 | 924 if n == m1.get(f, nullid): # same as parent |
925 self.ui.debug("remote deleted %s\n" % f) | |
926 remove.append(f) | |
927 else: | |
928 self.ui.debug("working dir created %s, keeping\n" % f) | |
46 | 929 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
930 for f, n in m2.iteritems(): |
256 | 931 if f[0] == "/": continue |
275 | 932 if not force and f in ma and n != ma[f]: |
933 r = self.ui.prompt( | |
934 ("remote changed %s which local deleted\n" % f) + | |
935 "(k)eep or (d)elete?", "[kd]", "k") | |
936 if r == "d": remove.append(f) | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
937 else: |
254 | 938 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
|
939 get[f] = n |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
940 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
941 del mw, m1, m2, ma |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
942 |
275 | 943 if force: |
944 for f in merge: | |
945 get[f] = merge[f][1] | |
946 merge = {} | |
947 | |
254 | 948 if not merge: |
949 # we don't need to do any magic, just jump to the new rev | |
950 mode = 'n' | |
951 p1, p2 = p2, nullid | |
952 else: | |
275 | 953 if not allow: |
954 self.ui.status("the following files conflict:\n") | |
955 for f in merge: | |
956 self.ui.status(" %s\n" % f) | |
957 self.ui.warn("aborting update due to conflicting files!\n") | |
958 self.ui.status("(use update -m to allow a merge)\n") | |
959 return 1 | |
254 | 960 # we have to remember what files we needed to get/change |
961 # because any file that's different from either one of its | |
962 # parents must be in the changeset | |
963 mode = 'm' | |
964 | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
965 self.dirstate.setparents(p1, p2) |
191
d7e859cf2f1b
merge: add count of new manifests, files, and revisions
mpm@selenic.com
parents:
190
diff
changeset
|
966 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
967 # 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
|
968 files = get.keys() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
969 files.sort() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
970 for f in files: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
971 if f[0] == "/": continue |
273
4f8174389001
merge: Fix bug where we overwrote local when local was newer
mpm@selenic.com
parents:
263
diff
changeset
|
972 self.ui.note("getting %s\n" % f) |
276 | 973 t = self.file(f).read(get[f]) |
974 wp = self.wjoin(f) | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
975 try: |
276 | 976 file(wp, "w").write(t) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
977 except IOError: |
276 | 978 os.makedirs(os.path.dirname(wp)) |
979 file(wp, "w").write(t) | |
980 set_exec(wp, mf2[f]) | |
254 | 981 self.dirstate.update([f], mode) |
46 | 982 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
983 # merge the tricky bits |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
984 files = merge.keys() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
985 files.sort() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
986 for f in files: |
256 | 987 self.ui.status("merging %s\n" % f) |
276 | 988 m, o, flag = merge[f] |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
989 self.merge3(f, m, o) |
276 | 990 set_exec(wp, flag) |
254 | 991 self.dirstate.update([f], 'm') |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
992 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
993 for f in remove: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
994 self.ui.note("removing %s\n" % f) |
254 | 995 os.unlink(f) |
996 if mode == 'n': | |
997 self.dirstate.forget(remove) | |
998 else: | |
999 self.dirstate.update(remove, 'r') | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1000 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1001 def merge3(self, fn, my, other): |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1002 """perform a 3-way merge in the working directory""" |
249 | 1003 |
96 | 1004 def temp(prefix, node): |
1005 pre = "%s~%s." % (os.path.basename(fn), prefix) | |
1006 (fd, name) = tempfile.mkstemp("", pre) | |
1007 f = os.fdopen(fd, "w") | |
1008 f.write(fl.revision(node)) | |
1009 f.close() | |
1010 return name | |
1011 | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1012 fl = self.file(fn) |
96 | 1013 base = fl.ancestor(my, other) |
244 | 1014 a = self.wjoin(fn) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1015 b = temp("other", other) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1016 c = temp("base", base) |
96 | 1017 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1018 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
|
1019 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
|
1020 (fn, short(other), short(base))) |
96 | 1021 |
240 | 1022 cmd = os.environ.get("HGMERGE", "hgmerge") |
1023 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
|
1024 if r: |
275 | 1025 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
|
1026 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1027 os.unlink(b) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1028 os.unlink(c) |
96 | 1029 |
247 | 1030 def verify(self): |
1031 filelinkrevs = {} | |
1032 filenodes = {} | |
1033 manifestchangeset = {} | |
1034 changesets = revisions = files = 0 | |
1035 errors = 0 | |
1036 | |
1037 self.ui.status("checking changesets\n") | |
1038 for i in range(self.changelog.count()): | |
1039 changesets += 1 | |
1040 n = self.changelog.node(i) | |
1041 for p in self.changelog.parents(n): | |
1042 if p not in self.changelog.nodemap: | |
1043 self.ui.warn("changeset %s has unknown parent %s\n" % | |
1044 (short(n), short(p))) | |
1045 errors += 1 | |
1046 try: | |
1047 changes = self.changelog.read(n) | |
1048 except Exception, inst: | |
1049 self.ui.warn("unpacking changeset %s: %s\n" % (short(n), inst)) | |
1050 errors += 1 | |
1051 | |
1052 manifestchangeset[changes[0]] = n | |
1053 for f in changes[3]: | |
1054 filelinkrevs.setdefault(f, []).append(i) | |
1055 | |
1056 self.ui.status("checking manifests\n") | |
1057 for i in range(self.manifest.count()): | |
1058 n = self.manifest.node(i) | |
1059 for p in self.manifest.parents(n): | |
1060 if p not in self.manifest.nodemap: | |
1061 self.ui.warn("manifest %s has unknown parent %s\n" % | |
1062 (short(n), short(p))) | |
1063 errors += 1 | |
1064 ca = self.changelog.node(self.manifest.linkrev(n)) | |
1065 cc = manifestchangeset[n] | |
1066 if ca != cc: | |
1067 self.ui.warn("manifest %s points to %s, not %s\n" % | |
1068 (hex(n), hex(ca), hex(cc))) | |
1069 errors += 1 | |
1070 | |
1071 try: | |
1072 delta = mdiff.patchtext(self.manifest.delta(n)) | |
1073 except KeyboardInterrupt: | |
1074 print "aborted" | |
1075 sys.exit(0) | |
1076 except Exception, inst: | |
1077 self.ui.warn("unpacking manifest %s: %s\n" | |
1078 % (short(n), inst)) | |
1079 errors += 1 | |
1080 | |
1081 ff = [ l.split('\0') for l in delta.splitlines() ] | |
1082 for f, fn in ff: | |
1083 filenodes.setdefault(f, {})[bin(fn)] = 1 | |
1084 | |
1085 self.ui.status("crosschecking files in changesets and manifests\n") | |
1086 for f in filenodes: | |
1087 if f not in filelinkrevs: | |
1088 self.ui.warn("file %s in manifest but not in changesets\n" % f) | |
1089 errors += 1 | |
1090 | |
1091 for f in filelinkrevs: | |
1092 if f not in filenodes: | |
1093 self.ui.warn("file %s in changeset but not in manifest\n" % f) | |
1094 errors += 1 | |
1095 | |
1096 self.ui.status("checking files\n") | |
1097 ff = filenodes.keys() | |
1098 ff.sort() | |
1099 for f in ff: | |
1100 if f == "/dev/null": continue | |
1101 files += 1 | |
1102 fl = self.file(f) | |
1103 nodes = { nullid: 1 } | |
1104 for i in range(fl.count()): | |
1105 revisions += 1 | |
1106 n = fl.node(i) | |
1107 | |
1108 if n not in filenodes[f]: | |
1109 self.ui.warn("%s: %d:%s not in manifests\n" | |
1110 % (f, i, short(n))) | |
1111 print len(filenodes[f].keys()), fl.count(), f | |
1112 errors += 1 | |
1113 else: | |
1114 del filenodes[f][n] | |
1115 | |
1116 flr = fl.linkrev(n) | |
1117 if flr not in filelinkrevs[f]: | |
1118 self.ui.warn("%s:%s points to unexpected changeset %d\n" | |
1119 % (f, short(n), fl.linkrev(n))) | |
1120 errors += 1 | |
1121 else: | |
1122 filelinkrevs[f].remove(flr) | |
1123 | |
1124 # verify contents | |
1125 try: | |
1126 t = fl.read(n) | |
1127 except Exception, inst: | |
1128 self.ui.warn("unpacking file %s %s: %s\n" | |
1129 % (f, short(n), inst)) | |
1130 errors += 1 | |
1131 | |
1132 # verify parents | |
1133 (p1, p2) = fl.parents(n) | |
1134 if p1 not in nodes: | |
1135 self.ui.warn("file %s:%s unknown parent 1 %s" % | |
1136 (f, short(n), short(p1))) | |
1137 errors += 1 | |
1138 if p2 not in nodes: | |
1139 self.ui.warn("file %s:%s unknown parent 2 %s" % | |
1140 (f, short(n), short(p1))) | |
1141 errors += 1 | |
1142 nodes[n] = 1 | |
1143 | |
1144 # cross-check | |
1145 for node in filenodes[f]: | |
1146 self.ui.warn("node %s in manifests not in %s\n" | |
1147 % (hex(n), f)) | |
1148 errors += 1 | |
1149 | |
1150 self.ui.status("%d files, %d changesets, %d total revisions\n" % | |
1151 (files, changesets, revisions)) | |
1152 | |
1153 if errors: | |
1154 self.ui.warn("%d integrity errors encountered!\n" % errors) | |
1155 return 1 | |
1156 | |
60 | 1157 class remoterepository: |
1158 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
|
1159 self.url = path |
60 | 1160 self.ui = ui |
1161 | |
1162 def do_cmd(self, cmd, **args): | |
83 | 1163 self.ui.debug("sending %s command\n" % cmd) |
60 | 1164 q = {"cmd": cmd} |
1165 q.update(args) | |
1166 qs = urllib.urlencode(q) | |
1167 cu = "%s?%s" % (self.url, qs) | |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1168 return urllib.urlopen(cu) |
60 | 1169 |
222 | 1170 def heads(self): |
1171 d = self.do_cmd("heads").read() | |
1172 try: | |
1173 return map(bin, d[:-1].split(" ")) | |
1174 except: | |
1175 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |
1176 raise | |
1177 | |
60 | 1178 def branches(self, nodes): |
1179 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
|
1180 d = self.do_cmd("branches", nodes=n).read() |
217 | 1181 try: |
1182 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ] | |
1183 return br | |
1184 except: | |
1185 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |
1186 raise | |
60 | 1187 |
1188 def between(self, pairs): | |
1189 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
|
1190 d = self.do_cmd("between", pairs=n).read() |
217 | 1191 try: |
1192 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ] | |
1193 return p | |
1194 except: | |
1195 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |
1196 raise | |
60 | 1197 |
1198 def changegroup(self, nodes): | |
1199 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
|
1200 zd = zlib.decompressobj() |
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1201 f = self.do_cmd("changegroup", roots=n) |
192 | 1202 bytes = 0 |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1203 while 1: |
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1204 d = f.read(4096) |
192 | 1205 bytes += len(d) |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1206 if not d: |
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1207 yield zd.flush() |
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1208 break |
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1209 yield zd.decompress(d) |
192 | 1210 self.ui.note("%d bytes of data transfered\n" % bytes) |
60 | 1211 |
1212 def repository(ui, path=None, create=0): | |
176
1d8e9637a0a4
Change hg: protocol name to http: and http: to old-http:
mpm@selenic.com
parents:
171
diff
changeset
|
1213 if path and path[:7] == "http://": |
1d8e9637a0a4
Change hg: protocol name to http: and http: to old-http:
mpm@selenic.com
parents:
171
diff
changeset
|
1214 return remoterepository(ui, path) |
60 | 1215 if path and path[:5] == "hg://": |
176
1d8e9637a0a4
Change hg: protocol name to http: and http: to old-http:
mpm@selenic.com
parents:
171
diff
changeset
|
1216 return remoterepository(ui, path.replace("hg://", "http://")) |
1d8e9637a0a4
Change hg: protocol name to http: and http: to old-http:
mpm@selenic.com
parents:
171
diff
changeset
|
1217 if path and path[:11] == "old-http://": |
1d8e9637a0a4
Change hg: protocol name to http: and http: to old-http:
mpm@selenic.com
parents:
171
diff
changeset
|
1218 return localrepository(ui, path.replace("old-http://", "http://")) |
60 | 1219 else: |
1220 return localrepository(ui, path, create) | |
1221 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1222 class httprangereader: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1223 def __init__(self, url): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1224 self.url = url |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1225 self.pos = 0 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1226 def seek(self, pos): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1227 self.pos = pos |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1228 def read(self, bytes=None): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1229 opener = urllib2.build_opener(byterange.HTTPRangeHandler()) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1230 urllib2.install_opener(opener) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1231 req = urllib2.Request(self.url) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1232 end = '' |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1233 if bytes: end = self.pos + bytes |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1234 req.add_header('Range', 'bytes=%d-%s' % (self.pos, end)) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1235 f = urllib2.urlopen(req) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1236 return f.read() |