changeset 1828:ca82f20b0c19

merge with crew.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Fri, 03 Mar 2006 08:44:37 -0800
parents 26dd4ae77b7b (current diff) a9343f9d7365 (diff)
children bf118f39afd7
files
diffstat 7 files changed, 77 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- 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]}'
--- 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):
--- 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):
--- 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"""
--- 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
--- 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
--- 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: <urlopen error (111, 'Connection refused')>
+abort: Connection refused
 255
 ls: copy: No such file or directory
 changeset:   0:61c9426e69fe