mercurial/bookmarks.py
author Matt Mackall <mpm@selenic.com>
Thu, 08 Dec 2011 16:01:44 -0600
changeset 15623 fc8c7a5ccc4a
parent 15621 013688350c7d
child 15887 12dea4d998ec
permissions -rw-r--r--
merge with stable
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
13350
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# Mercurial bookmark support code
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2008 David Soria Parra <dsp@php.net>
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
from mercurial.i18n import _
14064
e4bfb9c337f3 remove unused imports and variables
Alexander Solovyov <alexander@solovyov.net>
parents: 14039
diff changeset
     9
from mercurial.node import hex
14027
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    10
from mercurial import encoding, error, util
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    11
import errno, os
13350
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    12
13425
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
    13
def valid(mark):
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
    14
    for c in (':', '\0', '\n', '\r'):
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
    15
        if c in mark:
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
    16
            return False
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
    17
    return True
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
    18
13351
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    19
def read(repo):
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    20
    '''Parse .hg/bookmarks file and return a dictionary
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    21
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    22
    Bookmarks are stored as {HASH}\\s{NAME}\\n (localtags format) values
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    23
    in the .hg/bookmarks file.
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    24
    Read the file and return a (name=>nodeid) dictionary
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    25
    '''
14027
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    26
    bookmarks = {}
13351
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    27
    try:
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    28
        for line in repo.opener('bookmarks'):
14845
677339529a53 bookmarks: more robust parsing of bookmarks file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 14559
diff changeset
    29
            line = line.strip()
14848
09c9c120a817 bookmarks: simplify warning code
Matt Mackall <mpm@selenic.com>
parents: 14847
diff changeset
    30
            if not line:
09c9c120a817 bookmarks: simplify warning code
Matt Mackall <mpm@selenic.com>
parents: 14847
diff changeset
    31
                continue
14845
677339529a53 bookmarks: more robust parsing of bookmarks file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 14559
diff changeset
    32
            if ' ' not in line:
14848
09c9c120a817 bookmarks: simplify warning code
Matt Mackall <mpm@selenic.com>
parents: 14847
diff changeset
    33
                repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n') % line)
14845
677339529a53 bookmarks: more robust parsing of bookmarks file
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 14559
diff changeset
    34
                continue
14847
400ba7cccbae bookmarks: drop superfluous strip
Matt Mackall <mpm@selenic.com>
parents: 14846
diff changeset
    35
            sha, refspec = line.split(' ', 1)
13351
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    36
            refspec = encoding.tolocal(refspec)
14027
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    37
            try:
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    38
                bookmarks[refspec] = repo.changelog.lookup(sha)
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    39
            except error.RepoLookupError:
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    40
                pass
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    41
    except IOError, inst:
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    42
        if inst.errno != errno.ENOENT:
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    43
            raise
13351
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    44
    return bookmarks
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    45
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    46
def readcurrent(repo):
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    47
    '''Get the current bookmark
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    48
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    49
    If we use gittishsh branches we have a current bookmark that
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    50
    we are on. This function returns the name of the bookmark. It
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    51
    is stored in .hg/bookmarks.current
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    52
    '''
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    53
    mark = None
14027
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    54
    try:
13351
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    55
        file = repo.opener('bookmarks.current')
14027
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    56
    except IOError, inst:
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    57
        if inst.errno != errno.ENOENT:
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    58
            raise
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    59
        return None
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    60
    try:
13351
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    61
        # No readline() in posixfile_nt, reading everything is cheap
13381
d073468e3c5f bookmarks: read current bookmark as utf-8 and convert it to local
David Soria Parra <dsp@php.net>
parents: 13354
diff changeset
    62
        mark = encoding.tolocal((file.readlines() or [''])[0])
13627
71a96f6c205d bookmarks: discard current bookmark if absent from the bookmarks (issue2692)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13478
diff changeset
    63
        if mark == '' or mark not in repo._bookmarks:
13351
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    64
            mark = None
14027
78ab705a8147 bookmarks: be more restrictive in our Exception catching
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 14004
diff changeset
    65
    finally:
13351
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    66
        file.close()
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    67
    return mark
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
    68
13350
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
def write(repo):
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
    '''Write bookmarks
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    71
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    72
    Write the given bookmark => hash dictionary to the .hg/bookmarks file
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
    in a format equal to those of localtags.
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
    We also store a backup of the previous state in undo.bookmarks that
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
    can be copied back on rollback.
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    77
    '''
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
    refs = repo._bookmarks
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    79
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
    if repo._bookmarkcurrent not in refs:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    81
        setcurrent(repo, None)
