Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/cmdutil.py @ 21041:a2cc3c08c3ac
cat: support cat with explicit paths in subrepos
The cat command with an explicit path into a subrepo is now handled by invoking
cat on the file, from that subrepo. The previous behavior was to complain that
the file didn't exist in the revision (of the top most repo). Now when the file
is actually missing, the revision of the subrepo is named instead (though it is
probably desirable to continue naming the top level repo).
The documented output formatters %d and %p reflect the path from the top level
repo, since the purpose of this is to give the illusion of a unified repository.
Support for the undocumented (for cat) formatters %H, %R, %h, %m and %r was
added long ago (I tested back as far as 0.5), but unfortunately these will
reflect the subrepo node instead of the parent context.
The previous implementation was a bit loose with the return value, i.e. it would
return 0 if _any_ file requested was cat'd successfully. This maintains that
behavior.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Fri, 14 Mar 2014 21:32:05 -0400 |
parents | bdf5ed5246d2 |
children | f0003f989e72 |
comparison
equal
deleted
inserted
replaced
21040:bdf5ed5246d2 | 21041:a2cc3c08c3ac |
---|---|
1810 rejected = wctx.forget(forget, prefix) | 1810 rejected = wctx.forget(forget, prefix) |
1811 bad.extend(f for f in rejected if f in match.files()) | 1811 bad.extend(f for f in rejected if f in match.files()) |
1812 forgot.extend(forget) | 1812 forgot.extend(forget) |
1813 return bad, forgot | 1813 return bad, forgot |
1814 | 1814 |
1815 def cat(ui, repo, ctx, matcher, **opts): | 1815 def cat(ui, repo, ctx, matcher, prefix, **opts): |
1816 err = 1 | 1816 err = 1 |
1817 | 1817 |
1818 def write(path): | 1818 def write(path): |
1819 fp = makefileobj(repo, opts.get('output'), ctx.node(), pathname=path) | 1819 fp = makefileobj(repo, opts.get('output'), ctx.node(), |
1820 pathname=os.path.join(prefix, path)) | |
1820 data = ctx[path].data() | 1821 data = ctx[path].data() |
1821 if opts.get('decode'): | 1822 if opts.get('decode'): |
1822 data = repo.wwritedata(path, data) | 1823 data = repo.wwritedata(path, data) |
1823 fp.write(data) | 1824 fp.write(data) |
1824 fp.close() | 1825 fp.close() |
1831 mfnode = ctx._changeset[0] | 1832 mfnode = ctx._changeset[0] |
1832 if mf.find(mfnode, file)[0]: | 1833 if mf.find(mfnode, file)[0]: |
1833 write(file) | 1834 write(file) |
1834 return 0 | 1835 return 0 |
1835 | 1836 |
1837 # Don't warn about "missing" files that are really in subrepos | |
1838 bad = matcher.bad | |
1839 | |
1840 def badfn(path, msg): | |
1841 for subpath in ctx.substate: | |
1842 if path.startswith(subpath): | |
1843 return | |
1844 bad(path, msg) | |
1845 | |
1846 matcher.bad = badfn | |
1847 | |
1836 for abs in ctx.walk(matcher): | 1848 for abs in ctx.walk(matcher): |
1837 write(abs) | 1849 write(abs) |
1838 err = 0 | 1850 err = 0 |
1851 | |
1852 matcher.bad = bad | |
1853 | |
1854 for subpath in sorted(ctx.substate): | |
1855 sub = ctx.sub(subpath) | |
1856 try: | |
1857 submatch = matchmod.narrowmatcher(subpath, matcher) | |
1858 | |
1859 if not sub.cat(ui, submatch, os.path.join(prefix, sub._path), | |
1860 **opts): | |
1861 err = 0 | |
1862 except error.RepoLookupError: | |
1863 ui.status(_("skipping missing subrepository: %s\n") | |
1864 % os.path.join(prefix, subpath)) | |
1865 | |
1839 return err | 1866 return err |
1840 | 1867 |
1841 def duplicatecopies(repo, rev, fromrev): | 1868 def duplicatecopies(repo, rev, fromrev): |
1842 '''reproduce copies from fromrev to rev in the dirstate''' | 1869 '''reproduce copies from fromrev to rev in the dirstate''' |
1843 for dst, src in copies.pathcopies(repo[fromrev], repo[rev]).iteritems(): | 1870 for dst, src in copies.pathcopies(repo[fromrev], repo[rev]).iteritems(): |