##// 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 self.lines = kwt.shrinklines(self.fname, self.lines)
511 self.lines = kwt.shrinklines(self.fname, self.lines)
512
512
513 def kw_diff(orig, repo, node1=None, node2=None, match=None, changes=None,
513 def kw_diff(orig, repo, node1=None, node2=None, match=None, changes=None,
514 opts=None):
514 opts=None, prefix=''):
515 '''Monkeypatch patch.diff to avoid expansion except when
515 '''Monkeypatch patch.diff to avoid expansion except when
516 comparing against working dir.'''
516 comparing against working dir.'''
517 if node2 is not None:
517 if node2 is not None:
518 kwt.match = util.never
518 kwt.match = util.never
519 elif node1 is not None and node1 != repo['.'].node():
519 elif node1 is not None and node1 != repo['.'].node():
520 kwt.restrict = True
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 def kwweb_skip(orig, web, req, tmpl):
523 def kwweb_skip(orig, web, req, tmpl):
524 '''Wraps webcommands.x turning off keyword expansion.'''
524 '''Wraps webcommands.x turning off keyword expansion.'''
@@ -5,7 +5,7 b''
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
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 from i18n import _
9 from i18n import _
10 import os, sys, errno, re, glob, tempfile
10 import os, sys, errno, re, glob, tempfile
11 import util, templater, patch, error, encoding, templatekw
11 import util, templater, patch, error, encoding, templatekw
@@ -655,7 +655,8 b" def export(repo, revs, template='hg-%h.p"
655 single(rev, seqno + 1, fp)
655 single(rev, seqno + 1, fp)
656
656
657 def diffordiffstat(ui, repo, diffopts, node1, node2, match,
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 '''show diff or diffstat.'''
660 '''show diff or diffstat.'''
660 if fp is None:
661 if fp is None:
661 write = ui.write
662 write = ui.write
@@ -668,16 +669,27 b' def diffordiffstat(ui, repo, diffopts, n'
668 width = 80
669 width = 80
669 if not ui.plain():
670 if not ui.plain():
670 width = util.termwidth()
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 for chunk, label in patch.diffstatui(util.iterlines(chunks),
674 for chunk, label in patch.diffstatui(util.iterlines(chunks),
673 width=width,
675 width=width,
674 git=diffopts.git):
676 git=diffopts.git):
675 write(chunk, label=label)
677 write(chunk, label=label)
676 else:
678 else:
677 for chunk, label in patch.diffui(repo, node1, node2, match,
679 for chunk, label in patch.diffui(repo, node1, node2, match,
678 changes, diffopts):
680 changes, diffopts, prefix=prefix):
679 write(chunk, label=label)
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 class changeset_printer(object):
693 class changeset_printer(object):
682 '''show changeset information when templating not requested.'''
694 '''show changeset information when templating not requested.'''
683
695
@@ -1471,7 +1471,8 b' def diff(ui, repo, *pats, **opts):'
1471
1471
1472 diffopts = patch.diffopts(ui, opts)
1472 diffopts = patch.diffopts(ui, opts)
1473 m = cmdutil.match(repo, pats, opts)
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 def export(ui, repo, *changesets, **opts):
1477 def export(ui, repo, *changesets, **opts):
1477 """dump the header and diffs for one or more changesets
1478 """dump the header and diffs for one or more changesets
@@ -4183,7 +4184,7 b' table = {'
4183 _('revision'), _('REV')),
4184 _('revision'), _('REV')),
4184 ('c', 'change', '',
4185 ('c', 'change', '',
4185 _('change made by revision'), _('REV'))
4186 _('change made by revision'), _('REV'))
4186 ] + diffopts + diffopts2 + walkopts,
4187 ] + diffopts + diffopts2 + walkopts + subrepoopts,
4187 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4188 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4188 "^export":
4189 "^export":
4189 (export,
4190 (export,
@@ -1404,7 +1404,7 b' def diffopts(ui, opts=None, untrusted=Fa'
1404 context=get('unified', getter=ui.config))
1404 context=get('unified', getter=ui.config))
1405
1405
1406 def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None,
1406 def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None,
1407 losedatafn=None):
1407 losedatafn=None, prefix=''):
1408 '''yields diff of changes to files between two nodes, or node and
1408 '''yields diff of changes to files between two nodes, or node and
1409 working directory.
1409 working directory.
1410
1410
@@ -1418,6 +1418,9 b' def diff(repo, node1=None, node2=None, m'
1418 called with the name of current file being diffed as 'fn'. If set
1418 called with the name of current file being diffed as 'fn'. If set
1419 to None, patches will always be upgraded to git format when
1419 to None, patches will always be upgraded to git format when
1420 necessary.
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 if opts is None:
1426 if opts is None:
@@ -1462,7 +1465,7 b' def diff(repo, node1=None, node2=None, m'
1462 copy = copies.copies(repo, ctx1, ctx2, repo[nullid])[0]
1465 copy = copies.copies(repo, ctx1, ctx2, repo[nullid])[0]
1463
1466
1464 difffn = lambda opts, losedata: trydiff(repo, revs, ctx1, ctx2,
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 if opts.upgrade and not opts.git:
1469 if opts.upgrade and not opts.git:
1467 try:
1470 try:
1468 def losedata(fn):
1471 def losedata(fn):
@@ -1518,7 +1521,10 b' def _addmodehdr(header, omode, nmode):'
1518 header.append('new mode %s\n' % nmode)
1521 header.append('new mode %s\n' % nmode)
1519
1522
1520 def trydiff(repo, revs, ctx1, ctx2, modified, added, removed,
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 date1 = util.datestr(ctx1.date())
1529 date1 = util.datestr(ctx1.date())
1524 man1 = ctx1.manifest()
1530 man1 = ctx1.manifest()
@@ -1557,8 +1563,8 b' def trydiff(repo, revs, ctx1, ctx2, modi'
1557 gone.add(a)
1563 gone.add(a)
1558 else:
1564 else:
1559 op = 'copy'
1565 op = 'copy'
1560 header.append('%s from %s\n' % (op, a))
1566 header.append('%s from %s\n' % (op, join(a)))
1561 header.append('%s to %s\n' % (op, f))
1567 header.append('%s to %s\n' % (op, join(f)))
1562 to = getfilectx(a, ctx1).data()
1568 to = getfilectx(a, ctx1).data()
1563 else:
1569 else:
1564 losedatafn(f)
1570 losedatafn(f)
@@ -1600,7 +1606,7 b' def trydiff(repo, revs, ctx1, ctx2, modi'
1600 elif binary or nflag != oflag:
1606 elif binary or nflag != oflag:
1601 losedatafn(f)
1607 losedatafn(f)
1602 if opts.git:
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 if dodiff:
1611 if dodiff:
1606 if dodiff == 'binary':
1612 if dodiff == 'binary':
@@ -1609,7 +1615,7 b' def trydiff(repo, revs, ctx1, ctx2, modi'
1609 text = mdiff.unidiff(to, date1,
1615 text = mdiff.unidiff(to, date1,
1610 # ctx2 date may be dynamic
1616 # ctx2 date may be dynamic
1611 tn, util.datestr(ctx2.date()),
1617 tn, util.datestr(ctx2.date()),
1612 a, b, revs, opts=opts)
1618 join(a), join(b), revs, opts=opts)
1613 if header and (text or len(header) > 1):
1619 if header and (text or len(header) > 1):
1614 yield ''.join(header)
1620 yield ''.join(header)
1615 if text:
1621 if text:
@@ -7,7 +7,7 b''
7
7
8 import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath
8 import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath
9 from i18n import _
9 from i18n import _
10 import config, util, node, error
10 import config, util, node, error, cmdutil
11 hg = None
11 hg = None
12
12
13 nullstate = ('', '', 'empty')
13 nullstate = ('', '', 'empty')
@@ -249,6 +249,9 b' class abstractsubrepo(object):'
249 def status(self, rev2, **opts):
249 def status(self, rev2, **opts):
250 return [], [], [], [], [], [], []
250 return [], [], [], [], [], [], []
251
251
252 def diff(self, diffopts, node2, match, prefix, **opts):
253 pass
254
252 class hgsubrepo(abstractsubrepo):
255 class hgsubrepo(abstractsubrepo):
253 def __init__(self, ctx, path, state):
256 def __init__(self, ctx, path, state):
254 self._path = path
257 self._path = path
@@ -289,6 +292,17 b' class hgsubrepo(abstractsubrepo):'
289 % (inst, relpath(self)))
292 % (inst, relpath(self)))
290 return [], [], [], [], [], [], []
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 def dirty(self):
306 def dirty(self):
293 r = self._state[1]
307 r = self._state[1]
294 if r == '':
308 if r == '':
@@ -180,7 +180,7 b' Show all commands + options'
180 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude
180 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude
181 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd
181 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd
182 commit: addremove, close-branch, include, exclude, message, logfile, date, user
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 export: output, switch-parent, rev, text, git, nodates
184 export: output, switch-parent, rev, text, git, nodates
185 forget: include, exclude
185 forget: include, exclude
186 init: ssh, remotecmd
186 init: ssh, remotecmd
@@ -471,6 +471,7 b' Test command without options'
471 --stat output diffstat-style summary of changes
471 --stat output diffstat-style summary of changes
472 -I --include PATTERN [+] include names matching the given patterns
472 -I --include PATTERN [+] include names matching the given patterns
473 -X --exclude PATTERN [+] exclude names matching the given patterns
473 -X --exclude PATTERN [+] exclude names matching the given patterns
474 -S --subrepos recurse into subrepositories
474
475
475 [+] marked option can be specified multiple times
476 [+] marked option can be specified multiple times
476
477
@@ -2,6 +2,7 b' Make status look into subrepositories by'
2
2
3 $ echo '[defaults]' >> $HGRCPATH
3 $ echo '[defaults]' >> $HGRCPATH
4 $ echo 'status = -S' >> $HGRCPATH
4 $ echo 'status = -S' >> $HGRCPATH
5 $ echo 'diff = --nodates -S' >> $HGRCPATH
5
6
6 Create test repository:
7 Create test repository:
7
8
@@ -54,6 +55,21 b' Change working directory:'
54 $ hg status
55 $ hg status
55 M foo/bar/z.txt
56 M foo/bar/z.txt
56 M foo/y.txt
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 Status call crossing repository boundaries:
74 Status call crossing repository boundaries:
59
75
@@ -64,6 +80,21 b' Status call crossing repository boundari'
64 $ hg status -I '**/?.txt'
80 $ hg status -I '**/?.txt'
65 M foo/bar/z.txt
81 M foo/bar/z.txt
66 M foo/y.txt
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 Status from within a subdirectory:
99 Status from within a subdirectory:
69
100
@@ -74,6 +105,21 b' Status from within a subdirectory:'
74 M foo/bar/z.txt
105 M foo/bar/z.txt
75 M foo/y.txt
106 M foo/y.txt
76 ? dir/a.txt
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 Status with relative path:
124 Status with relative path:
79
125
@@ -81,17 +127,66 b' Status with relative path:'
81 M ../foo/bar/z.txt
127 M ../foo/bar/z.txt
82 M ../foo/y.txt
128 M ../foo/y.txt
83 ? a.txt
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 $ cd ..
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 Status between revisions:
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 $ hg status
174 $ hg status
93 $ hg status --rev 0:1
175 $ hg status --rev 0:1
94 M .hgsubstate
176 M .hgsubstate
95 M foo/.hgsubstate
177 M foo/.hgsubstate
96 M foo/bar/z.txt
178 M foo/bar/z.txt
97 M foo/y.txt
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