13425
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
    82
    for mark in refs.keys():
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
    83
        if not valid(mark):
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
    84
            raise util.Abort(_("bookmark '%s' contains illegal "
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
    85
                "character" % mark))
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
    86
13350
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    87
    wlock = repo.wlock()
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    88
    try:
13425
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
    89
13350
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    90
        file = repo.opener('bookmarks', 'w', atomictemp=True)
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    91
        for refspec, node in refs.iteritems():
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    92
            file.write("%s %s\n" % (hex(node), encoding.fromlocal(refspec)))
15057
774da7121fc9 atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents: 14946
diff changeset
    93
        file.close()
13350
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    94
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    95
        # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    96
        try:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    97
            os.utime(repo.sjoin('00changelog.i'), None)
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    98
        except OSError:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    99
            pass
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   100
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   101
    finally:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   102
        wlock.release()
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   103
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   104
def setcurrent(repo, mark):
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   105
    '''Set the name of the bookmark that we are currently on
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   106
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   107
    Set the name of the bookmark that we are on (hg update <bookmark>).
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   108
    The name is recorded in .hg/bookmarks.current
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   109
    '''
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   110
    current = repo._bookmarkcurrent
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   111
    if current == mark:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   112
        return
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   113
13647
c0c599709846 bookmarks: remove API limitation in setcurrent
David Soria Parra <dsp@php.net>
parents: 13646
diff changeset
   114
    if mark not in repo._bookmarks:
13350
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   115
        mark = ''
13425
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
   116
    if not valid(mark):
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
   117
        raise util.Abort(_("bookmark '%s' contains illegal "
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
   118
            "character" % mark))
0fe36c347c00 bookmarks: forbid \0 \r \n : in bookmark names (BC)
David Soria Parra <dsp@php.net>
parents: 13416
diff changeset
   119
13350
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   120
    wlock = repo.wlock()
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   121
    try:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   122
        file = repo.opener('bookmarks.current', 'w', atomictemp=True)
14559
e29821ca94cf bookmarks: recognize the current bookmark when the local encoding isn't UTF-8
LUO Zheng <xmuluo@gmail.com>
parents: 14268
diff changeset
   123
        file.write(encoding.fromlocal(mark))
15057
774da7121fc9 atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents: 14946
diff changeset
   124
        file.close()
13350
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   125
    finally:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   126
        wlock.release()
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   127
    repo._bookmarkcurrent = mark
13352
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
   128
13663
d16c99f16f00 bundle: update current bookmark to most recent revision on current branch
David Soria Parra <dsp@php.net>
parents: 13647
diff changeset
   129
def updatecurrentbookmark(repo, oldnode, curbranch):
d16c99f16f00 bundle: update current bookmark to most recent revision on current branch
David Soria Parra <dsp@php.net>
parents: 13647
diff changeset
   130
    try:
15621
013688350c7d bookmarks: update and updatecurrentbookmark return status
Kevin Bullock <kbullock@ringworld.org>
parents: 15614
diff changeset
   131
        return update(repo, oldnode, repo.branchtags()[curbranch])
13663
d16c99f16f00 bundle: update current bookmark to most recent revision on current branch
David Soria Parra <dsp@php.net>
parents: 13647
diff changeset
   132
    except KeyError:
d16c99f16f00 bundle: update current bookmark to most recent revision on current branch
David Soria Parra <dsp@php.net>
parents: 13647
diff changeset
   133
        if curbranch == "default": # no default branch!
15621
013688350c7d bookmarks: update and updatecurrentbookmark return status
Kevin Bullock <kbullock@ringworld.org>
parents: 15614
diff changeset
   134
            return update(repo, oldnode, repo.lookup("tip"))
13663
d16c99f16f00 bundle: update current bookmark to most recent revision on current branch
David Soria Parra <dsp@php.net>
parents: 13647
diff changeset
   135
        else:
d16c99f16f00 bundle: update current bookmark to most recent revision on current branch
David Soria Parra <dsp@php.net>
parents: 13647
diff changeset
   136
            raise util.Abort(_("branch %s not found") % curbranch)
d16c99f16f00 bundle: update current bookmark to most recent revision on current branch
David Soria Parra <dsp@php.net>
parents: 13647
diff changeset
   137
