# HG changeset patch # User Vadim Gelfer # Date 1141404277 28800 # Node ID ca82f20b0c195ef6a1f169de131ef5143b3c0756 # Parent 26dd4ae77b7b22cd3bddee5c5afb431a01a22827# Parent a9343f9d7365ebdf114501ce09acc76fd8294751 merge with crew. diff -r 26dd4ae77b7b -r ca82f20b0c19 contrib/bash_completion --- a/contrib/bash_completion Thu Mar 02 11:38:39 2006 -0800 +++ b/contrib/bash_completion Fri Mar 03 08:44:37 2006 -0800 @@ -4,19 +4,22 @@ { "$hg" --debug help 2>/dev/null | \ awk -F', ' '/^list of commands:/ {commands=1} - commands && /^ [^ ]/ { - sub(/ /, "") - sub(/:.*/, "") - command = $1 + commands==1 && /^ [^ ]/ { + line = substr($0, 2) + colon = index(line, ":") + if (colon > 0) + line = substr(line, 1, colon-1) + n = split(line, aliases) + command = aliases[1] if (index(command, "debug") == 1) { - for (i=1; i<=NF; i++) - debug[j++] = $i + for (i=1; i<=n; i++) + debug[j++] = aliases[i] next } print command - for (i=2; i<=NF; i++) - if (index(command, $i) != 1) - print $i + for (i=2; i<=n; i++) + if (index(command, aliases[i]) != 1) + print aliases[i] } /^global options:/ {exit 0} END {for (i in debug) print debug[i]}' diff -r 26dd4ae77b7b -r ca82f20b0c19 mercurial/commands.py --- a/mercurial/commands.py Thu Mar 02 11:38:39 2006 -0800 +++ b/mercurial/commands.py Fri Mar 03 08:44:37 2006 -0800 @@ -825,7 +825,8 @@ except ValueError, inst: raise util.Abort(str(inst)) -def docopy(ui, repo, pats, opts): +def docopy(ui, repo, pats, opts, wlock): + # called with the repo lock held cwd = repo.getcwd() errors = 0 copied = [] @@ -871,8 +872,16 @@ if not os.path.isdir(targetdir): os.makedirs(targetdir) try: - shutil.copyfile(relsrc, reltarget) - shutil.copymode(relsrc, reltarget) + restore = repo.dirstate.state(abstarget) == 'r' + if restore: + repo.undelete([abstarget], wlock) + try: + shutil.copyfile(relsrc, reltarget) + shutil.copymode(relsrc, reltarget) + restore = False + finally: + if restore: + repo.remove([abstarget], wlock) except shutil.Error, inst: raise util.Abort(str(inst)) except IOError, inst: @@ -886,7 +895,8 @@ if ui.verbose or not exact: ui.status(_('copying %s to %s\n') % (relsrc, reltarget)) targets[abstarget] = abssrc - repo.copy(origsrc, abstarget) + if abstarget != origsrc: + repo.copy(origsrc, abstarget, wlock) copied.append((abssrc, relsrc, exact)) def targetpathfn(pat, dest, srcs): @@ -994,7 +1004,12 @@ should properly record copied files, this information is not yet fully used by merge, nor fully reported by log. """ - errs, copied = docopy(ui, repo, pats, opts) + try: + wlock = repo.wlock(0) + errs, copied = docopy(ui, repo, pats, opts, wlock) + except lock.LockHeld, inst: + ui.warn(_("repository lock held by %s\n") % inst.args[0]) + errs = 1 return errs def debugancestor(ui, index, rev1, rev2): @@ -1953,13 +1968,18 @@ should properly record rename files, this information is not yet fully used by merge, nor fully reported by log. """ - errs, copied = docopy(ui, repo, pats, opts) - names = [] - for abs, rel, exact in copied: - if ui.verbose or not exact: - ui.status(_('removing %s\n') % rel) - names.append(abs) - repo.remove(names, unlink=True) + try: + wlock = repo.wlock(0) + errs, copied = docopy(ui, repo, pats, opts, wlock) + names = [] + for abs, rel, exact in copied: + if ui.verbose or not exact: + ui.status(_('removing %s\n') % rel) + names.append(abs) + repo.remove(names, True, wlock) + except lock.LockHeld, inst: + ui.warn(_("repository lock held by %s\n") % inst.args[0]) + errs = 1 return errs def revert(ui, repo, *pats, **opts): diff -r 26dd4ae77b7b -r ca82f20b0c19 mercurial/hgweb.py --- a/mercurial/hgweb.py Thu Mar 02 11:38:39 2006 -0800 +++ b/mercurial/hgweb.py Fri Mar 03 08:44:37 2006 -0800 @@ -73,31 +73,28 @@ return os.stat(hg_path).st_mtime def staticfile(directory, fname): - fname = os.path.realpath(os.path.join(directory, fname)) + """return a file inside directory with guessed content-type header + + fname always uses '/' as directory separator and isn't allowed to + contain unusual path components. + Content-type is guessed using the mimetypes module. + Return an empty string if fname is illegal or file not found. + """ + parts = fname.split('/') + path = directory + for part in parts: + if (part in ('', os.curdir, os.pardir) or + os.sep in part or os.altsep is not None and os.altsep in part): + return "" + path = os.path.join(path, part) try: - # the static dir should be a substring in the real - # file path, if it is not, we have something strange - # going on => security breach attempt? - # - # This will either: - # 1) find the `static' path at index 0 = success - # 2) find the `static' path at other index = error - # 3) not find the `static' path = ValueError generated - if fname.index(directory) != 0: - # generate ValueError manually - raise ValueError() - - os.stat(fname) - - ct = mimetypes.guess_type(fname)[0] or "text/plain" - return "Content-type: %s\n\n%s" % (ct, file(fname).read()) - except ValueError: - # security breach attempt + os.stat(path) + ct = mimetypes.guess_type(path)[0] or "text/plain" + return "Content-type: %s\n\n%s" % (ct, file(path).read()) + except (TypeError, OSError): + # illegal fname or unreadable file return "" - except OSError, e: - if e.errno == errno.ENOENT: - return "" class hgrequest(object): def __init__(self, inp=None, out=None, env=None): diff -r 26dd4ae77b7b -r ca82f20b0c19 mercurial/statichttprepo.py --- a/mercurial/statichttprepo.py Thu Mar 02 11:38:39 2006 -0800 +++ b/mercurial/statichttprepo.py Fri Mar 03 08:44:37 2006 -0800 @@ -15,8 +15,10 @@ def read(self, size=None): try: return httprangereader.httprangereader.read(self, size) + except urllib2.HTTPError, inst: + raise IOError(None, inst) except urllib2.URLError, inst: - raise IOError(None, str(inst)) + raise IOError(None, inst.reason[1]) def opener(base): """return a function that opens files over http""" diff -r 26dd4ae77b7b -r ca82f20b0c19 tests/test-rename --- a/tests/test-rename Thu Mar 02 11:38:39 2006 -0800 +++ b/tests/test-rename Fri Mar 03 08:44:37 2006 -0800 @@ -171,3 +171,11 @@ hg rename --after d1/bb d1/bc hg status hg update -C + +echo "# idempotent renames (d1/b -> d1/bb followed by d1/bb -> d1/b)" +hg rename d1/b d1/bb +echo "some stuff added to d1/bb" >> d1/bb +hg rename d1/bb d1/b +hg status +hg debugstate | grep copy +hg update -C diff -r 26dd4ae77b7b -r ca82f20b0c19 tests/test-rename.out --- a/tests/test-rename.out Thu Mar 02 11:38:39 2006 -0800 +++ b/tests/test-rename.out Fri Mar 03 08:44:37 2006 -0800 @@ -252,3 +252,5 @@ # transitive rename --after A d1/bc R d1/b +# idempotent renames (d1/b -> d1/bb followed by d1/bb -> d1/b) +M d1/b diff -r 26dd4ae77b7b -r ca82f20b0c19 tests/test-static-http.out --- a/tests/test-static-http.out Thu Mar 02 11:38:39 2006 -0800 +++ b/tests/test-static-http.out Fri Mar 03 08:44:37 2006 -0800 @@ -1,4 +1,4 @@ -abort: +abort: Connection refused 255 ls: copy: No such file or directory changeset: 0:61c9426e69fe