changeset 2593:0a30407fff72

merge with crew.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Tue, 11 Jul 2006 13:47:51 -0700
parents 911b56853fdd (diff) 457846f400e8 (current diff)
children e3258cc3ed63
files
diffstat 14 files changed, 199 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/darcs2hg.py
+++ b/contrib/darcs2hg.py
@@ -4,12 +4,11 @@
 # -----------------------------------------------------------------------------
 # Project   : Basic Darcs to Mercurial conversion script
 # -----------------------------------------------------------------------------
-# Author    : Sebastien Pierre <sebastien@xprima.com>
+# Authors   : Sebastien Pierre                           <sebastien@xprima.com>
+#             TK Soh                                      <teekaysoh@gmail.com>
+# -----------------------------------------------------------------------------
 # Creation  : 24-May-2006
-# Last mod  : 26-May-2006
-# History   :
-#             26-May-2006 - Updated
-#             24-May-2006 - First implementation
+# Last mod  : 05-Jun-2006
 # -----------------------------------------------------------------------------
 
 import os, sys
@@ -21,12 +20,14 @@ DARCS_REPO = None
 HG_REPO    = None
 
 USAGE = """\
-%s DARCSREPO HGREPO
+%s DARCSREPO HGREPO [SKIP]
 
     Converts the given Darcs repository to a new Mercurial repository. The given
     HGREPO must not exist, as it will be created and filled up (this will avoid
     overwriting valuable data.
 
+    In case an error occurs within the process, you can resume the process by
+    giving the last successfuly applied change number.
 """ % (os.path.basename(sys.argv[0]))
 
 # ------------------------------------------------------------------------------
@@ -35,7 +36,7 @@ USAGE = """\
 #
 # ------------------------------------------------------------------------------
 
-def cmd(text, path=None):
+def cmd(text, path=None, silent=False):
 	"""Executes a command, in the given directory (if any), and returns the
 	command result as a string."""
 	cwd = None
@@ -43,7 +44,7 @@ def cmd(text, path=None):
 		path = os.path.abspath(path)
 		cwd  = os.getcwd()
 		os.chdir(path)
-	print text
+	if not silent: print "> ", text
 	res = os.popen(text).read()
 	if path:
 		os.chdir(cwd)
@@ -53,6 +54,14 @@ def writefile(path, data):
 	"""Writes the given data into the given file."""
 	f = file(path, "w") ; f.write(data)  ; f.close()
 
+def error( *args ):
+	sys.stderr.write("ERROR: ")
+	for a in args: sys.stderr.write(str(a))
+	sys.stderr.write("\n")
+	sys.stderr.write("You can make manual fixes if necessary and then resume by"
+	" giving the last changeset number")
+	sys.exit(-1)
+
 # ------------------------------------------------------------------------------
 #
 # Darcs interface
@@ -64,7 +73,6 @@ def darcs_changes(darcsRepo):
 	chronological list of changes as (change name, change summary)."""
 	changes    = cmd("darcs changes --reverse --xml-output", darcsRepo)
 	doc        = xml_dom.parseString(changes)
-	res        = []
 	for patch_node in doc.childNodes[0].childNodes:
 		name = filter(lambda n:n.nodeName == "name", patch_node.childNodes)
 		comm = filter(lambda n:n.nodeName == "comment", patch_node.childNodes)
@@ -73,11 +81,22 @@ def darcs_changes(darcsRepo):
 		if not comm: comm = ""
 		else: comm = comm[0].childNodes[0].data
 		author = patch_node.getAttribute("author")
-		date = patch_node.getAttribute("date")
-		yield author, date, name, comm
+		date   = patch_node.getAttribute("date")
+		chash  = os.path.splitext(patch_node.getAttribute("hash"))[0]
+		yield author, date, name, chash, comm
 
-def darcs_pull(hg_repo, darcs_repo, change):
-	cmd("darcs pull '%s' --all --patches='%s'" % (darcs_repo, change), hg_repo)
+def darcs_tip(darcs_repo):
+	changes = cmd("darcs changes",darcs_repo,silent=True)
+	changes = filter(lambda l:l.strip().startswith("* "), changes.split("\n"))
+	return len(changes)
+
+def darcs_pull(hg_repo, darcs_repo, chash):
+	old_tip = darcs_tip(darcs_repo)
+	res     = cmd("darcs pull '%s' --all --match='hash %s'" % (darcs_repo, chash), hg_repo)
+	print res
+	new_tip = darcs_tip(darcs_repo)
+	if not new_tip != old_tip + 1:
+		error("Darcs pull did not work as expected: " + res)
 
 # ------------------------------------------------------------------------------
 #
