474 else: |
474 else: |
475 for src, fn in self.dirstate.walk(files, match): |
475 for src, fn in self.dirstate.walk(files, match): |
476 yield src, fn |
476 yield src, fn |
477 |
477 |
478 def changes(self, node1=None, node2=None, files=[], match=util.always): |
478 def changes(self, node1=None, node2=None, files=[], match=util.always): |
479 mf2, u = None, [] |
479 """return changes between two nodes or node and working directory |
|
480 |
|
481 If node1 is None, use the first dirstate parent instead. |
|
482 If node2 is None, compare node1 with working directory. |
|
483 """ |
480 |
484 |
481 def fcmp(fn, mf): |
485 def fcmp(fn, mf): |
482 t1 = self.wread(fn) |
486 t1 = self.wread(fn) |
483 t2 = self.file(fn).read(mf.get(fn, nullid)) |
487 t2 = self.file(fn).read(mf.get(fn, nullid)) |
484 return cmp(t1, t2) |
488 return cmp(t1, t2) |
485 |
489 |
486 def mfmatches(node): |
490 def mfmatches(node): |
487 mf = dict(self.manifest.read(node)) |
491 change = self.changelog.read(node) |
|
492 mf = dict(self.manifest.read(change[0])) |
488 for fn in mf.keys(): |
493 for fn in mf.keys(): |
489 if not match(fn): |
494 if not match(fn): |
490 del mf[fn] |
495 del mf[fn] |
491 return mf |
496 return mf |
492 |
497 |
494 if not node2: |
499 if not node2: |
495 try: |
500 try: |
496 wlock = self.wlock(wait=0) |
501 wlock = self.wlock(wait=0) |
497 except lock.LockHeld: |
502 except lock.LockHeld: |
498 wlock = None |
503 wlock = None |
499 l, c, a, d, u = self.dirstate.changes(files, match) |
504 lookup, modified, added, deleted, unknown = ( |
|
505 self.dirstate.changes(files, match)) |
500 |
506 |
501 # are we comparing working dir against its parent? |
507 # are we comparing working dir against its parent? |
502 if not node1: |
508 if not node1: |
503 if l: |
509 if lookup: |
504 # do a full compare of any files that might have changed |
510 # do a full compare of any files that might have changed |
505 change = self.changelog.read(self.dirstate.parents()[0]) |
511 mf2 = mfmatches(self.dirstate.parents()[0]) |
506 mf2 = mfmatches(change[0]) |
512 for f in lookup: |
507 for f in l: |
|
508 if fcmp(f, mf2): |
513 if fcmp(f, mf2): |
509 c.append(f) |
514 modified.append(f) |
510 elif wlock is not None: |
515 elif wlock is not None: |
511 self.dirstate.update([f], "n") |
516 self.dirstate.update([f], "n") |
512 |
517 else: |
513 for l in c, a, d, u: |
518 # we are comparing working dir against non-parent |
514 l.sort() |
519 # generate a pseudo-manifest for the working dir |
515 |
520 mf2 = mfmatches(self.dirstate.parents()[0]) |
516 return (c, a, d, u) |
521 for f in lookup + modified + added: |
517 |
522 mf2[f] = "" |
518 # are we comparing working dir against non-tip? |
523 for f in deleted: |
519 # generate a pseudo-manifest for the working dir |
524 if f in mf2: |
520 if not node2: |
525 del mf2[f] |
521 if not mf2: |
|
522 change = self.changelog.read(self.dirstate.parents()[0]) |
|
523 mf2 = mfmatches(change[0]) |
|
524 for f in a + c + l: |
|
525 mf2[f] = "" |
|
526 for f in d: |
|
527 if f in mf2: |
|
528 del mf2[f] |
|
529 else: |
526 else: |
530 change = self.changelog.read(node2) |
527 # we are comparing two revisions |
531 mf2 = mfmatches(change[0]) |
528 unknown = [] |
532 |
529 mf2 = mfmatches(node2) |
533 # flush lists from dirstate before comparing manifests |
530 |
534 c, a = [], [] |
531 if node1: |
535 |
532 # flush lists from dirstate before comparing manifests |
536 change = self.changelog.read(node1) |
533 modified, added = [], [] |
537 mf1 = mfmatches(change[0]) |
534 |
538 |
535 mf1 = mfmatches(node1) |
539 for fn in mf2: |
536 |
540 if mf1.has_key(fn): |
537 for fn in mf2: |
541 if mf1[fn] != mf2[fn]: |
538 if mf1.has_key(fn): |
542 if mf2[fn] != "" or fcmp(fn, mf1): |
539 if mf1[fn] != mf2[fn] and (mf2[fn] != "" or fcmp(fn, mf1)): |
543 c.append(fn) |
540 modified.append(fn) |
544 del mf1[fn] |
541 del mf1[fn] |
545 else: |
542 else: |
546 a.append(fn) |
543 added.append(fn) |
547 |
544 |
548 d = mf1.keys() |
545 deleted = mf1.keys() |
549 |
546 |
550 for l in c, a, d, u: |
547 # sort and return results: |
|
548 for l in modified, added, deleted, unknown: |
551 l.sort() |
549 l.sort() |
552 |
550 return (modified, added, deleted, unknown) |
553 return (c, a, d, u) |
|
554 |
551 |
555 def add(self, list): |
552 def add(self, list): |
556 wlock = self.wlock() |
553 wlock = self.wlock() |
557 for f in list: |
554 for f in list: |
558 p = self.wjoin(f) |
555 p = self.wjoin(f) |