merge with crew
authorPatrick Mezard <pmezard@gmail.com>
Mon, 14 Mar 2011 22:37:50 +0100
changeset 13652 0652b2da832d
parent 13648 d943efb9701f (diff)
parent 13650 56e71e7d2ba2 (current diff)
child 13653 30a0e3519f69
merge with crew
--- a/.hgignore	Mon Mar 14 21:31:54 2011 +0100
+++ b/.hgignore	Mon Mar 14 22:37:50 2011 +0100
@@ -7,6 +7,7 @@
 *.mergebackup
 *.o
 *.so
+*.dll
 *.pyd
 *.pyc
 *.pyo
--- a/hgext/color.py	Mon Mar 14 21:31:54 2011 +0100
+++ b/hgext/color.py	Mon Mar 14 22:37:50 2011 +0100
@@ -203,7 +203,7 @@
     if mode == 'win32':
         if w32effects is None:
             # only warn if color.mode is explicitly set to win32
-            ui.warn(_('win32console not found, please install pywin32\n'))
+            ui.warn(_('warning: failed to set color mode to %s\n') % mode)
             return
         _effects.update(w32effects)
     elif mode != 'ansi':
@@ -231,52 +231,96 @@
          _("when to colorize (boolean, always, auto, or never)"),
          _('TYPE')))
 
-try:
-    import re, pywintypes, win32console as win32c
+if os.name != 'nt':
+    w32effects = None
+else:
+    import re, ctypes
+
+    _kernel32 = ctypes.windll.kernel32
+
+    _WORD = ctypes.c_ushort
+
+    _INVALID_HANDLE_VALUE = -1
+
+    class _COORD(ctypes.Structure):
+        _fields_ = [('X', ctypes.c_short),
+                    ('Y', ctypes.c_short)]
+
+    class _SMALL_RECT(ctypes.Structure):
+        _fields_ = [('Left', ctypes.c_short),
+                    ('Top', ctypes.c_short),
+                    ('Right', ctypes.c_short),
+                    ('Bottom', ctypes.c_short)]
+
+    class _CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
+        _fields_ = [('dwSize', _COORD),
+                    ('dwCursorPosition', _COORD),
+                    ('wAttributes', _WORD),
+                    ('srWindow', _SMALL_RECT),
+                    ('dwMaximumWindowSize', _COORD)]
+
+    _STD_OUTPUT_HANDLE = 0xfffffff5L # (DWORD)-11
+    _STD_ERROR_HANDLE = 0xfffffff4L  # (DWORD)-12
+
+    _FOREGROUND_BLUE = 0x0001
+    _FOREGROUND_GREEN = 0x0002
+    _FOREGROUND_RED = 0x0004
+    _FOREGROUND_INTENSITY = 0x0008
+
+    _BACKGROUND_BLUE = 0x0010
+    _BACKGROUND_GREEN = 0x0020
+    _BACKGROUND_RED = 0x0040
+    _BACKGROUND_INTENSITY = 0x0080
+
+    _COMMON_LVB_REVERSE_VIDEO = 0x4000
+    _COMMON_LVB_UNDERSCORE = 0x8000
 
     # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx
     w32effects = {
         'none': -1,
         'black': 0,
-        'red': win32c.FOREGROUND_RED,
-        'green': win32c.FOREGROUND_GREEN,
-        'yellow': win32c.FOREGROUND_RED | win32c.FOREGROUND_GREEN,
-        'blue': win32c.FOREGROUND_BLUE,
-        'magenta': win32c.FOREGROUND_BLUE | win32c.FOREGROUND_RED,
-        'cyan': win32c.FOREGROUND_BLUE | win32c.FOREGROUND_GREEN,
-        'white': (win32c.FOREGROUND_RED | win32c.FOREGROUND_GREEN |
-                  win32c.FOREGROUND_BLUE),
-        'bold': win32c.FOREGROUND_INTENSITY,
+        'red': _FOREGROUND_RED,
+        'green': _FOREGROUND_GREEN,
+        'yellow': _FOREGROUND_RED | _FOREGROUND_GREEN,
+        'blue': _FOREGROUND_BLUE,
+        'magenta': _FOREGROUND_BLUE | _FOREGROUND_RED,
+        'cyan': _FOREGROUND_BLUE | _FOREGROUND_GREEN,
+        'white': _FOREGROUND_RED | _FOREGROUND_GREEN | _FOREGROUND_BLUE,
+        'bold': _FOREGROUND_INTENSITY,
         'black_background': 0x100,                  # unused value > 0x0f
-        'red_background': win32c.BACKGROUND_RED,
-        'green_background': win32c.BACKGROUND_GREEN,
-        'yellow_background': win32c.BACKGROUND_RED | win32c.BACKGROUND_GREEN,
-        'blue_background': win32c.BACKGROUND_BLUE,
-        'purple_background': win32c.BACKGROUND_BLUE | win32c.BACKGROUND_RED,
-        'cyan_background': win32c.BACKGROUND_BLUE | win32c.BACKGROUND_GREEN,
-        'white_background': (win32c.BACKGROUND_RED | win32c.BACKGROUND_GREEN |
-                             win32c.BACKGROUND_BLUE),
-        'bold_background': win32c.BACKGROUND_INTENSITY,
-        'underline': win32c.COMMON_LVB_UNDERSCORE,  # double-byte charsets only
-        'inverse': win32c.COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
+        'red_background': _BACKGROUND_RED,
+        'green_background': _BACKGROUND_GREEN,
+        'yellow_background': _BACKGROUND_RED | _BACKGROUND_GREEN,
+        'blue_background': _BACKGROUND_BLUE,
+        'purple_background': _BACKGROUND_BLUE | _BACKGROUND_RED,
+        'cyan_background': _BACKGROUND_BLUE | _BACKGROUND_GREEN,
+        'white_background': (_BACKGROUND_RED | _BACKGROUND_GREEN |
+                             _BACKGROUND_BLUE),
+        'bold_background': _BACKGROUND_INTENSITY,
+        'underline': _COMMON_LVB_UNDERSCORE,  # double-byte charsets only
+        'inverse': _COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
     }
 
