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