Merge with main
authorBrendan Cully <brendan@kublai.com>
Mon, 27 Jul 2009 19:23:04 -0700
changeset 9282 f9087eea293a
parent 9281 2a4131b264c3 (current diff)
parent 9248 ac02b43bc08a (diff)
child 9285 25255ce87bcf
Merge with main
hgext/bookmarks.py
--- a/hgext/bookmarks.py	Sun Jul 26 10:45:35 2009 +0100
+++ b/hgext/bookmarks.py	Mon Jul 27 19:23:04 2009 -0700
@@ -249,12 +249,12 @@
                 key = self._bookmarks[key]
             return super(bookmark_repo, self).lookup(key)
 
-        def commit(self, *k, **kw):
+        def commitctx(self, ctx, error=False):
             """Add a revision to the repository and
             move the bookmark"""
             wlock = self.wlock() # do both commit and bookmark with lock held
             try:
-                node  = super(bookmark_repo, self).commit(*k, **kw)
+                node  = super(bookmark_repo, self).commitctx(ctx, error)
                 if node is None:
                     return None
                 parents = self.changelog.parents(node)
@@ -262,12 +262,13 @@
                     parents = (parents[0],)
                 marks = parse(self)
                 update = False
-                for mark, n in marks.items():
-                    if ui.configbool('bookmarks', 'track.current'):
-                        if mark == current(self) and n in parents:
-                            marks[mark] = node
-                            update = True
-                    else:
+                if ui.configbool('bookmarks', 'track.current'):
+                    mark = current(self)
+                    if mark and marks[mark] in parents:
+                        marks[mark] = node
+                        update = True
+                else:
+                    for mark, n in marks.items():
                         if n in parents:
                             marks[mark] = node
                             update = True
@@ -288,10 +289,16 @@
             node = self.changelog.tip()
             marks = parse(self)
             update = False
-            for mark, n in marks.items():
-                if n in parents:
+            if ui.configbool('bookmarks', 'track.current'):
+                mark = current(self)
+                if mark and marks[mark] in parents:
                     marks[mark] = node
                     update = True
+            else:
+                for mark, n in marks.items():
+                    if n in parents:
+                        marks[mark] = node
+                        update = True
             if update:
                 write(self, marks)
             return result
--- a/mercurial/dirstate.py	Sun Jul 26 10:45:35 2009 +0100
+++ b/mercurial/dirstate.py	Mon Jul 27 19:23:04 2009 -0700
@@ -59,7 +59,7 @@
     def _foldmap(self):
         f = {}
         for name in self._map:
-            f[os.path.normcase(name)] = name
+            f[util.realpath(self._join(name))] = name
         return f
 
     @propertycache
@@ -340,7 +340,7 @@
             self._ui.warn(_("not in dirstate: %s\n") % f)
 
     def _normalize(self, path, knownpath):
-        norm_path = os.path.normcase(path)
+        norm_path = util.realpath(self._join(path))
         fold_path = self._foldmap.get(norm_path, None)
         if fold_path is None:
             if knownpath or not os.path.exists(os.path.join(self._root, path)):
--- a/mercurial/hg.py	Sun Jul 26 10:45:35 2009 +0100
+++ b/mercurial/hg.py	Mon Jul 27 19:23:04 2009 -0700
@@ -138,7 +138,7 @@
             try:
                 uprev = r.lookup(test)
                 break
-            except:
+            except LookupError:
                 continue
         _update(r, uprev)
 
--- a/mercurial/mail.py	Sun Jul 26 10:45:35 2009 +0100
+++ b/mercurial/mail.py	Mon Jul 27 19:23:04 2009 -0700
@@ -36,7 +36,10 @@
     if username and password:
         ui.note(_('(authenticating to mail server as %s)\n') %
                   (username))
-        s.login(username, password)
+        try:
+            s.login(username, password)
+        except smtplib.SMTPException, inst:
+            raise util.Abort(inst)
 
     def send(sender, recipients, msg):
         try:
--- a/mercurial/patch.py	Sun Jul 26 10:45:35 2009 +0100
+++ b/mercurial/patch.py	Mon Jul 27 19:23:04 2009 -0700
@@ -182,6 +182,7 @@
     lineno = 0
     for line in lr:
         lineno += 1
+        line = line.rstrip(' \r\n')
         if line.startswith('diff --git'):
             m = gitre.match(line)
             if m:
@@ -200,23 +201,23 @@
                 continue
             if line.startswith('rename from '):
                 gp.op = 'RENAME'