13352
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
   138
def update(repo, parents, node):
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
   139
    marks = repo._bookmarks
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
   140
    update = False
13416
5431b3f3e52e bookmarks: make track.current=True default behaviour and remove option (BC)
David Soria Parra <dsp@php.net>
parents: 13381
diff changeset
   141
    mark = repo._bookmarkcurrent
5431b3f3e52e bookmarks: make track.current=True default behaviour and remove option (BC)
David Soria Parra <dsp@php.net>
parents: 13381
diff changeset
   142
    if mark and marks[mark] in parents:
13478
c631ac076375 bookmarks: restrict moving a bookmark to its descendants (issue1502)
David Soria Parra <dsp@php.net>
parents: 13425
diff changeset
   143
        old = repo[marks[mark]]
c631ac076375 bookmarks: restrict moving a bookmark to its descendants (issue1502)
David Soria Parra <dsp@php.net>
parents: 13425
diff changeset
   144
        new = repo[node]
c631ac076375 bookmarks: restrict moving a bookmark to its descendants (issue1502)
David Soria Parra <dsp@php.net>
parents: 13425
diff changeset
   145
        if new in old.descendants():
c631ac076375 bookmarks: restrict moving a bookmark to its descendants (issue1502)
David Soria Parra <dsp@php.net>
parents: 13425
diff changeset
   146
            marks[mark] = new.node()
c631ac076375 bookmarks: restrict moving a bookmark to its descendants (issue1502)
David Soria Parra <dsp@php.net>
parents: 13425
diff changeset
   147
            update = True
13352
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
   148
    if update:
15237
7196ed7a1505 bookmarks: delegate writing to the repo just like reading
Augie Fackler <durin42@gmail.com>
parents: 15057
diff changeset
   149
        repo._writebookmarks(marks)
15621
013688350c7d bookmarks: update and updatecurrentbookmark return status
Kevin Bullock <kbullock@ringworld.org>
parents: 15614
diff changeset
   150
    return update
13353
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   151
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   152
def listbookmarks(repo):
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   153
    # We may try to list bookmarks on a repo type that does not
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   154
    # support it (e.g., statichttprepository).
14946
28762bf809d8 bookmarks: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14848
diff changeset
   155
    marks = getattr(repo, '_bookmarks', {})
13353
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   156
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   157
    d = {}
14946
28762bf809d8 bookmarks: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14848
diff changeset
   158
    for k, v in marks.iteritems():
15613
2fad18f15409 bookmarks: shadow divergent bookmarks of foo with foo@n
Matt Mackall <mpm@selenic.com>
parents: 15237
diff changeset
   159
        # don't expose local divergent bookmarks
2fad18f15409 bookmarks: shadow divergent bookmarks of foo with foo@n
Matt Mackall <mpm@selenic.com>
parents: 15237
diff changeset
   160
        if '@' not in k and not k.endswith('@'):
2fad18f15409 bookmarks: shadow divergent bookmarks of foo with foo@n
Matt Mackall <mpm@selenic.com>
parents: 15237
diff changeset
   161
            d[k] = hex(v)
13353
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   162
    return d
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   163
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   164
def pushbookmark(repo, key, old, new):
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   165
    w = repo.wlock()
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   166
    try:
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   167
        marks = repo._bookmarks
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   168
        if hex(marks.get(key, '')) != old:
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   169
            return False
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   170
        if new == '':
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   171
            del marks[key]
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   172
        else:
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   173
            if new not in repo:
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   174
                return False
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   175
            marks[key] = repo[new].node()
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   176
        write(repo)
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   177
        return True
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   178
    finally:
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 13352
diff changeset
   179
        w.release()
13354
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   180
15614
260a6449d83a bookmarks: mark divergent bookmarks with book@pathalias when source in [paths]
Matt Mackall <mpm@selenic.com>
parents: 15613
diff changeset
   181
def updatefromremote(ui, repo, remote, path):
13646
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   182
    ui.debug("checking for updated bookmarks\n")
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   183
    rb = remote.listkeys('bookmarks')
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   184
    changed = False
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   185
    for k in rb.keys():
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   186
        if k in repo._bookmarks:
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   187
            nr, nl = rb[k], repo._bookmarks[k]
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   188
            if nr in repo:
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   189
                cr = repo[nr]
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   190
                cl = repo[nl]
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   191
                if cl.rev() >= cr.rev():
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   192
                    continue
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   193
                if cr in cl.descendants():
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   194
                    repo._bookmarks[k] = cr.node()
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   195
                    changed = True
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   196
                    ui.status(_("updating bookmark %s\n") % k)
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   197
                else:
