big heap of command clean-up work
authormpm@selenic.com
Sat, 04 Jun 2005 11:18:56 -0800
changeset 245 fef0f8e041aa
parent 244 43105253cf5e
child 246 96cde50a746f
big heap of command clean-up work -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 big heap of command clean-up work Migrate add, forget, remove, commit, diff, addremove, tip, log, recover, and serve. Fix up filterfiles, relfilter, and relpath to be a bit more bulletproof Alphabetize functions and the command table Make everything in commands.py relative-path aware manifest hash: f0856031a7be4e49289677b467f29bcf24ebce4a -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCof6gywK+sNU5EO8RAoW1AJsHu8vchPSjls7wVbvsq/UKlGhqtgCgtnnl xSBxyf/TEVWjHIk3uTa8WSE= =YPMl -----END PGP SIGNATURE-----
hg
mercurial/commands.py
--- a/hg	Sat Jun 04 11:13:25 2005 -0800
+++ b/hg	Sat Jun 04 11:18:56 2005 -0800
@@ -19,32 +19,6 @@
 import sys, os, time
 from mercurial import hg, mdiff, fancyopts, ui, commands
 
-def help():
-    ui.status("""\
- commands:
-
- add [files...]        add the given files in the next commit
- addremove             add all new files, delete all missing files
- annotate [files...]   show changeset number per file line
- branch <path>         create a branch of <path> in this directory
- checkout [changeset]  checkout the latest or given changeset
- commit                commit all changes to the repository
- diff [files...]       diff working directory (or selected files)
- dump <file> [rev]     dump the latest or given revision of a file
- dumpmanifest [rev]    dump the latest or given revision of the manifest
- export <rev>          dump the changeset header and diffs for a revision
- history               show changeset history
- init                  create a new repository in this directory
- log <file>            show revision history of a single file
- merge <path>          merge changes from <path> into local repository
- recover               rollback an interrupted transaction
- remove [files...]     remove the given files in the next commit
- serve                 export the repository via HTTP
- status                show new, missing, and changed files in working dir
- tags                  show current changeset tags
- undo                  undo the last transaction
-""")
-
 def filterfiles(list, files):
     l = [ x for x in list if x in files ]
 
@@ -126,21 +100,6 @@
 if os.getcwd() != repo.root:
     relpath = os.getcwd()[len(repo.root) + 1: ]
 
-elif cmd == "add":
-    repo.add(args)
-
-elif cmd == "forget":
-    repo.forget(args)
-
-elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
-    repo.remove(args)
-
-elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
-    if 1:
-        if len(args) > 0:
-            repo.commit(args)
-        else:
-            repo.commit()
 elif cmd == "rawcommit":
     "raw commit interface"
     rc = {}
@@ -205,26 +164,6 @@
                 raise "patch failed!"
         repo.commit(files, text)
 
-elif cmd == "diff":
-    revs = []
-
-    if args:
-        doptions = {}
-        opts = [('r', 'revision', [], 'revision')]
-        args = fancyopts.fancyopts(args, opts, doptions,
-                                   'hg diff [options] [files]')
-        revs = map(lambda x: repo.lookup(x), doptions['revision'])
-    
-    if len(revs) > 2:
-        self.ui.warn("too many revisions to diff\n")
-        sys.exit(1)
-
-    if relpath:
-        if not args: args = [ relpath ]
-        else: args = [ os.path.join(relpath, x) for x in args ]
-
-    diff(args, *revs)
-
 elif cmd == "export":
     node = repo.lookup(args[0])
     prev, other = repo.changelog.parents(node)
@@ -249,11 +188,6 @@
     data = sys.stdin.read()
     repo.addchangegroup(data)
 
-elif cmd == "addremove":
-    (c, a, d, u) = repo.diffdir(repo.root)
-    repo.add(a)
-    repo.remove(d)
-    
 elif cmd == "history":
     for i in range(repo.changelog.count()):
         n = repo.changelog.node(i)
@@ -273,41 +207,6 @@
         print "description:"
         print changes[4]
 
