##// END OF EJS Templates
Work on walk code.
Bryan O'Sullivan -
r723:9e0f3ba4 default
parent child Browse files
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(None, None)
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(None, None)
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(None, None)
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(None, None)
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.dirty = 1
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.dirty = 1
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.dirty = 1
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.dirty = 1
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.dirty = 1
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 if ignore(os.path.join(d, sd +'/')):
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 not ignore(fn): unknown.append(fn)
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(None, None)
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, self.ignore)
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 = self.manifest.read(change[0])
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 = self.manifest.read(change[0]).copy()
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 = self.manifest.read(change[0])
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 = self.manifest.read(change[0]).copy()
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(None, None)
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