Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/localrepo.py @ 1447:508a3f559553
revert added and removed files to their normal state before reverting
add a test for revert
author | Benoit Boissinot <benoit.boissinot@ens-lyon.org> |
---|---|
date | Tue, 25 Oct 2005 15:51:28 -0700 |
parents | 0980d77f5e9a |
children | 182879d71922 |
rev | line source |
---|---|
1089 | 1 # localrepo.py - read/write repository class for mercurial |
0
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 |
1097 | 8 import struct, os, util |
1100 | 9 import filelog, manifest, changelog, dirstate, repo |
1089 | 10 from node import * |
1400
cf9a1233738a
i18n first part: make '_' available for files who need it
Benoit Boissinot <benoit.boissinot@ens-lyon.org
parents:
1398
diff
changeset
|
11 from i18n import gettext as _ |
262 | 12 from demandload import * |
1353
a0c68981a5f4
Fix misleading abort message when permissions are bad.
Eric Hopper <hopper@omnifarious.org>
parents:
1349
diff
changeset
|
13 demandload(globals(), "re lock transaction tempfile stat mdiff errno") |
499 | 14 |
60 | 15 class localrepository: |
1102 | 16 def __init__(self, ui, path=None, create=0): |
1101 | 17 if not path: |
18 p = os.getcwd() | |
19 while not os.path.isdir(os.path.join(p, ".hg")): | |
20 oldp = p | |
21 p = os.path.dirname(p) | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
22 if p == oldp: raise repo.RepoError(_("no repo found")) |
1101 | 23 path = p |
24 self.path = os.path.join(path, ".hg") | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
25 |
1101 | 26 if not create and not os.path.isdir(self.path): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
27 raise repo.RepoError(_("repository %s not found") % self.path) |
405 | 28 |
933
9c43d68ad59f
Fixed --repository option when handling relative path
tksoh@users.sf.net
parents:
926
diff
changeset
|
29 self.root = os.path.abspath(path) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
30 self.ui = ui |
1102 | 31 self.opener = util.opener(self.path) |
32 self.wopener = util.opener(self.root) | |
1100 | 33 self.manifest = manifest.manifest(self.opener) |
34 self.changelog = changelog.changelog(self.opener) | |
343 | 35 self.tagscache = None |
36 self.nodetagscache = None | |
1258 | 37 self.encodepats = None |
38 self.decodepats = None | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
39 |
1133
899b619a7eb2
Create [web] section with short username as contact on hg init and hg clone.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1117
diff
changeset
|
40 if create: |
899b619a7eb2
Create [web] section with short username as contact on hg init and hg clone.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1117
diff
changeset
|
41 os.mkdir(self.path) |
899b619a7eb2
Create [web] section with short username as contact on hg init and hg clone.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1117
diff
changeset
|
42 os.mkdir(self.join("data")) |
899b619a7eb2
Create [web] section with short username as contact on hg init and hg clone.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1117
diff
changeset
|
43 |
1101 | 44 self.dirstate = dirstate.dirstate(self.opener, ui, self.root) |
45 try: | |
46 self.ui.readconfig(self.opener("hgrc")) | |
47 except IOError: pass | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
48 |
487 | 49 def hook(self, name, **args): |
50 s = self.ui.config("hooks", name) | |
51 if s: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
52 self.ui.note(_("running hook %s: %s\n") % (name, s)) |
487 | 53 old = {} |
54 for k, v in args.items(): | |
55 k = k.upper() | |
56 old[k] = os.environ.get(k, None) | |
57 os.environ[k] = v | |
58 | |
1346 | 59 # Hooks run in the repository root |
60 olddir = os.getcwd() | |
61 os.chdir(self.root) | |
487 | 62 r = os.system(s) |
1346 | 63 os.chdir(olddir) |
487 | 64 |
65 for k, v in old.items(): | |
66 if v != None: | |
67 os.environ[k] = v | |
68 else: | |
69 del os.environ[k] | |
70 | |
71 if r: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
72 self.ui.warn(_("abort: %s hook failed with status %d!\n") % |
487 | 73 (name, r)) |
74 return False | |
75 return True | |
76 | |
343 | 77 def tags(self): |
78 '''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
|
79 if not self.tagscache: |
343 | 80 self.tagscache = {} |
609
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
81 def addtag(self, k, n): |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
82 try: |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
83 bin_n = bin(n) |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
84 except TypeError: |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
85 bin_n = '' |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
86 self.tagscache[k.strip()] = bin_n |
659 | 87 |
67 | 88 try: |
254 | 89 # read each head of the tags file, ending with the tip |
90 # and add each tag found to the map, with "newer" ones | |
91 # taking precedence | |
67 | 92 fl = self.file(".hgtags") |
254 | 93 h = fl.heads() |
94 h.reverse() | |
95 for r in h: | |
994
88c15682d9b0
Fix callers to file.revision to use file.read
mpm@selenic.com
parents:
993
diff
changeset
|
96 for l in fl.read(r).splitlines(): |
254 | 97 if l: |
385
e9e1efd5291c
Fixed problems with extra spaces around tags in .hgtags
Thomas Arendsen Hein <thomas@intevation.de>
parents:
383
diff
changeset
|
98 n, k = l.split(" ", 1) |
609
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
99 addtag(self, k, n) |
477
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
100 except KeyError: |
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
101 pass |
659 | 102 |
609
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
103 try: |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
104 f = self.opener("localtags") |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
105 for l in f: |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
106 n, k = l.split(" ", 1) |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
107 addtag(self, k, n) |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
108 except IOError: |
2acf1f5df2e6
[PATCH] hg tag: local tag support in file .hg/localtags
Matt Mackall <mpm@selenic.com>
parents:
608
diff
changeset
|
109 pass |
659 | 110 |
343 | 111 self.tagscache['tip'] = self.changelog.tip() |
659 | 112 |
343 | 113 return self.tagscache |
114 | |
115 def tagslist(self): | |
116 '''return a list of tags ordered by revision''' | |
117 l = [] | |
477
520540fd6b64
Handle errors in .hgtags or hgrc [tags] section more gracefully.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
471
diff
changeset
|
118 for t, n in self.tags().items(): |
343 | 119 try: |
120 r = self.changelog.rev(n) | |
121 except: | |
122 r = -2 # sort to the beginning of the list if unknown | |
123 l.append((r,t,n)) | |
124 l.sort() | |
125 return [(t,n) for r,t,n in l] | |
126 | |
127 def nodetags(self, node): | |
128 '''return the tags associated with a node''' | |
129 if not self.nodetagscache: | |
130 self.nodetagscache = {} | |
131 for t,n in self.tags().items(): | |
132 self.nodetagscache.setdefault(n,[]).append(t) | |
133 return self.nodetagscache.get(node, []) | |
134 | |
135 def lookup(self, key): | |
67 | 136 try: |
343 | 137 return self.tags()[key] |
67 | 138 except KeyError: |
658
f8098ae9f5b6
Generate a friendlier except for failed lookups
Matt Mackall <mpm@selenic.com>
parents:
657
diff
changeset
|
139 try: |
f8098ae9f5b6
Generate a friendlier except for failed lookups
Matt Mackall <mpm@selenic.com>
parents:
657
diff
changeset
|
140 return self.changelog.lookup(key) |
f8098ae9f5b6
Generate a friendlier except for failed lookups
Matt Mackall <mpm@selenic.com>
parents:
657
diff
changeset
|
141 except: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
142 raise repo.RepoError(_("unknown revision '%s'") % key) |
67 | 143 |
634
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
144 def dev(self): |
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
145 return os.stat(self.path).st_dev |
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
146 |
926 | 147 def local(self): |
1101 | 148 return True |
926 | 149 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
150 def join(self, f): |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
151 return os.path.join(self.path, f) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
152 |
244 | 153 def wjoin(self, f): |
154 return os.path.join(self.root, f) | |
155 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
156 def file(self, f): |
192 | 157 if f[0] == '/': f = f[1:] |
1100 | 158 return filelog.filelog(self.opener, f) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
159 |
627 | 160 def getcwd(self): |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
839
diff
changeset
|
161 return self.dirstate.getcwd() |
627 | 162 |
291
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
163 def wfile(self, f, mode='r'): |
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
164 return self.wopener(f, mode) |
2c4f2be05587
Add wopener for opening files in the working directory
mpm@selenic.com
parents:
288
diff
changeset
|
165 |
1019
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
166 def wread(self, filename): |
1258 | 167 if self.encodepats == None: |
168 l = [] | |
169 for pat, cmd in self.ui.configitems("encode"): | |
170 mf = util.matcher("", "/", [pat], [], [])[1] | |
171 l.append((mf, cmd)) | |
172 self.encodepats = l | |
173 | |
174 data = self.wopener(filename, 'r').read() | |
175 | |
176 for mf, cmd in self.encodepats: | |
177 if mf(filename): | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
178 self.ui.debug(_("filtering %s through %s\n") % (filename, cmd)) |
1258 | 179 data = util.filter(data, cmd) |
180 break | |
181 | |
182 return data | |
1019
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
183 |
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
184 def wwrite(self, filename, data, fd=None): |
1258 | 185 if self.decodepats == None: |
186 l = [] | |
187 for pat, cmd in self.ui.configitems("decode"): | |
188 mf = util.matcher("", "/", [pat], [], [])[1] | |
189 l.append((mf, cmd)) | |
190 self.decodepats = l | |
191 | |
192 for mf, cmd in self.decodepats: | |
193 if mf(filename): | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
194 self.ui.debug(_("filtering %s through %s\n") % (filename, cmd)) |
1258 | 195 data = util.filter(data, cmd) |
196 break | |
197 | |
1019
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
198 if fd: |
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
199 return fd.write(data) |
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
200 return self.wopener(filename, 'w').write(data) |
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
201 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
202 def transaction(self): |
251 | 203 # save dirstate for undo |
263 | 204 try: |
205 ds = self.opener("dirstate").read() | |
206 except IOError: | |
207 ds = "" | |
785 | 208 self.opener("journal.dirstate", "w").write(ds) |
515 | 209 |
785 | 210 def after(): |
211 util.rename(self.join("journal"), self.join("undo")) | |
212 util.rename(self.join("journal.dirstate"), | |
213 self.join("undo.dirstate")) | |
214 | |
215 return transaction.transaction(self.ui.warn, self.opener, | |
216 self.join("journal"), after) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
217 |
210 | 218 def recover(self): |
225 | 219 lock = self.lock() |
557 | 220 if os.path.exists(self.join("journal")): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
221 self.ui.status(_("rolling back interrupted transaction\n")) |
557 | 222 return transaction.rollback(self.opener, self.join("journal")) |
210 | 223 else: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
224 self.ui.warn(_("no interrupted transaction available\n")) |
210 | 225 |
226 def undo(self): | |
225 | 227 lock = self.lock() |
210 | 228 if os.path.exists(self.join("undo")): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
229 self.ui.status(_("rolling back last transaction\n")) |
262 | 230 transaction.rollback(self.opener, self.join("undo")) |
251 | 231 self.dirstate = None |
421 | 232 util.rename(self.join("undo.dirstate"), self.join("dirstate")) |
1100 | 233 self.dirstate = dirstate.dirstate(self.opener, self.ui, self.root) |
163 | 234 else: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
235 self.ui.warn(_("no undo information available\n")) |
162 | 236 |
1062 | 237 def lock(self, wait=1): |
161 | 238 try: |
239 return lock.lock(self.join("lock"), 0) | |
240 except lock.LockHeld, inst: | |
241 if wait: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
242 self.ui.warn(_("waiting for lock held by %s\n") % inst.args[0]) |
161 | 243 return lock.lock(self.join("lock"), wait) |
244 raise inst | |
245 | |
203 | 246 def rawcommit(self, files, text, user, date, p1=None, p2=None): |
442 | 247 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
|
248 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
|
249 p2 = p2 or self.dirstate.parents()[1] or nullid |
302 | 250 c1 = self.changelog.read(p1) |
251 c2 = self.changelog.read(p2) | |
252 m1 = self.manifest.read(c1[0]) | |
253 mf1 = self.manifest.readflags(c1[0]) | |
254 m2 = self.manifest.read(c2[0]) | |
992
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
255 changed = [] |
302 | 256 |
442 | 257 if orig_parent == p1: |
258 update_dirstate = 1 | |
259 else: | |
260 update_dirstate = 0 | |
261 | |
203 | 262 tr = self.transaction() |
302 | 263 mm = m1.copy() |
264 mfm = mf1.copy() | |
203 | 265 linkrev = self.changelog.count() |
266 for f in files: | |
267 try: | |
1019
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
268 t = self.wread(f) |
441 | 269 tm = util.is_exec(self.wjoin(f), mfm.get(f, False)) |
302 | 270 r = self.file(f) |
271 mfm[f] = tm | |
990 | 272 |
273 fp1 = m1.get(f, nullid) | |
274 fp2 = m2.get(f, nullid) | |
275 | |
276 # is the same revision on two branches of a merge? | |
277 if fp2 == fp1: | |
278 fp2 = nullid | |
279 | |
280 if fp2 != nullid: | |
281 # is one parent an ancestor of the other? | |
282 fpa = r.ancestor(fp1, fp2) | |
283 if fpa == fp1: | |
284 fp1, fp2 = fp2, nullid | |
285 elif fpa == fp2: | |
286 fp2 = nullid | |
287 | |
288 # is the file unmodified from the parent? | |
289 if t == r.read(fp1): | |
290 # record the proper existing parent in manifest | |
291 # no need to add a revision | |
292 mm[f] = fp1 | |
293 continue | |
294 | |
295 mm[f] = r.add(t, {}, tr, linkrev, fp1, fp2) | |
992
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
296 changed.append(f) |
442 | 297 if update_dirstate: |
298 self.dirstate.update([f], "n") | |
203 | 299 except IOError: |
314
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
300 try: |
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
301 del mm[f] |
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
302 del mfm[f] |
442 | 303 if update_dirstate: |
304 self.dirstate.forget([f]) | |
314
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
305 except: |
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
306 # deleted from p2? |
3402cb9a4c06
More tweaking to rawcommit for repo conversion
mpm@selenic.com
parents:
313
diff
changeset
|
307 pass |
203 | 308 |
302 | 309 mnode = self.manifest.add(mm, mfm, tr, linkrev, c1[0], c2[0]) |
608
d2994b5298fb
Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents:
588
diff
changeset
|
310 user = user or self.ui.username() |
992
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
311 n = self.changelog.add(mnode, changed, text, tr, p1, p2, user, date) |
203 | 312 tr.close() |
442 | 313 if update_dirstate: |
314 self.dirstate.setparents(n, nullid) | |
203 | 315 |
813
80fd2958235a
Adapt commit to use file matching code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
786
diff
changeset
|
316 def commit(self, files = None, text = "", user = None, date = None, |
900
ba8cf1f2210c
Add force option to repo.commit, allowing commits where no files change
mason@suse.com
parents:
898
diff
changeset
|
317 match = util.always, force=False): |
220 | 318 commit = [] |
319 remove = [] | |
992
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
320 changed = [] |
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
321 |
220 | 322 if files: |
323 for f in files: | |
324 s = self.dirstate.state(f) | |
244 | 325 if s in 'nmai': |
220 | 326 commit.append(f) |
327 elif s == 'r': | |
328 remove.append(f) | |
329 else: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
330 self.ui.warn(_("%s not tracked!\n") % f) |
220 | 331 else: |
1062 | 332 (c, a, d, u) = self.changes(match=match) |
220 | 333 commit = c + a |
334 remove = d | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
335 |
990 | 336 p1, p2 = self.dirstate.parents() |
337 c1 = self.changelog.read(p1) | |
338 c2 = self.changelog.read(p2) | |
339 m1 = self.manifest.read(c1[0]) | |
340 mf1 = self.manifest.readflags(c1[0]) | |
341 m2 = self.manifest.read(c2[0]) | |
342 | |
343 if not commit and not remove and not force and p2 == nullid: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
344 self.ui.status(_("nothing changed\n")) |
901
120cba94d5aa
Change repo.comit to return None on error or the new revision number on
mason@suse.com
parents:
900
diff
changeset
|
345 return None |
151 | 346 |
487 | 347 if not self.hook("precommit"): |
901
120cba94d5aa
Change repo.comit to return None on error or the new revision number on
mason@suse.com
parents:
900
diff
changeset
|
348 return None |
487 | 349 |
225 | 350 lock = self.lock() |
151 | 351 tr = self.transaction() |
352 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
353 # check in files |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
354 new = {} |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
355 linkrev = self.changelog.count() |
220 | 356 commit.sort() |
357 for f in commit: | |
83 | 358 self.ui.note(f + "\n") |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
359 try: |
441 | 360 mf1[f] = util.is_exec(self.wjoin(f), mf1.get(f, False)) |
1019
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
361 t = self.wread(f) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
362 except IOError: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
363 self.ui.warn(_("trouble committing %s!\n") % f) |
220 | 364 raise |
365 | |
1117 | 366 r = self.file(f) |
367 | |
363 | 368 meta = {} |
369 cp = self.dirstate.copied(f) | |
370 if cp: | |
371 meta["copy"] = cp | |
372 meta["copyrev"] = hex(m1.get(cp, m2.get(cp, nullid))) | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
373 self.ui.debug(_(" %s: copy %s:%s\n") % (f, cp, meta["copyrev"])) |
1117 | 374 fp1, fp2 = nullid, nullid |
375 else: | |
376 fp1 = m1.get(f, nullid) | |
377 fp2 = m2.get(f, nullid) | |
990 | 378 |
379 # is the same revision on two branches of a merge? | |
380 if fp2 == fp1: | |
381 fp2 = nullid | |
382 | |
383 if fp2 != nullid: | |
384 # is one parent an ancestor of the other? | |
385 fpa = r.ancestor(fp1, fp2) | |
386 if fpa == fp1: | |
387 fp1, fp2 = fp2, nullid | |
388 elif fpa == fp2: | |
389 fp2 = nullid | |
390 | |
391 # is the file unmodified from the parent? | |
392 if not meta and t == r.read(fp1): | |
393 # record the proper existing parent in manifest | |
394 # no need to add a revision | |
395 new[f] = fp1 | |
396 continue | |
397 | |
363 | 398 new[f] = r.add(t, meta, tr, linkrev, fp1, fp2) |
992
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
399 # remember what we've added so that we can later calculate |
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
400 # the files to pull from a set of changesets |
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
401 changed.append(f) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
402 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
403 # update manifest |
229 | 404 m1.update(new) |
416
5e9e8b8d2629
[PATCH] Removal of a file added by merging branches
mpm@selenic.com
parents:
415
diff
changeset
|
405 for f in remove: |
5e9e8b8d2629
[PATCH] Removal of a file added by merging branches
mpm@selenic.com
parents:
415
diff
changeset
|
406 if f in m1: |
5e9e8b8d2629
[PATCH] Removal of a file added by merging branches
mpm@selenic.com
parents:
415
diff
changeset
|
407 del m1[f] |
741 | 408 mn = self.manifest.add(m1, mf1, tr, linkrev, c1[0], c2[0], |
409 (new, remove)) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
410 |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
411 # add changeset |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
412 new = new.keys() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
413 new.sort() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
414 |
288 | 415 if not text: |
992
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
416 edittext = "" |
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
417 if p2 != nullid: |
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
418 edittext += "HG: branch merge\n" |
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
419 edittext += "\n" + "HG: manifest hash %s\n" % hex(mn) |
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
420 edittext += "".join(["HG: changed %s\n" % f for f in changed]) |
288 | 421 edittext += "".join(["HG: removed %s\n" % f for f in remove]) |
992
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
422 if not changed and not remove: |
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
423 edittext += "HG: no files changed\n" |
288 | 424 edittext = self.ui.edit(edittext) |
425 if not edittext.rstrip(): | |
901
120cba94d5aa
Change repo.comit to return None on error or the new revision number on
mason@suse.com
parents:
900
diff
changeset
|
426 return None |
288 | 427 text = edittext |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
428 |
608
d2994b5298fb
Add username/merge/editor to .hgrc
Matt Mackall <mpm@selenic.com>
parents:
588
diff
changeset
|
429 user = user or self.ui.username() |
992
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
430 n = self.changelog.add(mn, changed, text, tr, p1, p2, user, date) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
431 tr.close() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
432 |
229 | 433 self.dirstate.setparents(n) |
220 | 434 self.dirstate.update(new, "n") |
435 self.dirstate.forget(remove) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
436 |
660
2c83350784c3
Move commit hook after commit completes
Matt Mackall <mpm@selenic.com>
parents:
659
diff
changeset
|
437 if not self.hook("commit", node=hex(n)): |
901
120cba94d5aa
Change repo.comit to return None on error or the new revision number on
mason@suse.com
parents:
900
diff
changeset
|
438 return None |
120cba94d5aa
Change repo.comit to return None on error or the new revision number on
mason@suse.com
parents:
900
diff
changeset
|
439 return n |
660
2c83350784c3
Move commit hook after commit completes
Matt Mackall <mpm@selenic.com>
parents:
659
diff
changeset
|
440 |
1062 | 441 def walk(self, node=None, files=[], match=util.always): |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
723
diff
changeset
|
442 if node: |
726
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
443 for fn in self.manifest.read(self.changelog.read(node)[0]): |
820
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
444 if match(fn): yield 'm', fn |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
723
diff
changeset
|
445 else: |
726
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
446 for src, fn in self.dirstate.walk(files, match): |
809a870a0e73
Add a source designator to the walk methods.
Bryan O'Sullivan <bos@serpentine.com>
parents:
725
diff
changeset
|
447 yield src, fn |
723 | 448 |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
723
diff
changeset
|
449 def changes(self, node1 = None, node2 = None, files = [], |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
723
diff
changeset
|
450 match = util.always): |
566 | 451 mf2, u = None, [] |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
452 |
536 | 453 def fcmp(fn, mf): |
1019
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
454 t1 = self.wread(fn) |
994
88c15682d9b0
Fix callers to file.revision to use file.read
mpm@selenic.com
parents:
993
diff
changeset
|
455 t2 = self.file(fn).read(mf.get(fn, nullid)) |
29 | 456 return cmp(t1, t2) |
457 | |
723 | 458 def mfmatches(node): |
459 mf = dict(self.manifest.read(node)) | |
460 for fn in mf.keys(): | |
461 if not match(fn): | |
462 del mf[fn] | |
463 return mf | |
741 | 464 |
536 | 465 # are we comparing the working directory? |
561 | 466 if not node2: |
723 | 467 l, c, a, d, u = self.dirstate.changes(files, match) |
536 | 468 |
469 # are we comparing working dir against its parent? | |
561 | 470 if not node1: |
536 | 471 if l: |
472 # do a full compare of any files that might have changed | |
473 change = self.changelog.read(self.dirstate.parents()[0]) | |
723 | 474 mf2 = mfmatches(change[0]) |
548 | 475 for f in l: |
561 | 476 if fcmp(f, mf2): |
536 | 477 c.append(f) |
561 | 478 |
479 for l in c, a, d, u: | |
480 l.sort() | |
481 | |
536 | 482 return (c, a, d, u) |
515 | 483 |
536 | 484 # are we comparing working dir against non-tip? |
485 # generate a pseudo-manifest for the working dir | |
561 | 486 if not node2: |
487 if not mf2: | |
536 | 488 change = self.changelog.read(self.dirstate.parents()[0]) |
723 | 489 mf2 = mfmatches(change[0]) |
536 | 490 for f in a + c + l: |
561 | 491 mf2[f] = "" |
536 | 492 for f in d: |
561 | 493 if f in mf2: del mf2[f] |
536 | 494 else: |
561 | 495 change = self.changelog.read(node2) |
723 | 496 mf2 = mfmatches(change[0]) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
497 |
566 | 498 # flush lists from dirstate before comparing manifests |
499 c, a = [], [] | |
500 | |
561 | 501 change = self.changelog.read(node1) |
723 | 502 mf1 = mfmatches(change[0]) |
32 | 503 |
504 for fn in mf2: | |
505 if mf1.has_key(fn): | |
506 if mf1[fn] != mf2[fn]: | |
561 | 507 if mf2[fn] != "" or fcmp(fn, mf1): |
536 | 508 c.append(fn) |
32 | 509 del mf1[fn] |
510 else: | |
536 | 511 a.append(fn) |
515 | 512 |
536 | 513 d = mf1.keys() |
561 | 514 |
515 for l in c, a, d, u: | |
516 l.sort() | |
515 | 517 |
536 | 518 return (c, a, d, u) |
32 | 519 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
520 def add(self, list): |
220 | 521 for f in list: |
244 | 522 p = self.wjoin(f) |
611
48c3eb2bf844
* clean up error handling when user requests to use a non file object
shaleh@speakeasy.net
parents:
609
diff
changeset
|
523 if not os.path.exists(p): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
524 self.ui.warn(_("%s does not exist!\n") % f) |
611
48c3eb2bf844
* clean up error handling when user requests to use a non file object
shaleh@speakeasy.net
parents:
609
diff
changeset
|
525 elif not os.path.isfile(p): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
526 self.ui.warn(_("%s not added: only files supported currently\n") % f) |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
723
diff
changeset
|
527 elif self.dirstate.state(f) in 'an': |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
528 self.ui.warn(_("%s already tracked!\n") % f) |
220 | 529 else: |
530 self.dirstate.update([f], "a") | |
531 | |
532 def forget(self, list): | |
533 for f in list: | |
534 if self.dirstate.state(f) not in 'ai': | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
535 self.ui.warn(_("%s not added!\n") % f) |
220 | 536 else: |
537 self.dirstate.forget([f]) | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
538 |
1415
c6e6ca96a033
refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1402
diff
changeset
|
539 def remove(self, list, unlink=False): |
c6e6ca96a033
refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1402
diff
changeset
|
540 if unlink: |
c6e6ca96a033
refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1402
diff
changeset
|
541 for f in list: |
c6e6ca96a033
refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1402
diff
changeset
|
542 try: |
c6e6ca96a033
refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1402
diff
changeset
|
543 util.unlink(self.wjoin(f)) |
c6e6ca96a033
refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1402
diff
changeset
|
544 except OSError, inst: |
c6e6ca96a033
refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1402
diff
changeset
|
545 if inst.errno != errno.ENOENT: raise |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
546 for f in list: |
244 | 547 p = self.wjoin(f) |
611
48c3eb2bf844
* clean up error handling when user requests to use a non file object
shaleh@speakeasy.net
parents:
609
diff
changeset
|
548 if os.path.exists(p): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
549 self.ui.warn(_("%s still exists!\n") % f) |
402 | 550 elif self.dirstate.state(f) == 'a': |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
551 self.ui.warn(_("%s never committed!\n") % f) |
657
22bc6fb9aefc
dirstate.forget() takes a list
Matt Mackall <mpm@selenic.com>
parents:
656
diff
changeset
|
552 self.dirstate.forget([f]) |
220 | 553 elif f not in self.dirstate: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
554 self.ui.warn(_("%s not tracked!\n") % f) |
220 | 555 else: |
556 self.dirstate.update([f], "r") | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
557 |
1447
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
558 def undelete(self, list): |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
559 pl = self.dirstate.parents() |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
560 if pl[1] != nullid: |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
561 self.ui.warn("aborting: outstanding uncommitted merges\n") |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
562 return 1 |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
563 p = pl[0] |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
564 mn = self.changelog.read(p)[0] |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
565 mf = self.manifest.readflags(mn) |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
566 m = self.manifest.read(mn) |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
567 for f in list: |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
568 if self.dirstate.state(f) not in "r": |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
569 self.ui.warn("%s not removed!\n" % f) |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
570 else: |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
571 t = self.file(f).read(m[f]) |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
572 try: |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
573 self.wwrite(f, t) |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
574 except IOError, e: |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
575 if e.errno != errno.ENOENT: |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
576 raise |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
577 os.makedirs(os.path.dirname(self.wjoin(f))) |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
578 self.wwrite(f, t) |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
579 util.set_exec(self.wjoin(f), mf[f]) |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
580 self.dirstate.update([f], "n") |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
581 |
363 | 582 def copy(self, source, dest): |
583 p = self.wjoin(dest) | |
781 | 584 if not os.path.exists(p): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
585 self.ui.warn(_("%s does not exist!\n") % dest) |
781 | 586 elif not os.path.isfile(p): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
587 self.ui.warn(_("copy failed: %s is not a file\n") % dest) |
363 | 588 else: |
589 if self.dirstate.state(dest) == '?': | |
590 self.dirstate.update([dest], "a") | |
591 self.dirstate.copy(source, dest) | |
592 | |
222 | 593 def heads(self): |
594 return self.changelog.heads() | |
595 | |
898 | 596 # branchlookup returns a dict giving a list of branches for |
597 # each head. A branch is defined as the tag of a node or | |
598 # the branch of the node's parents. If a node has multiple | |
599 # branch tags, tags are eliminated if they are visible from other | |
600 # branch tags. | |
601 # | |
602 # So, for this graph: a->b->c->d->e | |
603 # \ / | |
604 # aa -----/ | |
919 | 605 # a has tag 2.6.12 |
898 | 606 # d has tag 2.6.13 |
607 # e would have branch tags for 2.6.12 and 2.6.13. Because the node | |
608 # for 2.6.12 can be reached from the node 2.6.13, that is eliminated | |
609 # from the list. | |
610 # | |
611 # It is possible that more than one head will have the same branch tag. | |
612 # callers need to check the result for multiple heads under the same | |
613 # branch tag if that is a problem for them (ie checkout of a specific | |
614 # branch). | |
615 # | |
616 # passing in a specific branch will limit the depth of the search | |
617 # through the parents. It won't limit the branches returned in the | |
618 # result though. | |
619 def branchlookup(self, heads=None, branch=None): | |
620 if not heads: | |
621 heads = self.heads() | |
622 headt = [ h for h in heads ] | |
623 chlog = self.changelog | |
624 branches = {} | |
625 merges = [] | |
626 seenmerge = {} | |
627 | |
628 # traverse the tree once for each head, recording in the branches | |
629 # dict which tags are visible from this head. The branches | |
630 # dict also records which tags are visible from each tag | |
631 # while we traverse. | |
632 while headt or merges: | |
633 if merges: | |
634 n, found = merges.pop() | |
635 visit = [n] | |
636 else: | |
637 h = headt.pop() | |
638 visit = [h] | |
639 found = [h] | |
640 seen = {} | |
641 while visit: | |
642 n = visit.pop() | |
643 if n in seen: | |
644 continue | |
645 pp = chlog.parents(n) | |
646 tags = self.nodetags(n) | |
647 if tags: | |
648 for x in tags: | |
649 if x == 'tip': | |
650 continue | |
651 for f in found: | |
652 branches.setdefault(f, {})[n] = 1 | |
653 branches.setdefault(n, {})[n] = 1 | |
654 break | |
655 if n not in found: | |
656 found.append(n) | |
657 if branch in tags: | |
658 continue | |
659 seen[n] = 1 | |
660 if pp[1] != nullid and n not in seenmerge: | |
661 merges.append((pp[1], [x for x in found])) | |
662 seenmerge[n] = 1 | |
663 if pp[0] != nullid: | |
664 visit.append(pp[0]) | |
665 # traverse the branches dict, eliminating branch tags from each | |
666 # head that are visible from another branch tag for that head. | |
667 out = {} | |
668 viscache = {} | |
669 for h in heads: | |
670 def visible(node): | |
671 if node in viscache: | |
672 return viscache[node] | |
673 ret = {} | |
674 visit = [node] | |
675 while visit: | |
676 x = visit.pop() | |
677 if x in viscache: | |
678 ret.update(viscache[x]) | |
679 elif x not in ret: | |
680 ret[x] = 1 | |
681 if x in branches: | |
682 visit[len(visit):] = branches[x].keys() | |
683 viscache[node] = ret | |
684 return ret | |
685 if h not in branches: | |
686 continue | |
687 # O(n^2), but somewhat limited. This only searches the | |
688 # tags visible from a specific head, not all the tags in the | |
689 # whole repo. | |
690 for b in branches[h]: | |
691 vis = False | |
692 for bb in branches[h].keys(): | |
693 if b != bb: | |
694 if b in visible(bb): | |
695 vis = True | |
696 break | |
697 if not vis: | |
698 l = out.setdefault(h, []) | |
699 l[len(l):] = self.nodetags(b) | |
700 return out | |
701 | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
702 def branches(self, nodes): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
703 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
|
704 b = [] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
705 for n in nodes: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
706 t = n |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
707 while n: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
708 p = self.changelog.parents(n) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
709 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
|
710 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
|
711 break |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
712 n = p[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
713 return b |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
714 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
715 def between(self, pairs): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
716 r = [] |
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 for top, bottom in pairs: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
719 n, l, i = top, [], 0 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
720 f = 1 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
721 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
722 while n != bottom: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
723 p = self.changelog.parents(n)[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
724 if i == f: |
575 | 725 l.append(n) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
726 f = f * 2 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
727 n = p |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
728 i += 1 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
729 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
730 r.append(l) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
731 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
732 return r |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
733 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
734 def newer(self, nodes): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
735 m = {} |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
736 nl = [] |
94 | 737 pm = {} |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
738 cl = self.changelog |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
739 t = l = cl.count() |
94 | 740 |
741 # find the lowest numbered node | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
742 for n in nodes: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
743 l = min(l, cl.rev(n)) |
94 | 744 m[n] = 1 |
46 | 745 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
746 for i in xrange(l, t): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
747 n = cl.node(i) |
94 | 748 if n in m: # explicitly listed |
749 pm[n] = 1 | |
750 nl.append(n) | |
751 continue | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
752 for p in cl.parents(n): |
94 | 753 if p in pm: # parent listed |
754 pm[n] = 1 | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
755 nl.append(n) |
94 | 756 break |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
757 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
758 return nl |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
759 |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
760 def findincoming(self, remote, base=None, heads=None): |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
761 m = self.changelog.nodemap |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
762 search = [] |
1072 | 763 fetch = {} |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
764 seen = {} |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
765 seenbranch = {} |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
766 if base == None: |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
767 base = {} |
192 | 768 |
636
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
769 # 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
|
770 # and start by examining the heads |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
771 self.ui.status(_("searching for changes\n")) |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
772 |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
773 if not heads: |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
774 heads = remote.heads() |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
775 |
222 | 776 unknown = [] |
777 for h in heads: | |
778 if h not in m: | |
779 unknown.append(h) | |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
780 else: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
781 base[h] = 1 |
46 | 782 |
222 | 783 if not unknown: |
60 | 784 return None |
324 | 785 |
786 rep = {} | |
787 reqcnt = 0 | |
515 | 788 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
789 # search through remote branches |
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
790 # 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
|
791 # head, root, first parent, second parent |
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
792 # (a branch always has two parents (or none) by definition) |
222 | 793 unknown = remote.branches(unknown) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
794 while unknown: |
324 | 795 r = [] |
796 while unknown: | |
797 n = unknown.pop(0) | |
798 if n[0] in seen: | |
799 continue | |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
800 |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
801 self.ui.debug(_("examining %s:%s\n") % (short(n[0]), short(n[1]))) |
324 | 802 if n[0] == nullid: |
803 break | |
328 | 804 if n in seenbranch: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
805 self.ui.debug(_("branch already found\n")) |
324 | 806 continue |
807 if n[1] and n[1] in m: # do we know the base? | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
808 self.ui.debug(_("found incomplete branch %s:%s\n") |
324 | 809 % (short(n[0]), short(n[1]))) |
810 search.append(n) # schedule branch range for scanning | |
328 | 811 seenbranch[n] = 1 |
324 | 812 else: |
813 if n[1] not in seen and n[1] not in fetch: | |
814 if n[2] in m and n[3] in m: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
815 self.ui.debug(_("found new changeset %s\n") % |
324 | 816 short(n[1])) |
1072 | 817 fetch[n[1]] = 1 # earliest unknown |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
818 base[n[2]] = 1 # latest known |
324 | 819 continue |
820 | |
821 for a in n[2:4]: | |
822 if a not in rep: | |
823 r.append(a) | |
824 rep[a] = 1 | |
825 | |
328 | 826 seen[n[0]] = 1 |
827 | |
324 | 828 if r: |
829 reqcnt += 1 | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
830 self.ui.debug(_("request %d: %s\n") % |
324 | 831 (reqcnt, " ".join(map(short, r)))) |
832 for p in range(0, len(r), 10): | |
833 for b in remote.branches(r[p:p+10]): | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
834 self.ui.debug(_("received %s:%s\n") % |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
835 (short(b[0]), short(b[1]))) |
1072 | 836 if b[0] in m: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
837 self.ui.debug(_("found base node %s\n") % short(b[0])) |
1072 | 838 base[b[0]] = 1 |
839 elif b[0] not in seen: | |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
840 unknown.append(b) |
515 | 841 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
842 # 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
|
843 while search: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
844 n = search.pop(0) |
324 | 845 reqcnt += 1 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
846 l = remote.between([(n[0], n[1])])[0] |
328 | 847 l.append(n[1]) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
848 p = n[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
849 f = 1 |
328 | 850 for i in l: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
851 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
|
852 if i in m: |
85 | 853 if f <= 2: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
854 self.ui.debug(_("found new branch changeset %s\n") % |
83 | 855 short(p)) |
1072 | 856 fetch[p] = 1 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
857 base[i] = 1 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
858 else: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
859 self.ui.debug(_("narrowed branch search to %s:%s\n") |
83 | 860 % (short(p), short(i))) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
861 search.append((p, i)) |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
862 break |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
863 p, f = i, f * 2 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
864 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
865 # sanity check our fetch list |
1072 | 866 for f in fetch.keys(): |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
867 if f in m: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
868 raise repo.RepoError(_("already have changeset ") + short(f[:4])) |
83 | 869 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
870 if base.keys() == [nullid]: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
871 self.ui.warn(_("warning: pulling from an unrelated repository!\n")) |
511 | 872 |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
873 self.ui.note(_("found new changesets starting at ") + |
83 | 874 " ".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
|
875 |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
876 self.ui.debug(_("%d total queries\n") % reqcnt) |
324 | 877 |
1072 | 878 return fetch.keys() |
516 | 879 |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
880 def findoutgoing(self, remote, base=None, heads=None): |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
881 if base == None: |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
882 base = {} |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
883 self.findincoming(remote, base, heads) |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
884 |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
885 self.ui.debug(_("common changesets up to ") |
1072 | 886 + " ".join(map(short, base.keys())) + "\n") |
887 | |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
888 remain = dict.fromkeys(self.changelog.nodemap) |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
889 |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
890 # prune everything remote has from the tree |
637
31e090c34d3b
Fix up the broken bits in findoutgoing
Matt Mackall <mpm@selenic.com>
parents:
636
diff
changeset
|
891 del remain[nullid] |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
892 remove = base.keys() |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
893 while remove: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
894 n = remove.pop(0) |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
895 if n in remain: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
896 del remain[n] |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
897 for p in self.changelog.parents(n): |
637
31e090c34d3b
Fix up the broken bits in findoutgoing
Matt Mackall <mpm@selenic.com>
parents:
636
diff
changeset
|
898 remove.append(p) |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
899 |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
900 # find every node whose parents have been pruned |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
901 subset = [] |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
902 for n in remain: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
903 p1, p2 = self.changelog.parents(n) |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
904 if p1 not in remain and p2 not in remain: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
905 subset.append(n) |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
906 |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
907 # this is the set of all roots we have to push |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
908 return subset |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
909 |
622
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
910 def pull(self, remote): |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
911 lock = self.lock() |
636
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
912 |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
913 # if we have an empty repo, fetch everything |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
914 if self.changelog.tip() == nullid: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
915 self.ui.status(_("requesting all changes\n")) |
636
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
916 fetch = [nullid] |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
917 else: |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
918 fetch = self.findincoming(remote) |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
919 |
622
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
920 if not fetch: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
921 self.ui.status(_("no changes found\n")) |
622
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
922 return 1 |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
923 |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
924 cg = remote.changegroup(fetch) |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
925 return self.addchangegroup(cg) |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
926 |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
927 def push(self, remote, force=False): |
622
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
928 lock = remote.lock() |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
929 |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
930 base = {} |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
931 heads = remote.heads() |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
932 inc = self.findincoming(remote, base, heads) |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
933 if not force and inc: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
934 self.ui.warn(_("abort: unsynced remote changes!\n")) |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
935 self.ui.status(_("(did you forget to sync? use push -f to force)\n")) |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
936 return 1 |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
937 |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
938 update = self.findoutgoing(remote, base) |
622
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
939 if not update: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
940 self.ui.status(_("no changes found\n")) |
622
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
941 return 1 |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
942 elif not force: |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
943 if len(heads) < len(self.changelog.heads()): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
944 self.ui.warn(_("abort: push creates new remote branches!\n")) |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
945 self.ui.status(_("(did you forget to merge?" |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
946 " use push -f to force)\n")) |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
947 return 1 |
622
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
948 |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
949 cg = self.changegroup(update) |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
950 return remote.addchangegroup(cg) |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
951 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
952 def changegroup(self, basenodes): |
1199
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1133
diff
changeset
|
953 genread = util.chunkbuffer |
515 | 954 |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
955 def gengroup(): |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
956 nodes = self.newer(basenodes) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
957 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
958 # construct the link map |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
959 linkmap = {} |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
960 for n in nodes: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
961 linkmap[self.changelog.rev(n)] = n |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
962 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
963 # construct a list of all changed files |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
964 changed = {} |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
965 for n in nodes: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
966 c = self.changelog.read(n) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
967 for f in c[3]: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
968 changed[f] = 1 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
969 changed = changed.keys() |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
970 changed.sort() |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
971 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
972 # the changegroup is changesets + manifests + all file revs |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
973 revs = [ self.changelog.rev(n) for n in nodes ] |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
974 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
975 for y in self.changelog.group(linkmap): yield y |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
976 for y in self.manifest.group(linkmap): yield y |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
977 for f in changed: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
978 yield struct.pack(">l", len(f) + 4) + f |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
979 g = self.file(f).group(linkmap) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
980 for y in g: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
981 yield y |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
982 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
983 yield struct.pack(">l", 0) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
984 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
985 return genread(gengroup()) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
986 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
987 def addchangegroup(self, source): |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
988 |
222 | 989 def getchunk(): |
990 d = source.read(4) | |
991 if not d: return "" | |
992 l = struct.unpack(">l", d)[0] | |
993 if l <= 4: return "" | |
1280
50553b99a5c9
pull/unbundle: raise an exception on premature EOF
mpm@selenic.com
parents:
1260
diff
changeset
|
994 d = source.read(l - 4) |
50553b99a5c9
pull/unbundle: raise an exception on premature EOF
mpm@selenic.com
parents:
1260
diff
changeset
|
995 if len(d) < l - 4: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
996 raise repo.RepoError(_("premature EOF reading chunk" |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
997 " (got %d bytes, expected %d)") |
1280
50553b99a5c9
pull/unbundle: raise an exception on premature EOF
mpm@selenic.com
parents:
1260
diff
changeset
|
998 % (len(d), l - 4)) |
50553b99a5c9
pull/unbundle: raise an exception on premature EOF
mpm@selenic.com
parents:
1260
diff
changeset
|
999 return d |
222 | 1000 |
1001 def getgroup(): | |
1002 while 1: | |
1003 c = getchunk() | |
1004 if not c: break | |
1005 yield c | |
1006 | |
1007 def csmap(x): | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1008 self.ui.debug(_("add changeset %s\n") % short(x)) |
222 | 1009 return self.changelog.count() |
1010 | |
1011 def revmap(x): | |
1012 return self.changelog.rev(x) | |
1013 | |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1014 if not source: return |
222 | 1015 changesets = files = revisions = 0 |
225 | 1016 |
222 | 1017 tr = self.transaction() |
1018 | |
1040
35e883d1ff9b
Show number of new heads when doing a pull
mpm@selenic.com
parents:
1019
diff
changeset
|
1019 oldheads = len(self.changelog.heads()) |
35e883d1ff9b
Show number of new heads when doing a pull
mpm@selenic.com
parents:
1019
diff
changeset
|
1020 |
222 | 1021 # pull off the changeset group |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1022 self.ui.status(_("adding changesets\n")) |
222 | 1023 co = self.changelog.tip() |
224
ccbcc4d76f81
fix bad assumption about uniqueness of file versions
mpm@selenic.com
parents:
223
diff
changeset
|
1024 cn = self.changelog.addgroup(getgroup(), csmap, tr, 1) # unique |
1316 | 1025 cnr, cor = map(self.changelog.rev, (cn, co)) |
1375
f2b00be33e2c
Fix traceback when nothing was added during unbundle
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1353
diff
changeset
|
1026 if cn == nullid: |
f2b00be33e2c
Fix traceback when nothing was added during unbundle
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1353
diff
changeset
|
1027 cnr = cor |
1316 | 1028 changesets = cnr - cor |
222 | 1029 |
1030 # pull off the manifest group | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1031 self.ui.status(_("adding manifests\n")) |
222 | 1032 mm = self.manifest.tip() |
1033 mo = self.manifest.addgroup(getgroup(), revmap, tr) | |
1034 | |
1035 # process the files | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1036 self.ui.status(_("adding file changes\n")) |
222 | 1037 while 1: |
1038 f = getchunk() | |
1039 if not f: break | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1040 self.ui.debug(_("adding %s revisions\n") % f) |
222 | 1041 fl = self.file(f) |
529
aace5b681fe9
Attempt to fix negative revision count from pull
mpm@selenic.com
parents:
522
diff
changeset
|
1042 o = fl.count() |
222 | 1043 n = fl.addgroup(getgroup(), revmap, tr) |
529
aace5b681fe9
Attempt to fix negative revision count from pull
mpm@selenic.com
parents:
522
diff
changeset
|
1044 revisions += fl.count() - o |
222 | 1045 files += 1 |
1046 | |
1040
35e883d1ff9b
Show number of new heads when doing a pull
mpm@selenic.com
parents:
1019
diff
changeset
|
1047 newheads = len(self.changelog.heads()) |
35e883d1ff9b
Show number of new heads when doing a pull
mpm@selenic.com
parents:
1019
diff
changeset
|
1048 heads = "" |
35e883d1ff9b
Show number of new heads when doing a pull
mpm@selenic.com
parents:
1019
diff
changeset
|
1049 if oldheads and newheads > oldheads: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1050 heads = _(" (+%d heads)") % (newheads - oldheads) |
1040
35e883d1ff9b
Show number of new heads when doing a pull
mpm@selenic.com
parents:
1019
diff
changeset
|
1051 |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1052 self.ui.status(_("added %d changesets" |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1053 " with %d changes to %d files%s\n") |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1054 % (changesets, revisions, files, heads)) |
222 | 1055 |
1056 tr.close() | |
780 | 1057 |
1375
f2b00be33e2c
Fix traceback when nothing was added during unbundle
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1353
diff
changeset
|
1058 if changesets > 0: |
f2b00be33e2c
Fix traceback when nothing was added during unbundle
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1353
diff
changeset
|
1059 if not self.hook("changegroup", |
f2b00be33e2c
Fix traceback when nothing was added during unbundle
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1353
diff
changeset
|
1060 node=hex(self.changelog.node(cor+1))): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1061 self.ui.warn(_("abort: changegroup hook returned failure!\n")) |
1375
f2b00be33e2c
Fix traceback when nothing was added during unbundle
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1353
diff
changeset
|
1062 return 1 |
780 | 1063 |
1375
f2b00be33e2c
Fix traceback when nothing was added during unbundle
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1353
diff
changeset
|
1064 for i in range(cor + 1, cnr + 1): |
f2b00be33e2c
Fix traceback when nothing was added during unbundle
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1353
diff
changeset
|
1065 self.hook("commit", node=hex(self.changelog.node(i))) |
1316 | 1066 |
222 | 1067 return |
1068 | |
588 | 1069 def update(self, node, allow=False, force=False, choose=None, |
1070 moddirstate=True): | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1071 pl = self.dirstate.parents() |
275 | 1072 if not force and pl[1] != nullid: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1073 self.ui.warn(_("aborting: outstanding uncommitted merges\n")) |
690 | 1074 return 1 |
46 | 1075 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1076 p1, p2 = pl[0], node |
305 | 1077 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
|
1078 m1n = self.changelog.read(p1)[0] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1079 m2n = self.changelog.read(p2)[0] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1080 man = self.manifest.ancestor(m1n, m2n) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1081 m1 = self.manifest.read(m1n) |
276 | 1082 mf1 = self.manifest.readflags(m1n) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1083 m2 = self.manifest.read(m2n) |
276 | 1084 mf2 = self.manifest.readflags(m2n) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1085 ma = self.manifest.read(man) |
412 | 1086 mfa = self.manifest.readflags(man) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1087 |
723 | 1088 (c, a, d, u) = self.changes() |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1089 |
408
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1090 # 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
|
1091 # from p1 to p2? |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1092 linear_path = (pa == p1 or pa == p2) |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1093 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1094 # 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
|
1095 # we care about merging |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1096 self.ui.note(_("resolving manifests\n")) |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1097 self.ui.debug(_(" force %s allow %s moddirstate %s linear %s\n") % |
650
2c934c7b79dc
Fix bug in reverting deleted files
Matt Mackall <mpm@selenic.com>
parents:
649
diff
changeset
|
1098 (force, allow, moddirstate, linear_path)) |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1099 self.ui.debug(_(" ancestor %s local %s remote %s\n") % |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1100 (short(man), short(m1n), short(m2n))) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1101 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1102 merge = {} |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1103 get = {} |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1104 remove = [] |
46 | 1105 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1106 # construct a working dir manifest |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1107 mw = m1.copy() |
276 | 1108 mfw = mf1.copy() |
576 | 1109 umap = dict.fromkeys(u) |
1110 | |
254 | 1111 for f in a + c + u: |
1112 mw[f] = "" | |
441 | 1113 mfw[f] = util.is_exec(self.wjoin(f), mfw.get(f, False)) |
576 | 1114 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1115 for f in d: |
254 | 1116 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
|
1117 |
408
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1118 # 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
|
1119 # 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
|
1120 # 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
|
1121 # 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
|
1122 # longer in the manifest. |
588 | 1123 if moddirstate and linear_path and f not in m2: |
408
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1124 self.dirstate.forget((f,)) |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1125 |
576 | 1126 # Compare manifests |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1127 for f, n in mw.iteritems(): |
588 | 1128 if choose and not choose(f): continue |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1129 if f in m2: |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1130 s = 0 |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1131 |
407
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1132 # is the wfile new since m1, and match m2? |
428 | 1133 if f not in m1: |
1019
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
1134 t1 = self.wread(f) |
994
88c15682d9b0
Fix callers to file.revision to use file.read
mpm@selenic.com
parents:
993
diff
changeset
|
1135 t2 = self.file(f).read(m2[f]) |
407
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1136 if cmp(t1, t2) == 0: |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1137 n = m2[f] |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1138 del t1, t2 |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1139 |
296
a3d83bf86755
hg update: fix clobbering files when going backwards
mpm@selenic.com
parents:
292
diff
changeset
|
1140 # are files different? |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1141 if n != m2[f]: |
254 | 1142 a = ma.get(f, nullid) |
296
a3d83bf86755
hg update: fix clobbering files when going backwards
mpm@selenic.com
parents:
292
diff
changeset
|
1143 # are both different from the ancestor? |
254 | 1144 if n != a and m2[f] != a: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1145 self.ui.debug(_(" %s versions differ, resolve\n") % f) |
276 | 1146 # merge executable bits |
1147 # "if we changed or they changed, change in merge" | |
1148 a, b, c = mfa.get(f, 0), mfw[f], mf2[f] | |
1149 mode = ((a^b) | (a^c)) ^ a | |
1150 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
|
1151 s = 1 |
305 | 1152 # are we clobbering? |
1153 # is remote's version newer? | |
1154 # or are we going back in time? | |
1155 elif force or m2[f] != a or (p2 == pa and mw[f] == m1[f]): | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1156 self.ui.debug(_(" remote %s is newer, get\n") % f) |
254 | 1157 get[f] = m2[f] |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1158 s = 1 |
576 | 1159 elif f in umap: |
1160 # this unknown file is the same as the checkout | |
1161 get[f] = m2[f] | |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1162 |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1163 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
|
1164 if force: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1165 self.ui.debug(_(" updating permissions for %s\n") % f) |
441 | 1166 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
|
1167 else: |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1168 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
|
1169 mode = ((a^b) | (a^c)) ^ a |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1170 if mode != b: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1171 self.ui.debug(_(" updating permissions for %s\n") % f) |
441 | 1172 util.set_exec(self.wjoin(f), mode) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1173 del m2[f] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1174 elif f in ma: |
616 | 1175 if n != ma[f]: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1176 r = _("d") |
616 | 1177 if not force and (linear_path or allow): |
415
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1178 r = self.ui.prompt( |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1179 (_(" local changed %s which remote deleted\n") % f) + |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1180 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1181 if r == _("d"): |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1182 remove.append(f) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1183 else: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1184 self.ui.debug(_("other deleted %s\n") % f) |
254 | 1185 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
|
1186 else: |
1236
67a28636ea64
Fix bug with co -C across branches, update tests
mpm@selenic.com
parents:
1234
diff
changeset
|
1187 # file is created on branch or in working directory |
67a28636ea64
Fix bug with co -C across branches, update tests
mpm@selenic.com
parents:
1234
diff
changeset
|
1188 if force and f not in umap: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1189 self.ui.debug(_("remote deleted %s, clobbering\n") % f) |
1236
67a28636ea64
Fix bug with co -C across branches, update tests
mpm@selenic.com
parents:
1234
diff
changeset
|
1190 remove.append(f) |
67a28636ea64
Fix bug with co -C across branches, update tests
mpm@selenic.com
parents:
1234
diff
changeset
|
1191 elif n == m1.get(f, nullid): # same as parent |
1234
9ee8428d84a1
Revert unrelated changes in previous commit
mpm@selenic.com
parents:
1233
diff
changeset
|
1192 if p2 == pa: # going backwards? |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1193 self.ui.debug(_("remote deleted %s\n") % f) |
1234
9ee8428d84a1
Revert unrelated changes in previous commit
mpm@selenic.com
parents:
1233
diff
changeset
|
1194 remove.append(f) |
9ee8428d84a1
Revert unrelated changes in previous commit
mpm@selenic.com
parents:
1233
diff
changeset
|
1195 else: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1196 self.ui.debug(_("local modified %s, keeping\n") % f) |
254 | 1197 else: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1198 self.ui.debug(_("working dir created %s, keeping\n") % f) |
46 | 1199 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1200 for f, n in m2.iteritems(): |
588 | 1201 if choose and not choose(f): continue |
256 | 1202 if f[0] == "/": continue |
616 | 1203 if f in ma and n != ma[f]: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1204 r = _("k") |
616 | 1205 if not force and (linear_path or allow): |
415
c2b9502a4e96
[PATCH] Don't prompt user for keep-vs-delete when the merge is about to be aborted
mpm@selenic.com
parents:
413
diff
changeset
|
1206 r = self.ui.prompt( |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1207 (_("remote changed %s which local deleted\n") % f) + |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1208 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1209 if r == _("k"): get[f] = n |
616 | 1210 elif f not in ma: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1211 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
|
1212 get[f] = n |
616 | 1213 else: |
680
4b7b79d2db2c
Handle undeletion of files when checking out old revisions
Matt Mackall <mpm@selenic.com>
parents:
679
diff
changeset
|
1214 if force or p2 == pa: # going backwards? |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1215 self.ui.debug(_("local deleted %s, recreating\n") % f) |
650
2c934c7b79dc
Fix bug in reverting deleted files
Matt Mackall <mpm@selenic.com>
parents:
649
diff
changeset
|
1216 get[f] = n |
680
4b7b79d2db2c
Handle undeletion of files when checking out old revisions
Matt Mackall <mpm@selenic.com>
parents:
679
diff
changeset
|
1217 else: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1218 self.ui.debug(_("local deleted %s\n") % f) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1219 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1220 del mw, m1, m2, ma |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1221 |
275 | 1222 if force: |
1223 for f in merge: | |
1224 get[f] = merge[f][1] | |
1225 merge = {} | |
1226 | |
690 | 1227 if linear_path or force: |
254 | 1228 # we don't need to do any magic, just jump to the new rev |
993 | 1229 branch_merge = False |
254 | 1230 p1, p2 = p2, nullid |
1231 else: | |
275 | 1232 if not allow: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1233 self.ui.status(_("this update spans a branch" |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1234 " affecting the following files:\n")) |
305 | 1235 fl = merge.keys() + get.keys() |
1236 fl.sort() | |
1237 for f in fl: | |
1238 cf = "" | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1239 if f in merge: cf = _(" (resolve)") |
305 | 1240 self.ui.status(" %s%s\n" % (f, cf)) |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1241 self.ui.warn(_("aborting update spanning branches!\n")) |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1242 self.ui.status(_("(use update -m to merge across branches" |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1243 " or -C to lose changes)\n")) |
275 | 1244 return 1 |
993 | 1245 branch_merge = True |
254 | 1246 |
588 | 1247 if moddirstate: |
1248 self.dirstate.setparents(p1, p2) | |
191
d7e859cf2f1b
merge: add count of new manifests, files, and revisions
mpm@selenic.com
parents:
190
diff
changeset
|
1249 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1250 # 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
|
1251 files = get.keys() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1252 files.sort() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1253 for f in files: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1254 if f[0] == "/": continue |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1255 self.ui.note(_("getting %s\n") % f) |
276 | 1256 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
|
1257 try: |
1019
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
1258 self.wwrite(f, t) |
1353
a0c68981a5f4
Fix misleading abort message when permissions are bad.
Eric Hopper <hopper@omnifarious.org>
parents:
1349
diff
changeset
|
1259 except IOError, e: |
a0c68981a5f4
Fix misleading abort message when permissions are bad.
Eric Hopper <hopper@omnifarious.org>
parents:
1349
diff
changeset
|
1260 if e.errno != errno.ENOENT: |
a0c68981a5f4
Fix misleading abort message when permissions are bad.
Eric Hopper <hopper@omnifarious.org>
parents:
1349
diff
changeset
|
1261 raise |
297
0dbcf3c9ff20
Fixed usage of removed variable 'wp'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
292
diff
changeset
|
1262 os.makedirs(os.path.dirname(self.wjoin(f))) |
1019
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
1263 self.wwrite(f, t) |
441 | 1264 util.set_exec(self.wjoin(f), mf2[f]) |
588 | 1265 if moddirstate: |
993 | 1266 if branch_merge: |
1267 self.dirstate.update([f], 'n', st_mtime=-1) | |
992
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
1268 else: |
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
1269 self.dirstate.update([f], 'n') |
46 | 1270 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1271 # merge the tricky bits |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1272 files = merge.keys() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1273 files.sort() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1274 for f in files: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1275 self.ui.status(_("merging %s\n") % f) |
993 | 1276 my, other, flag = merge[f] |
1277 self.merge3(f, my, other) | |
441 | 1278 util.set_exec(self.wjoin(f), flag) |
862
d70c1c31fd45
Fix 3-way-merge of original parent, workdir and new parent.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
861
diff
changeset
|
1279 if moddirstate: |
993 | 1280 if branch_merge: |
1281 # We've done a branch merge, mark this file as merged | |
1282 # so that we properly record the merger later | |
1283 self.dirstate.update([f], 'm') | |
862
d70c1c31fd45
Fix 3-way-merge of original parent, workdir and new parent.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
861
diff
changeset
|
1284 else: |
993 | 1285 # We've update-merged a locally modified file, so |
1286 # we set the dirstate to emulate a normal checkout | |
1287 # of that file some time in the past. Thus our | |
1288 # merge will appear as a normal local file | |
1289 # modification. | |
1290 f_len = len(self.file(f).read(other)) | |
1291 self.dirstate.update([f], 'n', st_size=f_len, st_mtime=-1) | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1292 |
681 | 1293 remove.sort() |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1294 for f in remove: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1295 self.ui.note(_("removing %s\n") % f) |
690 | 1296 try: |
1415
c6e6ca96a033
refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1402
diff
changeset
|
1297 util.unlink(self.wjoin(f)) |
690 | 1298 except OSError, inst: |
1398
3f76ac60130d
make update quieter when nothing is wrong
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1384
diff
changeset
|
1299 if inst.errno != errno.ENOENT: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1300 self.ui.warn(_("update failed to remove %s: %s!\n") % |
1398
3f76ac60130d
make update quieter when nothing is wrong
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1384
diff
changeset
|
1301 (f, inst.strerror)) |
588 | 1302 if moddirstate: |
993 | 1303 if branch_merge: |
1304 self.dirstate.update(remove, 'r') | |
1305 else: | |
588 | 1306 self.dirstate.forget(remove) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1307 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1308 def merge3(self, fn, my, other): |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1309 """perform a 3-way merge in the working directory""" |
249 | 1310 |
96 | 1311 def temp(prefix, node): |
1312 pre = "%s~%s." % (os.path.basename(fn), prefix) | |
1313 (fd, name) = tempfile.mkstemp("", pre) | |
417 | 1314 f = os.fdopen(fd, "wb") |
1019
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
1315 self.wwrite(fn, fl.read(node), f) |
96 | 1316 f.close() |
1317 return name | |
1318 | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1319 fl = self.file(fn) |
96 | 1320 base = fl.ancestor(my, other) |
244 | 1321 a = self.wjoin(fn) |
346 | 1322 b = temp("base", base) |
1323 c = temp("other", other) | |
96 | 1324 |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1325 self.ui.note(_("resolving %s\n") % fn) |
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1326 self.ui.debug(_("file %s: my %s other %s ancestor %s\n") % |
1349
c6295d2a361e
More info on file merge for update --debug
Matt Mackall <mpm@selenic.com>
parents:
1346
diff
changeset
|
1327 (fn, short(my), short(other), short(base))) |
96 | 1328 |
703
fb6f85ecc863
merge program setting from hgrc wasn't used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
691
diff
changeset
|
1329 cmd = (os.environ.get("HGMERGE") or self.ui.config("ui", "merge") |
fb6f85ecc863
merge program setting from hgrc wasn't used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
691
diff
changeset
|
1330 or "hgmerge") |
1427
0980d77f5e9a
Fixed problem with invoking hgmerge on paths with spaces.
michael.w.dales@intel.com
parents:
1415
diff
changeset
|
1331 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
|
1332 if r: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1333 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
|
1334 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1335 os.unlink(b) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1336 os.unlink(c) |
96 | 1337 |
247 | 1338 def verify(self): |
1339 filelinkrevs = {} | |
1340 filenodes = {} | |
1341 changesets = revisions = files = 0 | |
1383
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1342 errors = [0] |
1382
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1343 neededmanifests = {} |
247 | 1344 |
1383
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1345 def err(msg): |
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1346 self.ui.warn(msg + "\n") |
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1347 errors[0] += 1 |
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1348 |
302 | 1349 seen = {} |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1350 self.ui.status(_("checking changesets\n")) |
247 | 1351 for i in range(self.changelog.count()): |
1352 changesets += 1 | |
1353 n = self.changelog.node(i) | |
1382
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1354 l = self.changelog.linkrev(n) |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1355 if l != i: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1356 err(_("incorrect link (%d) for changeset revision %d") %(l, i)) |
302 | 1357 if n in seen: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1358 err(_("duplicate changeset at revision %d") % i) |
302 | 1359 seen[n] = 1 |
515 | 1360 |
247 | 1361 for p in self.changelog.parents(n): |
1362 if p not in self.changelog.nodemap: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1363 err(_("changeset %s has unknown parent %s") % |
247 | 1364 (short(n), short(p))) |
1365 try: | |
1366 changes = self.changelog.read(n) | |
1367 except Exception, inst: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1368 err(_("unpacking changeset %s: %s") % (short(n), inst)) |
247 | 1369 |
1382
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1370 neededmanifests[changes[0]] = n |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1371 |
247 | 1372 for f in changes[3]: |
1373 filelinkrevs.setdefault(f, []).append(i) | |
1374 | |
302 | 1375 seen = {} |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1376 self.ui.status(_("checking manifests\n")) |
247 | 1377 for i in range(self.manifest.count()): |
1378 n = self.manifest.node(i) | |
1382
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1379 l = self.manifest.linkrev(n) |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1380 |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1381 if l < 0 or l >= self.changelog.count(): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1382 err(_("bad manifest link (%d) at revision %d") % (l, i)) |
1382
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1383 |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1384 if n in neededmanifests: |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1385 del neededmanifests[n] |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1386 |
302 | 1387 if n in seen: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1388 err(_("duplicate manifest at revision %d") % i) |
1383
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1389 |
302 | 1390 seen[n] = 1 |
515 | 1391 |
247 | 1392 for p in self.manifest.parents(n): |
1393 if p not in self.manifest.nodemap: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1394 err(_("manifest %s has unknown parent %s") % |
1383
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1395 (short(n), short(p))) |
247 | 1396 |
1397 try: | |
1398 delta = mdiff.patchtext(self.manifest.delta(n)) | |
1399 except KeyboardInterrupt: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1400 self.ui.warn(_("interrupted")) |
1097 | 1401 raise |
247 | 1402 except Exception, inst: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1403 err(_("unpacking manifest %s: %s") % (short(n), inst)) |
247 | 1404 |
1405 ff = [ l.split('\0') for l in delta.splitlines() ] | |
1406 for f, fn in ff: | |
284 | 1407 filenodes.setdefault(f, {})[bin(fn[:40])] = 1 |
247 | 1408 |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1409 self.ui.status(_("crosschecking files in changesets and manifests\n")) |
1382
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1410 |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1411 for m,c in neededmanifests.items(): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1412 err(_("Changeset %s refers to unknown manifest %s") % |
1384
d729850d52fa
hg verify: add some bin to hex conversions
Matt Mackall <mpm@selenic.com>
parents:
1383
diff
changeset
|
1413 (short(m), short(c))) |
1382
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1414 del neededmanifests |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1415 |
247 | 1416 for f in filenodes: |
1417 if f not in filelinkrevs: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1418 err(_("file %s in manifest but not in changesets") % f) |
247 | 1419 |
1420 for f in filelinkrevs: | |
1421 if f not in filenodes: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1422 err(_("file %s in changeset but not in manifest") % f) |
247 | 1423 |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1424 self.ui.status(_("checking files\n")) |
247 | 1425 ff = filenodes.keys() |
1426 ff.sort() | |
1427 for f in ff: | |
1428 if f == "/dev/null": continue | |
1429 files += 1 | |
1430 fl = self.file(f) | |
1431 nodes = { nullid: 1 } | |
302 | 1432 seen = {} |
247 | 1433 for i in range(fl.count()): |
1434 revisions += 1 | |
1435 n = fl.node(i) | |
1436 | |
302 | 1437 if n in seen: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1438 err(_("%s: duplicate revision %d") % (f, i)) |
247 | 1439 if n not in filenodes[f]: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1440 err(_("%s: %d:%s not in manifests") % (f, i, short(n))) |
247 | 1441 else: |
1442 del filenodes[f][n] | |
1443 | |
1444 flr = fl.linkrev(n) | |
1445 if flr not in filelinkrevs[f]: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1446 err(_("%s:%s points to unexpected changeset %d") |
1383
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1447 % (f, short(n), flr)) |
247 | 1448 else: |
1449 filelinkrevs[f].remove(flr) | |
1450 | |
1451 # verify contents | |
1452 try: | |
1453 t = fl.read(n) | |
1454 except Exception, inst: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1455 err(_("unpacking file %s %s: %s") % (f, short(n), inst)) |
247 | 1456 |
1457 # verify parents | |
1458 (p1, p2) = fl.parents(n) | |
1459 if p1 not in nodes: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1460 err(_("file %s:%s unknown parent 1 %s") % |
1383
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1461 (f, short(n), short(p1))) |
247 | 1462 if p2 not in nodes: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1463 err(_("file %s:%s unknown parent 2 %s") % |
247 | 1464 (f, short(n), short(p1))) |
1465 nodes[n] = 1 | |
1466 | |
1467 # cross-check | |
1468 for node in filenodes[f]: | |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1469 err(_("node %s in manifests not in %s") % (hex(node), f)) |
247 | 1470 |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1471 self.ui.status(_("%d files, %d changesets, %d total revisions\n") % |
247 | 1472 (files, changesets, revisions)) |
1473 | |
1383
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1474 if errors[0]: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
1475 self.ui.warn(_("%d integrity errors encountered!\n") % errors[0]) |
247 | 1476 return 1 |