-elif cmd == "tip":
-    n = repo.changelog.tip()
-    t = repo.changelog.rev(n)
-    ui.status("%d:%s\n" % (t, hg.hex(n)))
-
-elif cmd == "log":
-
-    if len(args) == 1:
-        if relpath:
-            args[0] = os.path.join(relpath, args[0])
-
-        r = repo.file(args[0])
-        for i in range(r.count()):
-            n = r.node(i)
-            (p1, p2) = r.parents(n)
-            (h, h1, h2) = map(hg.hex, (n, p1, p2))
-            (i1, i2) = map(r.rev, (p1, p2))
-            cr = r.linkrev(n)
-            cn = hg.hex(repo.changelog.node(cr))
-            print "rev:       %4d:%s" % (i, h)
-            print "changeset: %4d:%s" % (cr, cn)
-            print "parents:   %4d:%s" % (i1, h1)
-            if i2: print "           %4d:%s" % (i2, h2)
-            changes = repo.changelog.read(repo.changelog.node(cr))
-            print "user: %s" % changes[1]
-            print "date: %s" % time.asctime(
-                time.localtime(float(changes[2].split(' ')[0])))
-            print "description:"
-            print changes[4]
-            print
-    elif len(args) > 1:
-        print "too many args"
-    else:
-        print "missing filename"
-
 elif cmd == "dump":
     if args:
         r = repo.file(args[0])
@@ -384,9 +283,6 @@
             r = "?"
         print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
 
-elif cmd == "recover":
-    repo.recover()
-
 elif cmd == "verify":
     filelinkrevs = {}
     filenodes = {}
@@ -510,23 +406,6 @@
         ui.warn("%d integrity errors encountered!\n" % errors)
         sys.exit(1)
 
-elif cmd == "serve":
-    from mercurial import hgweb
-    
-    soptions = {}
-    opts = [('p', 'port', 8000, 'listen port'),
-            ('a', 'address', '', 'interface address'),
-            ('n', 'name', os.getcwd(), 'repository name'),
-            ('t', 'templates', "", 'template map')
-            ]
-    
-    args = fancyopts.fancyopts(args, opts, soptions,
-                              'hg serve [options]')
-
-    hgweb.server(repo.root, soptions["name"], soptions["templates"],
-                 soptions["address"], soptions["port"])
-    
 else:
     if cmd: ui.warn("unknown command\n\n")
-    help()
     sys.exit(1)
--- a/mercurial/commands.py	Sat Jun 04 11:13:25 2005 -0800
+++ b/mercurial/commands.py	Sat Jun 04 11:18:56 2005 -0800
@@ -1,27 +1,64 @@
-import os, re, traceback, sys, signal, time
+import os, re, traceback, sys, signal, time, mdiff
 from mercurial import fancyopts, ui, hg
 
 class UnknownCommand(Exception): pass
 
-def filterfiles(list, files):
-    l = [ x for x in list if x in files ]
+def filterfiles(filters, files):
+    l = [ x for x in files if x in filters ]
 
-    for f in files:
-        if f[-1] != os.sep: f += os.sep
-        l += [ x for x in list if x.startswith(f) ]
+    for t in filters:
+        if t and t[-1] != os.sep: t += os.sep
+        l += [ x for x in files if x.startswith(t) ]
     return l
 
-def relfilter(repo, args):
+def relfilter(repo, files):
     if os.getcwd() != repo.root:
         p = os.getcwd()[len(repo.root) + 1: ]
-        return filterfiles(p, args)
-    return args
+        return filterfiles(p, files)
+    return files
 
 def relpath(repo, args):
     if os.getcwd() != repo.root:
         p = os.getcwd()[len(repo.root) + 1: ]
-        return [ os.path.join(p, x) for x in args ]
+        return [ os.path.normpath(os.path.join(p, x)) for x in args ]
     return args
+
+def dodiff(repo, files = None, node1 = None, node2 = None):
+    def date(c):
+        return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
+
+    if node2:
+        change = repo.changelog.read(node2)
+        mmap2 = repo.manifest.read(change[0])
+        (c, a, d) = repo.diffrevs(node1, node2)
+        def read(f): return repo.file(f).read(mmap2[f])
+        date2 = date(change)
+    else:
+        date2 = time.asctime()
+        (c, a, d, u) = repo.diffdir(repo.root, node1)
+        if not node1:
+            node1 = repo.dirstate.parents()[0]
+        def read(f): return file(os.path.join(repo.root, f)).read()
+
+    change = repo.changelog.read(node1)
+    mmap = repo.manifest.read(change[0])
+    date1 = date(change)
+
+    if files:
+        c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
+
+    for f in c:
+        to = repo.file(f).read(mmap[f])
+        tn = read(f)
+        sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
+    for f in a:
+        to = ""
+        tn = read(f)
+        sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
+    for f in d:
+        to = repo.file(f).read(mmap[f])
+        tn = ""
+        sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
     
 def help(ui, cmd=None):
     '''show help'''
