Show More
@@ -307,7 +307,7 b' def addremove(ui, repo, *files):' | |||
|
307 | 307 | elif s not in 'nmai' and isfile: |
|
308 | 308 | u.append(f) |
|
309 | 309 | else: |
|
310 |
(c, a, d, u) = repo.changes( |
|
|
310 | (c, a, d, u) = repo.changes() | |
|
311 | 311 | repo.add(u) |
|
312 | 312 | repo.remove(d) |
|
313 | 313 | |
@@ -584,7 +584,7 b' def identify(ui, repo):' | |||
|
584 | 584 | return |
|
585 | 585 | |
|
586 | 586 | hexfunc = ui.verbose and hg.hex or hg.short |
|
587 |
(c, a, d, u) = repo.changes( |
|
|
587 | (c, a, d, u) = repo.changes() | |
|
588 | 588 | output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]), |
|
589 | 589 | (c or a or d) and "+" or "")] |
|
590 | 590 | |
@@ -984,7 +984,7 b' def status(ui, repo):' | |||
|
984 | 984 | R = removed |
|
985 | 985 | ? = not tracked''' |
|
986 | 986 | |
|
987 |
(c, a, d, u) = repo.changes( |
|
|
987 | (c, a, d, u) = repo.changes() | |
|
988 | 988 | (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u)) |
|
989 | 989 | |
|
990 | 990 | for f in c: |
@@ -1015,7 +1015,7 b' def tag(ui, repo, name, rev=None, **opts' | |||
|
1015 | 1015 | repo.opener("localtags", "a").write("%s %s\n" % (r, name)) |
|
1016 | 1016 | return |
|
1017 | 1017 | |
|
1018 |
(c, a, d, u) = repo.changes( |
|
|
1018 | (c, a, d, u) = repo.changes() | |
|
1019 | 1019 | for x in (c, a, d, u): |
|
1020 | 1020 | if ".hgtags" in x: |
|
1021 | 1021 | ui.warn("abort: working copy of .hgtags is changed!\n") |
@@ -13,6 +13,9 b' demandload(globals(), "re lock urllib ur' | |||
|
13 | 13 | demandload(globals(), "tempfile httprangereader bdiff") |
|
14 | 14 | demandload(globals(), "bisect select") |
|
15 | 15 | |
|
16 | def always(fn): | |
|
17 | return True | |
|
18 | ||
|
16 | 19 | class filelog(revlog): |
|
17 | 20 | def __init__(self, opener, path): |
|
18 | 21 | revlog.__init__(self, opener, |
@@ -276,6 +279,33 b' class dirstate:' | |||
|
276 | 279 | self.map = None |
|
277 | 280 | self.pl = None |
|
278 | 281 | self.copies = {} |
|
282 | self.ignorefunc = None | |
|
283 | ||
|
284 | def wjoin(self, f): | |
|
285 | return os.path.join(self.root, f) | |
|
286 | ||
|
287 | def ignore(self, f): | |
|
288 | if not self.ignorefunc: | |
|
289 | bigpat = [] | |
|
290 | try: | |
|
291 | l = file(self.wjoin(".hgignore")) | |
|
292 | for pat in l: | |
|
293 | if pat != "\n": | |
|
294 | p = util.pconvert(pat[:-1]) | |
|
295 | try: | |
|
296 | r = re.compile(p) | |
|
297 | except: | |
|
298 | self.ui.warn("ignoring invalid ignore" | |
|
299 | + " regular expression '%s'\n" % p) | |
|
300 | else: | |
|
301 | bigpat.append(util.pconvert(pat[:-1])) | |
|
302 | except IOError: pass | |
|
303 | ||
|
304 | s = "(?:%s)" % (")|(?:".join(bigpat)) | |
|
305 | r = re.compile(s) | |
|
306 | self.ignorefunc = r.search | |
|
307 | ||
|
308 | return self.ignorefunc(f) | |
|
279 | 309 | |
|
280 | 310 | def __del__(self): |
|
281 | 311 | if self.dirty: |
@@ -297,8 +327,12 b' class dirstate:' | |||
|
297 | 327 | self.read() |
|
298 | 328 | return self.pl |
|
299 | 329 | |
|
330 | def markdirty(self): | |
|
331 | if not self.dirty: | |
|
332 | self.dirty = 1 | |
|
333 | ||
|
300 | 334 | def setparents(self, p1, p2 = nullid): |
|
301 |
self. |
|
|
335 | self.markdirty() | |
|
302 | 336 | self.pl = p1, p2 |
|
303 | 337 | |
|
304 | 338 | def state(self, key): |
@@ -333,7 +367,7 b' class dirstate:' | |||
|
333 | 367 | |
|
334 | 368 | def copy(self, source, dest): |
|
335 | 369 | self.read() |
|
336 |
self. |
|
|
370 | self.markdirty() | |
|
337 | 371 | self.copies[dest] = source |
|
338 | 372 | |
|
339 | 373 | def copied(self, file): |
@@ -348,7 +382,7 b' class dirstate:' | |||
|
348 | 382 | |
|
349 | 383 | if not files: return |
|
350 | 384 | self.read() |
|
351 |
self. |
|
|
385 | self.markdirty() | |
|
352 | 386 | for f in files: |
|
353 | 387 | if state == "r": |
|
354 | 388 | self.map[f] = ('r', 0, 0, 0) |
@@ -359,7 +393,7 b' class dirstate:' | |||
|
359 | 393 | def forget(self, files): |
|
360 | 394 | if not files: return |
|
361 | 395 | self.read() |
|
362 |
self. |
|
|
396 | self.markdirty() | |
|
363 | 397 | for f in files: |
|
364 | 398 | try: |
|
365 | 399 | del self.map[f] |
@@ -369,7 +403,7 b' class dirstate:' | |||
|
369 | 403 | |
|
370 | 404 | def clear(self): |
|
371 | 405 | self.map = {} |
|
372 |
self. |
|
|
406 | self.markdirty() | |
|
373 | 407 | |
|
374 | 408 | def write(self): |
|
375 | 409 | st = self.opener("dirstate", "w") |
@@ -382,23 +416,23 b' class dirstate:' | |||
|
382 | 416 | st.write(e + f) |
|
383 | 417 | self.dirty = 0 |
|
384 | 418 | |
|
385 | def changes(self, files, ignore): | |
|
419 | def walk(self, files = None, match = always): | |
|
386 | 420 | self.read() |
|
387 | 421 | dc = self.map.copy() |
|
388 | lookup, changed, added, unknown = [], [], [], [] | |
|
389 | ||
|
390 | # compare all files by default | |
|
422 | # walk all files by default | |
|
391 | 423 | if not files: files = [self.root] |
|
392 | ||
|
393 | # recursive generator of all files listed | |
|
394 | def walk(files): | |
|
424 | def traverse(): | |
|
395 | 425 | for f in util.unique(files): |
|
396 | 426 | f = os.path.join(self.root, f) |
|
397 | 427 | if os.path.isdir(f): |
|
398 | 428 | for dir, subdirs, fl in os.walk(f): |
|
399 | 429 | d = dir[len(self.root) + 1:] |
|
430 | if d == '.hg': | |
|
431 | subdirs[:] = [] | |
|
432 | continue | |
|
400 | 433 | for sd in subdirs: |
|
401 |
|
|
|
434 | ds = os.path.join(d, sd +'/') | |
|
435 | if self.ignore(ds) or not match(ds): | |
|
402 | 436 | subdirs.remove(sd) |
|
403 | 437 | for fn in fl: |
|
404 | 438 | fn = util.pconvert(os.path.join(d, fn)) |
@@ -409,7 +443,23 b' class dirstate:' | |||
|
409 | 443 | for k in dc.keys(): |
|
410 | 444 | yield k |
|
411 | 445 | |
|
412 | for fn in util.unique(walk(files)): | |
|
446 | # yield only files that match: all in dirstate, others only if | |
|
447 | # not in .hgignore | |
|
448 | ||
|
449 | for fn in util.unique(traverse()): | |
|
450 | if fn in dc: | |
|
451 | del dc[fn] | |
|
452 | elif self.ignore(fn): | |
|
453 | continue | |
|
454 | if match(fn): | |
|
455 | yield fn | |
|
456 | ||
|
457 | def changes(self, files = None, match = always): | |
|
458 | self.read() | |
|
459 | dc = self.map.copy() | |
|
460 | lookup, changed, added, unknown = [], [], [], [] | |
|
461 | ||
|
462 | for fn in self.walk(files, match): | |
|
413 | 463 | try: s = os.stat(os.path.join(self.root, fn)) |
|
414 | 464 | except: continue |
|
415 | 465 | |
@@ -428,7 +478,7 b' class dirstate:' | |||
|
428 | 478 | elif c[1] != s.st_mode or c[3] != s.st_mtime: |
|
429 | 479 | lookup.append(fn) |
|
430 | 480 | else: |
|
431 |
if |
|
|
481 | if match(fn): unknown.append(fn) | |
|
432 | 482 | |
|
433 | 483 | return (lookup, changed, added, dc.keys(), unknown) |
|
434 | 484 | |
@@ -492,7 +542,6 b' class localrepository:' | |||
|
492 | 542 | self.wopener = opener(self.root) |
|
493 | 543 | self.manifest = manifest(self.opener) |
|
494 | 544 | self.changelog = changelog(self.opener) |
|
495 | self.ignorefunc = None | |
|
496 | 545 | self.tagscache = None |
|
497 | 546 | self.nodetagscache = None |
|
498 | 547 | |
@@ -502,29 +551,6 b' class localrepository:' | |||
|
502 | 551 | self.ui.readconfig(self.opener("hgrc")) |
|
503 | 552 | except IOError: pass |
|
504 | 553 | |
|
505 | def ignore(self, f): | |
|
506 | if not self.ignorefunc: | |
|
507 | bigpat = ["^.hg/$"] | |
|
508 | try: | |
|
509 | l = file(self.wjoin(".hgignore")) | |
|
510 | for pat in l: | |
|
511 | if pat != "\n": | |
|
512 | p = util.pconvert(pat[:-1]) | |
|
513 | try: | |
|
514 | r = re.compile(p) | |
|
515 | except: | |
|
516 | self.ui.warn("ignoring invalid ignore" | |
|
517 | + " regular expression '%s'\n" % p) | |
|
518 | else: | |
|
519 | bigpat.append(util.pconvert(pat[:-1])) | |
|
520 | except IOError: pass | |
|
521 | ||
|
522 | s = "(?:%s)" % (")|(?:".join(bigpat)) | |
|
523 | r = re.compile(s) | |
|
524 | self.ignorefunc = r.search | |
|
525 | ||
|
526 | return self.ignorefunc(f) | |
|
527 | ||
|
528 | 554 | def hook(self, name, **args): |
|
529 | 555 | s = self.ui.config("hooks", name) |
|
530 | 556 | if s: |
@@ -737,7 +763,7 b' class localrepository:' | |||
|
737 | 763 | else: |
|
738 | 764 | self.ui.warn("%s not tracked!\n" % f) |
|
739 | 765 | else: |
|
740 |
(c, a, d, u) = self.changes( |
|
|
766 | (c, a, d, u) = self.changes() | |
|
741 | 767 | commit = c + a |
|
742 | 768 | remove = d |
|
743 | 769 | |
@@ -814,7 +840,12 b' class localrepository:' | |||
|
814 | 840 | if not self.hook("commit", node=hex(n)): |
|
815 | 841 | return 1 |
|
816 | 842 | |
|
817 | def changes(self, node1, node2, files=None): | |
|
843 | def walk(self, rev = None, files = [], match = always): | |
|
844 | if rev is None: fns = self.dirstate.walk(files, match) | |
|
845 | else: fns = filter(match, self.manifest.read(rev)) | |
|
846 | for fn in fns: yield fn | |
|
847 | ||
|
848 | def changes(self, node1 = None, node2 = None, files = [], match = always): | |
|
818 | 849 | mf2, u = None, [] |
|
819 | 850 | |
|
820 | 851 | def fcmp(fn, mf): |
@@ -822,16 +853,23 b' class localrepository:' | |||
|
822 | 853 | t2 = self.file(fn).revision(mf[fn]) |
|
823 | 854 | return cmp(t1, t2) |
|
824 | 855 | |
|
856 | def mfmatches(node): | |
|
857 | mf = dict(self.manifest.read(node)) | |
|
858 | for fn in mf.keys(): | |
|
859 | if not match(fn): | |
|
860 | del mf[fn] | |
|
861 | return mf | |
|
862 | ||
|
825 | 863 | # are we comparing the working directory? |
|
826 | 864 | if not node2: |
|
827 |
l, c, a, d, u = self.dirstate.changes(files, |
|
|
865 | l, c, a, d, u = self.dirstate.changes(files, match) | |
|
828 | 866 | |
|
829 | 867 | # are we comparing working dir against its parent? |
|
830 | 868 | if not node1: |
|
831 | 869 | if l: |
|
832 | 870 | # do a full compare of any files that might have changed |
|
833 | 871 | change = self.changelog.read(self.dirstate.parents()[0]) |
|
834 |
mf2 = |
|
|
872 | mf2 = mfmatches(change[0]) | |
|
835 | 873 | for f in l: |
|
836 | 874 | if fcmp(f, mf2): |
|
837 | 875 | c.append(f) |
@@ -846,20 +884,20 b' class localrepository:' | |||
|
846 | 884 | if not node2: |
|
847 | 885 | if not mf2: |
|
848 | 886 | change = self.changelog.read(self.dirstate.parents()[0]) |
|
849 |
mf2 = |
|
|
887 | mf2 = mfmatches(change[0]) | |
|
850 | 888 | for f in a + c + l: |
|
851 | 889 | mf2[f] = "" |
|
852 | 890 | for f in d: |
|
853 | 891 | if f in mf2: del mf2[f] |
|
854 | 892 | else: |
|
855 | 893 | change = self.changelog.read(node2) |
|
856 |
mf2 = |
|
|
894 | mf2 = mfmatches(change[0]) | |
|
857 | 895 | |
|
858 | 896 | # flush lists from dirstate before comparing manifests |
|
859 | 897 | c, a = [], [] |
|
860 | 898 | |
|
861 | 899 | change = self.changelog.read(node1) |
|
862 |
mf1 = |
|
|
900 | mf1 = mfmatches(change[0]) | |
|
863 | 901 | |
|
864 | 902 | for fn in mf2: |
|
865 | 903 | if mf1.has_key(fn): |
@@ -1267,7 +1305,7 b' class localrepository:' | |||
|
1267 | 1305 | ma = self.manifest.read(man) |
|
1268 | 1306 | mfa = self.manifest.readflags(man) |
|
1269 | 1307 | |
|
1270 |
(c, a, d, u) = self.changes( |
|
|
1308 | (c, a, d, u) = self.changes() | |
|
1271 | 1309 | |
|
1272 | 1310 | # is this a jump, or a merge? i.e. is there a linear path |
|
1273 | 1311 | # from p1 to p2? |
General Comments 0
You need to be logged in to leave comments.
Login now