Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/localrepo.py @ 1448:182879d71922
Allow reverting a deleted file with two parents
As elsewhere, we choose the first parent by default
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Tue, 25 Oct 2005 15:52:27 -0700 |
parents | 508a3f559553 |
children | 0847c45ffee6 |
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): |
1448
182879d71922
Allow reverting a deleted file with two parents
Matt Mackall <mpm@selenic.com>
parents:
1447
diff
changeset
|
559 p = self.dirstate.parents()[0] |
1447
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
560 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
|
561 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
|
562 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
|
563 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
|
564 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
|
565 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
|
566 else: |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
567 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
|
568 try: |
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.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
|
570 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
|
571 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
|
572 raise |
508a3f559553
revert added and removed files to their normal state before reverting
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1427
diff
changeset
|
573 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
|
574 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
|
575 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
|
576 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
|
577 |
363 | 578 def copy(self, source, dest): |
579 p = self.wjoin(dest) | |
781 | 580 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
|
581 self.ui.warn(_("%s does not exist!\n") % dest) |
781 | 582 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
|
583 self.ui.warn(_("copy failed: %s is not a file\n") % dest) |
363 | 584 else: |
585 if self.dirstate.state(dest) == '?': | |
586 self.dirstate.update([dest], "a") | |
587 self.dirstate.copy(source, dest) | |
588 | |
222 | 589 def heads(self): |
590 return self.changelog.heads() | |
591 | |
898 | 592 # branchlookup returns a dict giving a list of branches for |
593 # each head. A branch is defined as the tag of a node or | |
594 # the branch of the node's parents. If a node has multiple | |
595 # branch tags, tags are eliminated if they are visible from other | |
596 # branch tags. | |
597 # | |
598 # So, for this graph: a->b->c->d->e | |
599 # \ / | |
600 # aa -----/ | |
919 | 601 # a has tag 2.6.12 |
898 | 602 # d has tag 2.6.13 |
603 # e would have branch tags for 2.6.12 and 2.6.13. Because the node | |
604 # for 2.6.12 can be reached from the node 2.6.13, that is eliminated | |
605 # from the list. | |
606 # | |
607 # It is possible that more than one head will have the same branch tag. | |
608 # callers need to check the result for multiple heads under the same | |
609 # branch tag if that is a problem for them (ie checkout of a specific | |
610 # branch). | |
611 # | |
612 # passing in a specific branch will limit the depth of the search | |
613 # through the parents. It won't limit the branches returned in the | |
614 # result though. | |
615 def branchlookup(self, heads=None, branch=None): | |
616 if not heads: | |
617 heads = self.heads() | |
618 headt = [ h for h in heads ] | |
619 chlog = self.changelog | |
620 branches = {} | |
621 merges = [] | |
622 seenmerge = {} | |
623 | |
624 # traverse the tree once for each head, recording in the branches | |
625 # dict which tags are visible from this head. The branches | |
626 # dict also records which tags are visible from each tag | |
627 # while we traverse. | |
628 while headt or merges: | |
629 if merges: | |
630 n, found = merges.pop() | |
631 visit = [n] | |
632 else: | |
633 h = headt.pop() | |
634 visit = [h] | |
635 found = [h] | |
636 seen = {} | |
637 while visit: | |
638 n = visit.pop() | |
639 if n in seen: | |
640 continue | |
641 pp = chlog.parents(n) | |
642 tags = self.nodetags(n) | |
643 if tags: | |
644 for x in tags: | |
645 if x == 'tip': | |
646 continue | |
647 for f in found: | |
648 branches.setdefault(f, {})[n] = 1 | |
649 branches.setdefault(n, {})[n] = 1 | |
650 break | |
651 if n not in found: | |
652 found.append(n) | |
653 if branch in tags: | |
654 continue | |
655 seen[n] = 1 | |
656 if pp[1] != nullid and n not in seenmerge: | |
657 merges.append((pp[1], [x for x in found])) | |
658 seenmerge[n] = 1 | |
659 if pp[0] != nullid: | |
660 visit.append(pp[0]) | |
661 # traverse the branches dict, eliminating branch tags from each | |
662 # head that are visible from another branch tag for that head. | |
663 out = {} | |
664 viscache = {} | |
665 for h in heads: | |
666 def visible(node): | |
667 if node in viscache: | |
668 return viscache[node] | |
669 ret = {} | |
670 visit = [node] | |
671 while visit: | |
672 x = visit.pop() | |
673 if x in viscache: | |
674 ret.update(viscache[x]) | |
675 elif x not in ret: | |
676 ret[x] = 1 | |
677 if x in branches: | |
678 visit[len(visit):] = branches[x].keys() | |
679 viscache[node] = ret | |
680 return ret | |
681 if h not in branches: | |
682 continue | |
683 # O(n^2), but somewhat limited. This only searches the | |
684 # tags visible from a specific head, not all the tags in the | |
685 # whole repo. | |
686 for b in branches[h]: | |
687 vis = False | |
688 for bb in branches[h].keys(): | |
689 if b != bb: | |
690 if b in visible(bb): | |
691 vis = True | |
692 break | |
693 if not vis: | |
694 l = out.setdefault(h, []) | |
695 l[len(l):] = self.nodetags(b) | |
696 return out | |
697 | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
698 def branches(self, nodes): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
699 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
|
700 b = [] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
701 for n in nodes: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
702 t = n |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
703 while n: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
704 p = self.changelog.parents(n) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
705 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
|
706 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
|
707 break |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
708 n = p[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
709 return b |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
710 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
711 def between(self, pairs): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
712 r = [] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
713 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
714 for top, bottom in pairs: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
715 n, l, i = top, [], 0 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
716 f = 1 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
717 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
718 while n != bottom: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
719 p = self.changelog.parents(n)[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
720 if i == f: |
575 | 721 l.append(n) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
722 f = f * 2 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
723 n = p |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
724 i += 1 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
725 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
726 r.append(l) |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
727 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
728 return r |
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 def newer(self, nodes): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
731 m = {} |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
732 nl = [] |
94 | 733 pm = {} |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
734 cl = self.changelog |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
735 t = l = cl.count() |
94 | 736 |
737 # find the lowest numbered node | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
738 for n in nodes: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
739 l = min(l, cl.rev(n)) |
94 | 740 m[n] = 1 |
46 | 741 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
742 for i in xrange(l, t): |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
743 n = cl.node(i) |
94 | 744 if n in m: # explicitly listed |
745 pm[n] = 1 | |
746 nl.append(n) | |
747 continue | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
748 for p in cl.parents(n): |
94 | 749 if p in pm: # parent listed |
750 pm[n] = 1 | |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
751 nl.append(n) |
94 | 752 break |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
753 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
754 return nl |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
755 |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
756 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
|
757 m = self.changelog.nodemap |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
758 search = [] |
1072 | 759 fetch = {} |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
760 seen = {} |
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
761 seenbranch = {} |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
762 if base == None: |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
763 base = {} |
192 | 764 |
636
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
765 # 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
|
766 # 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
|
767 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
|
768 |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
769 if not heads: |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
770 heads = remote.heads() |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
771 |
222 | 772 unknown = [] |
773 for h in heads: | |
774 if h not in m: | |
775 unknown.append(h) | |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
776 else: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
777 base[h] = 1 |
46 | 778 |
222 | 779 if not unknown: |
60 | 780 return None |
324 | 781 |
782 rep = {} | |
783 reqcnt = 0 | |
515 | 784 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
785 # search through remote branches |
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
786 # 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
|
787 # head, root, first parent, second parent |
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
788 # (a branch always has two parents (or none) by definition) |
222 | 789 unknown = remote.branches(unknown) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
790 while unknown: |
324 | 791 r = [] |
792 while unknown: | |
793 n = unknown.pop(0) | |
794 if n[0] in seen: | |
795 continue | |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
796 |
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
|
797 self.ui.debug(_("examining %s:%s\n") % (short(n[0]), short(n[1]))) |
324 | 798 if n[0] == nullid: |
799 break | |
328 | 800 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
|
801 self.ui.debug(_("branch already found\n")) |
324 | 802 continue |
803 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
|
804 self.ui.debug(_("found incomplete branch %s:%s\n") |
324 | 805 % (short(n[0]), short(n[1]))) |
806 search.append(n) # schedule branch range for scanning | |
328 | 807 seenbranch[n] = 1 |
324 | 808 else: |
809 if n[1] not in seen and n[1] not in fetch: | |
810 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
|
811 self.ui.debug(_("found new changeset %s\n") % |
324 | 812 short(n[1])) |
1072 | 813 fetch[n[1]] = 1 # earliest unknown |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
814 base[n[2]] = 1 # latest known |
324 | 815 continue |
816 | |
817 for a in n[2:4]: | |
818 if a not in rep: | |
819 r.append(a) | |
820 rep[a] = 1 | |
821 | |
328 | 822 seen[n[0]] = 1 |
823 | |
324 | 824 if r: |
825 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
|
826 self.ui.debug(_("request %d: %s\n") % |
324 | 827 (reqcnt, " ".join(map(short, r)))) |
828 for p in range(0, len(r), 10): | |
829 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
|
830 self.ui.debug(_("received %s:%s\n") % |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
831 (short(b[0]), short(b[1]))) |
1072 | 832 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
|
833 self.ui.debug(_("found base node %s\n") % short(b[0])) |
1072 | 834 base[b[0]] = 1 |
835 elif b[0] not in seen: | |
148
c32286d0a665
Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents:
146
diff
changeset
|
836 unknown.append(b) |
515 | 837 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
838 # 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
|
839 while search: |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
840 n = search.pop(0) |
324 | 841 reqcnt += 1 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
842 l = remote.between([(n[0], n[1])])[0] |
328 | 843 l.append(n[1]) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
844 p = n[0] |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
845 f = 1 |
328 | 846 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
|
847 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
|
848 if i in m: |
85 | 849 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
|
850 self.ui.debug(_("found new branch changeset %s\n") % |
83 | 851 short(p)) |
1072 | 852 fetch[p] = 1 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
853 base[i] = 1 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
854 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
|
855 self.ui.debug(_("narrowed branch search to %s:%s\n") |
83 | 856 % (short(p), short(i))) |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
857 search.append((p, i)) |
65
d40cc5aacc31
Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents:
64
diff
changeset
|
858 break |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
859 p, f = i, f * 2 |
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
860 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
861 # sanity check our fetch list |
1072 | 862 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
|
863 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
|
864 raise repo.RepoError(_("already have changeset ") + short(f[:4])) |
83 | 865 |
579
ffeb2c3a1966
Actually warn on pulling from an unrelated repository
mpm@selenic.com
parents:
578
diff
changeset
|
866 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
|
867 self.ui.warn(_("warning: pulling from an unrelated repository!\n")) |
511 | 868 |
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
|
869 self.ui.note(_("found new changesets starting at ") + |
83 | 870 " ".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
|
871 |
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
|
872 self.ui.debug(_("%d total queries\n") % reqcnt) |
324 | 873 |
1072 | 874 return fetch.keys() |
516 | 875 |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
876 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
|
877 if base == None: |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
878 base = {} |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
879 self.findincoming(remote, base, heads) |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
880 |
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
|
881 self.ui.debug(_("common changesets up to ") |
1072 | 882 + " ".join(map(short, base.keys())) + "\n") |
883 | |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
884 remain = dict.fromkeys(self.changelog.nodemap) |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
885 |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
886 # 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
|
887 del remain[nullid] |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
888 remove = base.keys() |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
889 while remove: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
890 n = remove.pop(0) |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
891 if n in remain: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
892 del remain[n] |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
893 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
|
894 remove.append(p) |
621
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
895 |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
896 # 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
|
897 subset = [] |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
898 for n in remain: |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
899 p1, p2 = self.changelog.parents(n) |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
900 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
|
901 subset.append(n) |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
902 |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
903 # 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
|
904 return subset |
004e811f7706
Add a function to calculate the outgoing changegroup
Matt Mackall <mpm@selenic.com>
parents:
616
diff
changeset
|
905 |
622
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
906 def pull(self, remote): |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
907 lock = self.lock() |
636
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
908 |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
909 # 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
|
910 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
|
911 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
|
912 fetch = [nullid] |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
913 else: |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
914 fetch = self.findincoming(remote) |
ac0ec421e3a5
Move the empty changeset detection out of findincoming to pull
Matt Mackall <mpm@selenic.com>
parents:
635
diff
changeset
|
915 |
622
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
916 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
|
917 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
|
918 return 1 |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
919 |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
920 cg = remote.changegroup(fetch) |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
921 return self.addchangegroup(cg) |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
922 |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
923 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
|
924 lock = remote.lock() |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
925 |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
926 base = {} |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
927 heads = remote.heads() |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
928 inc = self.findincoming(remote, base, heads) |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
929 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
|
930 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
|
931 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
|
932 return 1 |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
933 |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
934 update = self.findoutgoing(remote, base) |
622
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
935 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
|
936 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
|
937 return 1 |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
938 elif not force: |
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
939 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
|
940 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
|
941 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
|
942 " use push -f to force)\n")) |
816
8674b7803714
Warn on pushing unsynced repo or adding new heads
mpm@selenic.com
parents:
814
diff
changeset
|
943 return 1 |
622
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
944 |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
945 cg = self.changegroup(update) |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
946 return remote.addchangegroup(cg) |
e9fe5d5e67f7
Add generic repo commands for pull and push
Matt Mackall <mpm@selenic.com>
parents:
621
diff
changeset
|
947 |
56
ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents:
55
diff
changeset
|
948 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
|
949 genread = util.chunkbuffer |
515 | 950 |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
951 def gengroup(): |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
952 nodes = self.newer(basenodes) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
953 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
954 # construct the link map |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
955 linkmap = {} |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
956 for n in nodes: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
957 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
|
958 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
959 # 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
|
960 changed = {} |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
961 for n in nodes: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
962 c = self.changelog.read(n) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
963 for f in c[3]: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
964 changed[f] = 1 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
965 changed = changed.keys() |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
966 changed.sort() |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
967 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
968 # 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
|
969 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
|
970 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
971 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
|
972 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
|
973 for f in changed: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
974 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
|
975 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
|
976 for y in g: |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
977 yield y |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
978 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
979 yield struct.pack(">l", 0) |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
980 |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
981 return genread(gengroup()) |
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 def addchangegroup(self, source): |
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
984 |
222 | 985 def getchunk(): |
986 d = source.read(4) | |
987 if not d: return "" | |
988 l = struct.unpack(">l", d)[0] | |
989 if l <= 4: return "" | |
1280
50553b99a5c9
pull/unbundle: raise an exception on premature EOF
mpm@selenic.com
parents:
1260
diff
changeset
|
990 d = source.read(l - 4) |
50553b99a5c9
pull/unbundle: raise an exception on premature EOF
mpm@selenic.com
parents:
1260
diff
changeset
|
991 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
|
992 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
|
993 " (got %d bytes, expected %d)") |
1280
50553b99a5c9
pull/unbundle: raise an exception on premature EOF
mpm@selenic.com
parents:
1260
diff
changeset
|
994 % (len(d), l - 4)) |
50553b99a5c9
pull/unbundle: raise an exception on premature EOF
mpm@selenic.com
parents:
1260
diff
changeset
|
995 return d |
222 | 996 |
997 def getgroup(): | |
998 while 1: | |
999 c = getchunk() | |
1000 if not c: break | |
1001 yield c | |
1002 | |
1003 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
|
1004 self.ui.debug(_("add changeset %s\n") % short(x)) |
222 | 1005 return self.changelog.count() |
1006 | |
1007 def revmap(x): | |
1008 return self.changelog.rev(x) | |
1009 | |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
1010 if not source: return |
222 | 1011 changesets = files = revisions = 0 |
225 | 1012 |
222 | 1013 tr = self.transaction() |
1014 | |
1040
35e883d1ff9b
Show number of new heads when doing a pull
mpm@selenic.com
parents:
1019
diff
changeset
|
1015 oldheads = len(self.changelog.heads()) |
35e883d1ff9b
Show number of new heads when doing a pull
mpm@selenic.com
parents:
1019
diff
changeset
|
1016 |
222 | 1017 # 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
|
1018 self.ui.status(_("adding changesets\n")) |
222 | 1019 co = self.changelog.tip() |
224
ccbcc4d76f81
fix bad assumption about uniqueness of file versions
mpm@selenic.com
parents:
223
diff
changeset
|
1020 cn = self.changelog.addgroup(getgroup(), csmap, tr, 1) # unique |
1316 | 1021 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
|
1022 if cn == nullid: |
f2b00be33e2c
Fix traceback when nothing was added during unbundle
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1353
diff
changeset
|
1023 cnr = cor |
1316 | 1024 changesets = cnr - cor |
222 | 1025 |
1026 # 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
|
1027 self.ui.status(_("adding manifests\n")) |
222 | 1028 mm = self.manifest.tip() |
1029 mo = self.manifest.addgroup(getgroup(), revmap, tr) | |
1030 | |
1031 # 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
|
1032 self.ui.status(_("adding file changes\n")) |
222 | 1033 while 1: |
1034 f = getchunk() | |
1035 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
|
1036 self.ui.debug(_("adding %s revisions\n") % f) |
222 | 1037 fl = self.file(f) |
529
aace5b681fe9
Attempt to fix negative revision count from pull
mpm@selenic.com
parents:
522
diff
changeset
|
1038 o = fl.count() |
222 | 1039 n = fl.addgroup(getgroup(), revmap, tr) |
529
aace5b681fe9
Attempt to fix negative revision count from pull
mpm@selenic.com
parents:
522
diff
changeset
|
1040 revisions += fl.count() - o |
222 | 1041 files += 1 |
1042 | |
1040
35e883d1ff9b
Show number of new heads when doing a pull
mpm@selenic.com
parents:
1019
diff
changeset
|
1043 newheads = len(self.changelog.heads()) |
35e883d1ff9b
Show number of new heads when doing a pull
mpm@selenic.com
parents:
1019
diff
changeset
|
1044 heads = "" |
35e883d1ff9b
Show number of new heads when doing a pull
mpm@selenic.com
parents:
1019
diff
changeset
|
1045 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
|
1046 heads = _(" (+%d heads)") % (newheads - oldheads) |
1040
35e883d1ff9b
Show number of new heads when doing a pull
mpm@selenic.com
parents:
1019
diff
changeset
|
1047 |
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
|
1048 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
|
1049 " 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
|
1050 % (changesets, revisions, files, heads)) |
222 | 1051 |
1052 tr.close() | |
780 | 1053 |
1375
f2b00be33e2c
Fix traceback when nothing was added during unbundle
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1353
diff
changeset
|
1054 if changesets > 0: |
f2b00be33e2c
Fix traceback when nothing was added during unbundle
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1353
diff
changeset
|
1055 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
|
1056 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
|
1057 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
|
1058 return 1 |
780 | 1059 |
1375
f2b00be33e2c
Fix traceback when nothing was added during unbundle
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1353
diff
changeset
|
1060 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
|
1061 self.hook("commit", node=hex(self.changelog.node(i))) |
1316 | 1062 |
222 | 1063 return |
1064 | |
588 | 1065 def update(self, node, allow=False, force=False, choose=None, |
1066 moddirstate=True): | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1067 pl = self.dirstate.parents() |
275 | 1068 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
|
1069 self.ui.warn(_("aborting: outstanding uncommitted merges\n")) |
690 | 1070 return 1 |
46 | 1071 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1072 p1, p2 = pl[0], node |
305 | 1073 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
|
1074 m1n = self.changelog.read(p1)[0] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1075 m2n = self.changelog.read(p2)[0] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1076 man = self.manifest.ancestor(m1n, m2n) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1077 m1 = self.manifest.read(m1n) |
276 | 1078 mf1 = self.manifest.readflags(m1n) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1079 m2 = self.manifest.read(m2n) |
276 | 1080 mf2 = self.manifest.readflags(m2n) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1081 ma = self.manifest.read(man) |
412 | 1082 mfa = self.manifest.readflags(man) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1083 |
723 | 1084 (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
|
1085 |
408
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1086 # 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
|
1087 # from p1 to p2? |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1088 linear_path = (pa == p1 or pa == p2) |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1089 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1090 # 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
|
1091 # 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
|
1092 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
|
1093 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
|
1094 (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
|
1095 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
|
1096 (short(man), short(m1n), short(m2n))) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1097 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1098 merge = {} |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1099 get = {} |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1100 remove = [] |
46 | 1101 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1102 # construct a working dir manifest |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1103 mw = m1.copy() |
276 | 1104 mfw = mf1.copy() |
576 | 1105 umap = dict.fromkeys(u) |
1106 | |
254 | 1107 for f in a + c + u: |
1108 mw[f] = "" | |
441 | 1109 mfw[f] = util.is_exec(self.wjoin(f), mfw.get(f, False)) |
576 | 1110 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1111 for f in d: |
254 | 1112 if f in mw: del mw[f] |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1113 |
408
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1114 # If we're jumping between revisions (as opposed to merging), |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1115 # and if neither the working directory nor the target rev has |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1116 # the file, then we need to remove it from the dirstate, to |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1117 # prevent the dirstate from listing the file when it is no |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1118 # longer in the manifest. |
588 | 1119 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
|
1120 self.dirstate.forget((f,)) |
3695fbd2c33b
[PATCH] Merging files that are deleted in both branches
mpm@selenic.com
parents:
407
diff
changeset
|
1121 |
576 | 1122 # Compare manifests |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1123 for f, n in mw.iteritems(): |
588 | 1124 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
|
1125 if f in m2: |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1126 s = 0 |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1127 |
407
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1128 # is the wfile new since m1, and match m2? |
428 | 1129 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
|
1130 t1 = self.wread(f) |
994
88c15682d9b0
Fix callers to file.revision to use file.read
mpm@selenic.com
parents:
993
diff
changeset
|
1131 t2 = self.file(f).read(m2[f]) |
407
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1132 if cmp(t1, t2) == 0: |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1133 n = m2[f] |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1134 del t1, t2 |
0e0d0670b2bc
[PATCH] Merging identical changes from another branch
mpm@selenic.com
parents:
405
diff
changeset
|
1135 |
296
a3d83bf86755
hg update: fix clobbering files when going backwards
mpm@selenic.com
parents:
292
diff
changeset
|
1136 # are files different? |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1137 if n != m2[f]: |
254 | 1138 a = ma.get(f, nullid) |
296
a3d83bf86755
hg update: fix clobbering files when going backwards
mpm@selenic.com
parents:
292
diff
changeset
|
1139 # are both different from the ancestor? |
254 | 1140 if n != a and m2[f] != a: |
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
|
1141 self.ui.debug(_(" %s versions differ, resolve\n") % f) |
276 | 1142 # merge executable bits |
1143 # "if we changed or they changed, change in merge" | |
1144 a, b, c = mfa.get(f, 0), mfw[f], mf2[f] | |
1145 mode = ((a^b) | (a^c)) ^ a | |
1146 merge[f] = (m1.get(f, nullid), m2[f], mode) | |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1147 s = 1 |
305 | 1148 # are we clobbering? |
1149 # is remote's version newer? | |
1150 # or are we going back in time? | |
1151 elif force or m2[f] != a or (p2 == pa and mw[f] == m1[f]): | |
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
|
1152 self.ui.debug(_(" remote %s is newer, get\n") % f) |
254 | 1153 get[f] = m2[f] |
277
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1154 s = 1 |
576 | 1155 elif f in umap: |
1156 # this unknown file is the same as the checkout | |
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 |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1159 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
|
1160 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
|
1161 self.ui.debug(_(" updating permissions for %s\n") % f) |
441 | 1162 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
|
1163 else: |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1164 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
|
1165 mode = ((a^b) | (a^c)) ^ a |
79279550c8ff
merge: update permissions even if file contents didn't change
mpm@selenic.com
parents:
276
diff
changeset
|
1166 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
|
1167 self.ui.debug(_(" updating permissions for %s\n") % f) |
441 | 1168 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
|
1169 del m2[f] |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1170 elif f in ma: |
616 | 1171 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
|
1172 r = _("d") |
616 | 1173 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
|
1174 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
|
1175 (_(" 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
|
1176 _("(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
|
1177 if r == _("d"): |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1178 remove.append(f) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1179 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
|
1180 self.ui.debug(_("other deleted %s\n") % f) |
254 | 1181 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
|
1182 else: |
1236
67a28636ea64
Fix bug with co -C across branches, update tests
mpm@selenic.com
parents:
1234
diff
changeset
|
1183 # 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
|
1184 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
|
1185 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
|
1186 remove.append(f) |
67a28636ea64
Fix bug with co -C across branches, update tests
mpm@selenic.com
parents:
1234
diff
changeset
|
1187 elif n == m1.get(f, nullid): # same as parent |
1234
9ee8428d84a1
Revert unrelated changes in previous commit
mpm@selenic.com
parents:
1233
diff
changeset
|
1188 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
|
1189 self.ui.debug(_("remote deleted %s\n") % f) |
1234
9ee8428d84a1
Revert unrelated changes in previous commit
mpm@selenic.com
parents:
1233
diff
changeset
|
1190 remove.append(f) |
9ee8428d84a1
Revert unrelated changes in previous commit
mpm@selenic.com
parents:
1233
diff
changeset
|
1191 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
|
1192 self.ui.debug(_("local modified %s, keeping\n") % f) |
254 | 1193 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
|
1194 self.ui.debug(_("working dir created %s, keeping\n") % f) |
46 | 1195 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1196 for f, n in m2.iteritems(): |
588 | 1197 if choose and not choose(f): continue |
256 | 1198 if f[0] == "/": continue |
616 | 1199 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
|
1200 r = _("k") |
616 | 1201 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
|
1202 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
|
1203 (_("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
|
1204 _("(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
|
1205 if r == _("k"): get[f] = n |
616 | 1206 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
|
1207 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
|
1208 get[f] = n |
616 | 1209 else: |
680
4b7b79d2db2c
Handle undeletion of files when checking out old revisions
Matt Mackall <mpm@selenic.com>
parents:
679
diff
changeset
|
1210 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
|
1211 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
|
1212 get[f] = n |
680
4b7b79d2db2c
Handle undeletion of files when checking out old revisions
Matt Mackall <mpm@selenic.com>
parents:
679
diff
changeset
|
1213 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
|
1214 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
|
1215 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1216 del mw, m1, m2, ma |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1217 |
275 | 1218 if force: |
1219 for f in merge: | |
1220 get[f] = merge[f][1] | |
1221 merge = {} | |
1222 | |
690 | 1223 if linear_path or force: |
254 | 1224 # we don't need to do any magic, just jump to the new rev |
993 | 1225 branch_merge = False |
254 | 1226 p1, p2 = p2, nullid |
1227 else: | |
275 | 1228 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
|
1229 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
|
1230 " affecting the following files:\n")) |
305 | 1231 fl = merge.keys() + get.keys() |
1232 fl.sort() | |
1233 for f in fl: | |
1234 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
|
1235 if f in merge: cf = _(" (resolve)") |
305 | 1236 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
|
1237 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
|
1238 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
|
1239 " or -C to lose changes)\n")) |
275 | 1240 return 1 |
993 | 1241 branch_merge = True |
254 | 1242 |
588 | 1243 if moddirstate: |
1244 self.dirstate.setparents(p1, p2) | |
191
d7e859cf2f1b
merge: add count of new manifests, files, and revisions
mpm@selenic.com
parents:
190
diff
changeset
|
1245 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1246 # 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
|
1247 files = get.keys() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1248 files.sort() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1249 for f in files: |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1250 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
|
1251 self.ui.note(_("getting %s\n") % f) |
276 | 1252 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
|
1253 try: |
1019
a9cca981c423
Create helper functions for I/O to files in the working directory
mpm@selenic.com
parents:
1013
diff
changeset
|
1254 self.wwrite(f, t) |
1353
a0c68981a5f4
Fix misleading abort message when permissions are bad.
Eric Hopper <hopper@omnifarious.org>
parents:
1349
diff
changeset
|
1255 except IOError, e: |
a0c68981a5f4
Fix misleading abort message when permissions are bad.
Eric Hopper <hopper@omnifarious.org>
parents:
1349
diff
changeset
|
1256 if e.errno != errno.ENOENT: |
a0c68981a5f4
Fix misleading abort message when permissions are bad.
Eric Hopper <hopper@omnifarious.org>
parents:
1349
diff
changeset
|
1257 raise |
297
0dbcf3c9ff20
Fixed usage of removed variable 'wp'.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
292
diff
changeset
|
1258 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
|
1259 self.wwrite(f, t) |
441 | 1260 util.set_exec(self.wjoin(f), mf2[f]) |
588 | 1261 if moddirstate: |
993 | 1262 if branch_merge: |
1263 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
|
1264 else: |
f859e9cba1b9
Fix up some bugs introduced by recent merge changes
mpm@selenic.com
parents:
991
diff
changeset
|
1265 self.dirstate.update([f], 'n') |
46 | 1266 |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1267 # merge the tricky bits |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1268 files = merge.keys() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1269 files.sort() |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1270 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
|
1271 self.ui.status(_("merging %s\n") % f) |
993 | 1272 my, other, flag = merge[f] |
1273 self.merge3(f, my, other) | |
441 | 1274 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
|
1275 if moddirstate: |
993 | 1276 if branch_merge: |
1277 # We've done a branch merge, mark this file as merged | |
1278 # so that we properly record the merger later | |
1279 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
|
1280 else: |
993 | 1281 # We've update-merged a locally modified file, so |
1282 # we set the dirstate to emulate a normal checkout | |
1283 # of that file some time in the past. Thus our | |
1284 # merge will appear as a normal local file | |
1285 # modification. | |
1286 f_len = len(self.file(f).read(other)) | |
1287 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
|
1288 |
681 | 1289 remove.sort() |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1290 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
|
1291 self.ui.note(_("removing %s\n") % f) |
690 | 1292 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
|
1293 util.unlink(self.wjoin(f)) |
690 | 1294 except OSError, inst: |
1398
3f76ac60130d
make update quieter when nothing is wrong
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1384
diff
changeset
|
1295 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
|
1296 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
|
1297 (f, inst.strerror)) |
588 | 1298 if moddirstate: |
993 | 1299 if branch_merge: |
1300 self.dirstate.update(remove, 'r') | |
1301 else: | |
588 | 1302 self.dirstate.forget(remove) |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1303 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1304 def merge3(self, fn, my, other): |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1305 """perform a 3-way merge in the working directory""" |
249 | 1306 |
96 | 1307 def temp(prefix, node): |
1308 pre = "%s~%s." % (os.path.basename(fn), prefix) | |
1309 (fd, name) = tempfile.mkstemp("", pre) | |
417 | 1310 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
|
1311 self.wwrite(fn, fl.read(node), f) |
96 | 1312 f.close() |
1313 return name | |
1314 | |
232
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1315 fl = self.file(fn) |
96 | 1316 base = fl.ancestor(my, other) |
244 | 1317 a = self.wjoin(fn) |
346 | 1318 b = temp("base", base) |
1319 c = temp("other", other) | |
96 | 1320 |
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
|
1321 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
|
1322 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
|
1323 (fn, short(my), short(other), short(base))) |
96 | 1324 |
703
fb6f85ecc863
merge program setting from hgrc wasn't used.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
691
diff
changeset
|
1325 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
|
1326 or "hgmerge") |
1427
0980d77f5e9a
Fixed problem with invoking hgmerge on paths with spaces.
michael.w.dales@intel.com
parents:
1415
diff
changeset
|
1327 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
|
1328 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
|
1329 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
|
1330 |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1331 os.unlink(b) |
fc4a6e5b5812
hg resolve: merge a given node into the working directory
mpm@selenic.com
parents:
231
diff
changeset
|
1332 os.unlink(c) |
96 | 1333 |
247 | 1334 def verify(self): |
1335 filelinkrevs = {} | |
1336 filenodes = {} | |
1337 changesets = revisions = files = 0 | |
1383
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1338 errors = [0] |
1382
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1339 neededmanifests = {} |
247 | 1340 |
1383
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1341 def err(msg): |
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1342 self.ui.warn(msg + "\n") |
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1343 errors[0] += 1 |
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1344 |
302 | 1345 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
|
1346 self.ui.status(_("checking changesets\n")) |
247 | 1347 for i in range(self.changelog.count()): |
1348 changesets += 1 | |
1349 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
|
1350 l = self.changelog.linkrev(n) |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1351 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
|
1352 err(_("incorrect link (%d) for changeset revision %d") %(l, i)) |
302 | 1353 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
|
1354 err(_("duplicate changeset at revision %d") % i) |
302 | 1355 seen[n] = 1 |
515 | 1356 |
247 | 1357 for p in self.changelog.parents(n): |
1358 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
|
1359 err(_("changeset %s has unknown parent %s") % |
247 | 1360 (short(n), short(p))) |
1361 try: | |
1362 changes = self.changelog.read(n) | |
1363 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
|
1364 err(_("unpacking changeset %s: %s") % (short(n), inst)) |
247 | 1365 |
1382
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1366 neededmanifests[changes[0]] = n |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1367 |
247 | 1368 for f in changes[3]: |
1369 filelinkrevs.setdefault(f, []).append(i) | |
1370 | |
302 | 1371 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
|
1372 self.ui.status(_("checking manifests\n")) |
247 | 1373 for i in range(self.manifest.count()): |
1374 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
|
1375 l = self.manifest.linkrev(n) |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1376 |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1377 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
|
1378 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
|
1379 |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1380 if n in neededmanifests: |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1381 del neededmanifests[n] |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1382 |
302 | 1383 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
|
1384 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
|
1385 |
302 | 1386 seen[n] = 1 |
515 | 1387 |
247 | 1388 for p in self.manifest.parents(n): |
1389 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
|
1390 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
|
1391 (short(n), short(p))) |
247 | 1392 |
1393 try: | |
1394 delta = mdiff.patchtext(self.manifest.delta(n)) | |
1395 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
|
1396 self.ui.warn(_("interrupted")) |
1097 | 1397 raise |
247 | 1398 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
|
1399 err(_("unpacking manifest %s: %s") % (short(n), inst)) |
247 | 1400 |
1401 ff = [ l.split('\0') for l in delta.splitlines() ] | |
1402 for f, fn in ff: | |
284 | 1403 filenodes.setdefault(f, {})[bin(fn[:40])] = 1 |
247 | 1404 |
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
|
1405 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
|
1406 |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1407 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
|
1408 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
|
1409 (short(m), short(c))) |
1382
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1410 del neededmanifests |
b113e7db06e9
hg verify: more consistency checking between changesets and manifests
Matt Mackall <mpm@selenic.com>
parents:
1375
diff
changeset
|
1411 |
247 | 1412 for f in filenodes: |
1413 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
|
1414 err(_("file %s in manifest but not in changesets") % f) |
247 | 1415 |
1416 for f in filelinkrevs: | |
1417 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
|
1418 err(_("file %s in changeset but not in manifest") % f) |
247 | 1419 |
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
|
1420 self.ui.status(_("checking files\n")) |
247 | 1421 ff = filenodes.keys() |
1422 ff.sort() | |
1423 for f in ff: | |
1424 if f == "/dev/null": continue | |
1425 files += 1 | |
1426 fl = self.file(f) | |
1427 nodes = { nullid: 1 } | |
302 | 1428 seen = {} |
247 | 1429 for i in range(fl.count()): |
1430 revisions += 1 | |
1431 n = fl.node(i) | |
1432 | |
302 | 1433 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
|
1434 err(_("%s: duplicate revision %d") % (f, i)) |
247 | 1435 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
|
1436 err(_("%s: %d:%s not in manifests") % (f, i, short(n))) |
247 | 1437 else: |
1438 del filenodes[f][n] | |
1439 | |
1440 flr = fl.linkrev(n) | |
1441 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
|
1442 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
|
1443 % (f, short(n), flr)) |
247 | 1444 else: |
1445 filelinkrevs[f].remove(flr) | |
1446 | |
1447 # verify contents | |
1448 try: | |
1449 t = fl.read(n) | |
1450 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
|
1451 err(_("unpacking file %s %s: %s") % (f, short(n), inst)) |
247 | 1452 |
1453 # verify parents | |
1454 (p1, p2) = fl.parents(n) | |
1455 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
|
1456 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
|
1457 (f, short(n), short(p1))) |
247 | 1458 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
|
1459 err(_("file %s:%s unknown parent 2 %s") % |
247 | 1460 (f, short(n), short(p1))) |
1461 nodes[n] = 1 | |
1462 | |
1463 # cross-check | |
1464 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
|
1465 err(_("node %s in manifests not in %s") % (hex(node), f)) |
247 | 1466 |
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
|
1467 self.ui.status(_("%d files, %d changesets, %d total revisions\n") % |
247 | 1468 (files, changesets, revisions)) |
1469 | |
1383
3d6d45faf8b2
hg verify: add an error reporting helper function
Matt Mackall <mpm@selenic.com>
parents:
1382
diff
changeset
|
1470 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
|
1471 self.ui.warn(_("%d integrity errors encountered!\n") % errors[0]) |
247 | 1472 return 1 |