@@ -59,28 +96,16 @@
  undo                  undo the last transaction
 """)
 
-def init(ui):
-    """create a repository"""
-    hg.repository(ui, ".", create=1)
-
-def branch(ui, path):
-    '''branch from a local repository'''
-    # this should eventually support remote repos
-    os.system("cp -al %s/.hg .hg" % path)
+def add(ui, repo, file, *files):
+    '''add the specified files on the next commit'''
+    repo.add(relpath(repo, (file,) + files))
 
-def checkout(ui, repo, changeset=None):
-    '''checkout a given changeset or the current tip'''
+def addremove(ui, repo):
     (c, a, d, u) = repo.diffdir(repo.root)
-    if c or a or d:
-        ui.warn("aborting (outstanding changes in working directory)\n")
-        sys.exit(1)
+    repo.add(a)
+    repo.remove(d)
 
-    node = repo.changelog.tip()
-    if changeset:
-        node = repo.lookup(changeset)
-    repo.checkout(node)
-
-def annotate(u, repo, *args, **ops):
+def annotate(u, repo, file, *files, **ops):
     def getnode(rev):
         return hg.short(repo.changelog.node(rev))
 
@@ -101,7 +126,6 @@
     if not ops['user'] and not ops['changeset']:
         ops['number'] = 1
 
-    args = relpath(repo, args)
     node = repo.dirstate.parents()[0]
     if ops['revision']:
         node = repo.changelog.lookup(ops['revision'])
@@ -109,7 +133,7 @@
     mmap = repo.manifest.read(change[0])
     maxuserlen = 0
     maxchangelen = 0
-    for f in args:
+    for f in relpath(repo, (file,) + files):
         lines = repo.file(f).annotate(mmap[f])
         pieces = []
 
@@ -122,6 +146,47 @@
         for p,l in zip(zip(*pieces), lines):
             u.write(" ".join(p) + ": " + l[1])
 
+def branch(ui, path):
+    '''branch from a local repository'''
+    # this should eventually support remote repos
+    os.system("cp -al %s/.hg .hg" % path)
+
+def checkout(ui, repo, changeset=None):
+    '''checkout a given changeset or the current tip'''
+    (c, a, d, u) = repo.diffdir(repo.root)
+    if c or a or d:
+        ui.warn("aborting (outstanding changes in working directory)\n")
+        sys.exit(1)
+
+    node = repo.changelog.tip()
+    if changeset:
+        node = repo.lookup(changeset)
+    repo.checkout(node)
+
+def commit(ui, repo, *files):
+    """commit the specified files or all outstanding changes"""
+    repo.commit(relpath(repo, files))
+
+def diff(ui, repo, *files, **opts):
+    revs = []
+    if opts['rev']:
+        revs = map(lambda x: repo.lookup(x), opts['rev'])
+    
+    if len(revs) > 2:
+        self.ui.warn("too many revisions to diff\n")
+        sys.exit(1)
+
+    if files:
+        files = relpath(repo, files)
+    else:
+        files = relpath(repo, [""])
+
+    dodiff(repo, files, *revs)
+
+def forget(ui, repo, file, *files):
+    """don't add the specified files on the next commit"""
+    repo.forget(relpath(repo, (file,) + files))
+
 def heads(ui, repo):
     '''show current repository heads'''
     for n in repo.changelog.heads():
@@ -142,6 +207,33 @@
         print "description:"
         print changes[4]
 
