##// END OF EJS Templates
diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler -
r12167:d2c5b092 default
parent child Browse files
Show More
@@ -511,14 +511,14 b' def reposetup(ui, repo):'
511 511 self.lines = kwt.shrinklines(self.fname, self.lines)
512 512
513 513 def kw_diff(orig, repo, node1=None, node2=None, match=None, changes=None,
514 opts=None):
514 opts=None, prefix=''):
515 515 '''Monkeypatch patch.diff to avoid expansion except when
516 516 comparing against working dir.'''
517 517 if node2 is not None:
518 518 kwt.match = util.never
519 519 elif node1 is not None and node1 != repo['.'].node():
520 520 kwt.restrict = True
521 return orig(repo, node1, node2, match, changes, opts)
521 return orig(repo, node1, node2, match, changes, opts, prefix)
522 522
523 523 def kwweb_skip(orig, web, req, tmpl):
524 524 '''Wraps webcommands.x turning off keyword expansion.'''
@@ -5,7 +5,7 b''
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 from node import hex, nullid, nullrev, short
8 from node import hex, bin, nullid, nullrev, short
9 9 from i18n import _
10 10 import os, sys, errno, re, glob, tempfile
11 11 import util, templater, patch, error, encoding, templatekw
@@ -655,7 +655,8 b" def export(repo, revs, template='hg-%h.p"
655 655 single(rev, seqno + 1, fp)
656 656
657 657 def diffordiffstat(ui, repo, diffopts, node1, node2, match,
658 changes=None, stat=False, fp=None):
658 changes=None, stat=False, fp=None, prefix='',
659 listsubrepos=False):
659 660 '''show diff or diffstat.'''
660 661 if fp is None:
661 662 write = ui.write
@@ -668,16 +669,27 b' def diffordiffstat(ui, repo, diffopts, n'
668 669 width = 80
669 670 if not ui.plain():
670 671 width = util.termwidth()
671 chunks = patch.diff(repo, node1, node2, match, changes, diffopts)
672 chunks = patch.diff(repo, node1, node2, match, changes, diffopts,
673 prefix=prefix)
672 674 for chunk, label in patch.diffstatui(util.iterlines(chunks),
673 675 width=width,
674 676 git=diffopts.git):
675 677 write(chunk, label=label)
676 678 else:
677 679 for chunk, label in patch.diffui(repo, node1, node2, match,
678 changes, diffopts):
680 changes, diffopts, prefix=prefix):
679 681 write(chunk, label=label)
680 682
683 if listsubrepos:
684 ctx1 = repo[node1]
685 for subpath in ctx1.substate:
686 sub = ctx1.sub(subpath)
687 if node2 is not None:
688 node2 = bin(repo[node2].substate[subpath][1])
689 submatch = matchmod.narrowmatcher(subpath, match)
690 sub.diff(diffopts, node2, submatch, changes=changes,
691 stat=stat, fp=fp, prefix=prefix)
692
681 693 class changeset_printer(object):
682 694 '''show changeset information when templating not requested.'''
683 695
@@ -1471,7 +1471,8 b' def diff(ui, repo, *pats, **opts):'
1471 1471
1472 1472 diffopts = patch.diffopts(ui, opts)
1473 1473 m = cmdutil.match(repo, pats, opts)
1474 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat)
1474 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
1475 listsubrepos=opts.get('subrepos'))
1475 1476
1476 1477 def export(ui, repo, *changesets, **opts):
1477 1478 """dump the header and diffs for one or more changesets
@@ -4183,7 +4184,7 b' table = {'
4183 4184 _('revision'), _('REV')),
4184 4185 ('c', 'change', '',
4185 4186 _('change made by revision'), _('REV'))
4186 ] + diffopts + diffopts2 + walkopts,
4187 ] + diffopts + diffopts2 + walkopts + subrepoopts,
4187 4188 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4188 4189 "^export":
4189 4190 (export,
@@ -1404,7 +1404,7 b' def diffopts(ui, opts=None, untrusted=Fa'
1404 1404 context=get('unified', getter=ui.config))
1405 1405
1406 1406 def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None,
1407 losedatafn=None):
1407 losedatafn=None, prefix=''):
1408 1408 '''yields diff of changes to files between two nodes, or node and
1409 1409 working directory.
1410 1410
@@ -1418,6 +1418,9 b' def diff(repo, node1=None, node2=None, m'
1418 1418 called with the name of current file being diffed as 'fn'. If set
1419 1419 to None, patches will always be upgraded to git format when
1420 1420 necessary.
1421
1422 prefix is a filename prefix that is prepended to all filenames on
1423 display (used for subrepos).
1421 1424 '''
1422 1425
1423 1426 if opts is None:
@@ -1462,7 +1465,7 b' def diff(repo, node1=None, node2=None, m'
1462 1465 copy = copies.copies(repo, ctx1, ctx2, repo[nullid])[0]
1463 1466
1464 1467 difffn = lambda opts, losedata: trydiff(repo, revs, ctx1, ctx2,
1465 modified, added, removed, copy, getfilectx, opts, losedata)
1468 modified, added, removed, copy, getfilectx, opts, losedata, prefix)
1466 1469 if opts.upgrade and not opts.git:
1467 1470 try:
1468 1471 def losedata(fn):
@@ -1518,7 +1521,10 b' def _addmodehdr(header, omode, nmode):'
1518 1521 header.append('new mode %s\n' % nmode)
1519 1522
1520 1523 def trydiff(repo, revs, ctx1, ctx2, modified, added, removed,
1521 copy, getfilectx, opts, losedatafn):
1524 copy, getfilectx, opts, losedatafn, prefix):
1525
1526 def join(f):
1527 return os.path.join(prefix, f)
1522 1528
1523 1529 date1 = util.datestr(ctx1.date())
1524 1530 man1 = ctx1.manifest()
@@ -1557,8 +1563,8 b' def trydiff(repo, revs, ctx1, ctx2, modi'
1557 1563 gone.add(a)
1558 1564 else:
1559 1565 op = 'copy'
1560 header.append('%s from %s\n' % (op, a))
1561 header.append('%s to %s\n' % (op, f))
1566 header.append('%s from %s\n' % (op, join(a)))
1567 header.append('%s to %s\n' % (op, join(f)))
1562 1568 to = getfilectx(a, ctx1).data()
1563 1569 else:
1564 1570 losedatafn(f)
@@ -1600,7 +1606,7 b' def trydiff(repo, revs, ctx1, ctx2, modi'
1600 1606 elif binary or nflag != oflag:
1601 1607 losedatafn(f)
1602 1608 if opts.git:
1603 header.insert(0, mdiff.diffline(revs, a, b, opts))
1609 header.insert(0, mdiff.diffline(revs, join(a), join(b), opts))
1604 1610
1605 1611 if dodiff:
1606 1612 if dodiff == 'binary':
@@ -1609,7 +1615,7 b' def trydiff(repo, revs, ctx1, ctx2, modi'
1609 1615 text = mdiff.unidiff(to, date1,
1610 1616 # ctx2 date may be dynamic
1611 1617 tn, util.datestr(ctx2.date()),
1612 a, b, revs, opts=opts)
1618 join(a), join(b), revs, opts=opts)
1613 1619 if header and (text or len(header) > 1):
1614 1620 yield ''.join(header)
1615 1621 if text:
@@ -7,7 +7,7 b''
7 7
8 8 import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath
9 9 from i18n import _
10 import config, util, node, error
10 import config, util, node, error, cmdutil
11 11 hg = None
12 12
13 13 nullstate = ('', '', 'empty')
@@ -249,6 +249,9 b' class abstractsubrepo(object):'
249 249 def status(self, rev2, **opts):
250 250 return [], [], [], [], [], [], []
251 251
252 def diff(self, diffopts, node2, match, prefix, **opts):
253 pass
254
252 255 class hgsubrepo(abstractsubrepo):
253 256 def __init__(self, ctx, path, state):
254 257 self._path = path
@@ -289,6 +292,17 b' class hgsubrepo(abstractsubrepo):'
289 292 % (inst, relpath(self)))
290 293 return [], [], [], [], [], [], []
291 294
295 def diff(self, diffopts, node2, match, prefix, **opts):
296 try:
297 node1 = node.bin(self._state[1])
298 cmdutil.diffordiffstat(self._repo.ui, self._repo, diffopts,
299 node1, node2, match,
300 prefix=os.path.join(prefix, self._path),
301 listsubrepos=True, **opts)
302 except error.RepoLookupError, inst:
303 self._repo.ui.warn(_("warning: %s in %s\n")
304 % (inst, relpath(self)))
305
292 306 def dirty(self):
293 307 r = self._state[1]
294 308 if r == '':
@@ -180,7 +180,7 b' Show all commands + options'
180 180 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude
181 181 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd
182 182 commit: addremove, close-branch, include, exclude, message, logfile, date, user
183 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude
183 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
184 184 export: output, switch-parent, rev, text, git, nodates
185 185 forget: include, exclude
186 186 init: ssh, remotecmd
@@ -471,6 +471,7 b' Test command without options'
471 471 --stat output diffstat-style summary of changes
472 472 -I --include PATTERN [+] include names matching the given patterns
473 473 -X --exclude PATTERN [+] exclude names matching the given patterns
474 -S --subrepos recurse into subrepositories
474 475
475 476 [+] marked option can be specified multiple times
476 477
@@ -2,6 +2,7 b' Make status look into subrepositories by'
2 2
3 3 $ echo '[defaults]' >> $HGRCPATH
4 4 $ echo 'status = -S' >> $HGRCPATH
5 $ echo 'diff = --nodates -S' >> $HGRCPATH
5 6
6 7 Create test repository:
7 8
@@ -54,6 +55,21 b' Change working directory:'
54 55 $ hg status
55 56 M foo/bar/z.txt
56 57 M foo/y.txt
58 $ hg diff
59 diff -r d254738c5f5e foo/y.txt
60 --- a/foo/y.txt
61 +++ b/foo/y.txt
62 @@ -1,2 +1,3 @@
63 y1
64 y2
65 +y3
66 diff -r 9647f22de499 foo/bar/z.txt
67 --- a/foo/bar/z.txt
68 +++ b/foo/bar/z.txt
69 @@ -1,2 +1,3 @@
70 z1
71 z2
72 +z3
57 73
58 74 Status call crossing repository boundaries:
59 75
@@ -64,6 +80,21 b' Status call crossing repository boundari'
64 80 $ hg status -I '**/?.txt'
65 81 M foo/bar/z.txt
66 82 M foo/y.txt
83 $ hg diff -I '**/?.txt'
84 diff -r d254738c5f5e foo/y.txt
85 --- a/foo/y.txt
86 +++ b/foo/y.txt
87 @@ -1,2 +1,3 @@
88 y1
89 y2
90 +y3
91 diff -r 9647f22de499 foo/bar/z.txt
92 --- a/foo/bar/z.txt
93 +++ b/foo/bar/z.txt
94 @@ -1,2 +1,3 @@
95 z1
96 z2
97 +z3
67 98
68 99 Status from within a subdirectory:
69 100
@@ -74,6 +105,21 b' Status from within a subdirectory:'
74 105 M foo/bar/z.txt
75 106 M foo/y.txt
76 107 ? dir/a.txt
108 $ hg diff
109 diff -r d254738c5f5e foo/y.txt
110 --- a/foo/y.txt
111 +++ b/foo/y.txt
112 @@ -1,2 +1,3 @@
113 y1
114 y2
115 +y3
116 diff -r 9647f22de499 foo/bar/z.txt
117 --- a/foo/bar/z.txt
118 +++ b/foo/bar/z.txt
119 @@ -1,2 +1,3 @@
120 z1
121 z2
122 +z3
77 123
78 124 Status with relative path:
79 125
@@ -81,17 +127,66 b' Status with relative path:'
81 127 M ../foo/bar/z.txt
82 128 M ../foo/y.txt
83 129 ? a.txt
130 $ hg diff ..
131 diff -r d254738c5f5e foo/y.txt
132 --- a/foo/y.txt
133 +++ b/foo/y.txt
134 @@ -1,2 +1,3 @@
135 y1
136 y2
137 +y3
138 diff -r 9647f22de499 foo/bar/z.txt
139 --- a/foo/bar/z.txt
140 +++ b/foo/bar/z.txt
141 @@ -1,2 +1,3 @@
142 z1
143 z2
144 +z3
84 145 $ cd ..
85 146
147 Cleanup and final commit:
148
149 $ rm -r dir
150 $ hg commit -m 2-3-2
151 committing subrepository foo
152 committing subrepository foo/bar
153
154 Log with the relationships between repo and its subrepo:
155
156 $ hg log --template '{rev}:{node|short} {desc}\n'
157 2:1326fa26d0c0 2-3-2
158 1:4b3c9ff4f66b 1-2-1
159 0:23376cbba0d8 0-0-0
160
161 $ hg -R foo log --template '{rev}:{node|short} {desc}\n'
162 3:65903cebad86 2-3-2
163 2:d254738c5f5e 0-2-1
164 1:8629ce7dcc39 0-1-0
165 0:af048e97ade2 0-0-0
166
167 $ hg -R foo/bar log --template '{rev}:{node|short} {desc}\n'
168 2:31ecbdafd357 2-3-2
169 1:9647f22de499 0-1-1
170 0:4904098473f9 0-0-0
171
86 172 Status between revisions:
87 173
88 $ rm -r dir
89 $ hg commit -m 2-2-1
90 committing subrepository foo
91 committing subrepository foo/bar
92 174 $ hg status
93 175 $ hg status --rev 0:1
94 176 M .hgsubstate
95 177 M foo/.hgsubstate
96 178 M foo/bar/z.txt
97 179 M foo/y.txt
180 $ hg diff -I '**/?.txt' --rev 0:1
181 diff -r af048e97ade2 -r d254738c5f5e foo/y.txt
182 --- a/foo/y.txt
183 +++ b/foo/y.txt
184 @@ -1,1 +1,2 @@
185 y1
186 +y2
187 diff -r 4904098473f9 -r 9647f22de499 foo/bar/z.txt
188 --- a/foo/bar/z.txt
189 +++ b/foo/bar/z.txt
190 @@ -1,1 +1,2 @@
191 z1
192 +z2
General Comments 0
You need to be logged in to leave comments. Login now