Mercurial > hg
changeset 12167:d2c5b0927c28
diff: recurse into subrepositories with --subrepos/-S flag
author | Martin Geisler <mg@lazybytes.net> |
---|---|
date | Fri, 03 Sep 2010 12:58:51 +0200 |
parents | 441a74b8def1 |
children | ff4597f521a4 |
files | hgext/keyword.py mercurial/cmdutil.py mercurial/commands.py mercurial/patch.py mercurial/subrepo.py tests/test-debugcomplete.t tests/test-help.t tests/test-subrepo-recursion.t |
diffstat | 8 files changed, 150 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/keyword.py Fri Sep 03 12:58:51 2010 +0200 +++ b/hgext/keyword.py Fri Sep 03 12:58:51 2010 +0200 @@ -511,14 +511,14 @@ self.lines = kwt.shrinklines(self.fname, self.lines) def kw_diff(orig, repo, node1=None, node2=None, match=None, changes=None, - opts=None): + opts=None, prefix=''): '''Monkeypatch patch.diff to avoid expansion except when comparing against working dir.''' if node2 is not None: kwt.match = util.never elif node1 is not None and node1 != repo['.'].node(): kwt.restrict = True - return orig(repo, node1, node2, match, changes, opts) + return orig(repo, node1, node2, match, changes, opts, prefix) def kwweb_skip(orig, web, req, tmpl): '''Wraps webcommands.x turning off keyword expansion.'''
--- a/mercurial/cmdutil.py Fri Sep 03 12:58:51 2010 +0200 +++ b/mercurial/cmdutil.py Fri Sep 03 12:58:51 2010 +0200 @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -from node import hex, nullid, nullrev, short +from node import hex, bin, nullid, nullrev, short from i18n import _ import os, sys, errno, re, glob, tempfile import util, templater, patch, error, encoding, templatekw @@ -655,7 +655,8 @@ single(rev, seqno + 1, fp) def diffordiffstat(ui, repo, diffopts, node1, node2, match, - changes=None, stat=False, fp=None): + changes=None, stat=False, fp=None, prefix='', + listsubrepos=False): '''show diff or diffstat.''' if fp is None: write = ui.write @@ -668,16 +669,27 @@ width = 80 if not ui.plain(): width = util.termwidth() - chunks = patch.diff(repo, node1, node2, match, changes, diffopts) + chunks = patch.diff(repo, node1, node2, match, changes, diffopts, + prefix=prefix) for chunk, label in patch.diffstatui(util.iterlines(chunks), width=width, git=diffopts.git): write(chunk, label=label) else: for chunk, label in patch.diffui(repo, node1, node2, match, - changes, diffopts): + changes, diffopts, prefix=prefix): write(chunk, label=label) + if listsubrepos: + ctx1 = repo[node1] + for subpath in ctx1.substate: + sub = ctx1.sub(subpath) + if node2 is not None: + node2 = bin(repo[node2].substate[subpath][1]) + submatch = matchmod.narrowmatcher(subpath, match) + sub.diff(diffopts, node2, submatch, changes=changes, + stat=stat, fp=fp, prefix=prefix) + class changeset_printer(object): '''show changeset information when templating not requested.'''
--- a/mercurial/commands.py Fri Sep 03 12:58:51 2010 +0200 +++ b/mercurial/commands.py Fri Sep 03 12:58:51 2010 +0200 @@ -1471,7 +1471,8 @@ diffopts = patch.diffopts(ui, opts) m = cmdutil.match(repo, pats, opts) - cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat) + cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat, + listsubrepos=opts.get('subrepos')) def export(ui, repo, *changesets, **opts): """dump the header and diffs for one or more changesets @@ -4183,7 +4184,7 @@ _('revision'), _('REV')), ('c', 'change', '', _('change made by revision'), _('REV')) - ] + diffopts + diffopts2 + walkopts, + ] + diffopts + diffopts2 + walkopts + subrepoopts, _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')), "^export": (export,
--- a/mercurial/patch.py Fri Sep 03 12:58:51 2010 +0200 +++ b/mercurial/patch.py Fri Sep 03 12:58:51 2010 +0200 @@ -1404,7 +1404,7 @@ context=get('unified', getter=ui.config)) def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None, - losedatafn=None): + losedatafn=None, prefix=''): '''yields diff of changes to files between two nodes, or node and working directory. @@ -1418,6 +1418,9 @@ called with the name of current file being diffed as 'fn'. If set to None, patches will always be upgraded to git format when necessary. + + prefix is a filename prefix that is prepended to all filenames on + display (used for subrepos). ''' if opts is None: @@ -1462,7 +1465,7 @@ copy = copies.copies(repo, ctx1, ctx2, repo[nullid])[0] difffn = lambda opts, losedata: trydiff(repo, revs, ctx1, ctx2, - modified, added, removed, copy, getfilectx, opts, losedata) + modified, added, removed, copy, getfilectx, opts, losedata, prefix) if opts.upgrade and not opts.git: try: def losedata(fn): @@ -1518,7 +1521,10 @@ header.append('new mode %s\n' % nmode) def trydiff(repo, revs, ctx1, ctx2, modified, added, removed, - copy, getfilectx, opts, losedatafn): + copy, getfilectx, opts, losedatafn, prefix): + + def join(f): + return os.path.join(prefix, f) date1 = util.datestr(ctx1.date()) man1 = ctx1.manifest() @@ -1557,8 +1563,8 @@ gone.add(a) else: op = 'copy' - header.append('%s from %s\n' % (op, a)) - header.append('%s to %s\n' % (op, f)) + header.append('%s from %s\n' % (op, join(a))) + header.append('%s to %s\n' % (op, join(f))) to = getfilectx(a, ctx1).data() else: losedatafn(f) @@ -1600,7 +1606,7 @@ elif binary or nflag != oflag: losedatafn(f) if opts.git: - header.insert(0, mdiff.diffline(revs, a, b, opts)) + header.insert(0, mdiff.diffline(revs, join(a), join(b), opts)) if dodiff: if dodiff == 'binary': @@ -1609,7 +1615,7 @@ text = mdiff.unidiff(to, date1, # ctx2 date may be dynamic tn, util.datestr(ctx2.date()), - a, b, revs, opts=opts) + join(a), join(b), revs, opts=opts) if header and (text or len(header) > 1): yield ''.join(header) if text:
--- a/mercurial/subrepo.py Fri Sep 03 12:58:51 2010 +0200 +++ b/mercurial/subrepo.py Fri Sep 03 12:58:51 2010 +0200 @@ -7,7 +7,7 @@ import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath from i18n import _ -import config, util, node, error +import config, util, node, error, cmdutil hg = None nullstate = ('', '', 'empty') @@ -249,6 +249,9 @@ def status(self, rev2, **opts): return [], [], [], [], [], [], [] + def diff(self, diffopts, node2, match, prefix, **opts): + pass + class hgsubrepo(abstractsubrepo): def __init__(self, ctx, path, state): self._path = path @@ -289,6 +292,17 @@ % (inst, relpath(self))) return [], [], [], [], [], [], [] + def diff(self, diffopts, node2, match, prefix, **opts): + try: + node1 = node.bin(self._state[1]) + cmdutil.diffordiffstat(self._repo.ui, self._repo, diffopts, + node1, node2, match, + prefix=os.path.join(prefix, self._path), + listsubrepos=True, **opts) + except error.RepoLookupError, inst: + self._repo.ui.warn(_("warning: %s in %s\n") + % (inst, relpath(self))) + def dirty(self): r = self._state[1] if r == '':
--- a/tests/test-debugcomplete.t Fri Sep 03 12:58:51 2010 +0200 +++ b/tests/test-debugcomplete.t Fri Sep 03 12:58:51 2010 +0200 @@ -180,7 +180,7 @@ annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, include, exclude clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd commit: addremove, close-branch, include, exclude, message, logfile, date, user - diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude + diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos export: output, switch-parent, rev, text, git, nodates forget: include, exclude init: ssh, remotecmd
--- a/tests/test-help.t Fri Sep 03 12:58:51 2010 +0200 +++ b/tests/test-help.t Fri Sep 03 12:58:51 2010 +0200 @@ -471,6 +471,7 @@ --stat output diffstat-style summary of changes -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns + -S --subrepos recurse into subrepositories [+] marked option can be specified multiple times
--- a/tests/test-subrepo-recursion.t Fri Sep 03 12:58:51 2010 +0200 +++ b/tests/test-subrepo-recursion.t Fri Sep 03 12:58:51 2010 +0200 @@ -2,6 +2,7 @@ $ echo '[defaults]' >> $HGRCPATH $ echo 'status = -S' >> $HGRCPATH + $ echo 'diff = --nodates -S' >> $HGRCPATH Create test repository: @@ -54,6 +55,21 @@ $ hg status M foo/bar/z.txt M foo/y.txt + $ hg diff + diff -r d254738c5f5e foo/y.txt + --- a/foo/y.txt + +++ b/foo/y.txt + @@ -1,2 +1,3 @@ + y1 + y2 + +y3 + diff -r 9647f22de499 foo/bar/z.txt + --- a/foo/bar/z.txt + +++ b/foo/bar/z.txt + @@ -1,2 +1,3 @@ + z1 + z2 + +z3 Status call crossing repository boundaries: @@ -64,6 +80,21 @@ $ hg status -I '**/?.txt' M foo/bar/z.txt M foo/y.txt + $ hg diff -I '**/?.txt' + diff -r d254738c5f5e foo/y.txt + --- a/foo/y.txt + +++ b/foo/y.txt + @@ -1,2 +1,3 @@ + y1 + y2 + +y3 + diff -r 9647f22de499 foo/bar/z.txt + --- a/foo/bar/z.txt + +++ b/foo/bar/z.txt + @@ -1,2 +1,3 @@ + z1 + z2 + +z3 Status from within a subdirectory: @@ -74,6 +105,21 @@ M foo/bar/z.txt M foo/y.txt ? dir/a.txt + $ hg diff + diff -r d254738c5f5e foo/y.txt + --- a/foo/y.txt + +++ b/foo/y.txt + @@ -1,2 +1,3 @@ + y1 + y2 + +y3 + diff -r 9647f22de499 foo/bar/z.txt + --- a/foo/bar/z.txt + +++ b/foo/bar/z.txt + @@ -1,2 +1,3 @@ + z1 + z2 + +z3 Status with relative path: @@ -81,17 +127,66 @@ M ../foo/bar/z.txt M ../foo/y.txt ? a.txt + $ hg diff .. + diff -r d254738c5f5e foo/y.txt + --- a/foo/y.txt + +++ b/foo/y.txt + @@ -1,2 +1,3 @@ + y1 + y2 + +y3 + diff -r 9647f22de499 foo/bar/z.txt + --- a/foo/bar/z.txt + +++ b/foo/bar/z.txt + @@ -1,2 +1,3 @@ + z1 + z2 + +z3 $ cd .. +Cleanup and final commit: + + $ rm -r dir + $ hg commit -m 2-3-2 + committing subrepository foo + committing subrepository foo/bar + +Log with the relationships between repo and its subrepo: + + $ hg log --template '{rev}:{node|short} {desc}\n' + 2:1326fa26d0c0 2-3-2 + 1:4b3c9ff4f66b 1-2-1 + 0:23376cbba0d8 0-0-0 + + $ hg -R foo log --template '{rev}:{node|short} {desc}\n' + 3:65903cebad86 2-3-2 + 2:d254738c5f5e 0-2-1 + 1:8629ce7dcc39 0-1-0 + 0:af048e97ade2 0-0-0 + + $ hg -R foo/bar log --template '{rev}:{node|short} {desc}\n' + 2:31ecbdafd357 2-3-2 + 1:9647f22de499 0-1-1 + 0:4904098473f9 0-0-0 + Status between revisions: - $ rm -r dir - $ hg commit -m 2-2-1 - committing subrepository foo - committing subrepository foo/bar $ hg status $ hg status --rev 0:1 M .hgsubstate M foo/.hgsubstate M foo/bar/z.txt M foo/y.txt + $ hg diff -I '**/?.txt' --rev 0:1 + diff -r af048e97ade2 -r d254738c5f5e foo/y.txt + --- a/foo/y.txt + +++ b/foo/y.txt + @@ -1,1 +1,2 @@ + y1 + +y2 + diff -r 4904098473f9 -r 9647f22de499 foo/bar/z.txt + --- a/foo/bar/z.txt + +++ b/foo/bar/z.txt + @@ -1,1 +1,2 @@ + z1 + +z2