+def init(ui):
+    """create a repository"""
+    hg.repository(ui, ".", create=1)
+
+def log(ui, repo, f):
+    f = relpath(repo, [f])[0]
+
+    r = repo.file(f)
+    for i in range(r.count()):
+        n = r.node(i)
+        (p1, p2) = r.parents(n)
+        (h, h1, h2) = map(hg.hex, (n, p1, p2))
+        (i1, i2) = map(r.rev, (p1, p2))
+        cr = r.linkrev(n)
+        cn = hg.hex(repo.changelog.node(cr))
+        print "rev:       %4d:%s" % (i, h)
+        print "changeset: %4d:%s" % (cr, cn)
+        print "parents:   %4d:%s" % (i1, h1)
+        if i2: print "           %4d:%s" % (i2, h2)
+        changes = repo.changelog.read(repo.changelog.node(cr))
+        print "user: %s" % changes[1]
+        print "date: %s" % time.asctime(
+            time.localtime(float(changes[2].split(' ')[0])))
+        print "description:"
+        print changes[4].rstrip()
+        print
+
 def parents(ui, repo, node = None):
     '''show the parents of the current working dir'''
     if node:
@@ -153,7 +245,14 @@
         if n != hg.nullid:
             ui.write("%d:%s\n" % (repo.changelog.rev(n), hg.hex(n)))
 
-def resolve(ui, repo, node = None):
+def recover(ui, repo):
+    repo.recover()
+
+def remove(ui, repo, file, *files):
+    """remove the specified files on the next commit"""
+    repo.remove(relpath(repo, (file,) + files))
+
+def resolve(ui, repo, node=None):
     '''merge a given node or the current tip into the working dir'''
     if not node:
         node = repo.changelog.tip()
@@ -161,13 +260,19 @@
         node = repo.lookup(node)
     repo.resolve(node)
 
+def serve(ui, repo, **opts):
+    from mercurial import hgweb
+    hgweb.server(repo.root, opts["name"], opts["templates"],
+                 opts["address"], opts["port"])
+    
 def status(ui, repo):
     '''show changed files in the working directory
 
-C = changed
-A = added
-R = removed
-? = not tracked'''
+    C = changed
+    A = added
+    R = removed
+    ? = not tracked'''
+    
     (c, a, d, u) = repo.diffdir(repo.root)
     (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
 
@@ -176,24 +281,44 @@
     for f in d: print "R", f
     for f in u: print "?", f
 
+def tip(ui, repo):
+    n = repo.changelog.tip()
+    t = repo.changelog.rev(n)
+    ui.status("%d:%s\n" % (t, hg.hex(n)))
+
 def undo(ui, repo):
     repo.undo()
 
 table = {
-    "init": (init, [], 'hg init'),
-    "branch|clone": (branch, [], 'hg branch [path]'),
-    "heads": (heads, [], 'hg heads'),
-    "help": (help, [], 'hg help [command]'),
-    "checkout|co": (checkout, [], 'hg checkout [changeset]'),
+    "add": (add, [], "hg add [files]"),
+    "addremove": (addremove, [], "hg addremove"),
     "ann|annotate": (annotate,
                      [('r', 'revision', '', 'revision'),
                       ('u', 'user', None, 'show user'),
                       ('n', 'number', None, 'show revision number'),
                       ('c', 'changeset', None, 'show changeset')],
                      'hg annotate [-u] [-c] [-n] [-r id] [files]'),
+    "branch|clone": (branch, [], 'hg branch [path]'),
+    "checkout|co": (checkout, [], 'hg checkout [changeset]'),
+    "commit|ci": (commit, [], 'hg commit [files]'),
+    "diff": (diff, [('r', 'rev', [], 'revision')],
+             'hg diff [-r A] [-r B] [files]'),
+    "forget": (forget, [], "hg forget [files]"),
+    "heads": (heads, [], 'hg heads'),
+    "help": (help, [], 'hg help [command]'),
+    "init": (init, [], 'hg init'),
+    "log": (log, [], 'hg log <file>'),
     "parents": (parents, [], 'hg parents [node]'),
+    "recover": (recover, [], "hg recover"),
+    "remove": (remove, [], "hg remove [files]"),
     "resolve": (resolve, [], 'hg resolve [node]'),
+    "serve": (serve, [('p', 'port', 8000, 'listen port'),
+                      ('a', 'address', '', 'interface address'),
+                      ('n', 'name', os.getcwd(), 'repository name'),
+                      ('t', 'templates', "", 'template map')],
+              "hg serve [options]"),
     "status": (status, [], 'hg status'),
+    "tip": (tip, [], 'hg tip'),
     "undo": (undo, [], 'hg undo'),
     }