-    passthrough = set([win32c.FOREGROUND_INTENSITY,
-                       win32c.BACKGROUND_INTENSITY,
-                       win32c.COMMON_LVB_UNDERSCORE,
-                       win32c.COMMON_LVB_REVERSE_VIDEO])
+    passthrough = set([_FOREGROUND_INTENSITY,
+                       _BACKGROUND_INTENSITY,
+                       _COMMON_LVB_UNDERSCORE,
+                       _COMMON_LVB_REVERSE_VIDEO])
 
-    try:
-        stdout = win32c.GetStdHandle(win32c.STD_OUTPUT_HANDLE)
-        if stdout is None:
-            raise ImportError()
-        origattr = stdout.GetConsoleScreenBufferInfo()['Attributes']
-    except pywintypes.error:
-        # stdout may be defined but not support
-        # GetConsoleScreenBufferInfo(), when called from subprocess or
-        # redirected.
-        raise ImportError()
-    ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)', re.MULTILINE | re.DOTALL)
+    stdout = _kernel32.GetStdHandle(
+                  _STD_OUTPUT_HANDLE)  # don't close the handle returned
+    if stdout is None or stdout == _INVALID_HANDLE_VALUE:
+        w32effects = None
+    else:
+        csbi = _CONSOLE_SCREEN_BUFFER_INFO()
+        if not _kernel32.GetConsoleScreenBufferInfo(
+                    stdout, ctypes.byref(csbi)):
+            # stdout may not support GetConsoleScreenBufferInfo()
+            # when called from subprocess or redirected
+            w32effects = None
+        else:
+            origattr = csbi.wAttributes
+            ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)',
+                                re.MULTILINE | re.DOTALL)
 
     def win32print(text, orig, **opts):
         label = opts.get('label', '')
@@ -308,12 +352,9 @@
             for sattr in m.group(1).split(';'):
                 if sattr:
                     attr = mapcolor(int(sattr), attr)
-            stdout.SetConsoleTextAttribute(attr)
+            _kernel32.SetConsoleTextAttribute(stdout, attr)
             orig(m.group(2), **opts)
             m = re.match(ansire, m.group(3))
 
         # Explicity reset original attributes
-        stdout.SetConsoleTextAttribute(origattr)
-
-except ImportError:
-    w32effects = None
+        _kernel32.SetConsoleTextAttribute(stdout, origattr)
--- a/hgext/pager.py	Mon Mar 14 21:31:54 2011 +0100
+++ b/hgext/pager.py	Mon Mar 14 22:37:50 2011 +0100
@@ -59,14 +59,17 @@
 
 def _runpager(p):
     if not hasattr(os, 'fork'):
