mercurial/subrepo.py
author Matt Mackall <mpm@selenic.com>
Mon, 15 Jun 2009 02:45:38 -0500
changeset 8813 db3c1ab0e632
parent 8812 859f841937d0
child 8814 ab668c92a036
permissions -rw-r--r--
commit: recurse into subrepositories
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
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
     9
import config, util, node, error
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    10
localrepo = None
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    11
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    12
nullstate = ('', '')
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
def state(ctx):
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
    p = config.config()
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    16
    def read(f, sections=None, remap=None):
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
        if f in ctx:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
            try:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
                p.parse(f, ctx[f].data(), sections, remap)
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
            except IOError, err:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
                if err.errno != errno.ENOENT:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
                    raise
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
    read('.hgsub')
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
    rev = {}
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
    if '.hgsubstate' in ctx:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    27
        try:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    28
            for l in ctx['.hgsubstate'].data().splitlines():
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
                revision, path = l.split()
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
                rev[path] = revision
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    31
        except IOError, err:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
            if err.errno != errno.ENOENT:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    33
                raise
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
    state = {}
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
    for path, src in p[''].items():
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
        state[path] = (src, rev.get(path, ''))
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    39
    return state
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    40
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    41
def writestate(repo, state):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    42
    repo.wwrite('.hgsubstate',
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    43
                ''.join(['%s %s\n' % (state[s][1], s)
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    44
                         for s in sorted(state)]), '')
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    45
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    46
def subrepo(ctx, path):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    47
    # subrepo inherently violates our import layering rules
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    48
    # 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
    49
    # so we manually delay the circular imports to not break
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    50
    # scripts that don't use our demand-loading
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    51
    global localrepo
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    52
    import localrepo as l
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    53
    localrepo = l
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    54
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    55
    state = ctx.substate.get(path, nullstate)
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    56
    if state[0].startswith('['): # future expansion
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    57
        raise error.Abort('unknown subrepo source %s' % state[0])
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    58
    return hgsubrepo(ctx, path, state)
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    59
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    60
class hgsubrepo(object):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    61
    def __init__(self, ctx, path, state):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    62
        self._parent = ctx
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    63
        self._path = path
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    64
        self._state = state
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    65
        r = ctx._repo
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    66
        root = r.wjoin(path)
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    67
        self._repo = localrepo.localrepository(r.ui, root)
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    68
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    69
    def dirty(self):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    70
        r = self._state[1]
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    71
        if r == '':
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    72
            return True
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    73
        w = self._repo[None]
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    74
        if w.p1() != self._repo[r]: # version checked out changed
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    75
            return True
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    76
        return w.dirty() # working directory changed
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    77
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    78
    def commit(self, text, user, date):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    79
        n = self._repo.commit(text, user, date)
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    80
        if not n:
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    81
            return self._repo['.'].hex() # different version checked out
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    82
        return node.hex(n)