@@ -88,10 +107,24 @@ def darcs_pull(hg_repo, darcs_repo, chan
 def hg_commit( hg_repo, text, author, date ):
 	fd, tmpfile = tempfile.mkstemp(prefix="darcs2hg_")
 	writefile(tmpfile, text)
+	old_tip = hg_tip(hg_repo)
 	cmd("hg add -X _darcs", hg_repo)
 	cmd("hg remove -X _darcs --after", hg_repo)
-	cmd("hg commit -l %s -u '%s' -d '%s 0'"  % (tmpfile, author, date), hg_repo)
+	res = cmd("hg commit -l %s -u '%s' -d '%s 0'"  % (tmpfile, author, date), hg_repo)
 	os.unlink(tmpfile)
+	new_tip = hg_tip(hg_repo)
+	if not new_tip == old_tip + 1:
+		# Sometimes we may have empty commits, we simply skip them
+		if res.strip().lower().find("nothing changed") != -1:
+			pass
+		else:
+			error("Mercurial commit did not work as expected: " + res)
+
+def hg_tip( hg_repo ):
+	"""Returns the latest local revision number in the given repository."""
+	tip = cmd("hg tip", hg_repo, silent=True)
+	tip = tip.split("\n")[0].split(":")[1].strip()
+	return int(tip)
 
 # ------------------------------------------------------------------------------
 #
@@ -105,26 +138,41 @@ if __name__ == "__main__":
 	if len(args)   == 2:
 		darcs_repo = os.path.abspath(args[0])
 		hg_repo    = os.path.abspath(args[1])
+		skip       = None
+	elif len(args) == 3:
+		darcs_repo = os.path.abspath(args[0])
+		hg_repo    = os.path.abspath(args[1])
+		skip       = int(args[2])
 	else:
 		print USAGE
 		sys.exit(-1)
 	# Initializes the target repo
 	if not os.path.isdir(darcs_repo + "/_darcs"):
-		print "No darcs directory found at: " + darc_repo
+		print "No darcs directory found at: " + darcs_repo
 		sys.exit(-1)
 	if not os.path.isdir(hg_repo):
 		os.mkdir(hg_repo)
-	else:
-		print "Given HG repository must not exist. It will be created"
+	elif skip == None:
+		print "Given HG repository must not exist when no SKIP is specified."
 		sys.exit(-1)
-	cmd("hg init '%s'" % (hg_repo))
-	cmd("darcs initialize", hg_repo)
+	if skip == None:
+		cmd("hg init '%s'" % (hg_repo))
+		cmd("darcs initialize", hg_repo)
 	# Get the changes from the Darcs repository
-	for author, date, summary, description in darcs_changes(darcs_repo):
-		text = summary + "\n" + description
-		darcs_pull(hg_repo, darcs_repo, summary)
-		epoch = int(mktime(strptime(date, '%Y%m%d%H%M%S')))
-		hg_commit(hg_repo, text, author, epoch)
+	change_number = 0
+	for author, date, summary, chash, description in darcs_changes(darcs_repo):
+		print "== changeset", change_number,
+		if skip != None and change_number <= skip:
+			print "(skipping)"
+		else:
+			text = summary + "\n" + description
+			darcs_pull(hg_repo, darcs_repo, chash)
+			# The commit hash has a date like 20021020201112
+			# --------------------------------YYYYMMDDHHMMSS
+			date = chash.split("-")[0]
+			epoch = int(mktime(strptime(date, '%Y%m%d%H%M%S')))
+			hg_commit(hg_repo, text, author, epoch)
+		change_number += 1
+	print "Darcs repository (_darcs) was not deleted. You can keep or remove it."
 
 # EOF
-
--- a/doc/hgrc.5.txt
+++ b/doc/hgrc.5.txt
@@ -309,6 +309,9 @@ smtp::
     Optional.  Password to authenticate to SMTP server with.
     If username is specified, password must also be specified.
     Default: none.
+  local_hostname;;
+    Optional.  It's the hostname that the sender can use to identify itself
+    to the MTA.
 
 paths::
   Assigns symbolic names to repositories.  The left side is the
--- a/mercurial/bdiff.c
+++ b/mercurial/bdiff.c
@@ -65,7 +65,7 @@ static inline uint32_t rol32(uint32_t wo
 
 int splitlines(const char *a, int len, struct line **lr)
 {
-	int h, i;
+	int g, h, i;
 	const char *p, *b = a;
 	struct line *l;
 
@@ -82,7 +82,16 @@ int splitlines(const char *a, int len, s
 	/* build the line array and calculate hashes */
 	h = 0;
 	for (p = a; p < a + len; p++) {
-		h = *p + rol32(h, 7); /* a simple hash from GNU diff */
+		/*
+		 * a simple hash from GNU diff, with better collision
+		 * resistance from hashpjw. this slows down common
+		 * case by 10%, but speeds up worst case by 100x.
+		 */
+		h = *p + rol32(h, 7);
+		if ((g = h & 0xf0000000)) {
+			h ^= g >> 24;
+			h ^= g;
+		}
 		if (*p == '\n' || p == a + len - 1) {
 			l->len = p - b + 1;
 			l->h = h * l->len;
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -231,7 +231,7 @@ def revrange(ui, repo, revs):
     """Yield revision as strings from a list of revision specifications."""
     seen = {}
     for spec in revs:
-        if spec.find(revrangesep) >= 0:
+        if revrangesep in spec:
             start, end = spec.split(revrangesep, 1)
             start = revfix(repo, start, 0)
             end = revfix(repo, end, repo.changelog.count() - 1)
@@ -405,23 +405,33 @@ def dodiff(fp, ui, repo, node1, node2, f
     diffopts = ui.diffopts()
     showfunc = opts.get('show_function') or diffopts['showfunc']
     ignorews = opts.get('ignore_all_space') or diffopts['ignorews']
+    ignorewsamount = opts.get('ignore_space_change') or \
+                     diffopts['ignorewsamount']
+    ignoreblanklines = opts.get('ignore_blank_lines') or \
+                     diffopts['ignoreblanklines']
     for f in modified:
         to = None
         if f in mmap:
             to = repo.file(f).read(mmap[f])
         tn = read(f)
         fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, text=text,
-                               showfunc=showfunc, ignorews=ignorews))
+                               showfunc=showfunc, ignorews=ignorews,
+                               ignorewsamount=ignorewsamount,
+                               ignoreblanklines=ignoreblanklines))
     for f in added:
         to = None
         tn = read(f)
         fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, text=text,
-                               showfunc=showfunc, ignorews=ignorews))
+                               showfunc=showfunc, ignorews=ignorews,
+                               ignorewsamount=ignorewsamount,
+                               ignoreblanklines=ignoreblanklines))
     for f in removed:
         to = repo.file(f).read(mmap[f])
         tn = None
         fp.write(mdiff.unidiff(to, date1, tn, date2(f), f, r, text=text,
-                               showfunc=showfunc, ignorews=ignorews))
+                               showfunc=showfunc, ignorews=ignorews,
+                               ignorewsamount=ignorewsamount,
+                               ignoreblanklines=ignoreblanklines))
 
 def trimuser(ui, name, rev, revcache):
     """trim the name of the user who committed a change"""
