Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/hg.py @ 579:ffeb2c3a1966
Actually warn on pulling from an unrelated repository
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Actually warn on pulling from an unrelated repository
add some comments to findincoming
track the base nodes of the fetch set
report if the base set only contains nullid
add a test case
manifest hash: 3fc038a6041b0967a20503f5ec8876efc038841a
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCx0yLywK+sNU5EO8RAlK6AJ9J/GKPpYSMzTqmguXPWOISJ+zY5gCghd+j
ClLpn0dKZnB46dh0F8zhuuk=
=emNb
-----END PGP SIGNATURE-----
author | mpm@selenic.com |
---|---|
date | Sat, 02 Jul 2005 18:25:15 -0800 |
parents | e33c85d2812a |
children | df8a5a0098d4 |
rev | line source |
---|---|
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
1 # hg.py - repository classes for mercurial |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
2 # |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
3 # Copyright 2005 Matt Mackall <mpm@selenic.com> |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
4 # |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
6 # of the GNU General Public License, incorporated herein by reference. |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
7 |
249 | 8 import sys, struct, os |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
418
diff
changeset
|
9 import util |
262 | 10 from revlog import * |
11 from demandload import * | |
12 demandload(globals(), "re lock urllib urllib2 transaction time socket") | |
434 | 13 demandload(globals(), "tempfile httprangereader bdiff") |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
14 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
15 class filelog(revlog): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
16 def __init__(self, opener, path): |
144
ea9188538222
Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents:
140
diff
changeset
|
17 revlog.__init__(self, opener, |
ea9188538222
Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents:
140
diff
changeset
|
18 os.path.join("data", path + ".i"), |
ea9188538222
Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents:
140
diff
changeset
|
19 os.path.join("data", path + ".d")) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
20 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
21 def read(self, node): |
360 | 22 t = self.revision(node) |
23 if t[:2] != '\1\n': | |
24 return t | |
25 s = t.find('\1\n', 2) | |
26 return t[s+2:] | |
27 | |
28 def readmeta(self, node): | |
29 t = self.revision(node) | |
30 if t[:2] != '\1\n': | |
31 return t | |
32 s = t.find('\1\n', 2) | |
33 mt = t[2:s] | |
34 for l in mt.splitlines(): | |
35 k, v = l.split(": ", 1) | |
36 m[k] = v | |
37 return m | |
38 | |
39 def add(self, text, meta, transaction, link, p1=None, p2=None): | |
40 if meta or text[:2] == '\1\n': | |
41 mt = "" | |
42 if meta: | |
43 mt = [ "%s: %s\n" % (k, v) for k,v in meta.items() ] | |
44 text = "\1\n" + "".join(mt) + "\1\n" + text | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
45 return self.addrevision(text, transaction, link, p1, p2) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
46 |
79 | 47 def annotate(self, node): |
199 | 48 |
49 def decorate(text, rev): | |
436 | 50 return ([rev] * len(text.splitlines()), text) |
199 | 51 |
52 def pair(parent, child): | |
436 | 53 for a1, a2, b1, b2 in bdiff.blocks(parent[1], child[1]): |
471 | 54 child[0][b1:b2] = parent[0][a1:a2] |
55 return child | |
199 | 56 |
200 | 57 # find all ancestors |
216
201115f2859b
hg annotate: actually annotate the given version
mpm@selenic.com
parents:
210
diff
changeset
|
58 needed = {node:1} |
199 | 59 visit = [node] |
60 while visit: | |
61 n = visit.pop(0) | |
62 for p in self.parents(n): | |
63 if p not in needed: | |
64 needed[p] = 1 | |
65 visit.append(p) | |
200 | 66 else: |
67 # count how many times we'll use this | |
68 needed[p] += 1 | |
199 | 69 |
200 | 70 # sort by revision which is a topological order |
471 | 71 visit = [ (self.rev(n), n) for n in needed.keys() ] |
199 | 72 visit.sort() |
73 hist = {} | |
74 | |
471 | 75 for r,n in visit: |
199 | 76 curr = decorate(self.read(n), self.linkrev(n)) |
77 for p in self.parents(n): | |
78 if p != nullid: | |
79 curr = pair(hist[p], curr) | |
200 | 80 # trim the history of unneeded revs |
81 needed[p] -= 1 | |
82 if not needed[p]: | |
83 del hist[p] | |
199 | 84 hist[n] = curr |
85 | |
436 | 86 return zip(hist[n][0], hist[n][1].splitlines(1)) |
79 | 87 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
88 class manifest(revlog): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
89 def __init__(self, opener): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
90 self.mapcache = None |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
91 self.listcache = None |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
92 self.addlist = None |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
93 revlog.__init__(self, opener, "00manifest.i", "00manifest.d") |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
94 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
95 def read(self, node): |
313 | 96 if node == nullid: return {} # don't upset local cache |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
97 if self.mapcache and self.mapcache[0] == node: |
561 | 98 return self.mapcache[1] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
99 text = self.revision(node) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
100 map = {} |
276 | 101 flag = {} |
25
daa724b27300
Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents:
20
diff
changeset
|
102 self.listcache = (text, text.splitlines(1)) |
daa724b27300
Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents:
20
diff
changeset
|
103 for l in self.listcache[1]: |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
104 (f, n) = l.split('\0') |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
105 map[f] = bin(n[:40]) |
276 | 106 flag[f] = (n[40:-1] == "x") |
107 self.mapcache = (node, map, flag) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
108 return map |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
109 |
276 | 110 def readflags(self, node): |
313 | 111 if node == nullid: return {} # don't upset local cache |
358
9f4077d7ef6f
[PATCH] manifest.readflags performance buglet
mpm@selenic.com
parents:
350
diff
changeset
|
112 if not self.mapcache or self.mapcache[0] != node: |
276 | 113 self.read(node) |
114 return self.mapcache[2] | |
115 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
116 def diff(self, a, b): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
117 # this is sneaky, as we're not actually using a and b |
140 | 118 if self.listcache and self.addlist and self.listcache[0] == a: |
98 | 119 d = mdiff.diff(self.listcache[1], self.addlist, 1) |
120 if mdiff.patch(a, d) != b: | |
121 sys.stderr.write("*** sortdiff failed, falling back ***\n") | |
122 return mdiff.textdiff(a, b) | |
123 return d | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
124 else: |
44 | 125 return mdiff.textdiff(a, b) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
126 |
276 | 127 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
|
128 files = map.keys() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
129 files.sort() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
130 |
276 | 131 self.addlist = ["%s\000%s%s\n" % |
132 (f, hex(map[f]), flags[f] and "x" or '') | |
133 for f in files] | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
134 text = "".join(self.addlist) |
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 n = self.addrevision(text, transaction, link, p1, p2) |
302 | 137 self.mapcache = (n, map, flags) |
25
daa724b27300
Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents:
20
diff
changeset
|
138 self.listcache = (text, self.addlist) |
140 | 139 self.addlist = None |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
140 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
141 return n |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
142 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
143 class changelog(revlog): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
144 def __init__(self, opener): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
145 revlog.__init__(self, opener, "00changelog.i", "00changelog.d") |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
146 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
147 def extract(self, text): |
37 | 148 if not text: |
40 | 149 return (nullid, "", "0", [], "") |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
150 last = text.index("\n\n") |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
151 desc = text[last + 2:] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
152 l = text[:last].splitlines() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
153 manifest = bin(l[0]) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
154 user = l[1] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
155 date = l[2] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
156 files = l[3:] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
157 return (manifest, user, date, files, desc) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
158 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
159 def read(self, node): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
160 return self.extract(self.revision(node)) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
161 |
203 | 162 def add(self, manifest, list, desc, transaction, p1=None, p2=None, |
163 user=None, date=None): | |
164 user = (user or | |
165 os.environ.get("HGUSER") or | |
55
2add70d51441
From: Thomas Arendsen Hein <thomas@intevation.de>
mpm@selenic.com
parents:
48
diff
changeset
|
166 os.environ.get("EMAIL") or |
504 | 167 (os.environ.get("LOGNAME", |
168 os.environ.get("USERNAME", "unknown")) | |
169 + '@' + socket.getfqdn())) | |
203 | 170 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
|
171 list.sort() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
172 l = [hex(manifest), user, date] + list + ["", desc] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
173 text = "\n".join(l) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
174 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
|
175 |
220 | 176 class dirstate: |
244 | 177 def __init__(self, opener, ui, root): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
178 self.opener = opener |
244 | 179 self.root = root |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
180 self.dirty = 0 |
20 | 181 self.ui = ui |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
182 self.map = None |
227 | 183 self.pl = None |
363 | 184 self.copies = {} |
220 | 185 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
186 def __del__(self): |
220 | 187 if self.dirty: |
188 self.write() | |
189 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
190 def __getitem__(self, key): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
191 try: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
192 return self.map[key] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
193 except TypeError: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
194 self.read() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
195 return self[key] |
220 | 196 |
197 def __contains__(self, key): | |
198 if not self.map: self.read() | |
199 return key in self.map | |
200 | |
227 | 201 def parents(self): |
202 if not self.pl: | |
203 self.read() | |
204 return self.pl | |
205 | |
206 def setparents(self, p1, p2 = nullid): | |
207 self.dirty = 1 | |
208 self.pl = p1, p2 | |
209 | |
220 | 210 def state(self, key): |
211 try: | |
212 return self[key][0] | |
213 except KeyError: | |
214 return "?" | |
215 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
216 def read(self): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
217 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
|
218 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
219 self.map = {} |
227 | 220 self.pl = [nullid, nullid] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
221 try: |
220 | 222 st = self.opener("dirstate").read() |
311 | 223 if not st: return |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
224 except: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
225 |
227 | 226 self.pl = [st[:20], st[20: 40]] |
227 | |
228 pos = 40 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
229 while pos < len(st): |
220 | 230 e = struct.unpack(">cllll", st[pos:pos+17]) |
231 l = e[4] | |
232 pos += 17 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
233 f = st[pos:pos + l] |
515 | 234 if '\0' in f: |
363 | 235 f, c = f.split('\0') |
236 self.copies[f] = c | |
220 | 237 self.map[f] = e[:4] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
238 pos += l |
363 | 239 |
240 def copy(self, source, dest): | |
241 self.read() | |
242 self.dirty = 1 | |
243 self.copies[dest] = source | |
244 | |
245 def copied(self, file): | |
246 return self.copies.get(file, None) | |
515 | 247 |
220 | 248 def update(self, files, state): |
249 ''' current states: | |
250 n normal | |
231 | 251 m needs merging |
220 | 252 r marked for removal |
253 a marked for addition''' | |
254 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
255 if not files: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
256 self.read() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
257 self.dirty = 1 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
258 for f in files: |
220 | 259 if state == "r": |
260 self.map[f] = ('r', 0, 0, 0) | |
261 else: | |
253 | 262 s = os.stat(os.path.join(self.root, f)) |
263 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
|
264 |
220 | 265 def forget(self, files): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
266 if not files: return |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
267 self.read() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
268 self.dirty = 1 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
269 for f in files: |
20 | 270 try: |
271 del self.map[f] | |
272 except KeyError: | |
220 | 273 self.ui.warn("not in dirstate: %s!\n" % f) |
20 | 274 pass |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
275 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
276 def clear(self): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
277 self.map = {} |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
278 self.dirty = 1 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
279 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
280 def write(self): |
220 | 281 st = self.opener("dirstate", "w") |
227 | 282 st.write("".join(self.pl)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
283 for f, e in self.map.items(): |
363 | 284 c = self.copied(f) |
285 if c: | |
286 f = f + "\0" + c | |
220 | 287 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
|
288 st.write(e + f) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
289 self.dirty = 0 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
290 |
536 | 291 def changes(self, files, ignore): |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
292 self.read() |
536 | 293 dc = self.map.copy() |
294 lookup, changed, added, unknown = [], [], [], [] | |
295 | |
296 # compare all files by default | |
297 if not files: files = [self.root] | |
298 | |
299 # recursive generator of all files listed | |
300 def walk(files): | |
556 | 301 for f in util.unique(files): |
537 | 302 f = os.path.join(self.root, f) |
536 | 303 if os.path.isdir(f): |
304 for dir, subdirs, fl in os.walk(f): | |
305 d = dir[len(self.root) + 1:] | |
306 if ".hg" in subdirs: subdirs.remove(".hg") | |
307 for fn in fl: | |
308 fn = util.pconvert(os.path.join(d, fn)) | |
309 yield fn | |
310 else: | |
311 yield f[len(self.root) + 1:] | |
312 | |
556 | 313 for fn in util.unique(walk(files)): |
536 | 314 try: s = os.stat(os.path.join(self.root, fn)) |
315 except: continue | |
316 | |
317 if fn in dc: | |
318 c = dc[fn] | |
319 del dc[fn] | |
320 | |
321 if c[0] == 'm': | |
322 changed.append(fn) | |
323 elif c[0] == 'a': | |
324 added.append(fn) | |
325 elif c[0] == 'r': | |
326 unknown.append(fn) | |
327 elif c[2] != s.st_size or (c[1] ^ s.st_mode) & 0100: | |
328 changed.append(fn) | |
329 elif c[1] != s.st_mode or c[3] != s.st_mtime: | |
330 lookup.append(fn) | |
331 else: | |
332 if not ignore(fn): unknown.append(fn) | |
333 | |
334 return (lookup, changed, added, dc.keys(), unknown) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
335 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
336 # used to avoid circular references so destructors work |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
337 def opener(base): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
338 p = base |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
339 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
|
340 if p[:7] == "http://": |
6daf7757e92b
Fix network pull of repo files with "%" in their base64 encoding.
mpm@selenic.com
parents:
10
diff
changeset
|
341 f = os.path.join(p, urllib.quote(path)) |
372 | 342 return httprangereader.httprangereader(f) |
15
6daf7757e92b
Fix network pull of repo files with "%" in their base64 encoding.
mpm@selenic.com
parents:
10
diff
changeset
|
343 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
344 f = os.path.join(p, path) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
345 |
292 | 346 mode += "b" # for that other OS |
347 | |
348 if mode[0] != "r": | |
110
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
349 try: |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
350 s = os.stat(f) |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
351 except OSError: |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
352 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
|
353 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
|
354 os.makedirs(d) |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
355 else: |
c37c7f784ee3
Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents:
109
diff
changeset
|
356 if s.st_nlink > 1: |
417 | 357 file(f + ".tmp", "wb").write(file(f, "rb").read()) |
421 | 358 util.rename(f+".tmp", f) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
359 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
360 return file(f, mode) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
361 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
362 return o |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
363 |
499 | 364 class RepoError(Exception): pass |
365 | |
60 | 366 class localrepository: |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
367 def __init__(self, ui, path=None, create=0): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
368 self.remote = 0 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
369 if path and path[:7] == "http://": |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
370 self.remote = 1 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
371 self.path = path |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
372 else: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
373 if not path: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
374 p = os.getcwd() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
375 while not os.path.isdir(os.path.join(p, ".hg")): |
420
dbe86d465e09
[PATCH] Repo locator fix for the other `OS'
mpm@selenic.com
parents:
419
diff
changeset
|
376 oldp = p |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
377 p = os.path.dirname(p) |
499 | 378 if p == oldp: raise RepoError("no repo found") |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
379 path = p |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
380 self.path = os.path.join(path, ".hg") |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
381 |
405 | 382 if not create and not os.path.isdir(self.path): |
499 | 383 raise RepoError("repository %s not found" % self.path) |
405 | 384 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
385 self.root = path |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
386 self.ui = ui |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
387 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
388 if create: |
515 | 389 os.mkdir(self.path) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
390 os.mkdir(self.join("data")) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
391 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
392 self.opener = opener(self.path) |
291
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
393 self.wopener = opener(self.root) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
394 self.manifest = manifest(self.opener) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
395 self.changelog = changelog(self.opener) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
396 self.ignorelist = None |
343 | 397 self.tagscache = None |
398 self.nodetagscache = None | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
399 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
400 if not self.remote: |
244 | 401 self.dirstate = dirstate(self.opener, ui, self.root) |
337 | 402 try: |
403 self.ui.readconfig(self.opener("hgrc")) | |
404 except IOError: pass | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
405 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
406 def ignore(self, f): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
407 if self.ignorelist is None: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
408 self.ignorelist = [] |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
409 try: |
417 | 410 l = file(self.wjoin(".hgignore")) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
411 for pat in l: |
9 | 412 if pat != "\n": |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
418
diff
changeset
|
413 self.ignorelist.append(re.compile(util.pconvert(pat[:-1]))) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
414 except IOError: pass |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
415 for pat in self.ignorelist: |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
416 if pat.search(f): return True |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
417 return False |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
418 |
487 | 419 def hook(self, name, **args): |
420 s = self.ui.config("hooks", name) | |
421 if s: | |
422 self.ui.note("running hook %s: %s\n" % (name, s)) | |
423 old = {} | |
424 for k, v in args.items(): | |
425 k = k.upper() | |
426 old[k] = os.environ.get(k, None) | |
427 os.environ[k] = v | |
428 | |
429 r = os.system(s) | |
430 | |
431 for k, v in old.items(): | |
432 if v != None: | |
433 os.environ[k] = v | |
434 else: | |
435 del os.environ[k] | |
436 | |
437 if r: | |
438 self.ui.warn("abort: %s hook failed with status %d!\n" % | |
439 (name, r)) | |
440 return False | |
441 return True | |
442 | |
343 | 443 def tags(self): |
444 '''return a mapping of tag to node''' | |
477
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
445 if not self.tagscache: |
343 | 446 self.tagscache = {} |
67 | 447 try: |
254 | 448 # read each head of the tags file, ending with the tip |
449 # and add each tag found to the map, with "newer" ones | |
450 # taking precedence | |
67 | 451 fl = self.file(".hgtags") |
254 | 452 h = fl.heads() |
453 h.reverse() | |
454 for r in h: | |
455 for l in fl.revision(r).splitlines(): | |
456 if l: | |
385
e9e1efd5291c
Fixed problems with extra spaces around tags in .hgtags
Thomas Arendsen Hein <thomas@intevation.de>
parents:
383
diff
changeset
|
457 n, k = l.split(" ", 1) |
477
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
458 try: |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
459 bin_n = bin(n) |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
460 except TypeError: |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
461 bin_n = '' |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
462 self.tagscache[k.strip()] = bin_n |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
463 except KeyError: |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
464 pass |
454 | 465 for k, n in self.ui.configitems("tags"): |
477
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
466 try: |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
467 bin_n = bin(n) |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
468 except TypeError: |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
469 bin_n = '' |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
470 self.tagscache[k] = bin_n |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
471 |
343 | 472 self.tagscache['tip'] = self.changelog.tip() |
473 | |
474 return self.tagscache | |
475 | |
476 def tagslist(self): | |
477 '''return a list of tags ordered by revision''' | |
478 l = [] | |
477
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
479 for t, n in self.tags().items(): |
343 | 480 try: |
481 r = self.changelog.rev(n) | |
482 except: | |
483 r = -2 # sort to the beginning of the list if unknown | |
484 l.append((r,t,n)) | |
485 l.sort() | |
486 return [(t,n) for r,t,n in l] | |
487 | |
488 def nodetags(self, node): | |
489 '''return the tags associated with a node''' | |
490 if not self.nodetagscache: | |
491 self.nodetagscache = {} | |
492 for t,n in self.tags().items(): | |
493 self.nodetagscache.setdefault(n,[]).append(t) | |
494 return self.nodetagscache.get(node, []) | |
495 | |
496 def lookup(self, key): | |
67 | 497 try: |
343 | 498 return self.tags()[key] |
67 | 499 except KeyError: |
500 return self.changelog.lookup(key) | |
501 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
502 def join(self, f): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
503 return os.path.join(self.path, f) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
504 |
244 | 505 def wjoin(self, f): |
506 return os.path.join(self.root, f) | |
507 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
508 def file(self, f): |
192 | 509 if f[0] == '/': f = f[1:] |
144
ea9188538222
Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents:
140
diff
changeset
|
510 return filelog(self.opener, f) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
511 |
291
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
512 def wfile(self, f, mode='r'): |
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
513 return self.wopener(f, mode) |
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
514 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
515 def transaction(self): |
251 | 516 # save dirstate for undo |
263 | 517 try: |
518 ds = self.opener("dirstate").read() | |
519 except IOError: | |
520 ds = "" | |
251 | 521 self.opener("undo.dirstate", "w").write(ds) |
515 | 522 |
262 | 523 return transaction.transaction(self.opener, self.join("journal"), |
524 self.join("undo")) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
525 |
210 | 526 def recover(self): |
225 | 527 lock = self.lock() |
557 | 528 if os.path.exists(self.join("journal")): |
501 | 529 self.ui.status("rolling back interrupted transaction\n") |
557 | 530 return transaction.rollback(self.opener, self.join("journal")) |
210 | 531 else: |
532 self.ui.warn("no interrupted transaction available\n") | |
533 | |
534 def undo(self): | |
225 | 535 lock = self.lock() |
210 | 536 if os.path.exists(self.join("undo")): |
501 | 537 self.ui.status("rolling back last transaction\n") |
262 | 538 transaction.rollback(self.opener, self.join("undo")) |
251 | 539 self.dirstate = None |
421 | 540 util.rename(self.join("undo.dirstate"), self.join("dirstate")) |
251 | 541 self.dirstate = dirstate(self.opener, self.ui, self.root) |
163 | 542 else: |
210 | 543 self.ui.warn("no undo information available\n") |
162 | 544 |
161 | 545 def lock(self, wait = 1): |
546 try: | |
547 return lock.lock(self.join("lock"), 0) | |
548 except lock.LockHeld, inst: | |
549 if wait: | |
550 self.ui.warn("waiting for lock held by %s\n" % inst.args[0]) | |
551 return lock.lock(self.join("lock"), wait) | |
552 raise inst | |
553 | |
203 | 554 def rawcommit(self, files, text, user, date, p1=None, p2=None): |
442 | 555 orig_parent = self.dirstate.parents()[0] or nullid |
452
a1e91c24dab5
rawcommit: do lookup of parents at the appropriate layer
mpm@selenic.com
parents:
442
diff
changeset
|
556 p1 = p1 or self.dirstate.parents()[0] or nullid |
a1e91c24dab5
rawcommit: do lookup of parents at the appropriate layer
mpm@selenic.com
parents:
442
diff
changeset
|
557 p2 = p2 or self.dirstate.parents()[1] or nullid |
302 | 558 c1 = self.changelog.read(p1) |
559 c2 = self.changelog.read(p2) | |
560 m1 = self.manifest.read(c1[0]) | |
561 mf1 = self.manifest.readflags(c1[0]) | |
562 m2 = self.manifest.read(c2[0]) | |
563 | |
442 | 564 if orig_parent == p1: |
565 update_dirstate = 1 | |
566 else: | |
567 update_dirstate = 0 | |
568 | |
203 | 569 tr = self.transaction() |
302 | 570 mm = m1.copy() |
571 mfm = mf1.copy() | |
203 | 572 linkrev = self.changelog.count() |
573 for f in files: | |
574 try: | |
302 | 575 t = self.wfile(f).read() |
441 | 576 tm = util.is_exec(self.wjoin(f), mfm.get(f, False)) |
302 | 577 r = self.file(f) |
578 mfm[f] = tm | |
360 | 579 mm[f] = r.add(t, {}, tr, linkrev, |
302 | 580 m1.get(f, nullid), m2.get(f, nullid)) |
442 | 581 if update_dirstate: |
582 self.dirstate.update([f], "n") | |
203 | 583 except IOError: |
314
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
584 try: |
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
585 del mm[f] |
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
586 del mfm[f] |
442 | 587 if update_dirstate: |
588 self.dirstate.forget([f]) | |
314
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
589 except: |
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
590 # deleted from p2? |
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
591 pass |
203 | 592 |
302 | 593 mnode = self.manifest.add(mm, mfm, tr, linkrev, c1[0], c2[0]) |
594 n = self.changelog.add(mnode, files, text, tr, p1, p2, user, date) | |
203 | 595 tr.close() |
442 | 596 if update_dirstate: |
597 self.dirstate.setparents(n, nullid) | |
203 | 598 |
317 | 599 def commit(self, files = None, text = "", user = None, date = None): |
220 | 600 commit = [] |
601 remove = [] | |
602 if files: | |
603 for f in files: | |
604 s = self.dirstate.state(f) | |
244 | 605 if s in 'nmai': |
220 | 606 commit.append(f) |
607 elif s == 'r': | |
608 remove.append(f) | |
609 else: | |
244 | 610 self.ui.warn("%s not tracked!\n" % f) |
220 | 611 else: |
536 | 612 (c, a, d, u) = self.changes(None, None) |
220 | 613 commit = c + a |
614 remove = d | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
615 |
220 | 616 if not commit and not remove: |
151 | 617 self.ui.status("nothing changed\n") |
618 return | |
619 | |
487 | 620 if not self.hook("precommit"): |
621 return 1 | |
622 | |
229 | 623 p1, p2 = self.dirstate.parents() |
624 c1 = self.changelog.read(p1) | |
625 c2 = self.changelog.read(p2) | |
626 m1 = self.manifest.read(c1[0]) | |
276 | 627 mf1 = self.manifest.readflags(c1[0]) |
229 | 628 m2 = self.manifest.read(c2[0]) |
225 | 629 lock = self.lock() |
151 | 630 tr = self.transaction() |
631 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
632 # check in files |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
633 new = {} |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
634 linkrev = self.changelog.count() |
220 | 635 commit.sort() |
636 for f in commit: | |
83 | 637 self.ui.note(f + "\n") |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
638 try: |
441 | 639 mf1[f] = util.is_exec(self.wjoin(f), mf1.get(f, False)) |
418 | 640 t = self.wfile(f).read() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
641 except IOError: |
220 | 642 self.warn("trouble committing %s!\n" % f) |
643 raise | |
644 | |
363 | 645 meta = {} |
646 cp = self.dirstate.copied(f) | |
647 if cp: | |
648 meta["copy"] = cp | |
649 meta["copyrev"] = hex(m1.get(cp, m2.get(cp, nullid))) | |
575 | 650 self.ui.debug(" %s: copy %s:%s\n" % (f, cp, meta["copyrev"])) |
363 | 651 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
652 r = self.file(f) |
229 | 653 fp1 = m1.get(f, nullid) |
654 fp2 = m2.get(f, nullid) | |
363 | 655 new[f] = r.add(t, meta, tr, linkrev, fp1, fp2) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
656 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
657 # update manifest |
229 | 658 m1.update(new) |
416
5e9e8b8d2629
[PATCH] Removal of a file added by merging branches
mpm@selenic.com
parents:
415
diff
changeset
|
659 for f in remove: |
5e9e8b8d2629
[PATCH] Removal of a file added by merging branches
mpm@selenic.com
parents:
415
diff
changeset
|
660 if f in m1: |
5e9e8b8d2629
[PATCH] Removal of a file added by merging branches
mpm@selenic.com
parents:
415
diff
changeset
|
661 del m1[f] |
276 | 662 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
|
663 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
664 # add changeset |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
665 new = new.keys() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
666 new.sort() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
667 |
288 | 668 if not text: |
669 edittext = "\n" + "HG: manifest hash %s\n" % hex(mn) | |
670 edittext += "".join(["HG: changed %s\n" % f for f in new]) | |
671 edittext += "".join(["HG: removed %s\n" % f for f in remove]) | |
672 edittext = self.ui.edit(edittext) | |
673 if not edittext.rstrip(): | |
674 return 1 | |
675 text = edittext | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
676 |
317 | 677 n = self.changelog.add(mn, new, text, tr, p1, p2, user, date) |
487 | 678 |
679 if not self.hook("commit", node=hex(n)): | |
680 return 1 | |
681 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
682 tr.close() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
683 |
229 | 684 self.dirstate.setparents(n) |
220 | 685 self.dirstate.update(new, "n") |
686 self.dirstate.forget(remove) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
687 |
537 | 688 def changes(self, node1, node2, files=None): |
566 | 689 mf2, u = None, [] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
690 |
536 | 691 def fcmp(fn, mf): |
291
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
692 t1 = self.wfile(fn).read() |
29 | 693 t2 = self.file(fn).revision(mf[fn]) |
694 return cmp(t1, t2) | |
695 | |
536 | 696 # are we comparing the working directory? |
561 | 697 if not node2: |
536 | 698 l, c, a, d, u = self.dirstate.changes(files, self.ignore) |
699 | |
700 # are we comparing working dir against its parent? | |
561 | 701 if not node1: |
536 | 702 if l: |
703 # do a full compare of any files that might have changed | |
704 change = self.changelog.read(self.dirstate.parents()[0]) | |
561 | 705 mf2 = self.manifest.read(change[0]) |
548 | 706 for f in l: |
561 | 707 if fcmp(f, mf2): |
536 | 708 c.append(f) |
561 | 709 |
710 for l in c, a, d, u: | |
711 l.sort() | |
712 | |
536 | 713 return (c, a, d, u) |
515 | 714 |
536 | 715 # are we comparing working dir against non-tip? |
716 # generate a pseudo-manifest for the working dir | |
561 | 717 if not node2: |
718 if not mf2: | |
536 | 719 change = self.changelog.read(self.dirstate.parents()[0]) |
561 | 720 mf2 = self.manifest.read(change[0]).copy() |
536 | 721 for f in a + c + l: |
561 | 722 mf2[f] = "" |
536 | 723 for f in d: |
561 | 724 if f in mf2: del mf2[f] |
536 | 725 else: |
561 | 726 change = self.changelog.read(node2) |
727 mf2 = self.manifest.read(change[0]) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
728 |
566 | 729 # flush lists from dirstate before comparing manifests |
730 c, a = [], [] | |
731 | |
561 | 732 change = self.changelog.read(node1) |
733 mf1 = self.manifest.read(change[0]).copy() | |
32 | 734 |
735 for fn in mf2: | |
736 if mf1.has_key(fn): | |
737 if mf1[fn] != mf2[fn]: | |
561 | 738 if mf2[fn] != "" or fcmp(fn, mf1): |
536 | 739 c.append(fn) |
32 | 740 del mf1[fn] |
741 else: | |
536 | 742 a.append(fn) |
515 | 743 |
536 | 744 d = mf1.keys() |
561 | 745 |
746 for l in c, a, d, u: | |
747 l.sort() | |
515 | 748 |
536 | 749 return (c, a, d, u) |
32 | 750 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
751 def add(self, list): |
220 | 752 for f in list: |
244 | 753 p = self.wjoin(f) |
220 | 754 if not os.path.isfile(p): |
755 self.ui.warn("%s does not exist!\n" % f) | |
756 elif self.dirstate.state(f) == 'n': | |
757 self.ui.warn("%s already tracked!\n" % f) | |
758 else: | |
759 self.dirstate.update([f], "a") | |
760 | |
761 def forget(self, list): | |
762 for f in list: | |
763 if self.dirstate.state(f) not in 'ai': | |
764 self.ui.warn("%s not added!\n" % f) | |
765 else: | |
766 self.dirstate.forget([f]) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
767 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
768 def remove(self, list): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
769 for f in list: |
244 | 770 p = self.wjoin(f) |
220 | 771 if os.path.isfile(p): |
772 self.ui.warn("%s still exists!\n" % f) | |
402 | 773 elif self.dirstate.state(f) == 'a': |
774 self.ui.warn("%s never committed!\n" % f) | |
775 self.dirstate.forget(f) | |
220 | 776 elif f not in self.dirstate: |
777 self.ui.warn("%s not tracked!\n" % f) | |
778 else: | |
779 self.dirstate.update([f], "r") | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
780 |
363 | 781 def copy(self, source, dest): |
782 p = self.wjoin(dest) | |
783 if not os.path.isfile(dest): | |
784 self.ui.warn("%s does not exist!\n" % dest) | |
785 else: | |
786 if self.dirstate.state(dest) == '?': | |
787 self.dirstate.update([dest], "a") | |
788 self.dirstate.copy(source, dest) | |
789 | |
222 | 790 def heads(self): |
791 return self.changelog.heads() | |
792 | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
793 def branches(self, nodes): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
794 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
|
795 b = [] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
796 for n in nodes: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
797 t = n |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
798 while n: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
799 p = self.changelog.parents(n) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
800 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
|
801 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
|
802 break |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
803 n = p[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
804 return b |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
805 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
806 def between(self, pairs): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
807 r = [] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
808 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
809 for top, bottom in pairs: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
810 n, l, i = top, [], 0 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
811 f = 1 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
812 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
813 while n != bottom: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
814 p = self.changelog.parents(n)[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
815 if i == f: |
575 | 816 l.append(n) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
817 f = f * 2 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
818 n = p |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
819 i += 1 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
820 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
821 r.append(l) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
822 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
823 return r |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
824 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
825 def newer(self, nodes): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
826 m = {} |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
827 nl = [] |
94 | 828 pm = {} |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
829 cl = self.changelog |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
830 t = l = cl.count() |
94 | 831 |
832 # find the lowest numbered node | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
833 for n in nodes: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
834 l = min(l, cl.rev(n)) |
94 | 835 m[n] = 1 |
46 | 836 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
837 for i in xrange(l, t): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
838 n = cl.node(i) |
94 | 839 if n in m: # explicitly listed |
840 pm[n] = 1 | |
841 nl.append(n) | |
842 continue | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
843 for p in cl.parents(n): |
94 | 844 if p in pm: # parent listed |
845 pm[n] = 1 | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
846 nl.append(n) |
94 | 847 break |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
848 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
849 return nl |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
850 |
516 | 851 def findincoming(self, remote): |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
852 m = self.changelog.nodemap |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
853 search = [] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
854 fetch = [] |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
855 base = {} |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
856 seen = {} |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
857 seenbranch = {} |
192 | 858 |
190
3dd5ce2fddb6
merge: short-circuit search for merge into empty repo
mpm@selenic.com
parents:
187
diff
changeset
|
859 # 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
|
860 if self.changelog.tip() == nullid: |
222 | 861 self.ui.status("requesting all changes\n") |
516 | 862 return [nullid] |
190
3dd5ce2fddb6
merge: short-circuit search for merge into empty repo
mpm@selenic.com
parents:
187
diff
changeset
|
863 |
3dd5ce2fddb6
merge: short-circuit search for merge into empty repo
mpm@selenic.com
parents:
187
diff
changeset
|
864 # otherwise, assume we're closer to the tip than the root |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
865 # and start by examining the heads |
222 | 866 self.ui.status("searching for changes\n") |
867 heads = remote.heads() | |
868 unknown = [] | |
869 for h in heads: | |
870 if h not in m: | |
871 unknown.append(h) | |
46 | 872 |
222 | 873 if not unknown: |
60 | 874 return None |
324 | 875 |
876 rep = {} | |
877 reqcnt = 0 | |
515 | 878 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
879 # search through remote branches |
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
880 # a 'branch' here is a linear segment of history, with four parts: |
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
881 # head, root, first parent, second parent |
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
882 # (a branch always has two parents (or none) by definition) |
222 | 883 unknown = remote.branches(unknown) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
884 while unknown: |
324 | 885 r = [] |
886 while unknown: | |
887 n = unknown.pop(0) | |
888 if n[0] in seen: | |
889 continue | |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
890 |
324 | 891 self.ui.debug("examining %s:%s\n" % (short(n[0]), short(n[1]))) |
892 if n[0] == nullid: | |
893 break | |
328 | 894 if n in seenbranch: |
324 | 895 self.ui.debug("branch already found\n") |
896 continue | |
897 if n[1] and n[1] in m: # do we know the base? | |
898 self.ui.debug("found incomplete branch %s:%s\n" | |
899 % (short(n[0]), short(n[1]))) | |
900 search.append(n) # schedule branch range for scanning | |
328 | 901 seenbranch[n] = 1 |
324 | 902 else: |
903 if n[1] not in seen and n[1] not in fetch: | |
904 if n[2] in m and n[3] in m: | |
905 self.ui.debug("found new changeset %s\n" % | |
906 short(n[1])) | |
907 fetch.append(n[1]) # earliest unknown | |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
908 base[n[2]] = 1 # latest known |
324 | 909 continue |
910 | |
911 for a in n[2:4]: | |
912 if a not in rep: | |
913 r.append(a) | |
914 rep[a] = 1 | |
915 | |
328 | 916 seen[n[0]] = 1 |
917 | |
324 | 918 if r: |
919 reqcnt += 1 | |
920 self.ui.debug("request %d: %s\n" % | |
921 (reqcnt, " ".join(map(short, r)))) | |
922 for p in range(0, len(r), 10): | |
923 for b in remote.branches(r[p:p+10]): | |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
924 self.ui.debug("received %s:%s\n" % |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
925 (short(b[0]), short(b[1]))) |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
926 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
|
927 unknown.append(b) |
515 | 928 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
929 # do binary search on the branches we found |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
930 while search: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
931 n = search.pop(0) |
324 | 932 reqcnt += 1 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
933 l = remote.between([(n[0], n[1])])[0] |
328 | 934 l.append(n[1]) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
935 p = n[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
936 f = 1 |
328 | 937 for i in l: |
938 self.ui.debug("narrowing %d:%d %s\n" % (f, len(l), short(i))) | |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
939 if i in m: |
85 | 940 if f <= 2: |
83 | 941 self.ui.debug("found new branch changeset %s\n" % |
942 short(p)) | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
943 fetch.append(p) |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
944 base[i] = 1 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
945 else: |
83 | 946 self.ui.debug("narrowed branch search to %s:%s\n" |
947 % (short(p), short(i))) | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
948 search.append((p, i)) |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
949 break |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
950 p, f = i, f * 2 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
951 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
952 # sanity check our fetch list |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
953 for f in fetch: |
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
954 if f in m: |
499 | 955 raise RepoError("already have changeset " + short(f[:4])) |
83 | 956 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
957 if base.keys() == [nullid]: |
514
874e577e332e
change unrelated repository error to a warning
mpm@selenic.com
parents:
511
diff
changeset
|
958 self.ui.warn("warning: pulling from an unrelated repository!\n") |
511 | 959 |
94 | 960 self.ui.note("adding new changesets starting at " + |
83 | 961 " ".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
|
962 |
324 | 963 self.ui.debug("%d total queries\n" % reqcnt) |
964 | |
516 | 965 return fetch |
966 | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
967 def changegroup(self, basenodes): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
968 nodes = self.newer(basenodes) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
969 |
46 | 970 # construct the link map |
971 linkmap = {} | |
972 for n in nodes: | |
973 linkmap[self.changelog.rev(n)] = n | |
974 | |
975 # construct a list of all changed files | |
976 changed = {} | |
977 for n in nodes: | |
978 c = self.changelog.read(n) | |
979 for f in c[3]: | |
980 changed[f] = 1 | |
981 changed = changed.keys() | |
982 changed.sort() | |
983 | |
984 # the changegroup is changesets + manifests + all file revs | |
985 revs = [ self.changelog.rev(n) for n in nodes ] | |
986 | |
192 | 987 for y in self.changelog.group(linkmap): yield y |
988 for y in self.manifest.group(linkmap): yield y | |
46 | 989 for f in changed: |
192 | 990 yield struct.pack(">l", len(f) + 4) + f |
46 | 991 g = self.file(f).group(linkmap) |
192 | 992 for y in g: |
993 yield y | |
46 | 994 |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
995 def addchangegroup(self, generator): |
222 | 996 |
997 class genread: | |
998 def __init__(self, generator): | |
999 self.g = generator | |
1000 self.buf = "" | |
1001 def read(self, l): | |
1002 while l > len(self.buf): | |
1003 try: | |
1004 self.buf += self.g.next() | |
1005 except StopIteration: | |
1006 break | |
1007 d, self.buf = self.buf[:l], self.buf[l:] | |
1008 return d | |
515 | 1009 |
222 | 1010 def getchunk(): |
1011 d = source.read(4) | |
1012 if not d: return "" | |
1013 l = struct.unpack(">l", d)[0] | |
1014 if l <= 4: return "" | |
1015 return source.read(l - 4) | |
1016 | |
1017 def getgroup(): | |
1018 while 1: | |
1019 c = getchunk() | |
1020 if not c: break | |
1021 yield c | |
1022 | |
1023 def csmap(x): | |
1024 self.ui.debug("add changeset %s\n" % short(x)) | |
1025 return self.changelog.count() | |
1026 | |
1027 def revmap(x): | |
1028 return self.changelog.rev(x) | |
1029 | |
1030 if not generator: return | |
1031 changesets = files = revisions = 0 | |
225 | 1032 |
222 | 1033 source = genread(generator) |
225 | 1034 lock = self.lock() |
222 | 1035 tr = self.transaction() |
1036 | |
1037 # pull off the changeset group | |
1038 self.ui.status("adding changesets\n") | |
1039 co = self.changelog.tip() | |
224
ccbcc4d76f81
fix bad assumption about uniqueness of file versions
mpm@selenic.com
parents:
223
diff
changeset
|
1040 cn = self.changelog.addgroup(getgroup(), csmap, tr, 1) # unique |
222 | 1041 changesets = self.changelog.rev(cn) - self.changelog.rev(co) |
1042 | |
1043 # pull off the manifest group | |
1044 self.ui.status("adding manifests\n") | |
1045 mm = self.manifest.tip() | |
1046 mo = self.manifest.addgroup(getgroup(), revmap, tr) | |
1047 | |
1048 # process the files | |
1049 self.ui.status("adding file revisions\n") | |
1050 while 1: | |
1051 f = getchunk() | |
1052 if not f: break | |
1053 self.ui.debug("adding %s revisions\n" % f) | |
1054 fl = self.file(f) | |
529
aace5b681fe9
Attempt to fix negative revision count from pull
mpm@selenic.com
parents:
522
diff
changeset
|
1055 o = fl.count() |
222 | 1056 n = fl.addgroup(getgroup(), revmap, tr) |
529
aace5b681fe9
Attempt to fix negative revision count from pull
mpm@selenic.com
parents:
522
diff
changeset
|
1057 revisions += fl.count() - o |
222 | 1058 files += 1 |
1059 | |
1060 self.ui.status(("modified %d files, added %d changesets" + | |
1061 " and %d new revisions\n") | |
1062 % (files, changesets, revisions)) | |
1063 | |
1064 tr.close() | |
1065 return | |
1066 | |
275 | 1067 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
|
1068 pl = self.dirstate.parents() |
275 | 1069 if not force and pl[1] != nullid: |
254 | 1070 self.ui.warn("aborting: outstanding uncommitted merges\n") |
46 | 1071 return |
1072 | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1073 p1, p2 = pl[0], node |
305 | 1074 pa = self.changelog.ancestor(p1, p2) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1075 m1n = self.changelog.read(p1)[0] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1076 m2n = self.changelog.read(p2)[0] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1077 man = self.manifest.ancestor(m1n, m2n) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1078 m1 = self.manifest.read(m1n) |
276 | 1079 mf1 = self.manifest.readflags(m1n) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1080 m2 = self.manifest.read(m2n) |
276 | 1081 mf2 = self.manifest.readflags(m2n) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1082 ma = self.manifest.read(man) |
412 | 1083 mfa = self.manifest.readflags(man) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1084 |
536 | 1085 (c, a, d, u) = self.changes(None, None) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1086 |
408
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1087 # is this a jump, or a merge? i.e. is there a linear path |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1088 # from p1 to p2? |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1089 linear_path = (pa == p1 or pa == p2) |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1090 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1091 # 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
|
1092 # we care about merging |
254 | 1093 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
|
1094 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
|
1095 (short(man), short(m1n), short(m2n))) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1096 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1097 merge = {} |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1098 get = {} |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1099 remove = [] |
305 | 1100 mark = {} |
46 | 1101 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1102 # construct a working dir manifest |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1103 mw = m1.copy() |
276 | 1104 mfw = mf1.copy() |
576 | 1105 umap = dict.fromkeys(u) |
1106 | |
254 | 1107 for f in a + c + u: |
1108 mw[f] = "" | |
441 | 1109 mfw[f] = util.is_exec(self.wjoin(f), mfw.get(f, False)) |
576 | 1110 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1111 for f in d: |
254 | 1112 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
|
1113 |
408
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1114 # If we're jumping between revisions (as opposed to merging), |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1115 # and if neither the working directory nor the target rev has |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1116 # the file, then we need to remove it from the dirstate, to |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1117 # prevent the dirstate from listing the file when it is no |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1118 # longer in the manifest. |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1119 if linear_path and f not in m2: |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1120 self.dirstate.forget((f,)) |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1121 |
576 | 1122 # Compare manifests |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1123 for f, n in mw.iteritems(): |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1124 if f in m2: |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1125 s = 0 |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1126 |
407
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1127 # is the wfile new since m1, and match m2? |
428 | 1128 if f not in m1: |
407
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1129 t1 = self.wfile(f).read() |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1130 t2 = self.file(f).revision(m2[f]) |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1131 if cmp(t1, t2) == 0: |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1132 mark[f] = 1 |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1133 n = m2[f] |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1134 del t1, t2 |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1135 |
296
a3d83bf86755
hg update: fix clobbering files when going backwards
mpm@selenic.com
parents:
292
diff
changeset
|
1136 # are files different? |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1137 if n != m2[f]: |
254 | 1138 a = ma.get(f, nullid) |
296
a3d83bf86755
hg update: fix clobbering files when going backwards
mpm@selenic.com
parents:
292
diff
changeset
|
1139 # are both different from the ancestor? |
254 | 1140 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
|
1141 self.ui.debug(" %s versions differ, resolve\n" % f) |
276 | 1142 # merge executable bits |
1143 # "if we changed or they changed, change in merge" | |
1144 a, b, c = mfa.get(f, 0), mfw[f], mf2[f] | |
1145 mode = ((a^b) | (a^c)) ^ a | |
1146 merge[f] = (m1.get(f, nullid), m2[f], mode) | |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1147 s = 1 |
305 | 1148 # are we clobbering? |
1149 # is remote's version newer? | |
1150 # or are we going back in time? | |
1151 elif force or m2[f] != a or (p2 == pa and mw[f] == m1[f]): | |
273
4f8174389001
merge: Fix bug where we overwrote local when local was newer
mpm@selenic.com
parents:
263
diff
changeset
|
1152 self.ui.debug(" remote %s is newer, get\n" % f) |
254 | 1153 get[f] = m2[f] |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1154 s = 1 |
305 | 1155 else: |
1156 mark[f] = 1 | |
576 | 1157 elif f in umap: |
1158 # this unknown file is the same as the checkout | |
1159 get[f] = m2[f] | |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1160 |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1161 if not s and mfw[f] != mf2[f]: |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1162 if force: |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1163 self.ui.debug(" updating permissions for %s\n" % f) |
441 | 1164 util.set_exec(self.wjoin(f), mf2[f]) |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1165 else: |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1166 a, b, c = mfa.get(f, 0), mfw[f], mf2[f] |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1167 mode = ((a^b) | (a^c)) ^ a |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1168 if mode != b: |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1169 self.ui.debug(" updating permissions for %s\n" % f) |
441 | 1170 util.set_exec(self.wjoin(f), mode) |
305 | 1171 mark[f] = 1 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1172 del m2[f] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1173 elif f in ma: |
275 | 1174 if not force and n != ma[f]: |
415
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1175 r = "" |
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1176 if linear_path or allow: |
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1177 r = self.ui.prompt( |
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1178 (" local changed %s which remote deleted\n" % f) + |
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1179 "(k)eep or (d)elete?", "[kd]", "k") |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1180 if r == "d": |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1181 remove.append(f) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1182 else: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1183 self.ui.debug("other deleted %s\n" % f) |
254 | 1184 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
|
1185 else: |
254 | 1186 if n == m1.get(f, nullid): # same as parent |
383
4862a134e2c2
hg merge: fix time asymmetry bug with deleting files on update to past
mpm@selenic.com
parents:
377
diff
changeset
|
1187 if p2 == pa: # going backwards? |
4862a134e2c2
hg merge: fix time asymmetry bug with deleting files on update to past
mpm@selenic.com
parents:
377
diff
changeset
|
1188 self.ui.debug("remote deleted %s\n" % f) |
4862a134e2c2
hg merge: fix time asymmetry bug with deleting files on update to past
mpm@selenic.com
parents:
377
diff
changeset
|
1189 remove.append(f) |
4862a134e2c2
hg merge: fix time asymmetry bug with deleting files on update to past
mpm@selenic.com
parents:
377
diff
changeset
|
1190 else: |
4862a134e2c2
hg merge: fix time asymmetry bug with deleting files on update to past
mpm@selenic.com
parents:
377
diff
changeset
|
1191 self.ui.debug("local created %s, keeping\n" % f) |
254 | 1192 else: |
1193 self.ui.debug("working dir created %s, keeping\n" % f) | |
46 | 1194 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1195 for f, n in m2.iteritems(): |
256 | 1196 if f[0] == "/": continue |
275 | 1197 if not force and f in ma and n != ma[f]: |
415
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1198 r = "" |
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1199 if linear_path or allow: |
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1200 r = self.ui.prompt( |
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1201 ("remote changed %s which local deleted\n" % f) + |
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1202 "(k)eep or (d)elete?", "[kd]", "k") |
275 | 1203 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
|
1204 else: |
254 | 1205 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
|
1206 get[f] = n |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1207 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1208 del mw, m1, m2, ma |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1209 |
275 | 1210 if force: |
1211 for f in merge: | |
1212 get[f] = merge[f][1] | |
1213 merge = {} | |
1214 | |
408
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1215 if linear_path: |
254 | 1216 # we don't need to do any magic, just jump to the new rev |
1217 mode = 'n' | |
1218 p1, p2 = p2, nullid | |
1219 else: | |
275 | 1220 if not allow: |
305 | 1221 self.ui.status("this update spans a branch" + |
1222 " affecting the following files:\n") | |
1223 fl = merge.keys() + get.keys() | |
1224 fl.sort() | |
1225 for f in fl: | |
1226 cf = "" | |
1227 if f in merge: cf = " (resolve)" | |
1228 self.ui.status(" %s%s\n" % (f, cf)) | |
1229 self.ui.warn("aborting update spanning branches!\n") | |
1230 self.ui.status("(use update -m to perform a branch merge)\n") | |
275 | 1231 return 1 |
254 | 1232 # we have to remember what files we needed to get/change |
1233 # because any file that's different from either one of its | |
1234 # parents must be in the changeset | |
1235 mode = 'm' | |
305 | 1236 self.dirstate.update(mark.keys(), "m") |
254 | 1237 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1238 self.dirstate.setparents(p1, p2) |
191
d7e859cf2f1b
merge: add count of new manifests, files, and revisions
mpm@selenic.com
parents:
190
diff
changeset
|
1239 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1240 # 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
|
1241 files = get.keys() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1242 files.sort() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1243 for f in files: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1244 if f[0] == "/": continue |
273
4f8174389001
merge: Fix bug where we overwrote local when local was newer
mpm@selenic.com
parents:
263
diff
changeset
|
1245 self.ui.note("getting %s\n" % f) |
276 | 1246 t = self.file(f).read(get[f]) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1247 try: |
291
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
1248 self.wfile(f, "w").write(t) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1249 except IOError: |
297
0dbcf3c9ff20
Fixed usage of removed variable 'wp'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
292
diff
changeset
|
1250 os.makedirs(os.path.dirname(self.wjoin(f))) |
291
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
1251 self.wfile(f, "w").write(t) |
441 | 1252 util.set_exec(self.wjoin(f), mf2[f]) |
254 | 1253 self.dirstate.update([f], mode) |
46 | 1254 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1255 # merge the tricky bits |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1256 files = merge.keys() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1257 files.sort() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1258 for f in files: |
256 | 1259 self.ui.status("merging %s\n" % f) |
276 | 1260 m, o, flag = merge[f] |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1261 self.merge3(f, m, o) |
441 | 1262 util.set_exec(self.wjoin(f), flag) |
254 | 1263 self.dirstate.update([f], 'm') |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1264 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1265 for f in remove: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1266 self.ui.note("removing %s\n" % f) |
254 | 1267 os.unlink(f) |
578 | 1268 # try removing directories that might now be empty |
1269 try: os.removedirs(os.path.dirname(f)) | |
1270 except: pass | |
254 | 1271 if mode == 'n': |
1272 self.dirstate.forget(remove) | |
1273 else: | |
1274 self.dirstate.update(remove, 'r') | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1275 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1276 def merge3(self, fn, my, other): |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1277 """perform a 3-way merge in the working directory""" |
249 | 1278 |
96 | 1279 def temp(prefix, node): |
1280 pre = "%s~%s." % (os.path.basename(fn), prefix) | |
1281 (fd, name) = tempfile.mkstemp("", pre) | |
417 | 1282 f = os.fdopen(fd, "wb") |
96 | 1283 f.write(fl.revision(node)) |
1284 f.close() | |
1285 return name | |
1286 | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1287 fl = self.file(fn) |
96 | 1288 base = fl.ancestor(my, other) |
244 | 1289 a = self.wjoin(fn) |
346 | 1290 b = temp("base", base) |
1291 c = temp("other", other) | |
96 | 1292 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1293 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
|
1294 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
|
1295 (fn, short(other), short(base))) |
96 | 1296 |
240 | 1297 cmd = os.environ.get("HGMERGE", "hgmerge") |
1298 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
|
1299 if r: |
275 | 1300 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
|
1301 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1302 os.unlink(b) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1303 os.unlink(c) |
96 | 1304 |
247 | 1305 def verify(self): |
1306 filelinkrevs = {} | |
1307 filenodes = {} | |
1308 changesets = revisions = files = 0 | |
1309 errors = 0 | |
1310 | |
302 | 1311 seen = {} |
247 | 1312 self.ui.status("checking changesets\n") |
1313 for i in range(self.changelog.count()): | |
1314 changesets += 1 | |
1315 n = self.changelog.node(i) | |
302 | 1316 if n in seen: |
1317 self.ui.warn("duplicate changeset at revision %d\n" % i) | |
1318 errors += 1 | |
1319 seen[n] = 1 | |
515 | 1320 |
247 | 1321 for p in self.changelog.parents(n): |
1322 if p not in self.changelog.nodemap: | |
1323 self.ui.warn("changeset %s has unknown parent %s\n" % | |
1324 (short(n), short(p))) | |
1325 errors += 1 | |
1326 try: | |
1327 changes = self.changelog.read(n) | |
1328 except Exception, inst: | |
1329 self.ui.warn("unpacking changeset %s: %s\n" % (short(n), inst)) | |
1330 errors += 1 | |
1331 | |
1332 for f in changes[3]: | |
1333 filelinkrevs.setdefault(f, []).append(i) | |
1334 | |
302 | 1335 seen = {} |
247 | 1336 self.ui.status("checking manifests\n") |
1337 for i in range(self.manifest.count()): | |
1338 n = self.manifest.node(i) | |
302 | 1339 if n in seen: |
1340 self.ui.warn("duplicate manifest at revision %d\n" % i) | |
1341 errors += 1 | |
1342 seen[n] = 1 | |
515 | 1343 |
247 | 1344 for p in self.manifest.parents(n): |
1345 if p not in self.manifest.nodemap: | |
1346 self.ui.warn("manifest %s has unknown parent %s\n" % | |
1347 (short(n), short(p))) | |
1348 errors += 1 | |
1349 | |
1350 try: | |
1351 delta = mdiff.patchtext(self.manifest.delta(n)) | |
1352 except KeyboardInterrupt: | |
1353 print "aborted" | |
1354 sys.exit(0) | |
1355 except Exception, inst: | |
1356 self.ui.warn("unpacking manifest %s: %s\n" | |
1357 % (short(n), inst)) | |
1358 errors += 1 | |
1359 | |
1360 ff = [ l.split('\0') for l in delta.splitlines() ] | |
1361 for f, fn in ff: | |
284 | 1362 filenodes.setdefault(f, {})[bin(fn[:40])] = 1 |
247 | 1363 |
1364 self.ui.status("crosschecking files in changesets and manifests\n") | |
1365 for f in filenodes: | |
1366 if f not in filelinkrevs: | |
1367 self.ui.warn("file %s in manifest but not in changesets\n" % f) | |
1368 errors += 1 | |
1369 | |
1370 for f in filelinkrevs: | |
1371 if f not in filenodes: | |
1372 self.ui.warn("file %s in changeset but not in manifest\n" % f) | |
1373 errors += 1 | |
1374 | |
1375 self.ui.status("checking files\n") | |
1376 ff = filenodes.keys() | |
1377 ff.sort() | |
1378 for f in ff: | |
1379 if f == "/dev/null": continue | |
1380 files += 1 | |
1381 fl = self.file(f) | |
1382 nodes = { nullid: 1 } | |
302 | 1383 seen = {} |
247 | 1384 for i in range(fl.count()): |
1385 revisions += 1 | |
1386 n = fl.node(i) | |
1387 | |
302 | 1388 if n in seen: |
1389 self.ui.warn("%s: duplicate revision %d\n" % (f, i)) | |
1390 errors += 1 | |
1391 | |
247 | 1392 if n not in filenodes[f]: |
1393 self.ui.warn("%s: %d:%s not in manifests\n" | |
1394 % (f, i, short(n))) | |
1395 print len(filenodes[f].keys()), fl.count(), f | |
1396 errors += 1 | |
1397 else: | |
1398 del filenodes[f][n] | |
1399 | |
1400 flr = fl.linkrev(n) | |
1401 if flr not in filelinkrevs[f]: | |
1402 self.ui.warn("%s:%s points to unexpected changeset %d\n" | |
1403 % (f, short(n), fl.linkrev(n))) | |
1404 errors += 1 | |
1405 else: | |
1406 filelinkrevs[f].remove(flr) | |
1407 | |
1408 # verify contents | |
1409 try: | |
1410 t = fl.read(n) | |
1411 except Exception, inst: | |
1412 self.ui.warn("unpacking file %s %s: %s\n" | |
1413 % (f, short(n), inst)) | |
1414 errors += 1 | |
1415 | |
1416 # verify parents | |
1417 (p1, p2) = fl.parents(n) | |
1418 if p1 not in nodes: | |
1419 self.ui.warn("file %s:%s unknown parent 1 %s" % | |
1420 (f, short(n), short(p1))) | |
1421 errors += 1 | |
1422 if p2 not in nodes: | |
1423 self.ui.warn("file %s:%s unknown parent 2 %s" % | |
1424 (f, short(n), short(p1))) | |
1425 errors += 1 | |
1426 nodes[n] = 1 | |
1427 | |
1428 # cross-check | |
1429 for node in filenodes[f]: | |
1430 self.ui.warn("node %s in manifests not in %s\n" | |
1431 % (hex(n), f)) | |
1432 errors += 1 | |
1433 | |
1434 self.ui.status("%d files, %d changesets, %d total revisions\n" % | |
1435 (files, changesets, revisions)) | |
1436 | |
1437 if errors: | |
1438 self.ui.warn("%d integrity errors encountered!\n" % errors) | |
1439 return 1 | |
1440 | |
60 | 1441 class remoterepository: |
1442 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
|
1443 self.url = path |
60 | 1444 self.ui = ui |
321 | 1445 no_list = [ "localhost", "127.0.0.1" ] |
1446 host = ui.config("http_proxy", "host") | |
424
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1447 if host is None: |
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1448 host = os.environ.get("http_proxy") |
426
8c90ab5644c9
Allow hgrc's proxy host and $http_proxy env var to start with http://
Thomas Arendsen Hein <thomas@intevation.de>
parents:
424
diff
changeset
|
1449 if host and host.startswith('http://'): |
8c90ab5644c9
Allow hgrc's proxy host and $http_proxy env var to start with http://
Thomas Arendsen Hein <thomas@intevation.de>
parents:
424
diff
changeset
|
1450 host = host[7:] |
321 | 1451 user = ui.config("http_proxy", "user") |
1452 passwd = ui.config("http_proxy", "passwd") | |
1453 no = ui.config("http_proxy", "no") | |
424
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1454 if no is None: |
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1455 no = os.environ.get("no_proxy") |
321 | 1456 if no: |
1457 no_list = no_list + no.split(",") | |
515 | 1458 |
321 | 1459 no_proxy = 0 |
1460 for h in no_list: | |
1461 if (path.startswith("http://" + h + "/") or | |
1462 path.startswith("http://" + h + ":") or | |
1463 path == "http://" + h): | |
1464 no_proxy = 1 | |
1465 | |
1466 # Note: urllib2 takes proxy values from the environment and those will | |
1467 # take precedence | |
424
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1468 for env in ["HTTP_PROXY", "http_proxy", "no_proxy"]: |
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1469 if os.environ.has_key(env): |
9294dce4b633
Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
385
diff
changeset
|
1470 del os.environ[env] |
321 | 1471 |
1472 proxy_handler = urllib2.BaseHandler() | |
1473 if host and not no_proxy: | |
1474 proxy_handler = urllib2.ProxyHandler({"http" : "http://" + host}) | |
1475 | |
1476 authinfo = None | |
1477 if user and passwd: | |
1478 passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm() | |
1479 passmgr.add_password(None, host, user, passwd) | |
1480 authinfo = urllib2.ProxyBasicAuthHandler(passmgr) | |
1481 | |
1482 opener = urllib2.build_opener(proxy_handler, authinfo) | |
1483 urllib2.install_opener(opener) | |
60 | 1484 |
1485 def do_cmd(self, cmd, **args): | |
83 | 1486 self.ui.debug("sending %s command\n" % cmd) |
60 | 1487 q = {"cmd": cmd} |
1488 q.update(args) | |
1489 qs = urllib.urlencode(q) | |
1490 cu = "%s?%s" % (self.url, qs) | |
321 | 1491 return urllib2.urlopen(cu) |
60 | 1492 |
222 | 1493 def heads(self): |
1494 d = self.do_cmd("heads").read() | |
1495 try: | |
1496 return map(bin, d[:-1].split(" ")) | |
1497 except: | |
1498 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |
1499 raise | |
1500 | |
60 | 1501 def branches(self, nodes): |
1502 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
|
1503 d = self.do_cmd("branches", nodes=n).read() |
217 | 1504 try: |
1505 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ] | |
1506 return br | |
1507 except: | |
1508 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |
1509 raise | |
60 | 1510 |
1511 def between(self, pairs): | |
1512 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
|
1513 d = self.do_cmd("between", pairs=n).read() |
217 | 1514 try: |
1515 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ] | |
1516 return p | |
1517 except: | |
1518 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |
1519 raise | |
60 | 1520 |
1521 def changegroup(self, nodes): | |
1522 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
|
1523 zd = zlib.decompressobj() |
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1524 f = self.do_cmd("changegroup", roots=n) |
192 | 1525 bytes = 0 |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1526 while 1: |
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1527 d = f.read(4096) |
192 | 1528 bytes += len(d) |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1529 if not d: |
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1530 yield zd.flush() |
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1531 break |
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
1532 yield zd.decompress(d) |
192 | 1533 self.ui.note("%d bytes of data transfered\n" % bytes) |
60 | 1534 |
1535 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
|
1536 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
|
1537 return remoterepository(ui, path) |
60 | 1538 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
|
1539 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
|
1540 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
|
1541 return localrepository(ui, path.replace("old-http://", "http://")) |
60 | 1542 else: |
1543 return localrepository(ui, path, create) | |
1544 |