# HG changeset patch # User mpm@selenic.com # Date 1121410615 28800 # Node ID 57486910398547b25eb80db55e5630ad0ae00779 # Parent 51eb248d33488dc3cf9372304095ceeeab412535# Parent 5ca319a641e14f2addc2deaa89d037b3c98521b6 Merge with TAH manifest hash: 197e0d1a0d7376a9eb72381330462f06490ab821 diff -r 51eb248d3348 -r 574869103985 contrib/convert-repo diff -r 51eb248d3348 -r 574869103985 doc/hgrc.5.txt --- a/doc/hgrc.5.txt Thu Jul 14 22:37:46 2005 -0800 +++ b/doc/hgrc.5.txt Thu Jul 14 22:56:55 2005 -0800 @@ -93,22 +93,22 @@ ui:: User interface controls. debug;; - Print debugging information. True or False. Default is True. + Print debugging information. True or False. Default is False. editor;; - The editor to use during a commit. Default is "vi". + The editor to use during a commit. Default is $EDITOR or "vi". + interactive;; + Allow to prompt the user. True or False. Default is True. merge;; The conflict resolution program to use during a manual merge. - Default is "hgeditor". + Default is "hgmerge". quiet;; - Reduce the amount of output printed. True or False. Default is - False. + Reduce the amount of output printed. True or False. Default is False. username;; The committer of a changeset created when running "commit". Typically a person's name and email address, e.g. "Fred Widget - ". Default is username@hostname. + ". Default is $EMAIL or username@hostname. verbose;; - Increase the amount of output printed. True or False. Default is - False. + Increase the amount of output printed. True or False. Default is False. AUTHOR ------ diff -r 51eb248d3348 -r 574869103985 mercurial/commands.py --- a/mercurial/commands.py Thu Jul 14 22:37:46 2005 -0800 +++ b/mercurial/commands.py Thu Jul 14 22:56:55 2005 -0800 @@ -5,20 +5,22 @@ # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. -from demandload import * -demandload(globals(), "os re sys signal") +from demandload import demandload +demandload(globals(), "os re sys signal shutil") demandload(globals(), "fancyopts ui hg util") demandload(globals(), "fnmatch hgweb mdiff random signal time traceback") demandload(globals(), "errno socket version struct") -class UnknownCommand(Exception): pass +class UnknownCommand(Exception): + """Exception raised if command is not in the command table.""" def filterfiles(filters, files): - l = [ x for x in files if x in filters ] + l = [x for x in files if x in filters] for t in filters: - if t and t[-1] != "/": t += "/" - l += [ x for x in files if x.startswith(t) ] + if t and t[-1] != "/": + t += "/" + l += [x for x in files if x.startswith(t)] return l def relfilter(repo, files): @@ -30,21 +32,25 @@ def relpath(repo, args): cwd = repo.getcwd() if cwd: - return [ util.pconvert(os.path.normpath(os.path.join(cwd, x))) for x in args ] + return [util.pconvert(os.path.normpath(os.path.join(cwd, x))) + for x in args] return args revrangesep = ':' -def revrange(ui, repo, revs = [], revlog = None): +def revrange(ui, repo, revs, revlog=None): if revlog is None: revlog = repo.changelog revcount = revlog.count() def fix(val, defval): - if not val: return defval + if not val: + return defval try: num = int(val) - if str(num) != val: raise ValueError - if num < 0: num += revcount + if str(num) != val: + raise ValueError + if num < 0: + num += revcount if not (0 <= num < revcount): raise ValueError except ValueError: @@ -85,11 +91,14 @@ 'b': lambda: os.path.basename(repo.root), } - if node: expander.update(node_expander) + if node: + expander.update(node_expander) if node and revwidth is not None: expander['r'] = lambda: str(r.rev(node)).zfill(revwidth) - if total is not None: expander['N'] = lambda: str(total) - if seqno is not None: expander['n'] = lambda: str(seqno) + if total is not None: + expander['N'] = lambda: str(total) + if seqno is not None: + expander['n'] = lambda: str(seqno) if total is not None and seqno is not None: expander['n'] = lambda:str(seqno).zfill(len(str(total))) @@ -106,7 +115,7 @@ i += 1 return ''.join(newname) -def dodiff(fp, ui, repo, files = None, node1 = None, node2 = None): +def dodiff(fp, ui, repo, files=None, node1=None, node2=None): def date(c): return time.asctime(time.gmtime(float(c[2].split(' ')[0]))) @@ -120,13 +129,15 @@ if node2: change = repo.changelog.read(node2) mmap2 = repo.manifest.read(change[0]) - def read(f): return repo.file(f).read(mmap2[f]) date2 = date(change) + def read(f): + return repo.file(f).read(mmap2[f]) else: date2 = time.asctime() if not node1: node1 = repo.dirstate.parents()[0] - def read(f): return repo.wfile(f).read() + def read(f): + return repo.wfile(f).read() if ui.quiet: r = None @@ -222,8 +233,8 @@ "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" ) -def help(ui, cmd=None): - '''show help for a given command or all commands''' +def help_(ui, cmd=None): + """show help for a given command or all commands""" if cmd: try: i = find(cmd) @@ -231,12 +242,16 @@ if i[1]: for s, l, d, c in i[1]: - opt=' ' - if s: opt = opt + '-' + s + ' ' - if l: opt = opt + '--' + l + ' ' - if d: opt = opt + '(' + str(d) + ')' + opt = ' ' + if s: + opt = opt + '-' + s + ' ' + if l: + opt = opt + '--' + l + ' ' + if d: + opt = opt + '(' + str(d) + ')' ui.write(opt, "\n") - if c: ui.write(' %s\n' % c) + if c: + ui.write(' %s\n' % c) ui.write("\n") ui.write(i[0].__doc__, "\n") @@ -273,9 +288,9 @@ # Commands start here, listed alphabetically -def add(ui, repo, file, *files): +def add(ui, repo, file1, *files): '''add the specified files on the next commit''' - repo.add(relpath(repo, (file,) + files)) + repo.add(relpath(repo, (file1,) + files)) def addremove(ui, repo, *files): """add all new files, delete all missing files""" @@ -296,7 +311,7 @@ repo.add(u) repo.remove(d) -def annotate(u, repo, file, *files, **ops): +def annotate(u, repo, file1, *files, **ops): """show changeset information per file line""" def getnode(rev): return hg.short(repo.changelog.node(rev)) @@ -326,24 +341,26 @@ node = repo.changelog.lookup(ops['revision']) change = repo.changelog.read(node) mmap = repo.manifest.read(change[0]) - for f in relpath(repo, (file,) + files): + for f in relpath(repo, (file1,) + files): lines = repo.file(f).annotate(mmap[f]) pieces = [] for o, f in opmap: if ops[o]: - l = [ f(n) for n,t in lines ] + l = [f(n) for n, dummy in lines] m = max(map(len, l)) - pieces.append([ "%*s" % (m, x) for x in l]) + pieces.append(["%*s" % (m, x) for x in l]) - for p,l in zip(zip(*pieces), lines): + for p, l in zip(zip(*pieces), lines): u.write(" ".join(p) + ": " + l[1]) -def cat(ui, repo, file, rev = [], **opts): +def cat(ui, repo, file1, rev=None, **opts): """output the latest or given revision of a file""" - r = repo.file(relpath(repo, [file])[0]) - n = r.tip() - if rev: n = r.lookup(rev) + r = repo.file(relpath(repo, [file1])[0]) + if rev: + n = r.lookup(rev) + else: + n = r.tip() if opts['output'] and opts['output'] != '-': try: outname = make_filename(repo, r, opts['output'], node=n) @@ -356,7 +373,7 @@ fp = sys.stdout fp.write(r.read(n)) -def clone(ui, source, dest = None, **opts): +def clone(ui, source, dest=None, **opts): """make a copy of an existing repository""" if dest is None: dest = os.path.basename(os.path.normpath(source)) @@ -365,33 +382,34 @@ ui.warn("abort: destination '%s' already exists\n" % dest) return 1 - class dircleanup: - def __init__(self, dir): - import shutil + class Dircleanup: + def __init__(self, dir_): self.rmtree = shutil.rmtree - self.dir = dir - os.mkdir(dir) + self.dir_ = dir_ + os.mkdir(dir_) def close(self): - self.dir = None + self.dir_ = None def __del__(self): - if self.dir: - self.rmtree(self.dir, True) + if self.dir_: + self.rmtree(self.dir_, True) - d = dircleanup(dest) - link = 0 + d = Dircleanup(dest) abspath = source source = ui.expandpath(source) other = hg.repository(ui, source) if other.dev() != -1: abspath = os.path.abspath(source) - - if other.dev() != -1 and os.stat(dest).st_dev == other.dev(): - ui.note("cloning by hardlink\n") - util.system("cp -al '%s'/.hg '%s'/.hg" % (source, dest)) + copyfile = (os.stat(dest).st_dev == other.dev() + and getattr(os, 'link', None) or shutil.copy2) + if copyfile is not shutil.copy2: + ui.note("cloning by hardlink\n") + util.copytree(os.path.join(source, ".hg"), os.path.join(dest, ".hg"), + copyfile) try: - os.remove(os.path.join(dest, ".hg", "dirstate")) - except: pass + os.unlink(os.path.join(dest, ".hg", "dirstate")) + except IOError: + pass repo = hg.repository(ui, dest) @@ -411,9 +429,12 @@ def commit(ui, repo, *files, **opts): """commit the specified files or all outstanding changes""" text = opts['text'] - if not text and opts['logfile']: - try: text = open(opts['logfile']).read() - except IOError: pass + logfile = opts['logfile'] + if not text and logfile: + try: + text = open(logfile).read() + except IOError, why: + ui.warn("Can't read commit text %s: %s\n" % (logfile, why)) if opts['addremove']: addremove(ui, repo, *files) @@ -462,12 +483,12 @@ dc = repo.dirstate.map keys = dc.keys() keys.sort() - for file in keys: - ui.write("%c %s\n" % (dc[file][0], file)) + for file_ in keys: + ui.write("%c %s\n" % (dc[file_][0], file_)) -def debugindex(ui, file): +def debugindex(ui, file_): """dump the contents of an index file""" - r = hg.revlog(hg.opener(""), file, "") + r = hg.revlog(hg.opener(""), file_, "") ui.write(" rev offset length base linkrev" + " p1 p2 nodeid\n") for i in range(r.count()): @@ -476,9 +497,9 @@ i, e[0], e[1], e[2], e[3], hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))) -def debugindexdot(ui, file): +def debugindexdot(ui, file_): """dump an index DAG as a .dot file""" - r = hg.revlog(hg.opener(""), file, "") + r = hg.revlog(hg.opener(""), file_, "") ui.write("digraph G {\n") for i in range(r.count()): e = r.index[i] @@ -546,9 +567,9 @@ seqno += 1 doexport(ui, repo, cset, seqno, total, revwidth, opts) -def forget(ui, repo, file, *files): +def forget(ui, repo, file1, *files): """don't add the specified files on the next commit""" - repo.forget(relpath(repo, (file,) + files)) + repo.forget(relpath(repo, (file1,) + files)) def heads(ui, repo): """show current repository heads""" @@ -581,7 +602,7 @@ try: import psyco psyco.full() - except: + except ImportError: pass patches = (patch1,) + patches @@ -593,27 +614,32 @@ ui.status("applying %s\n" % patch) pf = os.path.join(d, patch) - text = "" - for l in file(pf): - if l.startswith("--- ") or l.startswith("diff -r"): break - text += l - - # parse values that exist when importing the result of an hg export - hgpatch = user = snippet = None - ui.debug('text:\n') - for t in text.splitlines(): - ui.debug(t,'\n') - if t == '# HG changeset patch' or hgpatch == True: + text = [] + user = None + hgpatch = False + for line in file(pf): + line = line.rstrip() + if line.startswith("--- ") or line.startswith("diff -r"): + break + elif hgpatch: + # parse values when importing the result of an hg export + if line.startswith("# User "): + user = line[7:] + ui.debug('User: %s\n' % user) + elif not line.startswith("# ") and line: + text.append(line) + hgpatch = False + elif line == '# HG changeset patch': hgpatch = True - if t.startswith("# User "): - user = t[7:] - ui.debug('User: %s\n' % user) - if not t.startswith("# ") and t.strip() and not snippet: snippet = t - if snippet: text = snippet + '\n' + text - ui.debug('text:\n%s\n' % text) + else: + text.append(line) # make sure text isn't empty - if not text: text = "imported patch %s\n" % patch + if not text: + text = "imported patch %s\n" % patch + else: + text = "%s\n" % '\n'.join(text) + ui.debug('text:\n%s\n' % text) f = os.popen("patch -p%d < %s" % (strip, pf)) files = [] @@ -639,7 +665,7 @@ if source: ui.warn("no longer supported: use \"hg clone\" instead\n") sys.exit(1) - repo = hg.repository(ui, ".", create=1) + hg.repository(ui, ".", create=1) def locate(ui, repo, *pats, **opts): """locate files matching specific patterns""" @@ -647,24 +673,24 @@ ui.warn("error: patterns may not contain '%s'\n" % os.sep) ui.warn("use '-i ' instead\n") sys.exit(1) - def compile(pats, head = '^', tail = os.sep, on_empty = True): + def compile(pats, head='^', tail=os.sep, on_empty=True): if not pats: class c: - def match(self, x): return on_empty + def match(self, x): + return on_empty return c() - regexp = r'%s(?:%s)%s' % ( - head, - '|'.join([fnmatch.translate(os.path.normpath(os.path.normcase(p)))[:-1] - for p in pats]), - tail) + fnpats = [fnmatch.translate(os.path.normpath(os.path.normcase(p)))[:-1] + for p in pats] + regexp = r'%s(?:%s)%s' % (head, '|'.join(fnpats), tail) return re.compile(regexp) - exclude = compile(opts['exclude'], on_empty = False) + exclude = compile(opts['exclude'], on_empty=False) include = compile(opts['include']) - pat = compile([os.path.normcase(p) for p in pats], head = '', tail = '$') - end = '\n' - if opts['print0']: end = '\0' - if opts['rev']: node = repo.manifest.lookup(opts['rev']) - else: node = repo.manifest.tip() + pat = compile(pats, head='', tail='$') + end = opts['print0'] and '\0' or '\n' + if opts['rev']: + node = repo.manifest.lookup(opts['rev']) + else: + node = repo.manifest.tip() manifest = repo.manifest.read(node) cwd = repo.getcwd() cwd_plus = cwd and (cwd + os.sep) @@ -673,12 +699,16 @@ f = os.path.normcase(f) if exclude.match(f) or not(include.match(f) and f.startswith(cwd_plus) and - pat.match(os.path.basename(f))): continue - if opts['fullpath']: f = os.path.join(repo.root, f) - elif cwd: f = f[len(cwd_plus):] + pat.match(os.path.basename(f))): + continue + if opts['fullpath']: + f = os.path.join(repo.root, f) + elif cwd: + f = f[len(cwd_plus):] found.append(f) found.sort() - for f in found: ui.write(f, end) + for f in found: + ui.write(f, end) def log(ui, repo, f=None, **opts): """show the revision history of the repository or a single file""" @@ -712,21 +742,20 @@ changenode = repo.changelog.node(i) prev, other = repo.changelog.parents(changenode) dodiff(sys.stdout, ui, repo, files, prev, changenode) - ui.write("\n") - ui.write("\n") + ui.write("\n\n") -def manifest(ui, repo, rev = []): +def manifest(ui, repo, rev=None): """output the latest or given revision of the project manifest""" - n = repo.manifest.tip() if rev: try: # assume all revision numbers are for changesets n = repo.lookup(rev) change = repo.changelog.read(n) n = change[0] - except: + except hg.RepoError: n = repo.manifest.lookup(rev) - + else: + n = repo.manifest.tip() m = repo.manifest.read(n) mf = repo.manifest.readflags(n) files = m.keys() @@ -735,7 +764,7 @@ for f in files: ui.write("%40s %3s %s\n" % (hg.hex(m[f]), mf[f] and "755" or "644", f)) -def parents(ui, repo, node = None): +def parents(ui, repo, node=None): '''show the parents of the current working dir''' if node: p = repo.changelog.parents(repo.lookup(hg.bin(node))) @@ -775,8 +804,10 @@ text = rc['text'] if not text and rc['logfile']: - try: text = open(rc['logfile']).read() - except IOError: pass + try: + text = open(rc['logfile']).read() + except IOError: + pass if not text and not rc['logfile']: ui.warn("abort: missing commit text\n") return 1 @@ -793,9 +824,9 @@ """roll back an interrupted transaction""" repo.recover() -def remove(ui, repo, file, *files): +def remove(ui, repo, file1, *files): """remove the specified files on the next commit""" - repo.remove(relpath(repo, (file,) + files)) + repo.remove(relpath(repo, (file1,) + files)) def revert(ui, repo, *names, **opts): """revert modified files or dirs back to their unmodified states""" @@ -819,14 +850,18 @@ def choose(name): def body(name): for r in relnames: - if not name.startswith(r): continue + if not name.startswith(r): + continue rest = name[len(r):] - if not rest: return r, True + if not rest: + return r, True depth = rest.count(os.sep) if not r: - if depth == 0 or not opts['nonrecursive']: return r, True + if depth == 0 or not opts['nonrecursive']: + return r, True elif rest[0] == os.sep: - if depth == 1 or not opts['nonrecursive']: return r, True + if depth == 1 or not opts['nonrecursive']: + return r, True return None, False relname, ret = body(name) if ret: @@ -875,7 +910,8 @@ lock = repo.lock() respond("") if cmd == "unlock": - if lock: lock.release() + if lock: + lock.release() lock = None respond("") elif cmd == "branches": @@ -887,7 +923,7 @@ respond("".join(r)) elif cmd == "between": arg, pairs = getarg() - pairs = [ map(hg.bin, p.split("-")) for p in pairs.split(" ") ] + pairs = [map(hg.bin, p.split("-")) for p in pairs.split(" ")] r = [] for b in repo.between(pairs): r.append(" ".join(map(hg.hex, b)) + "\n") @@ -900,7 +936,8 @@ cg = repo.changegroup(nodes) while 1: d = cg.read(4096) - if not d: break + if not d: + break fout.write(d) fout.flush() @@ -915,8 +952,10 @@ respond("") def openlog(opt, default): - if opts[opt] and opts[opt] != '-': return open(opts[opt], 'w') - else: return default + if opts[opt] and opts[opt] != '-': + return open(opts[opt], 'w') + else: + return default httpd = hgweb.create_server(repo.root, opts["name"], opts["templates"], opts["address"], opts["port"], @@ -929,7 +968,8 @@ else: try: addr = socket.gethostbyaddr(addr)[0] - except: pass + except socket.error: + pass if port != 80: ui.status('listening at http://%s:%d/\n' % (addr, port)) else: @@ -947,12 +987,16 @@ (c, a, d, u) = repo.changes(None, None) (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u)) - for f in c: ui.write("C ", f, "\n") - for f in a: ui.write("A ", f, "\n") - for f in d: ui.write("R ", f, "\n") - for f in u: ui.write("? ", f, "\n") + for f in c: + ui.write("C ", f, "\n") + for f in a: + ui.write("A ", f, "\n") + for f in d: + ui.write("R ", f, "\n") + for f in u: + ui.write("? ", f, "\n") -def tag(ui, repo, name, rev = None, **opts): +def tag(ui, repo, name, rev=None, **opts): """add a tag for the current tip or a given revision""" if name == "tip": @@ -978,10 +1022,10 @@ ui.status("(please commit .hgtags manually)\n") return -1 - add = 0 - if not os.path.exists(repo.wjoin(".hgtags")): add = 1 + add = not os.path.exists(repo.wjoin(".hgtags")) repo.wfile(".hgtags", "ab").write("%s %s\n" % (r, name)) - if add: repo.add([".hgtags"]) + if add: + repo.add([".hgtags"]) if not opts['text']: opts['text'] = "Added tag %s for changeset %s" % (name, r) @@ -1045,94 +1089,115 @@ table = { "^add": (add, [], "hg add [files]"), "addremove": (addremove, [], "hg addremove [files]"), - "^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]'), - "cat": (cat, [('o', 'output', "", 'output to file')], 'hg cat [-o outfile] [rev]'), - "^clone": (clone, [('U', 'noupdate', None, 'skip update after cloning')], - 'hg clone [options] [dest]'), - "^commit|ci": (commit, - [('t', 'text', "", 'commit text'), - ('A', 'addremove', None, 'run add/remove during commit'), - ('l', 'logfile', "", 'commit text file'), - ('d', 'date', "", 'date code'), - ('u', 'user', "", 'user')], - 'hg commit [files]'), + "^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]'), + "cat": + (cat, + [('o', 'output', "", 'output to file')], + 'hg cat [-o outfile] [rev]'), + "^clone": + (clone, + [('U', 'noupdate', None, 'skip update after cloning')], + 'hg clone [options] [dest]'), + "^commit|ci": + (commit, + [('t', 'text', "", 'commit text'), + ('A', 'addremove', None, 'run add/remove during commit'), + ('l', 'logfile', "", 'commit text file'), + ('d', 'date', "", 'date code'), + ('u', 'user', "", 'user')], + 'hg commit [files]'), "copy": (copy, [], 'hg copy '), "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'), "debugstate": (debugstate, [], 'debugstate'), "debugindex": (debugindex, [], 'debugindex '), "debugindexdot": (debugindexdot, [], 'debugindexdot '), - "^diff": (diff, [('r', 'rev', [], 'revision')], - 'hg diff [-r A] [-r B] [files]'), - "^export": (export, [('o', 'output', "", 'output to file')], - "hg export [-o file] ..."), + "^diff": + (diff, + [('r', 'rev', [], 'revision')], + 'hg diff [-r A] [-r B] [files]'), + "^export": + (export, + [('o', 'output', "", 'output to file')], + "hg export [-o file] ..."), "forget": (forget, [], "hg forget [files]"), "heads": (heads, [], 'hg heads'), - "help": (help, [], 'hg help [command]'), + "help": (help_, [], 'hg help [command]'), "identify|id": (identify, [], 'hg identify'), - "import|patch": (import_, - [('p', 'strip', 1, 'path strip'), - ('b', 'base', "", 'base path')], - "hg import [options] "), + "import|patch": + (import_, + [('p', 'strip', 1, 'path strip'), + ('b', 'base', "", 'base path')], + "hg import [options] "), "^init": (init, [], 'hg init'), - "locate": (locate, - [('0', 'print0', None, 'end records with NUL'), - ('f', 'fullpath', None, 'print complete paths'), - ('i', 'include', [], 'include path in search'), - ('r', 'rev', '', 'revision'), - ('x', 'exclude', [], 'exclude path from search')], - 'hg locate [options] [files]'), - "^log|history": (log, - [('r', 'rev', [], 'revision'), - ('p', 'patch', None, 'show patch')], - 'hg log [-r A] [-r B] [-p] [file]'), + "locate": + (locate, + [('0', 'print0', None, 'end records with NUL'), + ('f', 'fullpath', None, 'print complete paths'), + ('i', 'include', [], 'include path in search'), + ('r', 'rev', '', 'revision'), + ('x', 'exclude', [], 'exclude path from search')], + 'hg locate [options] [files]'), + "^log|history": + (log, + [('r', 'rev', [], 'revision'), + ('p', 'patch', None, 'show patch')], + 'hg log [-r A] [-r B] [-p] [file]'), "manifest": (manifest, [], 'hg manifest [rev]'), "parents": (parents, [], 'hg parents [node]'), - "^pull": (pull, - [('u', 'update', None, 'update working directory')], - 'hg pull [options] [source]'), + "^pull": + (pull, + [('u', 'update', None, 'update working directory')], + 'hg pull [options] [source]'), "^push": (push, [], 'hg push '), - "rawcommit": (rawcommit, - [('p', 'parent', [], 'parent'), - ('d', 'date', "", 'date code'), - ('u', 'user', "", 'user'), - ('F', 'files', "", 'file list'), - ('t', 'text', "", 'commit text'), - ('l', 'logfile', "", 'commit text file')], - 'hg rawcommit [options] [files]'), + "rawcommit": + (rawcommit, + [('p', 'parent', [], 'parent'), + ('d', 'date', "", 'date code'), + ('u', 'user', "", 'user'), + ('F', 'files', "", 'file list'), + ('t', 'text', "", 'commit text'), + ('l', 'logfile', "", 'commit text file')], + 'hg rawcommit [options] [files]'), "recover": (recover, [], "hg recover"), "^remove|rm": (remove, [], "hg remove [files]"), - "^revert": (revert, - [("n", "nonrecursive", None, "don't recurse into subdirs"), - ("r", "rev", "", "revision")], - "hg revert [files|dirs]"), + "^revert": + (revert, + [("n", "nonrecursive", None, "don't recurse into subdirs"), + ("r", "rev", "", "revision")], + "hg revert [files|dirs]"), "root": (root, [], "hg root"), - "^serve": (serve, [('A', 'accesslog', '', 'access log file'), - ('E', 'errorlog', '', 'error log file'), - ('p', 'port', 8000, 'listen port'), - ('a', 'address', '', 'interface address'), - ('n', 'name', os.getcwd(), 'repository name'), - ('', 'stdio', None, 'for remote clients'), - ('t', 'templates', "", 'template map')], - "hg serve [options]"), + "^serve": + (serve, + [('A', 'accesslog', '', 'access log file'), + ('E', 'errorlog', '', 'error log file'), + ('p', 'port', 8000, 'listen port'), + ('a', 'address', '', 'interface address'), + ('n', 'name', os.getcwd(), 'repository name'), + ('', 'stdio', None, 'for remote clients'), + ('t', 'templates', "", 'template map')], + "hg serve [options]"), "^status": (status, [], 'hg status'), - "tag": (tag, [('l', 'local', None, 'make the tag local'), - ('t', 'text', "", 'commit text'), - ('d', 'date', "", 'date code'), - ('u', 'user', "", 'user')], - 'hg tag [options] [rev]'), + "tag": + (tag, + [('l', 'local', None, 'make the tag local'), + ('t', 'text', "", 'commit text'), + ('d', 'date', "", 'date code'), + ('u', 'user', "", 'user')], + 'hg tag [options] [rev]'), "tags": (tags, [], 'hg tags'), "tip": (tip, [], 'hg tip'), "undo": (undo, [], 'hg undo'), "^update|up|checkout|co": - (update, - [('m', 'merge', None, 'allow merging of conflicts'), - ('C', 'clean', None, 'overwrite locally modified files')], - 'hg update [options] [node]'), + (update, + [('m', 'merge', None, 'allow merging of conflicts'), + ('C', 'clean', None, 'overwrite locally modified files')], + 'hg update [options] [node]'), "verify": (verify, [], 'hg verify'), "version": (show_version, [], 'hg version'), } @@ -1145,7 +1210,7 @@ ('', 'traceback', None, 'print traceback on exception'), ('y', 'noninteractive', None, 'run non-interactively'), ('', 'version', None, 'output version information and exit'), - ] + ] norepo = "clone init version help debugindex debugindexdot" @@ -1156,7 +1221,8 @@ raise UnknownCommand(cmd) -class SignalInterrupt(Exception): pass +class SignalInterrupt(Exception): + """Exception raised on SIGTERM and SIGHUP.""" def catchterm(*args): raise SignalInterrupt @@ -1164,7 +1230,8 @@ def run(): sys.exit(dispatch(sys.argv[1:])) -class ParseError(Exception): pass +class ParseError(Exception): + """Exception raised on errors in parsing the command line.""" def parse(args): options = {} @@ -1178,7 +1245,7 @@ if options["version"]: return ("version", show_version, [], options, cmdoptions) elif not args: - return ("help", help, [], options, cmdoptions) + return ("help", help_, [], options, cmdoptions) else: cmd, args = args[0], args[1:] @@ -1186,7 +1253,6 @@ # combine global options into local c = list(i[1]) - l = len(c) for o in globalopts: c.append((o[0], o[1], options[o[1]], o[3])) @@ -1205,8 +1271,10 @@ def dispatch(args): signal.signal(signal.SIGTERM, catchterm) - try: signal.signal(signal.SIGHUP, catchterm) - except: pass + try: + signal.signal(signal.SIGHUP, catchterm) + except AttributeError: + pass try: cmd, func, args, options, cmdoptions = parse(args) @@ -1214,19 +1282,19 @@ u = ui.ui() if inst.args[0]: u.warn("hg %s: %s\n" % (inst.args[0], inst.args[1])) - help(u, inst.args[0]) + help_(u, inst.args[0]) else: u.warn("hg: %s\n" % inst.args[1]) - help(u) + help_(u) sys.exit(-1) except UnknownCommand, inst: u = ui.ui() u.warn("hg: unknown command '%s'\n" % inst.args[0]) - help(u) + help_(u) sys.exit(1) u = ui.ui(options["verbose"], options["debug"], options["quiet"], - not options["noninteractive"]) + not options["noninteractive"]) try: try: @@ -1282,6 +1350,6 @@ raise u.debug(inst, "\n") u.warn("%s: invalid arguments\n" % cmd) - help(u, cmd) + help_(u, cmd) sys.exit(-1) diff -r 51eb248d3348 -r 574869103985 mercurial/hg.py --- a/mercurial/hg.py Thu Jul 14 22:37:46 2005 -0800 +++ b/mercurial/hg.py Thu Jul 14 22:56:55 2005 -0800 @@ -1498,8 +1498,8 @@ self.ui.debug("file %s: other %s ancestor %s\n" % (fn, short(other), short(base))) - cmd = os.environ.get("HGMERGE", "hgmerge") or \ - self.ui.config("ui", "merge") + cmd = (os.environ.get("HGMERGE") or self.ui.config("ui", "merge") + or "hgmerge") r = os.system("%s %s %s %s" % (cmd, a, b, c)) if r: self.ui.warn("merging %s failed!\n" % fn) diff -r 51eb248d3348 -r 574869103985 mercurial/lock.py --- a/mercurial/lock.py Thu Jul 14 22:37:46 2005 -0800 +++ b/mercurial/lock.py Thu Jul 14 22:56:55 2005 -0800 @@ -37,7 +37,7 @@ try: util.makelock(str(pid), self.f) self.held = 1 - except: + except (OSError, IOError): raise LockHeld(util.readlock(self.f)) def release(self): diff -r 51eb248d3348 -r 574869103985 mercurial/util.py --- a/mercurial/util.py Thu Jul 14 22:37:46 2005 -0800 +++ b/mercurial/util.py Thu Jul 14 22:56:55 2005 -0800 @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. -import os +import os, errno def unique(g): seen = {} @@ -46,6 +46,29 @@ os.unlink(dst) os.rename(src, dst) +def copytree(src, dst, copyfile): + """Copy a directory tree, files are copied using 'copyfile'.""" + names = os.listdir(src) + os.mkdir(dst) + + for name in names: + srcname = os.path.join(src, name) + dstname = os.path.join(dst, name) + if os.path.isdir(srcname): + copytree(srcname, dstname, copyfile) + elif os.path.isfile(srcname): + copyfile(srcname, dstname) + else: + raise IOError("Not a regular file: %r" % srcname) + +def _makelock_file(info, pathname): + ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL) + os.write(ld, info) + os.close(ld) + +def _readlock_file(pathname): + return file(pathname).read() + # Platfor specific varients if os.name == 'nt': nulldev = 'NUL:' @@ -59,13 +82,8 @@ def pconvert(path): return path.replace("\\", "/") - def makelock(info, pathname): - ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL) - os.write(ld, info) - os.close(ld) - - def readlock(pathname): - return file(pathname).read() + makelock = _makelock_file + readlock = _readlock_file else: nulldev = '/dev/null' @@ -90,7 +108,19 @@ return path def makelock(info, pathname): - os.symlink(info, pathname) + try: + os.symlink(info, pathname) + except OSError, why: + if why.errno == errno.EEXIST: + raise + else: + _makelock_file(info, pathname) def readlock(pathname): - return os.readlink(pathname) + try: + return os.readlink(pathname) + except OSError, why: + if why.errno == errno.EINVAL: + return _readlock_file(pathname) + else: + raise diff -r 51eb248d3348 -r 574869103985 tests/test-bad-pull --- a/tests/test-bad-pull Thu Jul 14 22:37:46 2005 -0800 +++ b/tests/test-bad-pull Thu Jul 14 22:56:55 2005 -0800 @@ -17,8 +17,9 @@ run() EOF +set +x # backgrounding sometimes disturbs the order of command tracing python dumb.py 2>/dev/null & -sleep 2 +set -x hg clone http://localhost:20059/foo copy2 echo $? diff -r 51eb248d3348 -r 574869103985 tests/test-bad-pull.out --- a/tests/test-bad-pull.out Thu Jul 14 22:37:46 2005 -0800 +++ b/tests/test-bad-pull.out Thu Jul 14 22:56:55 2005 -0800 @@ -6,8 +6,7 @@ + ls copy ls: copy: No such file or directory + cat -+ python dumb.py -+ sleep 2 ++ set +x + hg clone http://localhost:20059/foo copy2 requesting all changes abort: HTTP Error 404: File not found diff -r 51eb248d3348 -r 574869103985 tests/test-basic.out --- a/tests/test-basic.out Thu Jul 14 22:37:46 2005 -0800 +++ b/tests/test-basic.out Thu Jul 14 22:56:55 2005 -0800 @@ -11,7 +11,6 @@ date: Thu Jan 1 00:00:00 1970 summary: test - + hg manifest b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 644 a + hg cat a diff -r 51eb248d3348 -r 574869103985 tests/test-copy.out --- a/tests/test-copy.out Thu Jul 14 22:37:46 2005 -0800 +++ b/tests/test-copy.out Thu Jul 14 22:56:55 2005 -0800 @@ -19,21 +19,17 @@ date: Thu Jan 1 00:00:00 1970 summary: 2 - changeset: 0:c19d34741b0a4ced8e4ba74bb834597d5193851e user: test date: Thu Jan 1 00:00:00 1970 summary: 1 - + hg log a -revision: 0:b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 changeset: 0:c19d34741b0a4ced8e4ba74bb834597d5193851e user: test date: Thu Jan 1 00:00:00 1970 summary: 1 - + hexdump -C .hg/data/b.d 00000000 75 01 0a 63 6f 70 79 72 65 76 3a 20 62 37 38 39 |u..copyrev: b789| 00000010 66 64 64 39 36 64 63 32 66 33 62 64 32 32 39 63 |fdd96dc2f3bd229c| diff -r 51eb248d3348 -r 574869103985 tests/test-flags.out --- a/tests/test-flags.out Thu Jul 14 22:37:46 2005 -0800 +++ b/tests/test-flags.out Thu Jul 14 22:56:55 2005 -0800 @@ -52,19 +52,16 @@ date: Thu Jan 1 00:00:00 1970 summary: chmod +x a - changeset: 1:c6ecefc45368ed556d965f1c1086c6561a8b2ac5 user: test date: Thu Jan 1 00:00:00 1970 summary: a updated - changeset: 0:22a449e20da501ca558394c083ca470e9c81b9f7 user: test date: Thu Jan 1 00:00:00 1970 summary: added a b - + hg -v co -m resolving manifests merging a diff -r 51eb248d3348 -r 574869103985 tests/test-tag.out --- a/tests/test-tag.out Thu Jul 14 22:37:46 2005 -0800 +++ b/tests/test-tag.out Thu Jul 14 22:56:55 2005 -0800 @@ -9,7 +9,6 @@ date: Thu Jan 1 00:00:00 1970 summary: test - + hg tag -u test -d '0 0' bleah + hg history changeset: 1:863197ef03781c4fc00276d83eb66c4cb9cd91df @@ -18,14 +17,12 @@ date: Thu Jan 1 00:00:00 1970 summary: Added tag bleah for changeset acb14030fe0a21b60322c440ad2d20cf7685a376 - changeset: 0:acb14030fe0a21b60322c440ad2d20cf7685a376 tag: bleah user: test date: Thu Jan 1 00:00:00 1970 summary: test - + echo foo + hg tag -u test -d '0 0' bleah2 abort: working copy of .hgtags is changed! diff -r 51eb248d3348 -r 574869103985 tests/test-up-local-change.out --- a/tests/test-up-local-change.out Thu Jul 14 22:37:46 2005 -0800 +++ b/tests/test-up-local-change.out Thu Jul 14 22:56:55 2005 -0800 @@ -57,7 +57,6 @@ 2 - changeset: 0:c19d34741b0a4ced8e4ba74bb834597d5193851e manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 user: test @@ -67,7 +66,6 @@ 1 - + hg diff + sed 's/\(\(---\|+++\).*\)\t.*/\1/' diff -r 1e71731e6fbb a