-        sys.stderr = sys.stdout = util.popen(p, 'wb')
+        sys.stdout = util.popen(p, 'wb')
+        if sys.stderr.isatty():
+            sys.stderr = sys.stdout
         return
     fdin, fdout = os.pipe()
     pid = os.fork()
     if pid == 0:
         os.close(fdin)
         os.dup2(fdout, sys.stdout.fileno())
-        os.dup2(fdout, sys.stderr.fileno())
+        if sys.stderr.isatty():
+            os.dup2(fdout, sys.stderr.fileno())
         os.close(fdout)
         return
     os.dup2(fdin, sys.stdin.fileno())
--- a/mercurial/bookmarks.py	Mon Mar 14 21:31:54 2011 +0100
+++ b/mercurial/bookmarks.py	Mon Mar 14 22:37:50 2011 +0100
@@ -101,13 +101,7 @@
     if current == mark:
         return
 
-    refs = repo._bookmarks
-
-    # do not update if we do update to a rev equal to the current bookmark
-    if (mark and mark not in refs and
-        current and refs[current] == repo.changectx('.').node()):
-        return
-    if mark not in refs:
+    if mark not in repo._bookmarks:
         mark = ''
     if not valid(mark):
         raise util.Abort(_("bookmark '%s' contains illegal "
@@ -163,6 +157,28 @@
     finally:
         w.release()
 
+def updatefromremote(ui, repo, remote):
+    ui.debug("checking for updated bookmarks\n")
+    rb = remote.listkeys('bookmarks')
+    changed = False
+    for k in rb.keys():
+        if k in repo._bookmarks:
+            nr, nl = rb[k], repo._bookmarks[k]
+            if nr in repo:
+                cr = repo[nr]
+                cl = repo[nl]
+                if cl.rev() >= cr.rev():
+                    continue
+                if cr in cl.descendants():
+                    repo._bookmarks[k] = cr.node()
+                    changed = True
+                    ui.status(_("updating bookmark %s\n") % k)
+                else:
+                    ui.warn(_("not updating divergent"
+                                   " bookmark %s\n") % k)
+    if changed:
+        write(repo)
+
 def diff(ui, repo, remote):
     ui.status(_("searching for changed bookmarks\n"))
 
--- a/mercurial/commands.py	Mon Mar 14 21:31:54 2011 +0100
+++ b/mercurial/commands.py	Mon Mar 14 22:37:50 2011 +0100
@@ -2292,6 +2292,7 @@
     output = []
 
     revs = []
+    bms = []
     if source:
         source, branches = hg.parseurl(ui.expandpath(source))
         repo = hg.repository(ui, source)
@@ -2302,10 +2303,19 @@
             rev = revs[0]
         if not rev:
             rev = "tip"
-        if num or branch or tags or bookmarks:
-            raise util.Abort(_("can't query remote revision number,"
-                             " branch, tags, or bookmarks"))
-        output = [hexfunc(repo.lookup(rev))]
+        if num or branch or tags:
+            raise util.Abort(
+                _("can't query remote revision number, branch, or tags"))
+
+        remoterev = repo.lookup(rev)
+        if default or id:
+            output = [hexfunc(remoterev)]
+
+        if 'bookmarks' in repo.listkeys('namespaces'):
+            hexremoterev = hex(remoterev)
+            bms = [bm for bm, bmrev in repo.listkeys('bookmarks').iteritems()
+                   if bmrev == hexremoterev]
+
     elif not rev:
         ctx = repo[None]
         parents = ctx.parents()
@@ -2325,6 +2335,9 @@
         if num:
             output.append(str(ctx.rev()))
 
+    if repo.local():
+        bms = ctx.bookmarks()
+
     if repo.local() and default and not ui.quiet:
         b = ctx.branch()
         if b != 'default':
@@ -2335,8 +2348,9 @@
         if t:
             output.append(t)
 
+    if default and not ui.quiet:
         # multiple bookmarks for a single parent separated by '/'
-        bm = '/'.join(ctx.bookmarks())
+        bm = '/'.join(bms)
         if bm:
             output.append(bm)
 
@@ -2347,7 +2361,7 @@
         output.extend(ctx.tags())
 
     if bookmarks:
-        output.extend(ctx.bookmarks())
+        output.extend(bms)
 
     ui.write("%s\n" % ' '.join(output))
 
@@ -2963,6 +2977,7 @@
             raise util.Abort(err)
 
     modheads = repo.pull(other, heads=revs, force=opts.get('force'))
+    bookmarks.updatefromremote(ui, repo, other)
     if checkout:
         checkout = str(repo.changelog.rev(other.lookup(checkout)))
     repo._subtoppath = source
--- a/mercurial/hgweb/common.py	Mon Mar 14 21:31:54 2011 +0100
+++ b/mercurial/hgweb/common.py	Mon Mar 14 22:37:50 2011 +0100
@@ -73,7 +73,7 @@
     def __init__(self, code, message=None, headers=[]):
         if message is None:
             message = _statusmessage(code)
-        super(Exception, self).__init__()
+        Exception.__init__(self)
         self.code = code
         self.message = message
         self.headers = headers
--- a/mercurial/localrepo.py	Mon Mar 14 21:31:54 2011 +0100
+++ b/mercurial/localrepo.py	Mon Mar 14 22:37:50 2011 +0100
@@ -1346,27 +1346,6 @@
         finally:
             lock.release()
 
-        self.ui.debug("checking for updated bookmarks\n")
-        rb = remote.listkeys('bookmarks')
-        changed = False
-        for k in rb.keys():
-            if k in self._bookmarks:
-                nr, nl = rb[k], self._bookmarks[k]
-                if nr in self:
-                    cr = self[nr]
-                    cl = self[nl]
-                    if cl.rev() >= cr.rev():
-                        continue
-                    if cr in cl.descendants():
-                        self._bookmarks[k] = cr.node()
-                        changed = True
-                        self.ui.status(_("updating bookmark %s\n") % k)
-                    else:
-                        self.ui.warn(_("not updating divergent"
-                                       " bookmark %s\n") % k)
-        if changed:
-            bookmarks.write(self)
-
         return result
 
     def checkpush(self, force, revs):
--- a/mercurial/subrepo.py	Mon Mar 14 21:31:54 2011 +0100
+++ b/mercurial/subrepo.py	Mon Mar 14 22:37:50 2011 +0100
@@ -8,7 +8,7 @@
 import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath
 import stat, subprocess, tarfile
 from i18n import _
-import config, util, node, error, cmdutil
+import config, util, node, error, cmdutil, bookmarks
 hg = None
 
 nullstate = ('', '', 'empty')
@@ -441,6 +441,7 @@
                                  % (subrelpath(self), srcurl))
             other = hg.repository(self._repo.ui, srcurl)
             self._repo.pull(other)
+            bookmarks.updatefromremote(self._repo.ui, self._repo, other)
 
     def get(self, state, overwrite=False):
         self._get(state)
--- a/tests/test-http-proxy.t	Mon Mar 14 21:31:54 2011 +0100
+++ b/tests/test-http-proxy.t	Mon Mar 14 22:37:50 2011 +0100
@@ -105,20 +105,16 @@
   * - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
 
--- a/tests/test-identify.t	Mon Mar 14 21:31:54 2011 +0100
+++ b/tests/test-identify.t	Mon Mar 14 22:37:50 2011 +0100
@@ -65,26 +65,43 @@
 remote with rev number?
 
   $ hg id -n http://localhost:$HGPORT1/
-  abort: can't query remote revision number, branch, tags, or bookmarks
+  abort: can't query remote revision number, branch, or tags
   [255]
 
 remote with tags?
 
   $ hg id -t http://localhost:$HGPORT1/
-  abort: can't query remote revision number, branch, tags, or bookmarks
+  abort: can't query remote revision number, branch, or tags
   [255]
 
 remote with branch?
 
   $ hg id -b http://localhost:$HGPORT1/
-  abort: can't query remote revision number, branch, tags, or bookmarks
+  abort: can't query remote revision number, branch, or tags
   [255]
 
-remote with bookmarks?
+test bookmark support
 
-  $ hg id -B http://localhost:$HGPORT1/
-  abort: can't query remote revision number, branch, tags, or bookmarks
-  [255]
+  $ hg bookmark Y
+  $ hg bookmark Z
+  $ hg bookmarks
+     Y                         0:cb9a9f314b8b
+   * Z                         0:cb9a9f314b8b
+  $ hg id
+  cb9a9f314b8b+ tip Y/Z
+  $ hg id --bookmarks
+  Y Z
+
+test remote identify with bookmarks
+
+  $ hg id http://localhost:$HGPORT1/
+  cb9a9f314b8b Y/Z
+  $ hg id --bookmarks http://localhost:$HGPORT1/
+  Y Z
+  $ hg id -r . http://localhost:$HGPORT1/
+  cb9a9f314b8b Y/Z
+  $ hg id --bookmarks -r . http://localhost:$HGPORT1/
+  Y Z
 
 Make sure we do not obscure unknown requires file entries (issue2649)