mercurial/subrepo.py
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Fri, 04 Sep 2009 10:47:55 +0200
changeset 9420 d0db168136dc
parent 9219 3f650f6aa130
child 9508 e2fd9b62349b
permissions -rw-r--r--
manifest/revlog: do not let the revlog cache mutable objects If a buffer of an mutable object is passed to revlog.addrevision(), the revlog will happily store it in its cache. Later when the revlog reuses the cached entry, if the manifest modified the object in-between, all kind of bugs appears. We fix it by: - passing immutable objects to addrevision() if they are already available - only storing the text in the cache if it's of str type Then we can remove the conversion of the cache entry to str() during retrieval. That was probably just there hiding the bug for the common cases but not really fixing it.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# subrepo.py - sub-repository handling for Mercurial
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# GNU General Public License version 2, incorporated herein by reference.
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
     8
import errno, os
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
     9
from i18n import _
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    10
import config, util, node, error
9092
9aebeea7ac00 subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents: 9049
diff changeset
    11
hg = None
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    12
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    13
nullstate = ('', '')
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
def state(ctx):
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    16
    p = config.config()
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
    def read(f, sections=None, remap=None):
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
        if f in ctx:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
            try:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
                p.parse(f, ctx[f].data(), sections, remap)
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
            except IOError, err:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
                if err.errno != errno.ENOENT:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
                    raise
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
    read('.hgsub')
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
    rev = {}
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    27
    if '.hgsubstate' in ctx:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    28
        try:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
            for l in ctx['.hgsubstate'].data().splitlines():
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
                revision, path = l.split()
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    31
                rev[path] = revision
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
        except IOError, err:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    33
            if err.errno != errno.ENOENT:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
                raise
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
    state = {}
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
    for path, src in p[''].items():
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
        state[path] = (src, rev.get(path, ''))
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    39
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    40
    return state
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    41
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    42
def writestate(repo, state):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    43
    repo.wwrite('.hgsubstate',
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    44
                ''.join(['%s %s\n' % (state[s][1], s)
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    45
                         for s in sorted(state)]), '')
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    46
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    47
def submerge(repo, wctx, mctx, actx):
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    48
    if mctx == actx: # backwards?
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    49
        actx = wctx.p1()
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    50
    s1 = wctx.substate
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    51
    s2 = mctx.substate
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    52
    sa = actx.substate
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    53
    sm = {}
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    54
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    55
    for s, l in s1.items():
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    56
        a = sa.get(s, nullstate)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    57
        if s in s2:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    58
            r = s2[s]
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    59
            if l == r or r == a: # no change or local is newer
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    60
                sm[s] = l
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    61
                continue
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    62
            elif l == a: # other side changed
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    63
                wctx.sub(s).get(r)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    64
                sm[s] = r
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    65
            elif l[0] != r[0]: # sources differ
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8997
diff changeset
    66
                if repo.ui.promptchoice(
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    67
                    _(' subrepository sources for %s differ\n'
8908
105343f9f744 Fix warning: Seen unexpected token "%"
Dongsheng Song <dongsheng.song@gmail.com>
parents: 8815
diff changeset
    68
                      'use (l)ocal source (%s) or (r)emote source (%s)?')
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    69
                      % (s, l[0], r[0]),
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8997
diff changeset
    70
                      (_('&Local'), _('&Remote')), 0):
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    71
                    wctx.sub(s).get(r)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    72
                    sm[s] = r
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    73
            elif l[1] == a[1]: # local side is unchanged
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    74
                wctx.sub(s).get(r)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    75
                sm[s] = r
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    76
            else:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    77
                wctx.sub(s).merge(r)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    78
                sm[s] = l
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    79
        elif l == a: # remote removed, local unchanged
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    80
            wctx.sub(s).remove()
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    81
        else:
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8997
diff changeset
    82
            if repo.ui.promptchoice(
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    83
                _(' local changed subrepository %s which remote removed\n'
8908
105343f9f744 Fix warning: Seen unexpected token "%"
Dongsheng Song <dongsheng.song@gmail.com>
parents: 8815
diff changeset
    84
                  'use (c)hanged version or (d)elete?') % s,
9049
38b5d5e0efab filemerge, subrepo: correct indention
Martin Geisler <mg@lazybytes.net>
parents: 9048
diff changeset
    85
                (_('&Changed'), _('&Delete')), 0):
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    86
                wctx.sub(s).remove()
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    87
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    88
    for s, r in s2.items():
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    89
        if s in s1:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    90
            continue
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    91
        elif s not in sa:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    92
            wctx.sub(s).get(r)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    93
            sm[s] = r
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    94
        elif r != sa[s]:
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8997
diff changeset
    95
            if repo.ui.promptchoice(
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    96
                _(' remote changed subrepository %s which local removed\n'
8908
105343f9f744 Fix warning: Seen unexpected token "%"
Dongsheng Song <dongsheng.song@gmail.com>
parents: 8815
diff changeset
    97
                  'use (c)hanged version or (d)elete?') % s,
9049
38b5d5e0efab filemerge, subrepo: correct indention
Martin Geisler <mg@lazybytes.net>
parents: 9048
diff changeset
    98
                (_('&Changed'), _('&Delete')), 0) == 0:
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    99
                wctx.sub(s).get(r)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   100
                sm[s] = r
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   101
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   102
    # record merged .hgsubstate
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   103
    writestate(repo, sm)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   104
