5 # This software may be used and distributed according to the terms |
5 # This software may be used and distributed according to the terms |
6 # of the GNU General Public License, incorporated herein by reference. |
6 # of the GNU General Public License, incorporated herein by reference. |
7 |
7 |
8 from mercurial.demandload import * |
8 from mercurial.demandload import * |
9 demandload(globals(), 'time sys signal os') |
9 demandload(globals(), 'time sys signal os') |
10 demandload(globals(), 'mercurial:hg,mdiff,fancyopts,commands,ui,util') |
10 demandload(globals(), 'mercurial:hg,fancyopts,commands,ui,util,patch') |
11 |
|
12 def filterfiles(files, filters): |
|
13 l = [x for x in filters if x in files] |
|
14 |
|
15 for t in files: |
|
16 if not t.endswith("/"): |
|
17 t += "/" |
|
18 l += [x for x in filters if x.startswith(t)] |
|
19 return l |
|
20 |
|
21 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always, |
|
22 changes=None, text=False): |
|
23 def date(c): |
|
24 return time.asctime(time.gmtime(c[2][0])) |
|
25 |
|
26 if not changes: |
|
27 changes = repo.status(node1, node2, files, match=match)[:5] |
|
28 modified, added, removed, deleted, unknown = changes |
|
29 if files: |
|
30 modified, added, removed = map(lambda x: filterfiles(files, x), |
|
31 (modified, added, removed)) |
|
32 |
|
33 if not modified and not added and not removed: |
|
34 return |
|
35 |
|
36 if node2: |
|
37 change = repo.changelog.read(node2) |
|
38 mmap2 = repo.manifest.read(change[0]) |
|
39 date2 = date(change) |
|
40 def read(f): |
|
41 return repo.file(f).read(mmap2[f]) |
|
42 else: |
|
43 date2 = time.asctime() |
|
44 if not node1: |
|
45 node1 = repo.dirstate.parents()[0] |
|
46 def read(f): |
|
47 return repo.wfile(f).read() |
|
48 |
|
49 change = repo.changelog.read(node1) |
|
50 mmap = repo.manifest.read(change[0]) |
|
51 date1 = date(change) |
|
52 |
|
53 opts = mdiff.diffopts() |
|
54 opts.text = text |
|
55 for f in modified: |
|
56 to = None |
|
57 if f in mmap: |
|
58 to = repo.file(f).read(mmap[f]) |
|
59 tn = read(f) |
|
60 fp.write("diff --git a/%s b/%s\n" % (f, f)) |
|
61 fp.write(mdiff.unidiff(to, date1, tn, date2, f, None, opts=opts)) |
|
62 for f in added: |
|
63 to = None |
|
64 tn = read(f) |
|
65 fp.write("diff --git /dev/null b/%s\n" % (f)) |
|
66 fp.write(mdiff.unidiff(to, date1, tn, date2, f, None, opts=opts)) |
|
67 for f in removed: |
|
68 to = repo.file(f).read(mmap[f]) |
|
69 tn = None |
|
70 fp.write("diff --git a/%s /dev/null\n" % (f)) |
|
71 fp.write(mdiff.unidiff(to, date1, tn, date2, f, None, opts=opts)) |
|
72 |
11 |
73 def difftree(ui, repo, node1=None, node2=None, *files, **opts): |
12 def difftree(ui, repo, node1=None, node2=None, *files, **opts): |
74 """diff trees from two commits""" |
13 """diff trees from two commits""" |
75 def __difftree(repo, node1, node2, files=[]): |
14 def __difftree(repo, node1, node2, files=[]): |
76 if node2: |
15 if node2: |
121 node2 = node1 |
60 node2 = node1 |
122 node1 = repo.changelog.parents(node1)[0] |
61 node1 = repo.changelog.parents(node1)[0] |
123 if opts['patch']: |
62 if opts['patch']: |
124 if opts['pretty']: |
63 if opts['pretty']: |
125 catcommit(repo, node2, "") |
64 catcommit(repo, node2, "") |
126 dodiff(sys.stdout, ui, repo, node1, node2, files=files) |
65 patch.diff(repo, node1, node2, |
|
66 files=files, |
|
67 opts=patch.diffopts(ui, {'git': True})) |
127 else: |
68 else: |
128 __difftree(repo, node1, node2, files=files) |
69 __difftree(repo, node1, node2, files=files) |
129 if not opts['stdin']: |
70 if not opts['stdin']: |
130 break |
71 break |
131 |
72 |