Switch cat command to use walk code.
authorBryan O'Sullivan <bos@serpentine.com>
Wed, 14 Sep 2005 21:57:41 -0700
changeset 1254 e6560042b7b8
parent 1253 a45e717c61a8
child 1255 e825dfea3823
Switch cat command to use walk code. The old syntax of "hg cat FILE REV" is now obsolete. Use "hg cat -r REV FILE" instead, as for all other commands.
doc/hg.1.txt
mercurial/commands.py
tests/test-help.out
--- a/doc/hg.1.txt	Wed Sep 14 16:34:22 2005 -0700
+++ b/doc/hg.1.txt	Wed Sep 14 21:57:41 2005 -0700
@@ -121,10 +121,23 @@
     Unlike import/export, this exactly preserves all changeset
     contents including permissions, rename data, and revision history.
 
-cat <file> [revision]::
-    Output to stdout the given revision for the specified file.
+cat [options] <file ...>::
+    Print the specified files as they were at the given revision.
+    If no revision is given then the tip is used.
+
+    Output may be to a file, in which case the name of the file is
+    given using a format string.  The formatting rules are the same as
+    for the export command, with the following additions:
 
-    If no revision is given then the tip is used.
+    %s   basename of file being printed
+    %d   dirname of file being printed, or '.' if in repo root
+    %p   root-relative path name of file being printed
+
+    options:
+    -I, --include <pat>       include names matching the given patterns
+    -X, --exclude <pat>       exclude names matching the given patterns
+    -o, --output <filespec>   print output to file with formatted name
+    -r, --rev <rev>           print the given revision
 
 clone [-U] <source> [dest]::
     Create a copy of an existing repository in a new directory.
@@ -176,9 +189,11 @@
     This command takes effect in the next commit.
 
     Options:
-    -A, --after        record a copy that has already occurred
-    -f, --force        forcibly copy over an existing managed file
-    -p, --parents      append source path to dest
+    -A, --after           record a copy that has already occurred
+    -I, --include <pat>   include names matching the given patterns
+    -X, --exclude <pat>   exclude names matching the given patterns
+    -f, --force           forcibly copy over an existing managed file
+    -p, --parents         append source path to dest
     
     aliases: cp
 
@@ -226,7 +241,7 @@
 
     options:
     -a, --text                treat all files as text
-    -o, --output <filespec>   print output to file with formatted named
+    -o, --output <filespec>   print output to file with formatted name
 
 forget [options] [files]::
     Undo an 'hg add' scheduled for the next commit.
--- a/mercurial/commands.py	Wed Sep 14 16:34:22 2005 -0700
+++ b/mercurial/commands.py	Wed Sep 14 21:57:41 2005 -0700
@@ -194,7 +194,7 @@
             yield str(rev)
 
 def make_filename(repo, r, pat, node=None,
-                  total=None, seqno=None, revwidth=None):
+                  total=None, seqno=None, revwidth=None, pathname=None):
     node_expander = {
         'H': lambda: hex(node),
         'R': lambda: str(r.rev(node)),
@@ -216,6 +216,10 @@
             expander['n'] = lambda: str(seqno)
         if total is not None and seqno is not None:
             expander['n'] = lambda:str(seqno).zfill(len(str(total)))
+        if pathname is not None:
+            expander['s'] = lambda: os.path.basename(pathname)
+            expander['d'] = lambda: os.path.dirname(pathname) or '.'
+            expander['p'] = lambda: pathname
 
         newname = []
         patlen = len(pat)
@@ -234,14 +238,15 @@
                     inst.args[0])
 
 def make_file(repo, r, pat, node=None,
-              total=None, seqno=None, revwidth=None, mode='wb'):
+              total=None, seqno=None, revwidth=None, mode='wb', pathname=None):
     if not pat or pat == '-':
         return 'w' in mode and sys.stdout or sys.stdin
     if hasattr(pat, 'write') and 'w' in mode:
         return pat
     if hasattr(pat, 'read') and 'r' in mode:
         return pat
-    return open(make_filename(repo, r, pat, node, total, seqno, revwidth),
+    return open(make_filename(repo, r, pat, node, total, seqno, revwidth,
+                              pathname),
                 mode)
 
 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always,
@@ -569,25 +574,26 @@
     except:
         os.unlink(fname)
 
-def cat(ui, repo, file1, rev=None, **opts):
-    """output the latest or given revision of a file"""
-    r = repo.file(relpath(repo, [file1])[0])
-    if rev:
-        try:
-            # assume all revision numbers are for changesets
-            n = repo.lookup(rev)
-            change = repo.changelog.read(n)
-            m = repo.manifest.read(change[0])
-            n = m[relpath(repo, [file1])[0]]
-        except (hg.RepoError, KeyError):
+def cat(ui, repo, file1, *pats, **opts):
+    """output the latest or given revisions of files"""
+    mf = {}
+    if opts['rev']:
+        change = repo.changelog.read(repo.lookup(opts['rev']))
+        mf = repo.manifest.read(change[0])
+    for src, abs, rel, exact in walk(repo, (file1,) + pats, opts):
+        r = repo.file(abs)
+        if opts['rev']:
             try:
-                n = r.lookup(rev)
-            except KeyError, inst:
-                raise util.Abort('cannot find file %s in rev %s', file1, rev)
-    else:
-        n = r.tip()
-    fp = make_file(repo, r, opts['output'], node=n)
-    fp.write(r.read(n))
+                n = mf[abs]
+            except (hg.RepoError, KeyError):
+                try:
+                    n = r.lookup(rev)
+                except KeyError, inst:
+                    raise util.Abort('cannot find file %s in rev %s', rel, rev)
+        else:
+            n = r.tip()
+        fp = make_file(repo, r, opts['output'], node=n, pathname=abs)
+        fp.write(r.read(n))
 
 def clone(ui, source, dest=None, **opts):
     """make a copy of an existing repository"""
@@ -1765,8 +1771,11 @@
          'hg bundle FILE DEST'),
     "cat":
         (cat,
-         [('o', 'output', "", 'output to file')],
-         'hg cat [-o OUTFILE] FILE [REV]'),
+         [('I', 'include', [], 'include path in search'),
+          ('X', 'exclude', [], 'exclude path from search'),
+          ('o', 'output', "", 'output to file'),
+          ('r', 'rev', '', 'revision')],
+         'hg cat [OPTION]... FILE...'),
     "^clone":
         (clone,
          [('U', 'noupdate', None, 'skip update after cloning'),
--- a/tests/test-help.out	Wed Sep 14 16:34:22 2005 -0700
+++ b/tests/test-help.out	Wed Sep 14 21:57:41 2005 -0700
@@ -40,7 +40,7 @@
  addremove   add all new files, delete all missing files
  annotate    show changeset information per file line
  bundle      create a changegroup file
- cat         output the latest or given revision of a file
+ cat         output the latest or given revisions of files
  clone       make a copy of an existing repository
  commit      commit the specified files or all outstanding changes
  copy        mark files as copied for the next commit
@@ -82,7 +82,7 @@
  addremove   add all new files, delete all missing files
  annotate    show changeset information per file line
  bundle      create a changegroup file
- cat         output the latest or given revision of a file
+ cat         output the latest or given revisions of files
  clone       make a copy of an existing repository
  commit      commit the specified files or all outstanding changes
  copy        mark files as copied for the next commit