8815
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   105
def _abssource(repo, push=False):
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   106
    if hasattr(repo, '_subparent'):
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   107
        source = repo._subsource
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   108
        if source.startswith('/') or '://' in source:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   109
            return source
9186
f783bb979fb3 subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents: 8997
diff changeset
   110
        parent = _abssource(repo._subparent)
f783bb979fb3 subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents: 8997
diff changeset
   111
        if '://' in parent:
f783bb979fb3 subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents: 8997
diff changeset
   112
            if parent[-1] == '/':
f783bb979fb3 subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents: 8997
diff changeset
   113
                parent = parent[:-1]
f783bb979fb3 subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents: 8997
diff changeset
   114
            return parent + '/' + source
f783bb979fb3 subrepo: use '/' for joining non-local paths
Matt Mackall <mpm@selenic.com>
parents: 8997
diff changeset
   115
        return os.path.join(parent, repo._subsource)
8815
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   116
    if push and repo.ui.config('paths', 'default-push'):
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   117
        return repo.ui.config('paths', 'default-push', repo.root)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   118
    return repo.ui.config('paths', 'default', repo.root)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   119
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   120
def subrepo(ctx, path):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   121
    # subrepo inherently violates our import layering rules
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   122
    # because it wants to make repo objects from deep inside the stack
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   123
    # so we manually delay the circular imports to not break
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   124
    # scripts that don't use our demand-loading
9092
9aebeea7ac00 subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents: 9049
diff changeset
   125
    global hg
9aebeea7ac00 subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents: 9049
diff changeset
   126
    import hg as h
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   127
    hg = h
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   128
8997
70f5d3be5917 subrepo: audit subrepo paths
Matt Mackall <mpm@selenic.com>
parents: 8908
diff changeset
   129
    util.path_auditor(ctx._repo.root)(path)
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   130
    state = ctx.substate.get(path, nullstate)
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   131
    if state[0].startswith('['): # future expansion
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   132
        raise error.Abort('unknown subrepo source %s' % state[0])
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   133
    return hgsubrepo(ctx, path, state)
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   134
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   135
class hgsubrepo(object):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   136
    def __init__(self, ctx, path, state):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   137
        self._path = path
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   138
        self._state = state
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   139
        r = ctx._repo
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   140
        root = r.wjoin(path)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   141
        if os.path.exists(os.path.join(root, '.hg')):
9092
9aebeea7ac00 subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents: 9049
diff changeset
   142
            self._repo = hg.repository(r.ui, root)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   143
        else:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   144
            util.makedirs(root)
9092
9aebeea7ac00 subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents: 9049
diff changeset
   145
            self._repo = hg.repository(r.ui, root, create=True)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   146
        self._repo._subparent = r
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   147
        self._repo._subsource = state[0]
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   148
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   149
    def dirty(self):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   150
        r = self._state[1]
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   151
        if r == '':
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   152
            return True
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   153
        w = self._repo[None]
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   154
        if w.p1() != self._repo[r]: # version checked out changed
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   155
            return True
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   156
        return w.dirty() # working directory changed
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   157
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   158
    def commit(self, text, user, date):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   159
        n = self._repo.commit(text, user, date)
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   160
        if not n:
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   161
            return self._repo['.'].hex() # different version checked out
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   162
        return node.hex(n)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   163
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   164
    def remove(self):
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   165
        # we can't fully delete the repository as it may contain
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   166
        # local-only history
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   167
        self._repo.ui.note(_('removing subrepo %s\n') % self._path)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   168
        hg.clean(self._repo, node.nullid, False)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   169
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   170
    def get(self, state):
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   171
        source, revision = state
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   172
        try:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   173
            self._repo.lookup(revision)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   174
        except error.RepoError:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   175
            self._repo._subsource = source
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   176
            self._repo.ui.status(_('pulling subrepo %s\n') % self._path)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   177
            srcurl = _abssource(self._repo)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   178
            other = hg.repository(self._repo.ui, srcurl)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   179
            self._repo.pull(other)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   180
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   181
        hg.clean(self._repo, revision, False)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   182
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   183
    def merge(self, state):
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   184
        hg.merge(self._repo, state[1], remind=False)
8815
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   185
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   186
    def push(self, force):
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   187
        # push subrepos depth-first for coherent ordering
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   188
        c = self._repo['']
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   189
        subs = c.substate # only repos that are committed
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   190
        for s in sorted(subs):
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   191
            c.sub(s).push(force)
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   192
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   193
        self._repo.ui.status(_('pushing subrepo %s\n') % self._path)
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   194
        dsturl = _abssource(self._repo, True)
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   195
        other = hg.repository(self._repo.ui, dsturl)
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   196
        self._repo.push(other, force)
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   197