@@ -941,6 +951,10 @@ def clone(ui, source, dest=None, **opts)
     hardlinking.
 
     See pull for valid source format details.
+
+    It is possible to specify an ssh:// URL as the destination, but no
+    .hg/hgrc will be created on the remote side. Look at the help text
+    for the pull command for important details about ssh:// URLs.
     """
     if dest is None:
         dest = os.path.basename(os.path.normpath(source))
@@ -1950,6 +1964,10 @@ def init(ui, dest="."):
     directory does not exist, it is created.
 
     If no directory is given, the current directory is used.
+
+    It is possible to specify an ssh:// URL as the destination.
+    Look at the help text for the pull command for important details
+    about ssh:// URLs.
     """
     hg.repository(ui, dest, create=1)
 
@@ -2218,15 +2236,16 @@ def pull(ui, repo, source="default", **o
     Valid URLs are of the form:
 
       local/filesystem/path
-      http://[user@]host[:port][/path]
-      https://[user@]host[:port][/path]
-      ssh://[user@]host[:port][/path]
+      http://[user@]host[:port]/[path]
+      https://[user@]host[:port]/[path]
+      ssh://[user@]host[:port]/[path]
 
     Some notes about using SSH with Mercurial:
     - SSH requires an accessible shell account on the destination machine
       and a copy of hg in the remote path or specified with as remotecmd.
-    - /path is relative to the remote user's home directory by default.
-      Use two slashes at the start of a path to specify an absolute path.
+    - path is relative to the remote user's home directory by default.
+      Use an extra slash at the start of a path to specify an absolute path:
+        ssh://example.com//tmp/repository
     - Mercurial doesn't use its own compression via SSH; the right thing
       to do is to configure it in your ~/.ssh/ssh_config, e.g.:
         Host *.mylocalnetwork.example.com
@@ -2270,10 +2289,13 @@ def push(ui, repo, dest=None, **opts):
     Valid URLs are of the form:
 
       local/filesystem/path
-      ssh://[user@]host[:port][/path]
+      ssh://[user@]host[:port]/[path]
 
     Look at the help text for the pull command for important details
     about ssh:// URLs.
+
+    Pushing to http:// and https:// URLs is possible, too, if this
+    feature is enabled on the remote Mercurial server.
     """
     dest = ui.expandpath(dest or 'default-push', dest or 'default')
 
@@ -2742,7 +2764,7 @@ def tag(ui, repo, name, rev_=None, **opt
 
     disallowed = (revrangesep, '\r', '\n')
     for c in disallowed:
-        if name.find(c) >= 0:
+        if c in name:
             raise util.Abort(_("%s cannot be used in a tag name") % repr(c))
 
     repo.hook('pretag', throw=True, node=r, tag=name,
@@ -3018,6 +3040,10 @@ table = {
            _('show which function each change is in')),
           ('w', 'ignore-all-space', None,
            _('ignore white space when comparing lines')),
+          ('b', 'ignore-space-change', None,
+           _('ignore changes in the amount of white space')),
+          ('B', 'ignore-blank-lines', None,
+           _('ignore changes whose lines are all blank')),
           ('I', 'include', [], _('include names matching the given patterns')),
           ('X', 'exclude', [], _('exclude names matching the given patterns'))],
          _('hg diff [-a] [-I] [-X] [-r REV1 [-r REV2]] [FILE]...')),
--- a/mercurial/filelog.py
+++ b/mercurial/filelog.py
@@ -34,14 +34,14 @@ class filelog(revlog):
         t = self.revision(node)
         if not t.startswith('\1\n'):
             return t
-        s = t.find('\1\n', 2)
+        s = t.index('\1\n', 2)
         return t[s+2:]
 
     def readmeta(self, node):
         t = self.revision(node)
         if not t.startswith('\1\n'):
             return {}
-        s = t.find('\1\n', 2)
+        s = t.index('\1\n', 2)
         mt = t[2:s]
         m = {}
         for l in mt.splitlines():
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -61,8 +61,7 @@ def repository(ui, path=None, create=0):
     if not path: path = ''
     scheme = path
     if scheme:
-        c = scheme.find(':')
-        scheme = c >= 0 and scheme[:c]
+        scheme = scheme.split(":", 1)[0]
     ctor = schemes.get(scheme) or schemes['file']
     if create:
         try:
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -133,21 +133,29 @@ class hgweb(object):
         diffopts = self.repo.ui.diffopts()
         showfunc = diffopts['showfunc']
         ignorews = diffopts['ignorews']
+        ignorewsamount = diffopts['ignorewsamount']
+        ignoreblanklines = diffopts['ignoreblanklines']
         for f in modified:
             to = r.file(f).read(mmap1[f])
             tn = r.file(f).read(mmap2[f])
             yield diffblock(mdiff.unidiff(to, date1, tn, date2, f,
-                            showfunc=showfunc, ignorews=ignorews), f, tn)
+                            showfunc=showfunc, ignorews=ignorews,
+                            ignorewsamount=ignorewsamount,
+                            ignoreblanklines=ignoreblanklines), f, tn)
         for f in added:
             to = None
             tn = r.file(f).read(mmap2[f])
             yield diffblock(mdiff.unidiff(to, date1, tn, date2, f,
-                            showfunc=showfunc, ignorews=ignorews), f, tn)
+                            showfunc=showfunc, ignorews=ignorews,
+                            ignorewsamount=ignorewsamount,
+                            ignoreblanklines=ignoreblanklines), f, tn)
         for f in removed:
             to = r.file(f).read(mmap1[f])
             tn = None
             yield diffblock(mdiff.unidiff(to, date1, tn, date2, f,
-                            showfunc=showfunc, ignorews=ignorews), f, tn)
+                            showfunc=showfunc, ignorews=ignorews,
+                            ignorewsamount=ignorewsamount,
+                            ignoreblanklines=ignoreblanklines), f, tn)
 
     def changelog(self, pos):
         def changenav(**map):
@@ -462,7 +470,7 @@ class hgweb(object):
                 continue
             remain = f[l:]
             if "/" in remain:
-                short = remain[:remain.find("/") + 1] # bleah
+                short = remain[:remain.index("/") + 1] # bleah
                 files[short] = (f, None)
             else:
                 short = os.path.basename(remain)
--- a/mercurial/hgweb/server.py
+++ b/mercurial/hgweb/server.py
@@ -127,6 +127,11 @@ class _hgwebhandler(object, BaseHTTPServ
             if h[0].lower() == 'content-length':
                 should_close = False
                 self.length = int(h[1])
+        # The value of the Connection header is a list of case-insensitive
+        # tokens separated by commas and optional whitespace.
+        if 'close' in [token.strip().lower() for token in 
+                       self.headers.get('connection', '').split(',')]:
+            should_close = True
         if should_close:
             self.send_header('Connection', 'close')
         self.close_connection = should_close
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -74,8 +74,8 @@ class localrepository(object):
         self.transhandle = None
 
         if create:
-	    if not os.path.exists(path):
-		os.mkdir(path)
+            if not os.path.exists(path):
+                os.mkdir(path)
             os.mkdir(self.path)
             os.mkdir(self.join("data"))
 
@@ -101,9 +101,13 @@ class localrepository(object):
             try:
                 obj = __import__(modname)
             except ImportError:
-                raise util.Abort(_('%s hook is invalid '
-                                   '(import of "%s" failed)') %
-                                 (hname, modname))
+                try:
+                    # extensions are loaded with hgext_ prefix
+                    obj = __import__("hgext_%s" % modname)
+                except ImportError:
+                    raise util.Abort(_('%s hook is invalid '
+                                       '(import of "%s" failed)') %
+                                     (hname, modname))
             try:
                 for p in funcname.split('.')[1:]:
                     obj = getattr(obj, p)
--- a/mercurial/lock.py
+++ b/mercurial/lock.py
@@ -85,14 +85,14 @@ class lock(object):
         # see if locker is alive.  if locker is on this machine but
         # not alive, we can safely break lock.
         locker = util.readlock(self.f)
-        c = locker.find(':')
-        if c == -1:
+        try:
+            host, pid = locker.split(":", 1)
+        except ValueError:
             return locker
-        host = locker[:c]
         if host != self.host:
             return locker
         try:
-            pid = int(locker[c+1:])
+            pid = int(pid)
         except:
             return locker
         if util.testpid(pid):
--- a/mercurial/mdiff.py
+++ b/mercurial/mdiff.py
@@ -20,7 +20,8 @@ def splitnewlines(text):
     return lines
 
 def unidiff(a, ad, b, bd, fn, r=None, text=False,
-            showfunc=False, ignorews=False):
+            showfunc=False, ignorews=False, ignorewsamount=False,
+            ignoreblanklines=False):
 
     if not a and not b: return ""
     epoch = util.datestr((0, 0))
@@ -49,7 +50,9 @@ def unidiff(a, ad, b, bd, fn, r=None, te
         al = splitnewlines(a)
         bl = splitnewlines(b)
         l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn,
-                          showfunc=showfunc, ignorews=ignorews))
+                          showfunc=showfunc, ignorews=ignorews,
+                          ignorewsamount=ignorewsamount,
+                          ignoreblanklines=ignoreblanklines))
         if not l: return ""
         # difflib uses a space, rather than a tab
         l[0] = "%s\t%s\n" % (l[0][:-2], ad)
@@ -72,8 +75,10 @@ def unidiff(a, ad, b, bd, fn, r=None, te
 # context is the number of context lines
 # showfunc enables diff -p output
 # ignorews ignores all whitespace changes in the diff
+# ignorewsamount ignores changes in the amount of whitespace
+# ignoreblanklines ignores changes whose lines are all blank
 def bunidiff(t1, t2, l1, l2, header1, header2, context=3, showfunc=False,
-             ignorews=False):
+             ignorews=False, ignorewsamount=False, ignoreblanklines=False):
     def contextend(l, len):
         ret = l + context
         if ret > len:
@@ -116,6 +121,11 @@ def bunidiff(t1, t2, l1, l2, header1, he
 
     if showfunc:
         funcre = re.compile('\w')
+    if ignorewsamount:
+        wsamountre = re.compile('[ \t]+')
+        wsappendedre = re.compile(' \n')
+    if ignoreblanklines:
+        wsblanklinesre = re.compile('\n')
     if ignorews:
         wsre = re.compile('[ \t]')
 
@@ -149,6 +159,20 @@ def bunidiff(t1, t2, l1, l2, header1, he
         if not old and not new:
             continue
 
+        if ignoreblanklines:
+            wsold = wsblanklinesre.sub('', "".join(old))
+            wsnew = wsblanklinesre.sub('', "".join(new))
+            if wsold == wsnew:
+                continue
+
+        if ignorewsamount:
+            wsold = wsamountre.sub(' ', "".join(old))
+            wsold = wsappendedre.sub('\n', wsold)
+            wsnew = wsamountre.sub(' ', "".join(new))
+            wsnew = wsappendedre.sub('\n', wsnew)
+            if wsold == wsnew:
+                continue
+
         if ignorews:
             wsold = wsre.sub('', "".join(old))
             wsnew = wsre.sub('', "".join(new))
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -76,7 +76,7 @@ class ui(object):
         if root is None:
             root = os.path.expanduser('~')
         for name, path in self.configitems("paths"):
-            if path and path.find("://") == -1 and not os.path.isabs(path):
+            if path and "://" not in path and not os.path.isabs(path):
                 self.cdata.set("paths", name, os.path.join(root, path))
 
     def setconfig(self, section, name, val):
@@ -172,7 +172,8 @@ class ui(object):
     def diffopts(self):
         if self.diffcache:
             return self.diffcache
-        result = {'showfunc': True, 'ignorews': False}
+        result = {'showfunc': True, 'ignorews': False,
+                  'ignorewsamount': False, 'ignoreblanklines': False}
         for key, value in self.configitems("diff"):
             if value:
                 result[key.lower()] = (value.lower() == 'true')
@@ -208,7 +209,7 @@ class ui(object):
 
     def expandpath(self, loc, default=None):
         """Return repository location relative to cwd or from [paths]"""
-        if loc.find("://") != -1 or os.path.exists(loc):
+        if "://" in loc or os.path.exists(loc):
             return loc
 
         path = self.config("paths", loc)
@@ -298,7 +299,8 @@ class ui(object):
         def smtp():
             '''send mail using smtp.'''
 
-            s = smtplib.SMTP()
+            local_hostname = self.config('smtp', 'local_hostname')
+            s = smtplib.SMTP(local_hostname=local_hostname)
             mailhost = self.config('smtp', 'host')
             if not mailhost:
                 raise util.Abort(_('no [smtp]host in hgrc - cannot send mail'))
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -620,7 +620,7 @@ else:
     def parse_patch_output(output_line):
         """parses the output produced by patch and returns the file name"""
         pf = output_line[14:]
-        if pf.startswith("'") and pf.endswith("'") and pf.find(" ") >= 0:
+        if pf.startswith("'") and pf.endswith("'") and " " in pf:
             pf = pf[1:-1] # Remove the quotes
         return pf
 
--- a/tests/test-help.out
+++ b/tests/test-help.out
@@ -173,12 +173,14 @@ diff repository (or selected files)
 
 options:
 
- -r --rev               revision
- -a --text              treat all files as text
- -p --show-function     show which function each change is in
- -w --ignore-all-space  ignore white space when comparing lines
- -I --include           include names matching the given patterns
- -X --exclude           exclude names matching the given patterns
+ -r --rev                  revision
+ -a --text                 treat all files as text
+ -p --show-function        show which function each change is in
+ -w --ignore-all-space     ignore white space when comparing lines
+ -b --ignore-space-change  ignore changes in the amount of white space
+ -B --ignore-blank-lines   ignore changes whose lines are all blank
+ -I --include              include names matching the given patterns
+ -X --exclude              exclude names matching the given patterns
 hg status [OPTION]... [FILE]...
 
 show changed files in the working directory