##// END OF EJS Templates
Refactor diffrevs/diffdir into changes...
mpm@selenic.com -
r536:c15b4bc0 default
parent child Browse files
Show More
@@ -0,0 +1,12 b''
1 #!/bin/sh
2
3 hg init
4 touch a
5 hg add a
6 hg ci -t "a" -u test -d "0 0"
7
8 echo 123 > b
9 hg add b
10 hg diff | sed "s/\(\(---\|+++\).*\)\t.*/\1/"
11
12 hg diff -r tip | sed "s/\(\(---\|+++\).*\)\t.*/\1/"
@@ -0,0 +1,10 b''
1 diff -r 3903775176ed b
2 --- /dev/null
3 +++ b/b
4 @@ -0,0 +1,1 @@
5 +123
6 diff -r 3903775176ed b
7 --- /dev/null
8 +++ b/b
9 @@ -0,0 +1,1 @@
10 +123
@@ -39,12 +39,12 b' def dodiff(ui, repo, path, files = None,'
39 if node2:
39 if node2:
40 change = repo.changelog.read(node2)
40 change = repo.changelog.read(node2)
41 mmap2 = repo.manifest.read(change[0])
41 mmap2 = repo.manifest.read(change[0])
42 (c, a, d) = repo.diffrevs(node1, node2)
42 (c, a, d, u) = repo.changes(node1, node2)
43 def read(f): return repo.file(f).read(mmap2[f])
43 def read(f): return repo.file(f).read(mmap2[f])
44 date2 = date(change)
44 date2 = date(change)
45 else:
45 else:
46 date2 = time.asctime()
46 date2 = time.asctime()
47 (c, a, d, u) = repo.diffdir(path, node1)
47 (c, a, d, u) = repo.changes(None, node1, path)
48 if not node1:
48 if not node1:
49 node1 = repo.dirstate.parents()[0]
49 node1 = repo.dirstate.parents()[0]
50 def read(f): return repo.wfile(f).read()
50 def read(f): return repo.wfile(f).read()
@@ -124,7 +124,7 b' def show_changeset(ui, repo, rev=0, chan'
124 ui.status("date: %s\n" % time.asctime(
124 ui.status("date: %s\n" % time.asctime(
125 time.localtime(float(changes[2].split(' ')[0]))))
125 time.localtime(float(changes[2].split(' ')[0]))))
126 if ui.debugflag:
126 if ui.debugflag:
127 files = repo.diffrevs(changelog.parents(changenode)[0], changenode)
127 files = repo.changes(changelog.parents(changenode)[0], changenode)
128 for key, value in zip(["files:", "files+:", "files-:"], files):
128 for key, value in zip(["files:", "files+:", "files-:"], files):
129 if value:
129 if value:
130 ui.note("%-12s %s\n" % (key, " ".join(value)))
130 ui.note("%-12s %s\n" % (key, " ".join(value)))
@@ -214,7 +214,7 b' def addremove(ui, repo, *files):'
214 elif s not in 'nmai' and isfile:
214 elif s not in 'nmai' and isfile:
215 u.append(f)
215 u.append(f)
216 else:
216 else:
217 (c, a, d, u) = repo.diffdir(repo.root)
217 (c, a, d, u) = repo.changes(None, None)
218 repo.add(u)
218 repo.add(u)
219 repo.remove(d)
219 repo.remove(d)
220
220
@@ -447,7 +447,7 b' def identify(ui, repo):'
447 return
447 return
448
448
449 hexfunc = ui.verbose and hg.hex or hg.short
449 hexfunc = ui.verbose and hg.hex or hg.short
450 (c, a, d, u) = repo.diffdir(repo.root)
450 (c, a, d, u) = repo.changes(None, None)
451 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
451 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
452 (c or a or d) and "+" or "")]
452 (c or a or d) and "+" or "")]
453
453
@@ -645,7 +645,7 b' def status(ui, repo):'
645 R = removed
645 R = removed
646 ? = not tracked'''
646 ? = not tracked'''
647
647
648 (c, a, d, u) = repo.diffdir(os.getcwd())
648 (c, a, d, u) = repo.changes(None, None, os.getcwd())
649 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
649 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
650
650
651 for f in c: print "C", f
651 for f in c: print "C", f
@@ -660,7 +660,7 b' def tag(ui, repo, name, rev = None, **op'
660 ui.warn("abort: 'tip' is a reserved name!\n")
660 ui.warn("abort: 'tip' is a reserved name!\n")
661 return -1
661 return -1
662
662
663 (c, a, d, u) = repo.diffdir(repo.root)
663 (c, a, d, u) = repo.changes(None, None)
664 for x in (c, a, d, u):
664 for x in (c, a, d, u):
665 if ".hgtags" in x:
665 if ".hgtags" in x:
666 ui.warn("abort: working copy of .hgtags is changed!\n")
666 ui.warn("abort: working copy of .hgtags is changed!\n")
@@ -288,9 +288,56 b' class dirstate:'
288 st.write(e + f)
288 st.write(e + f)
289 self.dirty = 0
289 self.dirty = 0
290
290
291 def dup(self):
291 def changes(self, files, ignore):
292 self.read()
292 self.read()
293 return self.map.copy()
293 dc = self.map.copy()
294 lookup, changed, added, unknown = [], [], [], []
295
296 # compare all files by default
297 if not files: files = [self.root]
298
299 def uniq(g):
300 seen = {}
301 for f in g:
302 if f not in seen:
303 seen[f] = 1
304 yield f
305
306 # recursive generator of all files listed
307 def walk(files):
308 for f in uniq(files):
309 if os.path.isdir(f):
310 for dir, subdirs, fl in os.walk(f):
311 d = dir[len(self.root) + 1:]
312 if ".hg" in subdirs: subdirs.remove(".hg")
313 for fn in fl:
314 fn = util.pconvert(os.path.join(d, fn))
315 yield fn
316 else:
317 yield f[len(self.root) + 1:]
318
319 for fn in uniq(walk(files)):
320 try: s = os.stat(os.path.join(self.root, fn))
321 except: continue
322
323 if fn in dc:
324 c = dc[fn]
325 del dc[fn]
326
327 if c[0] == 'm':
328 changed.append(fn)
329 elif c[0] == 'a':
330 added.append(fn)
331 elif c[0] == 'r':
332 unknown.append(fn)
333 elif c[2] != s.st_size or (c[1] ^ s.st_mode) & 0100:
334 changed.append(fn)
335 elif c[1] != s.st_mode or c[3] != s.st_mtime:
336 lookup.append(fn)
337 else:
338 if not ignore(fn): unknown.append(fn)
339
340 return (lookup, changed, added, dc.keys(), unknown)
294
341
295 # used to avoid circular references so destructors work
342 # used to avoid circular references so destructors work
296 def opener(base):
343 def opener(base):
@@ -568,7 +615,7 b' class localrepository:'
568 else:
615 else:
569 self.ui.warn("%s not tracked!\n" % f)
616 self.ui.warn("%s not tracked!\n" % f)
570 else:
617 else:
571 (c, a, d, u) = self.diffdir(self.root)
618 (c, a, d, u) = self.changes(None, None)
572 commit = c + a
619 commit = c + a
573 remove = d
620 remove = d
574
621
@@ -644,81 +691,60 b' class localrepository:'
644 self.dirstate.update(new, "n")
691 self.dirstate.update(new, "n")
645 self.dirstate.forget(remove)
692 self.dirstate.forget(remove)
646
693
647 def diffdir(self, path, changeset = None):
694 def changes(self, node1, node2, *files):
648 changed = []
695 # changed, added, deleted, unknown
649 added = []
696 c, a, d, u, mf1 = [], [], [], [], None
650 unknown = []
651 mf = {}
652
697
653 if changeset:
698 def fcmp(fn, mf):
654 change = self.changelog.read(changeset)
655 mf = self.manifest.read(change[0])
656 dc = dict.fromkeys(mf)
657 else:
658 changeset = self.dirstate.parents()[0]
659 change = self.changelog.read(changeset)
660 mf = self.manifest.read(change[0])
661 dc = self.dirstate.dup()
662
663 def fcmp(fn):
664 t1 = self.wfile(fn).read()
699 t1 = self.wfile(fn).read()
665 t2 = self.file(fn).revision(mf[fn])
700 t2 = self.file(fn).revision(mf[fn])
666 return cmp(t1, t2)
701 return cmp(t1, t2)
667
702
668 for dir, subdirs, files in os.walk(path):
703 # are we comparing the working directory?
669 d = dir[len(self.root)+1:]
704 if not node1:
670 if ".hg" in subdirs: subdirs.remove(".hg")
705 l, c, a, d, u = self.dirstate.changes(files, self.ignore)
706
707 # are we comparing working dir against its parent?
708 if not node2:
709 if l:
710 # do a full compare of any files that might have changed
711 change = self.changelog.read(self.dirstate.parents()[0])
712 mf1 = self.manifest.read(change[0])
713 for f in lookup:
714 if fcmp(f, mf):
715 c.append(f)
716 return (c, a, d, u)
671
717
672 for f in files:
718 # are we comparing working dir against non-tip?
673 fn = util.pconvert(os.path.join(d, f))
719 # generate a pseudo-manifest for the working dir
674 try: s = os.stat(os.path.join(self.root, fn))
720 if not node1:
675 except: continue
721 if not mf1:
676 if fn in dc:
722 change = self.changelog.read(self.dirstate.parents()[0])
677 c = dc[fn]
723 mf1 = self.manifest.read(change[0])
678 del dc[fn]
724 for f in a + c + l:
679 if not c:
725 mf1[f] = ""
680 if fcmp(fn):
726 for f in d:
681 changed.append(fn)
727 if f in mf1: del mf1[f]
682 elif c[0] == 'm':
728 else:
683 changed.append(fn)
729 change = self.changelog.read(node1)
684 elif c[0] == 'a':
730 mf1 = self.manifest.read(change[0])
685 added.append(fn)
686 elif c[0] == 'r':
687 unknown.append(fn)
688 elif c[2] != s.st_size or (c[1] ^ s.st_mode) & 0100:
689 changed.append(fn)
690 elif c[1] != s.st_mode or c[3] != s.st_mtime:
691 if fcmp(fn):
692 changed.append(fn)
693 else:
694 if self.ignore(fn): continue
695 unknown.append(fn)
696
731
697 deleted = dc.keys()
698 deleted.sort()
699
700 return (changed, added, deleted, unknown)
701
702 def diffrevs(self, node1, node2):
703 changed, added = [], []
704
705 change = self.changelog.read(node1)
706 mf1 = self.manifest.read(change[0])
707 change = self.changelog.read(node2)
732 change = self.changelog.read(node2)
708 mf2 = self.manifest.read(change[0])
733 mf2 = self.manifest.read(change[0])
709
734
710 for fn in mf2:
735 for fn in mf2:
711 if mf1.has_key(fn):
736 if mf1.has_key(fn):
712 if mf1[fn] != mf2[fn]:
737 if mf1[fn] != mf2[fn]:
713 changed.append(fn)
738 if mf1[fn] != "" or fcmp(fn, mf2):
739 c.append(fn)
714 del mf1[fn]
740 del mf1[fn]
715 else:
741 else:
716 added.append(fn)
742 a.append(fn)
717
743
718 deleted = mf1.keys()
744 d = mf1.keys()
719 deleted.sort()
745 d.sort()
720
746
721 return (changed, added, deleted)
747 return (c, a, d, u)
722
748
723 def add(self, list):
749 def add(self, list):
724 for f in list:
750 for f in list:
@@ -1044,7 +1070,7 b' class localrepository:'
1044 ma = self.manifest.read(man)
1070 ma = self.manifest.read(man)
1045 mfa = self.manifest.readflags(man)
1071 mfa = self.manifest.readflags(man)
1046
1072
1047 (c, a, d, u) = self.diffdir(self.root)
1073 (c, a, d, u) = self.changes(None, None)
1048
1074
1049 # is this a jump, or a merge? i.e. is there a linear path
1075 # is this a jump, or a merge? i.e. is there a linear path
1050 # from p1 to p2?
1076 # from p1 to p2?
@@ -194,7 +194,7 b' class hgweb:'
194 date1 = self.date(change1)
194 date1 = self.date(change1)
195 date2 = self.date(change2)
195 date2 = self.date(change2)
196
196
197 c, a, d = r.diffrevs(node1, node2)
197 c, a, d = r.changes(node1, node2)
198 c, a, d = map(lambda x: filterfiles(x, files), (c, a, d))
198 c, a, d = map(lambda x: filterfiles(x, files), (c, a, d))
199
199
200 for f in c:
200 for f in c:
@@ -7,6 +7,7 b' rollback completed'
7 + echo 255
7 + echo 255
8 255
8 255
9 + ls copy
9 + ls copy
10 ls: copy: No such file or directory
10 + cat
11 + cat
11 + python dumb.py
12 + python dumb.py
12 + hg clone http://localhost:20059/foo copy2
13 + hg clone http://localhost:20059/foo copy2
General Comments 0
You need to be logged in to leave comments. Login now