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