# HG changeset patch # User mpm@selenic.com # Date 1117912736 28800 # Node ID fef0f8e041aad2b28566f6b3262fe8a6be70385a # Parent 43105253cf5e7630ac60397b413056c7afd9a03d 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----- diff -r 43105253cf5e -r fef0f8e041aa hg --- 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 create a branch of 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 [rev] dump the latest or given revision of a file - dumpmanifest [rev] dump the latest or given revision of the manifest - export dump the changeset header and diffs for a revision - history show changeset history - init create a new repository in this directory - log show revision history of a single file - merge merge changes from 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) diff -r 43105253cf5e -r fef0f8e041aa mercurial/commands.py --- 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 '), "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'), }