-                gp.oldpath = line[12:].rstrip()
+                gp.oldpath = line[12:]
             elif line.startswith('rename to '):
-                gp.path = line[10:].rstrip()
+                gp.path = line[10:]
             elif line.startswith('copy from '):
                 gp.op = 'COPY'
-                gp.oldpath = line[10:].rstrip()
+                gp.oldpath = line[10:]
             elif line.startswith('copy to '):
-                gp.path = line[8:].rstrip()
+                gp.path = line[8:]
             elif line.startswith('deleted file'):
                 gp.op = 'DELETE'
                 # is the deleted file a symlink?
-                gp.setmode(int(line.rstrip()[-6:], 8))
+                gp.setmode(int(line[-6:], 8))
             elif line.startswith('new file mode '):
                 gp.op = 'ADD'
-                gp.setmode(int(line.rstrip()[-6:], 8))
+                gp.setmode(int(line[-6:], 8))
             elif line.startswith('new mode '):
-                gp.setmode(int(line.rstrip()[-6:], 8))
+                gp.setmode(int(line[-6:], 8))
             elif line.startswith('GIT binary patch'):
                 dopatch |= GP_BINARY
                 gp.binary = True
--- a/mercurial/posix.py	Sun Jul 26 10:45:35 2009 +0100
+++ b/mercurial/posix.py	Mon Jul 27 19:23:04 2009 -0700
@@ -7,7 +7,7 @@
 
 from i18n import _
 import osutil
-import os, sys, errno, stat, getpass, pwd, grp
+import os, sys, errno, stat, getpass, pwd, grp, fcntl
 
 posixfile = open
 nulldev = '/dev/null'
@@ -104,6 +104,44 @@
 def localpath(path):
     return path
 
+if sys.platform == 'darwin':
+    def realpath(path):
+        '''
+        Returns the true, canonical file system path equivalent to the given
+        path.
+
+        Equivalent means, in this case, resulting in the same, unique
+        file system link to the path. Every file system entry, whether a file,
+        directory, hard link or symbolic link or special, will have a single
+        path preferred by the system, but may allow multiple, differing path
+        lookups to point to it.
+
+        Most regular UNIX file systems only allow a file system entry to be
+        looked up by its distinct path. Obviously, this does not apply to case
+        insensitive file systems, whether case preserving or not. The most
+        complex issue to deal with is file systems transparently reencoding the
+        path, such as the non-standard Unicode normalisation required for HFS+
+        and HFSX.
+        '''
+        # Constants copied from /usr/include/sys/fcntl.h
+        F_GETPATH = 50
+        O_SYMLINK = 0x200000
+
+        try:
+            fd = os.open(path, O_SYMLINK)
+        except OSError, err:
+            if err.errno is errno.ENOENT:
+                return path
+            raise
+
+        try:
+            return fcntl.fcntl(fd, F_GETPATH, '\0' * 1024).rstrip('\0')
+        finally:
+            os.close(fd)
+else:
+    # Fallback to the likely inadequate Python builtin function.
+    realpath = os.path.realpath
+
 def shellquote(s):
     if os.sys.platform == 'OpenVMS':
         return '"%s"' % s
--- a/mercurial/windows.py	Sun Jul 26 10:45:35 2009 +0100
+++ b/mercurial/windows.py	Mon Jul 27 19:23:04 2009 -0700
@@ -126,6 +126,15 @@
 def normpath(path):
     return pconvert(os.path.normpath(path))
 
+def realpath(path):
+    '''
+    Returns the true, canonical file system path equivalent to the given
+    path.
+    '''
+    # TODO: There may be a more clever way to do this that also handles other,
+    # less common file systems.
+    return os.path.normpath(os.path.normcase(os.path.realpath(path)))
+
 def samestat(s1, s2):
     return False
 
--- a/tests/hghave	Sun Jul 26 10:45:35 2009 +0100
+++ b/tests/hghave	Mon Jul 27 19:23:04 2009 -0700
@@ -39,7 +39,7 @@
     try:
         import bzrlib
         return (bzrlib.__doc__ != None
-                and bzrlib.version_info[:2] == (1, 14))
+                and bzrlib.version_info[:2] >= (1, 14))
     except ImportError:
         return False
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-path-normalization	Mon Jul 27 19:23:04 2009 -0700
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+hg clone --quiet $TESTDIR/test-path-normalization.hg t
+exec hg st -R t
Binary file tests/test-path-normalization.hg has changed