15614
260a6449d83a bookmarks: mark divergent bookmarks with book@pathalias when source in [paths]
Matt Mackall <mpm@selenic.com>
parents: 15613
diff changeset
   198
                    # find a unique @ suffix
15613
2fad18f15409 bookmarks: shadow divergent bookmarks of foo with foo@n
Matt Mackall <mpm@selenic.com>
parents: 15237
diff changeset
   199
                    for x in range(1, 100):
2fad18f15409 bookmarks: shadow divergent bookmarks of foo with foo@n
Matt Mackall <mpm@selenic.com>
parents: 15237
diff changeset
   200
                        n = '%s@%d' % (k, x)
2fad18f15409 bookmarks: shadow divergent bookmarks of foo with foo@n
Matt Mackall <mpm@selenic.com>
parents: 15237
diff changeset
   201
                        if n not in repo._bookmarks:
2fad18f15409 bookmarks: shadow divergent bookmarks of foo with foo@n
Matt Mackall <mpm@selenic.com>
parents: 15237
diff changeset
   202
                            break
15614
260a6449d83a bookmarks: mark divergent bookmarks with book@pathalias when source in [paths]
Matt Mackall <mpm@selenic.com>
parents: 15613
diff changeset
   203
                    # try to use an @pathalias suffix
260a6449d83a bookmarks: mark divergent bookmarks with book@pathalias when source in [paths]
Matt Mackall <mpm@selenic.com>
parents: 15613
diff changeset
   204
                    # if an @pathalias already exists, we overwrite (update) it
260a6449d83a bookmarks: mark divergent bookmarks with book@pathalias when source in [paths]
Matt Mackall <mpm@selenic.com>
parents: 15613
diff changeset
   205
                    for p, u in ui.configitems("paths"):
260a6449d83a bookmarks: mark divergent bookmarks with book@pathalias when source in [paths]
Matt Mackall <mpm@selenic.com>
parents: 15613
diff changeset
   206
                        if path == u:
260a6449d83a bookmarks: mark divergent bookmarks with book@pathalias when source in [paths]
Matt Mackall <mpm@selenic.com>
parents: 15613
diff changeset
   207
                            n = '%s@%s' % (k, p)
260a6449d83a bookmarks: mark divergent bookmarks with book@pathalias when source in [paths]
Matt Mackall <mpm@selenic.com>
parents: 15613
diff changeset
   208
15613
2fad18f15409 bookmarks: shadow divergent bookmarks of foo with foo@n
Matt Mackall <mpm@selenic.com>
parents: 15237
diff changeset
   209
                    repo._bookmarks[n] = cr.node()
2fad18f15409 bookmarks: shadow divergent bookmarks of foo with foo@n
Matt Mackall <mpm@selenic.com>
parents: 15237
diff changeset
   210
                    changed = True
2fad18f15409 bookmarks: shadow divergent bookmarks of foo with foo@n
Matt Mackall <mpm@selenic.com>
parents: 15237
diff changeset
   211
                    ui.warn(_("divergent bookmark %s stored as %s\n") % (k, n))
2fad18f15409 bookmarks: shadow divergent bookmarks of foo with foo@n
Matt Mackall <mpm@selenic.com>
parents: 15237
diff changeset
   212
13646
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   213
    if changed:
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   214
        write(repo)
31eac42d9123 bookmarks: separate bookmarks update code from localrepo's pull.
David Soria Parra <dsp@php.net>
parents: 13627
diff changeset
   215
13354
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   216
def diff(ui, repo, remote):
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   217
    ui.status(_("searching for changed bookmarks\n"))
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   218
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   219
    lmarks = repo.listkeys('bookmarks')
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   220
    rmarks = remote.listkeys('bookmarks')
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   221
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   222
    diff = sorted(set(rmarks) - set(lmarks))
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   223
    for k in diff:
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   224
        ui.write("   %-25s %s\n" % (k, rmarks[k][:12]))
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   225
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   226
    if len(diff) <= 0:
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   227
        ui.status(_("no changed bookmarks found\n"))
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   228
        return 1
4e1ba6ead69c bookmarks: move diff to core
Matt Mackall <mpm@selenic.com>
parents: 13353
diff changeset
   229
    return 0