mercurial/subrepo.py
author Martin von Zweigbergk <martinvonz@google.com>
Fri, 05 Dec 2014 16:51:37 -0800
changeset 23492 da733837cdd0
parent 23411 2d86f4e38c08
child 23521 f5de2a82b77e
permissions -rw-r--r--
largefiles: don't use 'r' action for normal file that doesn't exist When merging and the remote has turned a largefile into a normal file and the user chooses to keep the local largefile, we use the 'r' action for the remote normal file. This is wrong, since that file does not exist in the parent of the working copy. Use 'k', which does nothing but debug logging, instead.
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
#
10324
55d134ef8ab7 subrepo: correct copyright
David Soria Parra <dsp@php.net>
parents: 10299
diff changeset
     3
# Copyright 2009-2010 Matt Mackall <mpm@selenic.com>
8812
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
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10251
diff changeset
     6
# GNU General Public License version 2 or any later version.
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
19788
c26690fe5f08 subrepo: move import of xml.minidom.dom to its own line for check-code
Augie Fackler <raf@durin42.com>
parents: 19637
diff changeset
     8
import errno, os, re, shutil, posixpath, sys
c26690fe5f08 subrepo: move import of xml.minidom.dom to its own line for check-code
Augie Fackler <raf@durin42.com>
parents: 19637
diff changeset
     9
import xml.dom.minidom
13027
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
    10
import stat, subprocess, tarfile
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    11
from i18n import _
22914
c95db3208a33 status: update various other methods to return new class
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22695
diff changeset
    12
import config, util, node, error, cmdutil, scmutil, match as matchmod
20176
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
    13
import phases
20033
f962870712da pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents: 19811
diff changeset
    14
import pathutil
22619
f6cf96804d27 push: `exchange.push` instead of `localrepo.push`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22590
diff changeset
    15
import exchange
9092
9aebeea7ac00 subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents: 9049
diff changeset
    16
hg = None
14050
9e8a9d45945c subrepo: handle svn tracked/unknown directory collisions
Patrick Mezard <pmezard@gmail.com>
parents: 14025
diff changeset
    17
propertycache = util.propertycache
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    18
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
    19
nullstate = ('', '', 'empty')
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
18940
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
    21
def _expandedabspath(path):
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
    22
    '''
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
    23
    get a path or url and if it is a path expand it and return an absolute path
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
    24
    '''
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
    25
    expandedpath = util.urllocalpath(util.expandpath(path))
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
    26
    u = util.url(expandedpath)
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
    27
    if not u.scheme:
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
    28
        path = util.normpath(os.path.abspath(u.path))
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
    29
    return path
18936
1fa4edb8456e subrepo: introduce storeclean helper functions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18851
diff changeset
    30
1fa4edb8456e subrepo: introduce storeclean helper functions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18851
diff changeset
    31
def _getstorehashcachename(remotepath):
1fa4edb8456e subrepo: introduce storeclean helper functions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18851
diff changeset
    32
    '''get a unique filename for the store hash cache of a remote repository'''
18940
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
    33
    return util.sha1(_expandedabspath(remotepath)).hexdigest()[0:12]
18936
1fa4edb8456e subrepo: introduce storeclean helper functions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18851
diff changeset
    34
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    35
class SubrepoAbort(error.Abort):
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    36
    """Exception class used to avoid handling a subrepo error more than once"""
18263
9aa6bee6e9f9 subrepo: add subrepo property to SubrepoAbort exceptions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18109
diff changeset
    37
    def __init__(self, *args, **kw):
18296
a74101cd6965 subrepo: fix python2.4 compatibility after 9aa6bee6e9f9
Brendan Cully <brendan@kublai.com>
parents: 18263
diff changeset
    38
        error.Abort.__init__(self, *args, **kw)
18263
9aa6bee6e9f9 subrepo: add subrepo property to SubrepoAbort exceptions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18109
diff changeset
    39
        self.subrepo = kw.get('subrepo')
18964
ca480d710fe6 subrepo: chain the original exception to SubrepoAbort
Matt Harbison <matt_harbison@yahoo.com>
parents: 18943
diff changeset
    40
        self.cause = kw.get('cause')
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    41
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    42
def annotatesubrepoerror(func):
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    43
    def decoratedmethod(self, *args, **kargs):
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    44
        try:
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    45
            res = func(self, *args, **kargs)
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    46
        except SubrepoAbort, ex:
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    47
            # This exception has already been handled
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    48
            raise ex
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    49
        except error.Abort, ex:
18263
9aa6bee6e9f9 subrepo: add subrepo property to SubrepoAbort exceptions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18109
diff changeset
    50
            subrepo = subrelpath(self)
18297
7196f11c5c7d subrepo: make 'in subrepo' string easier to find by external tools
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18296
diff changeset
    51
            errormsg = str(ex) + ' ' + _('(in subrepo %s)') % subrepo
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    52
            # avoid handling this exception by raising a SubrepoAbort exception
18964
ca480d710fe6 subrepo: chain the original exception to SubrepoAbort
Matt Harbison <matt_harbison@yahoo.com>
parents: 18943
diff changeset
    53
            raise SubrepoAbort(errormsg, hint=ex.hint, subrepo=subrepo,
ca480d710fe6 subrepo: chain the original exception to SubrepoAbort
Matt Harbison <matt_harbison@yahoo.com>
parents: 18943
diff changeset
    54
                               cause=sys.exc_info())
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    55
        return res
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    56
    return decoratedmethod
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
    57
11775
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
    58
def state(ctx, ui):
11571
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
    59
    """return a state dict, mapping subrepo paths configured in .hgsub
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
    60
    to tuple: (source from .hgsub, revision from .hgsubstate, kind
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
    61
    (key in types dict))
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
    62
    """
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
    p = config.config()
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
    def read(f, sections=None, remap=None):
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
        if f in ctx:
13017
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    66
            try:
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    67
                data = ctx[f].data()
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    68
            except IOError, err:
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    69
                if err.errno != errno.ENOENT:
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    70
                    raise
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    71
                # handle missing subrepo spec files as removed
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    72
                ui.warn(_("warning: subrepo spec file %s not found\n") % f)
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    73
                return
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    74
            p.parse(f, data, sections, remap, read)
10174
65b6dc44cdbf subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents: 10069
diff changeset
    75
        else:
65b6dc44cdbf subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents: 10069
diff changeset
    76
            raise util.Abort(_("subrepo spec file %s not found") % f)
65b6dc44cdbf subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents: 10069
diff changeset
    77
65b6dc44cdbf subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents: 10069
diff changeset
    78
    if '.hgsub' in ctx:
65b6dc44cdbf subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents: 10069
diff changeset
    79
        read('.hgsub')
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
11775
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
    81
    for path, src in ui.configitems('subpaths'):
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
    82
        p.set('subpaths', path, src, ui.configsource('subpaths', path))
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
    83
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    84
    rev = {}
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
    if '.hgsubstate' in ctx:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    86
        try:
16596
95ca6c8b38da subrepo: do not traceback on .hgsubstate parsing errors
Patrick Mezard <patrick@mezard.eu>
parents: 16595
diff changeset
    87
            for i, l in enumerate(ctx['.hgsubstate'].data().splitlines()):
16595
2de6ac4ac17c subrepo: ignore blank lines in .hgsubstate (issue3424)
Patrick Mezard <patrick@mezard.eu>
parents: 16555
diff changeset
    88
                l = l.lstrip()
2de6ac4ac17c subrepo: ignore blank lines in .hgsubstate (issue3424)
Patrick Mezard <patrick@mezard.eu>
parents: 16555
diff changeset
    89
                if not l:
2de6ac4ac17c subrepo: ignore blank lines in .hgsubstate (issue3424)
Patrick Mezard <patrick@mezard.eu>
parents: 16555
diff changeset
    90
                    continue
16596
95ca6c8b38da subrepo: do not traceback on .hgsubstate parsing errors
Patrick Mezard <patrick@mezard.eu>
parents: 16595
diff changeset
    91
                try:
95ca6c8b38da subrepo: do not traceback on .hgsubstate parsing errors
Patrick Mezard <patrick@mezard.eu>
parents: 16595
diff changeset
    92
                    revision, path = l.split(" ", 1)
95ca6c8b38da subrepo: do not traceback on .hgsubstate parsing errors
Patrick Mezard <patrick@mezard.eu>
parents: 16595
diff changeset
    93
                except ValueError:
95ca6c8b38da subrepo: do not traceback on .hgsubstate parsing errors
Patrick Mezard <patrick@mezard.eu>
parents: 16595
diff changeset
    94
                    raise util.Abort(_("invalid subrepository revision "
95ca6c8b38da subrepo: do not traceback on .hgsubstate parsing errors
Patrick Mezard <patrick@mezard.eu>
parents: 16595
diff changeset
    95
                                       "specifier in .hgsubstate line %d")
95ca6c8b38da subrepo: do not traceback on .hgsubstate parsing errors
Patrick Mezard <patrick@mezard.eu>
parents: 16595
diff changeset
    96
                                     % (i + 1))
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    97
                rev[path] = revision
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    98
        except IOError, err:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    99
            if err.errno != errno.ENOENT:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   100
                raise
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   101
15149
eaec9cf91aea subrepo: refactor state function
Martin Geisler <mg@aragost.com>
parents: 15061
diff changeset
   102
    def remap(src):
11775
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
   103
        for pattern, repl in p.items('subpaths'):
11961
f3075ffa6b30 subrepos: handle backslashes in subpaths
Martin Geisler <mg@lazybytes.net>
parents: 11775
diff changeset
   104
            # Turn r'C:\foo\bar' into r'C:\\foo\\bar' since re.sub
f3075ffa6b30 subrepos: handle backslashes in subpaths
Martin Geisler <mg@lazybytes.net>
parents: 11775
diff changeset
   105
            # does a string decode.
f3075ffa6b30 subrepos: handle backslashes in subpaths
Martin Geisler <mg@lazybytes.net>
parents: 11775
diff changeset
   106
            repl = repl.encode('string-escape')
f3075ffa6b30 subrepos: handle backslashes in subpaths
Martin Geisler <mg@lazybytes.net>
parents: 11775
diff changeset
   107
            # However, we still want to allow back references to go
f3075ffa6b30 subrepos: handle backslashes in subpaths
Martin Geisler <mg@lazybytes.net>
parents: 11775
diff changeset
   108
            # through unharmed, so we turn r'\\1' into r'\1'. Again,
f3075ffa6b30 subrepos: handle backslashes in subpaths
Martin Geisler <mg@lazybytes.net>
parents: 11775
diff changeset
   109
            # extra escapes are needed because re.sub string decodes.
f3075ffa6b30 subrepos: handle backslashes in subpaths
Martin Geisler <mg@lazybytes.net>
parents: 11775
diff changeset
   110
            repl = re.sub(r'\\\\([0-9]+)', r'\\\1', repl)
11775
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
   111
            try:
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
   112
                src = re.sub(pattern, repl, src, 1)
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
   113
            except re.error, e:
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
   114
                raise util.Abort(_("bad subrepository pattern in %s: %s")
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
   115
                                 % (p.source('subpaths', pattern), e))
15149
eaec9cf91aea subrepo: refactor state function
Martin Geisler <mg@aragost.com>
parents: 15061
diff changeset
   116
        return src
11775
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
   117
15149
eaec9cf91aea subrepo: refactor state function
Martin Geisler <mg@aragost.com>
parents: 15061
diff changeset
   118
    state = {}
eaec9cf91aea subrepo: refactor state function
Martin Geisler <mg@aragost.com>
parents: 15061
diff changeset
   119
    for path, src in p[''].items():
eaec9cf91aea subrepo: refactor state function
Martin Geisler <mg@aragost.com>
parents: 15061
diff changeset
   120
        kind = 'hg'
eaec9cf91aea subrepo: refactor state function
Martin Geisler <mg@aragost.com>
parents: 15061
diff changeset
   121
        if src.startswith('['):
eaec9cf91aea subrepo: refactor state function
Martin Geisler <mg@aragost.com>
parents: 15061
diff changeset
   122
            if ']' not in src:
eaec9cf91aea subrepo: refactor state function
Martin Geisler <mg@aragost.com>
parents: 15061
diff changeset
   123
                raise util.Abort(_('missing ] in subrepo source'))
eaec9cf91aea subrepo: refactor state function
Martin Geisler <mg@aragost.com>
parents: 15061
diff changeset
   124
            kind, src = src.split(']', 1)
eaec9cf91aea subrepo: refactor state function
Martin Geisler <mg@aragost.com>
parents: 15061
diff changeset
   125
            kind = kind[1:]
15150
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   126
            src = src.lstrip() # strip any extra whitespace after ']'
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   127
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   128
        if not util.url(src).isabs():
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   129
            parent = _abssource(ctx._repo, abort=False)
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   130
            if parent:
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   131
                parent = util.url(parent)
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   132
                parent.path = posixpath.join(parent.path or '', src)
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   133
                parent.path = posixpath.normpath(parent.path)
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   134
                joined = str(parent)
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   135
                # Remap the full joined path and use it if it changes,
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   136
                # else remap the original source.
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   137
                remapped = remap(joined)
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   138
                if remapped == joined:
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   139
                    src = remap(src)
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   140
                else:
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   141
                    src = remapped
91dc8878f888 subrepo: try remapping subpaths using the "final" path
Martin Geisler <mg@aragost.com>
parents: 15149
diff changeset
   142
15149
eaec9cf91aea subrepo: refactor state function
Martin Geisler <mg@aragost.com>
parents: 15061
diff changeset
   143
        src = remap(src)
15723
1581da01d5c4 windows: use normalized path as path to subrepo
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15531
diff changeset
   144
        state[util.pconvert(path)] = (src.strip(), rev.get(path, ''), kind)
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   145
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   146
    return state
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   147
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   148
def writestate(repo, state):
11571
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
   149
    """rewrite .hgsubstate in (outer) repo with these subrepo states"""
14443
6fe6defdc924 subrepo: refactor writestate for clarity
Martin Geisler <mg@aragost.com>
parents: 14440
diff changeset
   150
    lines = ['%s %s\n' % (state[s][1], s) for s in sorted(state)]
6fe6defdc924 subrepo: refactor writestate for clarity
Martin Geisler <mg@aragost.com>
parents: 14440
diff changeset
   151
    repo.wwrite('.hgsubstate', ''.join(lines), '')
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   152
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 13287
diff changeset
   153
def submerge(repo, wctx, mctx, actx, overwrite):
11571
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
   154
    """delegated from merge.applyupdates: merging of .hgsubstate file
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
   155
    in working context, merging context and ancestor context"""
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   156
    if mctx == actx: # backwards?
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   157
        actx = wctx.p1()
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   158
    s1 = wctx.substate
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   159
    s2 = mctx.substate
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   160
    sa = actx.substate
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   161
    sm = {}
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   162
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   163
    repo.ui.debug("subrepo merge %s %s %s\n" % (wctx, mctx, actx))
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   164
9779
58a6f3f4d553 subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents: 9752
diff changeset
   165
    def debug(s, msg, r=""):
58a6f3f4d553 subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents: 9752
diff changeset
   166
        if r:
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
   167
            r = "%s:%s:%s" % r
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   168
        repo.ui.debug("  subrepo %s: %s %s\n" % (s, msg, r))
9779
58a6f3f4d553 subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents: 9752
diff changeset
   169
18364
6252b4f1c4b4 subrepos: process subrepos in sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 18297
diff changeset
   170
    for s, l in sorted(s1.iteritems()):
11470
34e33d50c26b subrepo: correctly handle update -C with modified subrepos (issue2022)
Matt Mackall <mpm@selenic.com>
parents: 11463
diff changeset
   171
        a = sa.get(s, nullstate)
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   172
        ld = l # local state with possible dirty flag for compares
11470
34e33d50c26b subrepo: correctly handle update -C with modified subrepos (issue2022)
Matt Mackall <mpm@selenic.com>
parents: 11463
diff changeset
   173
        if wctx.sub(s).dirty():
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   174
            ld = (l[0], l[1] + "+")
11470
34e33d50c26b subrepo: correctly handle update -C with modified subrepos (issue2022)
Matt Mackall <mpm@selenic.com>
parents: 11463
diff changeset
   175
        if wctx == actx: # overwrite
34e33d50c26b subrepo: correctly handle update -C with modified subrepos (issue2022)
Matt Mackall <mpm@selenic.com>
parents: 11463
diff changeset
   176
            a = ld
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   177
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   178
        if s in s2:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   179
            r = s2[s]
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   180
            if ld == r or r == a: # no change or local is newer
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   181
                sm[s] = l
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   182
                continue
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   183
            elif ld == a: # other side changed
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   184
                debug(s, "other changed, get", r)
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 13287
diff changeset
   185
                wctx.sub(s).get(r, overwrite)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   186
                sm[s] = r
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   187
            elif ld[0] != r[0]: # sources differ
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8997
diff changeset
   188
                if repo.ui.promptchoice(
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   189
                    _(' subrepository sources for %s differ\n'
19226
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19156
diff changeset
   190
                      'use (l)ocal source (%s) or (r)emote source (%s)?'
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19156
diff changeset
   191
                      '$$ &Local $$ &Remote') % (s, l[0], r[0]), 0):
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   192
                    debug(s, "prompt changed, get", r)
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 13287
diff changeset
   193
                    wctx.sub(s).get(r, overwrite)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   194
                    sm[s] = r
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   195
            elif ld[1] == a[1]: # local side is unchanged
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   196
                debug(s, "other side changed, get", r)
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 13287
diff changeset
   197
                wctx.sub(s).get(r, overwrite)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   198
                sm[s] = r
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   199
            else:
19811
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   200
                debug(s, "both sides changed")
21401
2c364f7801c8 subrepo: use subrepo shortid method to generate subrepo diverged promptchoice
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21400
diff changeset
   201
                srepo = wctx.sub(s)
19811
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   202
                option = repo.ui.promptchoice(
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   203
                    _(' subrepository %s diverged (local revision: %s, '
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   204
                      'remote revision: %s)\n'
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   205
                      '(M)erge, keep (l)ocal or keep (r)emote?'
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   206
                      '$$ &Merge $$ &Local $$ &Remote')
21401
2c364f7801c8 subrepo: use subrepo shortid method to generate subrepo diverged promptchoice
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21400
diff changeset
   207
                    % (s, srepo.shortid(l[1]), srepo.shortid(r[1])), 0)
19811
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   208
                if option == 0:
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   209
                    wctx.sub(s).merge(r)
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   210
                    sm[s] = l
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   211
                    debug(s, "merge with", r)
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   212
                elif option == 1:
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   213
                    sm[s] = l
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   214
                    debug(s, "keep local subrepo revision", l)
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   215
                else:
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   216
                    wctx.sub(s).get(r, overwrite)
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   217
                    sm[s] = r
5e10d41e7b9c merge: let the user choose to merge, keep local or keep remote subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19788
diff changeset
   218
                    debug(s, "get remote subrepo revision", r)
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   219
        elif ld == a: # remote removed, local unchanged
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   220
            debug(s, "remote removed, remove")
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   221
            wctx.sub(s).remove()
14417
25137d99a5ed subrepo: handle local added subrepo case correctly
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   222
        elif a == nullstate: # not present in remote or ancestor
25137d99a5ed subrepo: handle local added subrepo case correctly
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   223
            debug(s, "local added, keep")
25137d99a5ed subrepo: handle local added subrepo case correctly
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   224
            sm[s] = l
25137d99a5ed subrepo: handle local added subrepo case correctly
Matt Mackall <mpm@selenic.com>
parents: 14316
diff changeset
   225
            continue
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   226
        else:
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8997
diff changeset
   227
            if repo.ui.promptchoice(
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   228
                _(' local changed subrepository %s which remote removed\n'
19226
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19156
diff changeset
   229
                  'use (c)hanged version or (d)elete?'
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19156
diff changeset
   230
                  '$$ &Changed $$ &Delete') % s, 0):
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   231
                debug(s, "prompt remove")
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   232
                wctx.sub(s).remove()
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   233
13857
ba1f98f877ec subrepo: process merge substate in sorted order in submerge()
Adrian Buehlmann <adrian@cadifra.com>
parents: 13771
diff changeset
   234
    for s, r in sorted(s2.items()):
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   235
        if s in s1:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   236
            continue
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   237
        elif s not in sa:
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   238
            debug(s, "remote added, get", r)
10175
fc32b2fc468e subrepo: load from a context where the subrepo exists
Augie Fackler <durin42@gmail.com>
parents: 10174
diff changeset
   239
            mctx.sub(s).get(r)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   240
            sm[s] = r
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   241
        elif r != sa[s]:
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8997
diff changeset
   242
            if repo.ui.promptchoice(
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   243
                _(' remote changed subrepository %s which local removed\n'
19226
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19156
diff changeset
   244
                  'use (c)hanged version or (d)elete?'
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19156
diff changeset
   245
                  '$$ &Changed $$ &Delete') % s, 0) == 0:
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   246
                debug(s, "prompt recreate", r)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   247
                wctx.sub(s).get(r)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   248
                sm[s] = r
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   249
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   250
    # record merged .hgsubstate
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   251
    writestate(repo, sm)
19637
cc338115d3b2 subrepo: make submerge() return the merged substate
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 19226
diff changeset
   252
    return sm
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   253
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   254
def _updateprompt(ui, sub, dirty, local, remote):
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   255
    if dirty:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   256
        msg = (_(' subrepository sources for %s differ\n'
22590
d4c972b97fee subrepo: remove superfluous newline from subrepo prompt
Mads Kiilerich <madski@unity3d.com>
parents: 21891
diff changeset
   257
                 'use (l)ocal source (%s) or (r)emote source (%s)?'
19226
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19156
diff changeset
   258
                 '$$ &Local $$ &Remote')
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   259
               % (subrelpath(sub), local, remote))
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   260
    else:
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16596
diff changeset
   261
        msg = (_(' subrepository sources for %s differ (in checked out '
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16596
diff changeset
   262
                 'version)\n'
22590
d4c972b97fee subrepo: remove superfluous newline from subrepo prompt
Mads Kiilerich <madski@unity3d.com>
parents: 21891
diff changeset
   263
                 'use (l)ocal source (%s) or (r)emote source (%s)?'
19226
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19156
diff changeset
   264
                 '$$ &Local $$ &Remote')
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   265
               % (subrelpath(sub), local, remote))
19226
c58b6ab4c26f ui: merge prompt text components into a singe string
Matt Mackall <mpm@selenic.com>
parents: 19156
diff changeset
   266
    return ui.promptchoice(msg, 0)
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   267
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   268
def reporelpath(repo):
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   269
    """return path to this (sub)repo as seen from outermost repo"""
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   270
    parent = repo
14963
c035f1c53e39 subrepo: use safehasattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14898
diff changeset
   271
    while util.safehasattr(parent, '_subparent'):
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   272
        parent = parent._subparent
21568
8dd17b19e722 subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21567
diff changeset
   273
    return repo.root[len(pathutil.normasprefix(parent.root)):]
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   274
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   275
def subrelpath(sub):
11571
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
   276
    """return path to this subrepo as seen from outermost repo"""
14963
c035f1c53e39 subrepo: use safehasattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14898
diff changeset
   277
    if util.safehasattr(sub, '_relpath'):
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
   278
        return sub._relpath
14963
c035f1c53e39 subrepo: use safehasattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14898
diff changeset
   279
    if not util.safehasattr(sub, '_repo'):
11112
4a9bee613737 subrepo: print paths relative to upper repo root for push/pull/commit
Edouard Gomez <ed.gomez@free.fr>
parents: 11111
diff changeset
   280
        return sub._path
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   281
    return reporelpath(sub._repo)
11112
4a9bee613737 subrepo: print paths relative to upper repo root for push/pull/commit
Edouard Gomez <ed.gomez@free.fr>
parents: 11111
diff changeset
   282
12753
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   283
def _abssource(repo, push=False, abort=True):
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   284
    """return pull/push path of repo - either based on parent repo .hgsub info
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   285
    or on the top repo config. Abort or return None if no source found."""
14963
c035f1c53e39 subrepo: use safehasattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14898
diff changeset
   286
    if util.safehasattr(repo, '_subparent'):
14076
924c82157d46 url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents: 14052
diff changeset
   287
        source = util.url(repo._subsource)
14766
4f56b7530eab subrepos: be smarter about what's an absolute path (issue2808)
Matt Mackall <mpm@selenic.com>
parents: 14664
diff changeset
   288
        if source.isabs():
4f56b7530eab subrepos: be smarter about what's an absolute path (issue2808)
Matt Mackall <mpm@selenic.com>
parents: 14664
diff changeset
   289
            return str(source)
13771
ce6227306c9a subrepos: use url.url when normalizing repo paths
Brodie Rao <brodie@bitheap.org>
parents: 13753
diff changeset
   290
        source.path = posixpath.normpath(source.path)
12753
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   291
        parent = _abssource(repo._subparent, push, abort=False)
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   292
        if parent:
15498
ac5a340b26de subrepo: use correct paths for subrepos with ..-relative paths on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 15287
diff changeset
   293
            parent = util.url(util.pconvert(parent))
15055
d629f1e89021 subrepo: fix cloning of repos from urls without slash after host (issue2970)
Mads Kiilerich <mads@kiilerich.com>
parents: 14994
diff changeset
   294
            parent.path = posixpath.join(parent.path or '', source.path)
13771
ce6227306c9a subrepos: use url.url when normalizing repo paths
Brodie Rao <brodie@bitheap.org>
parents: 13753
diff changeset
   295
            parent.path = posixpath.normpath(parent.path)
ce6227306c9a subrepos: use url.url when normalizing repo paths
Brodie Rao <brodie@bitheap.org>
parents: 13753
diff changeset
   296
            return str(parent)
12753
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   297
    else: # recursion reached top repo
14963
c035f1c53e39 subrepo: use safehasattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14898
diff changeset
   298
        if util.safehasattr(repo, '_subtoppath'):
12852
5dbff89cf107 subrepo: propagate non-default pull/push path to relative subrepos (issue1852)
Mads Kiilerich <mads@kiilerich.com>
parents: 12799
diff changeset
   299
            return repo._subtoppath
12753
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   300
        if push and repo.ui.config('paths', 'default-push'):
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   301
            return repo.ui.config('paths', 'default-push')
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   302
        if repo.ui.config('paths', 'default'):
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   303
            return repo.ui.config('paths', 'default')
18510
f254ab6207ae subrepo: use sharepath if available when locating the source repo
Matt Harbison <matt_harbison@yahoo.com>
parents: 18364
diff changeset
   304
        if repo.sharedpath != repo.path:
f254ab6207ae subrepo: use sharepath if available when locating the source repo
Matt Harbison <matt_harbison@yahoo.com>
parents: 18364
diff changeset
   305
            # chop off the .hg component to get the default path form
f254ab6207ae subrepo: use sharepath if available when locating the source repo
Matt Harbison <matt_harbison@yahoo.com>
parents: 18364
diff changeset
   306
            return os.path.dirname(repo.sharedpath)
12753
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   307
    if abort:
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   308
        raise util.Abort(_("default path for subrepository not found"))
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   309
21567
5900bc09e684 subrepo: avoid sanitizing ".hg/hgrc" in meta data area for non-hg subrepos
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21566
diff changeset
   310
def _sanitize(ui, path, ignore):
21564
2e91d4964ecd subrepo: make "_sanitize()" work
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21041
diff changeset
   311
    for dirname, dirs, names in os.walk(path):
21567
5900bc09e684 subrepo: avoid sanitizing ".hg/hgrc" in meta data area for non-hg subrepos
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21566
diff changeset
   312
        for i, d in enumerate(dirs):
5900bc09e684 subrepo: avoid sanitizing ".hg/hgrc" in meta data area for non-hg subrepos
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21566
diff changeset
   313
            if d.lower() == ignore:
5900bc09e684 subrepo: avoid sanitizing ".hg/hgrc" in meta data area for non-hg subrepos
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21566
diff changeset
   314
                del dirs[i]
5900bc09e684 subrepo: avoid sanitizing ".hg/hgrc" in meta data area for non-hg subrepos
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21566
diff changeset
   315
                break
20104
224e96078708 subrepo: sanitize non-hg subrepos
Matt Mackall <mpm@selenic.com>
parents: 19811
diff changeset
   316
        if os.path.basename(dirname).lower() != '.hg':
21564
2e91d4964ecd subrepo: make "_sanitize()" work
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21041
diff changeset
   317
            continue
20104
224e96078708 subrepo: sanitize non-hg subrepos
Matt Mackall <mpm@selenic.com>
parents: 19811
diff changeset
   318
        for f in names:
224e96078708 subrepo: sanitize non-hg subrepos
Matt Mackall <mpm@selenic.com>
parents: 19811
diff changeset
   319
            if f.lower() == 'hgrc':
21564
2e91d4964ecd subrepo: make "_sanitize()" work
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21041
diff changeset
   320
                ui.warn(_("warning: removing potentially hostile 'hgrc' "
2e91d4964ecd subrepo: make "_sanitize()" work
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21041
diff changeset
   321
                          "in '%s'\n") % dirname)
20104
224e96078708 subrepo: sanitize non-hg subrepos
Matt Mackall <mpm@selenic.com>
parents: 19811
diff changeset
   322
                os.unlink(os.path.join(dirname, f))
224e96078708 subrepo: sanitize non-hg subrepos
Matt Mackall <mpm@selenic.com>
parents: 19811
diff changeset
   323
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   324
def subrepo(ctx, path):
11571
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
   325
    """return instance of the right subrepo class for subrepo in path"""
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   326
    # subrepo inherently violates our import layering rules
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   327
    # 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
   328
    # so we manually delay the circular imports to not break
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   329
    # 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
   330
    global hg
9aebeea7ac00 subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents: 9049
diff changeset
   331
    import hg as h
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   332
    hg = h
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   333
20033
f962870712da pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents: 19811
diff changeset
   334
    pathutil.pathauditor(ctx._repo.root)(path)
16756
2e3513e7348a subrepo: make subrepo.subrepo(<not a subrepo path>) fail
Dov Feldstern <dfeldstern@gmail.com>
parents: 16683
diff changeset
   335
    state = ctx.substate[path]
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
   336
    if state[2] not in types:
10299
e768941f14c1 subrepo: fix errors reported by pylint
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10273
diff changeset
   337
        raise util.Abort(_('unknown subrepo type %s') % state[2])
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
   338
    return types[state[2]](ctx, path, state[:2])
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   339
20176
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   340
def newcommitphase(ui, ctx):
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   341
    commitphase = phases.newcommitphase(ui)
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   342
    substate = getattr(ctx, "substate", None)
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   343
    if not substate:
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   344
        return commitphase
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   345
    check = ui.config('phases', 'checksubrepos', 'follow')
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   346
    if check not in ('ignore', 'follow', 'abort'):
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   347
        raise util.Abort(_('invalid phases.checksubrepos configuration: %s')
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   348
                         % (check))
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   349
    if check == 'ignore':
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   350
        return commitphase
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   351
    maxphase = phases.public
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   352
    maxsub = None
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   353
    for s in sorted(substate):
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   354
        sub = ctx.sub(s)
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   355
        subphase = sub.phase(substate[s][1])
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   356
        if maxphase < subphase:
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   357
            maxphase = subphase
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   358
            maxsub = s
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   359
    if commitphase < maxphase:
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   360
        if check == 'abort':
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   361
            raise util.Abort(_("can't commit in %s phase"
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   362
                               " conflicting %s from subrepository %s") %
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   363
                             (phases.phasenames[commitphase],
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   364
                              phases.phasenames[maxphase], maxsub))
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   365
        ui.warn(_("warning: changes are committed in"
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   366
                  " %s phase from subrepository %s\n") %
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   367
                (phases.phasenames[maxphase], maxsub))
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   368
        return maxphase
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   369
    return commitphase
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   370
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   371
# subrepo classes need to implement the following abstract class:
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   372
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   373
class abstractsubrepo(object):
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   374
18937
9a171baa9202 subrepo: introduce storeclean method
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18936
diff changeset
   375
    def storeclean(self, path):
9a171baa9202 subrepo: introduce storeclean method
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18936
diff changeset
   376
        """
9a171baa9202 subrepo: introduce storeclean method
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18936
diff changeset
   377
        returns true if the repository has not changed since it was last
9a171baa9202 subrepo: introduce storeclean method
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18936
diff changeset
   378
        cloned from or pushed to a given repository.
9a171baa9202 subrepo: introduce storeclean method
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18936
diff changeset
   379
        """
9a171baa9202 subrepo: introduce storeclean method
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18936
diff changeset
   380
        return False
9a171baa9202 subrepo: introduce storeclean method
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18936
diff changeset
   381
13174
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   382
    def dirty(self, ignoreupdate=False):
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   383
        """returns true if the dirstate of the subrepo is dirty or does not
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   384
        match current stored state. If ignoreupdate is true, only check
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   385
        whether the subrepo has uncommitted changes in its dirstate.
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   386
        """
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   387
        raise NotImplementedError
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   388
16072
bcb973abcc0b subrepo: add basestate method
Matt Mackall <mpm@selenic.com>
parents: 16022
diff changeset
   389
    def basestate(self):
bcb973abcc0b subrepo: add basestate method
Matt Mackall <mpm@selenic.com>
parents: 16022
diff changeset
   390
        """current working directory base state, disregarding .hgsubstate
bcb973abcc0b subrepo: add basestate method
Matt Mackall <mpm@selenic.com>
parents: 16022
diff changeset
   391
        state and working directory modifications"""
bcb973abcc0b subrepo: add basestate method
Matt Mackall <mpm@selenic.com>
parents: 16022
diff changeset
   392
        raise NotImplementedError
bcb973abcc0b subrepo: add basestate method
Matt Mackall <mpm@selenic.com>
parents: 16022
diff changeset
   393
12506
e7d45e41338c subrepos: add missing self argument to abstractsubrepo.checknested
Brodie Rao <brodie@bitheap.org>
parents: 12503
diff changeset
   394
    def checknested(self, path):
12162
af8c4929931c localrepo: add auditor attribute which knows about subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12060
diff changeset
   395
        """check if path is a subrepository within this repository"""
af8c4929931c localrepo: add auditor attribute which knows about subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12060
diff changeset
   396
        return False
af8c4929931c localrepo: add auditor attribute which knows about subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12060
diff changeset
   397
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   398
    def commit(self, text, user, date):
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   399
        """commit the current changes to the subrepo with the given
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   400
        log message. Use given user and date if possible. Return the
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   401
        new state of the subrepo.
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   402
        """
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   403
        raise NotImplementedError
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   404
20176
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   405
    def phase(self, state):
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   406
        """returns phase of specified state in the subrepository.
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   407
        """
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   408
        return phases.public
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   409
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   410
    def remove(self):
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   411
        """remove the subrepo
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   412
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   413
        (should verify the dirstate is not dirty first)
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   414
        """
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   415
        raise NotImplementedError
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   416
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 13287
diff changeset
   417
    def get(self, state, overwrite=False):
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   418
        """run whatever commands are needed to put the subrepo into
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   419
        this state
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   420
        """
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   421
        raise NotImplementedError
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   422
13413
fa921dcd9993 subrepo: remove argument introduced by mistake in c19b9282d3a7
Erik Zielke <ez@aragost.com>
parents: 13333
diff changeset
   423
    def merge(self, state):
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   424
        """merge currently-saved state with the new state."""
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   425
        raise NotImplementedError
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   426
15708
309e49491253 push: propagate --new-branch and --ssh options when pushing subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15614
diff changeset
   427
    def push(self, opts):
11572
324bad1dc230 Merge with stable
Martin Geisler <mg@lazybytes.net>
parents: 11560 11571
diff changeset
   428
        """perform whatever action is analogous to 'hg push'
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   429
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   430
        This may be a no-op on some systems.
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   431
        """
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   432
        raise NotImplementedError
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   433
15911
c654eac03452 add: fix subrepo recursion for explicit path handling
David M. Carr <david@carrclan.us>
parents: 15828
diff changeset
   434
    def add(self, ui, match, dryrun, listsubrepos, prefix, explicitonly):
12270
166b9866580a add: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12210
diff changeset
   435
        return []
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   436
21041
a2cc3c08c3ac cat: support cat with explicit paths in subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 20970
diff changeset
   437
    def cat(self, ui, match, prefix, **opts):
a2cc3c08c3ac cat: support cat with explicit paths in subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 20970
diff changeset
   438
        return 1
a2cc3c08c3ac cat: support cat with explicit paths in subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 20970
diff changeset
   439
12166
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   440
    def status(self, rev2, **opts):
22914
c95db3208a33 status: update various other methods to return new class
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22695
diff changeset
   441
        return scmutil.status([], [], [], [], [], [], [])
12166
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   442
18006
0c10cf819146 subrepo: add argument to "diff()" to pass "ui" of caller side (issue3712) (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17895
diff changeset
   443
    def diff(self, ui, diffopts, node2, match, prefix, **opts):
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   444
        pass
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   445
12272
42ecd56399d7 outgoing: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12270
diff changeset
   446
    def outgoing(self, ui, dest, opts):
42ecd56399d7 outgoing: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12270
diff changeset
   447
        return 1
42ecd56399d7 outgoing: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12270
diff changeset
   448
12274
c02e1ed3d407 incoming: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12272
diff changeset
   449
    def incoming(self, ui, source, opts):
c02e1ed3d407 incoming: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12272
diff changeset
   450
        return 1
c02e1ed3d407 incoming: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12272
diff changeset
   451
12322
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   452
    def files(self):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   453
        """return filename iterator"""
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   454
        raise NotImplementedError
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   455
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   456
    def filedata(self, name):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   457
        """return file data"""
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   458
        raise NotImplementedError
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   459
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   460
    def fileflags(self, name):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   461
        """return file flags"""
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   462
        return ''
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   463
17108
1894dac619de subrepo: propagate matcher to subrepos when archiving
Matt Harbison <matt_harbison@yahoo.com>
parents: 17036
diff changeset
   464
    def archive(self, ui, archiver, prefix, match=None):
1894dac619de subrepo: propagate matcher to subrepos when archiving
Matt Harbison <matt_harbison@yahoo.com>
parents: 17036
diff changeset
   465
        if match is not None:
1894dac619de subrepo: propagate matcher to subrepos when archiving
Matt Harbison <matt_harbison@yahoo.com>
parents: 17036
diff changeset
   466
            files = [f for f in self.files() if match(f)]
1894dac619de subrepo: propagate matcher to subrepos when archiving
Matt Harbison <matt_harbison@yahoo.com>
parents: 17036
diff changeset
   467
        else:
1894dac619de subrepo: propagate matcher to subrepos when archiving
Matt Harbison <matt_harbison@yahoo.com>
parents: 17036
diff changeset
   468
            files = self.files()
13144
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   469
        total = len(files)
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   470
        relpath = subrelpath(self)
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   471
        ui.progress(_('archiving (%s)') % relpath, 0,
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   472
                    unit=_('files'), total=total)
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   473
        for i, name in enumerate(files):
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   474
            flags = self.fileflags(name)
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   475
            mode = 'x' in flags and 0755 or 0644
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   476
            symlink = 'l' in flags
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   477
            archiver.addfile(os.path.join(prefix, self._path, name),
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   478
                             mode, symlink, self.filedata(name))
13144
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   479
            ui.progress(_('archiving (%s)') % relpath, i + 1,
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   480
                        unit=_('files'), total=total)
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   481
        ui.progress(_('archiving (%s)') % relpath, None)
18967
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18964
diff changeset
   482
        return total
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   483
15410
9e99d2bbb1b1 add: support adding explicit files in subrepos
David M. Carr <david@carrclan.us>
parents: 15287
diff changeset
   484
    def walk(self, match):
9e99d2bbb1b1 add: support adding explicit files in subrepos
David M. Carr <david@carrclan.us>
parents: 15287
diff changeset
   485
        '''
9e99d2bbb1b1 add: support adding explicit files in subrepos
David M. Carr <david@carrclan.us>
parents: 15287
diff changeset
   486
        walk recursively through the directory tree, finding all files
9e99d2bbb1b1 add: support adding explicit files in subrepos
David M. Carr <david@carrclan.us>
parents: 15287
diff changeset
   487
        matched by the match function
9e99d2bbb1b1 add: support adding explicit files in subrepos
David M. Carr <david@carrclan.us>
parents: 15287
diff changeset
   488
        '''
9e99d2bbb1b1 add: support adding explicit files in subrepos
David M. Carr <david@carrclan.us>
parents: 15287
diff changeset
   489
        pass
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   490
15912
2bd54ffaa27e forget: fix subrepo recursion for explicit path handling
David M. Carr <david@carrclan.us>
parents: 15911
diff changeset
   491
    def forget(self, ui, match, prefix):
16527
17a1f7690b49 subrepo: fix default implementation of forget() (issue3404)
Patrick Mezard <patrick@mezard.eu>
parents: 16468
diff changeset
   492
        return ([], [])
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   493
23325
4165cfd67519 remove: recurse into subrepositories with --subrepos/-S flag
Matt Harbison <matt_harbison@yahoo.com>
parents: 22927
diff changeset
   494
    def removefiles(self, ui, matcher, prefix, after, force, subrepos):
4165cfd67519 remove: recurse into subrepositories with --subrepos/-S flag
Matt Harbison <matt_harbison@yahoo.com>
parents: 22927
diff changeset
   495
        """remove the matched files from the subrepository and the filesystem,
4165cfd67519 remove: recurse into subrepositories with --subrepos/-S flag
Matt Harbison <matt_harbison@yahoo.com>
parents: 22927
diff changeset
   496
        possibly by force and/or after the file has been removed from the
4165cfd67519 remove: recurse into subrepositories with --subrepos/-S flag
Matt Harbison <matt_harbison@yahoo.com>
parents: 22927
diff changeset
   497
        filesystem.  Return 0 on success, 1 on any warning.
4165cfd67519 remove: recurse into subrepositories with --subrepos/-S flag
Matt Harbison <matt_harbison@yahoo.com>
parents: 22927
diff changeset
   498
        """
4165cfd67519 remove: recurse into subrepositories with --subrepos/-S flag
Matt Harbison <matt_harbison@yahoo.com>
parents: 22927
diff changeset
   499
        return 1
4165cfd67519 remove: recurse into subrepositories with --subrepos/-S flag
Matt Harbison <matt_harbison@yahoo.com>
parents: 22927
diff changeset
   500
16429
71dcce391a44 revert: add support for reverting subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16197
diff changeset
   501
    def revert(self, ui, substate, *pats, **opts):
16468
2fb521d75dc2 revert: show warning when reverting subrepos that do not support revert
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16451
diff changeset
   502
        ui.warn('%s: reverting %s subrepos is unsupported\n' \
2fb521d75dc2 revert: show warning when reverting subrepos that do not support revert
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16451
diff changeset
   503
            % (substate[0], substate[2]))
16429
71dcce391a44 revert: add support for reverting subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16197
diff changeset
   504
        return []
71dcce391a44 revert: add support for reverting subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16197
diff changeset
   505
21400
78a60daacea8 subrepo: add shortid() method to subrepo classes
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21041
diff changeset
   506
    def shortid(self, revid):
78a60daacea8 subrepo: add shortid() method to subrepo classes
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21041
diff changeset
   507
        return revid
78a60daacea8 subrepo: add shortid() method to subrepo classes
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21041
diff changeset
   508
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   509
class hgsubrepo(abstractsubrepo):
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   510
    def __init__(self, ctx, path, state):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   511
        self._path = path
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   512
        self._state = state
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   513
        r = ctx._repo
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   514
        root = r.wjoin(path)
23364
83736508e98a subrepo: replace "os.path.exists" by "exists" via wvfs of the parent
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23363
diff changeset
   515
        create = not r.wvfs.exists('%s/.hg' % path)
17873
573bec4ab7ba subrepo: isolate configuration between each repositories in subrepo tree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17707
diff changeset
   516
        self._repo = hg.repository(r.baseui, root, create=create)
573bec4ab7ba subrepo: isolate configuration between each repositories in subrepo tree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17707
diff changeset
   517
        for s, k in [('ui', 'commitsubrepos')]:
573bec4ab7ba subrepo: isolate configuration between each repositories in subrepo tree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17707
diff changeset
   518
            v = r.ui.config(s, k)
573bec4ab7ba subrepo: isolate configuration between each repositories in subrepo tree
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17707
diff changeset
   519
            if v:
20790
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20392
diff changeset
   520
                self._repo.ui.setconfig(s, k, v, 'subrepo')
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20392
diff changeset
   521
        self._repo.ui.setconfig('ui', '_usedassubrepo', 'True', 'subrepo')
14281
ccb7240acf32 subrepo: create subrepos using clone instead of pull
Martin Geisler <mg@aragost.com>
parents: 14221
diff changeset
   522
        self._initrepo(r, state[0], create)
ccb7240acf32 subrepo: create subrepos using clone instead of pull
Martin Geisler <mg@aragost.com>
parents: 14221
diff changeset
   523
18939
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   524
    def storeclean(self, path):
21885
fe9db58b0b2d subrepo: ensure "lock.release()" execution at the end of "storeclean()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21585
diff changeset
   525
        lock = self._repo.lock()
fe9db58b0b2d subrepo: ensure "lock.release()" execution at the end of "storeclean()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21585
diff changeset
   526
        try:
fe9db58b0b2d subrepo: ensure "lock.release()" execution at the end of "storeclean()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21585
diff changeset
   527
            return self._storeclean(path)
fe9db58b0b2d subrepo: ensure "lock.release()" execution at the end of "storeclean()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21585
diff changeset
   528
        finally:
fe9db58b0b2d subrepo: ensure "lock.release()" execution at the end of "storeclean()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21585
diff changeset
   529
            lock.release()
fe9db58b0b2d subrepo: ensure "lock.release()" execution at the end of "storeclean()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21585
diff changeset
   530
fe9db58b0b2d subrepo: ensure "lock.release()" execution at the end of "storeclean()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21585
diff changeset
   531
    def _storeclean(self, path):
18939
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   532
        clean = True
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   533
        itercache = self._calcstorehash(path)
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   534
        try:
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   535
            for filehash in self._readstorehashcache(path):
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   536
                if filehash != itercache.next():
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   537
                    clean = False
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   538
                    break
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   539
        except StopIteration:
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   540
            # the cached and current pull states have a different size
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   541
            clean = False
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   542
        if clean:
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   543
            try:
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   544
                itercache.next()
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   545
                # the cached and current pull states have a different size
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   546
                clean = False
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   547
            except StopIteration:
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   548
                pass
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   549
        return clean
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   550
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   551
    def _calcstorehash(self, remotepath):
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   552
        '''calculate a unique "store hash"
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   553
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   554
        This method is used to to detect when there are changes that may
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   555
        require a push to a given remote path.'''
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   556
        # sort the files that will be hashed in increasing (likely) file size
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   557
        filelist = ('bookmarks', 'store/phaseroots', 'store/00changelog.i')
18940
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
   558
        yield '# %s\n' % _expandedabspath(remotepath)
23365
2ff394bbfa74 subrepo: replace "_calcfilehash" invocation by "vfs.tryread"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23364
diff changeset
   559
        vfs = self._repo.vfs
18939
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   560
        for relname in filelist:
23365
2ff394bbfa74 subrepo: replace "_calcfilehash" invocation by "vfs.tryread"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23364
diff changeset
   561
            filehash = util.sha1(vfs.tryread(relname)).hexdigest()
2ff394bbfa74 subrepo: replace "_calcfilehash" invocation by "vfs.tryread"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23364
diff changeset
   562
            yield '%s = %s\n' % (relname, filehash)
18939
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   563
23367
115af8de76a4 subrepo: add "_cachestorehashvfs" to handle cache store hash files via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23366
diff changeset
   564
    @propertycache
115af8de76a4 subrepo: add "_cachestorehashvfs" to handle cache store hash files via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23366
diff changeset
   565
    def _cachestorehashvfs(self):
115af8de76a4 subrepo: add "_cachestorehashvfs" to handle cache store hash files via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23366
diff changeset
   566
        return scmutil.vfs(self._repo.join('cache/storehash'))
115af8de76a4 subrepo: add "_cachestorehashvfs" to handle cache store hash files via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23366
diff changeset
   567
18939
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   568
    def _readstorehashcache(self, remotepath):
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   569
        '''read the store hash cache for a given remote repository'''
23369
22e00674d17e subrepo: replace direct file APIs around "readlines" by "vfs.tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23367
diff changeset
   570
        cachefile = _getstorehashcachename(remotepath)
22e00674d17e subrepo: replace direct file APIs around "readlines" by "vfs.tryreadlines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23367
diff changeset
   571
        return self._cachestorehashvfs.tryreadlines(cachefile, 'r')
18939
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   572
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   573
    def _cachestorehash(self, remotepath):
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   574
        '''cache the current store hash
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   575
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   576
        Each remote repo requires its own store hash cache, because a subrepo
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   577
        store may be "clean" versus a given remote repo, but not versus another
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   578
        '''
23372
6cfa7a73b6e7 subrepo: replace direct file APIs around "writelines" by "vfs.writelines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23369
diff changeset
   579
        cachefile = _getstorehashcachename(remotepath)
18939
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   580
        lock = self._repo.lock()
21886
b9e8fdc35daf subrepo: ensure "lock.release()" execution at the end of "_cachestorehash()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21885
diff changeset
   581
        try:
b9e8fdc35daf subrepo: ensure "lock.release()" execution at the end of "_cachestorehash()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21885
diff changeset
   582
            storehash = list(self._calcstorehash(remotepath))
23372
6cfa7a73b6e7 subrepo: replace direct file APIs around "writelines" by "vfs.writelines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23369
diff changeset
   583
            vfs = self._cachestorehashvfs
6cfa7a73b6e7 subrepo: replace direct file APIs around "writelines" by "vfs.writelines"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23369
diff changeset
   584
            vfs.writelines(cachefile, storehash, mode='w', notindexed=True)
21886
b9e8fdc35daf subrepo: ensure "lock.release()" execution at the end of "_cachestorehash()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21885
diff changeset
   585
        finally:
b9e8fdc35daf subrepo: ensure "lock.release()" execution at the end of "_cachestorehash()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21885
diff changeset
   586
            lock.release()
18939
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   587
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   588
    @annotatesubrepoerror
14281
ccb7240acf32 subrepo: create subrepos using clone instead of pull
Martin Geisler <mg@aragost.com>
parents: 14221
diff changeset
   589
    def _initrepo(self, parentrepo, source, create):
ccb7240acf32 subrepo: create subrepos using clone instead of pull
Martin Geisler <mg@aragost.com>
parents: 14221
diff changeset
   590
        self._repo._subparent = parentrepo
ccb7240acf32 subrepo: create subrepos using clone instead of pull
Martin Geisler <mg@aragost.com>
parents: 14221
diff changeset
   591
        self._repo._subsource = source
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   592
10666
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   593
        if create:
21891
db8a27d92818 subrepo: ensure "close()" execution at the end of "_initrepo()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21889
diff changeset
   594
            lines = ['[paths]\n']
10666
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   595
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   596
            def addpathconfig(key, value):
12753
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   597
                if value:
21891
db8a27d92818 subrepo: ensure "close()" execution at the end of "_initrepo()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21889
diff changeset
   598
                    lines.append('%s = %s\n' % (key, value))
20790
49f2d5644f04 config: set a 'source' in most cases where config don't come from file but code
Mads Kiilerich <madski@unity3d.com>
parents: 20392
diff changeset
   599
                    self._repo.ui.setconfig('paths', key, value, 'subrepo')
10666
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   600
12753
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   601
            defpath = _abssource(self._repo, abort=False)
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   602
            defpushpath = _abssource(self._repo, True, abort=False)
10666
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   603
            addpathconfig('default', defpath)
10697
c90d923fff64 subrepo: fix hgrc paths section during subrepo pulling
Edouard Gomez <ed.gomez@free.fr>
parents: 10666
diff changeset
   604
            if defpath != defpushpath:
c90d923fff64 subrepo: fix hgrc paths section during subrepo pulling
Edouard Gomez <ed.gomez@free.fr>
parents: 10666
diff changeset
   605
                addpathconfig('default-push', defpushpath)
21891
db8a27d92818 subrepo: ensure "close()" execution at the end of "_initrepo()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21889
diff changeset
   606
db8a27d92818 subrepo: ensure "close()" execution at the end of "_initrepo()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21889
diff changeset
   607
            fp = self._repo.opener("hgrc", "w", text=True)
db8a27d92818 subrepo: ensure "close()" execution at the end of "_initrepo()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21889
diff changeset
   608
            try:
db8a27d92818 subrepo: ensure "close()" execution at the end of "_initrepo()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21889
diff changeset
   609
                fp.write(''.join(lines))
db8a27d92818 subrepo: ensure "close()" execution at the end of "_initrepo()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21889
diff changeset
   610
            finally:
db8a27d92818 subrepo: ensure "close()" execution at the end of "_initrepo()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21889
diff changeset
   611
                fp.close()
10666
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   612
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   613
    @annotatesubrepoerror
15911
c654eac03452 add: fix subrepo recursion for explicit path handling
David M. Carr <david@carrclan.us>
parents: 15828
diff changeset
   614
    def add(self, ui, match, dryrun, listsubrepos, prefix, explicitonly):
c654eac03452 add: fix subrepo recursion for explicit path handling
David M. Carr <david@carrclan.us>
parents: 15828
diff changeset
   615
        return cmdutil.add(ui, self._repo, match, dryrun, listsubrepos,
c654eac03452 add: fix subrepo recursion for explicit path handling
David M. Carr <david@carrclan.us>
parents: 15828
diff changeset
   616
                           os.path.join(prefix, self._path), explicitonly)
12270
166b9866580a add: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12210
diff changeset
   617
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   618
    @annotatesubrepoerror
21041
a2cc3c08c3ac cat: support cat with explicit paths in subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 20970
diff changeset
   619
    def cat(self, ui, match, prefix, **opts):
a2cc3c08c3ac cat: support cat with explicit paths in subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 20970
diff changeset
   620
        rev = self._state[1]
a2cc3c08c3ac cat: support cat with explicit paths in subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 20970
diff changeset
   621
        ctx = self._repo[rev]
a2cc3c08c3ac cat: support cat with explicit paths in subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 20970
diff changeset
   622
        return cmdutil.cat(ui, self._repo, ctx, match, prefix, **opts)
a2cc3c08c3ac cat: support cat with explicit paths in subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 20970
diff changeset
   623
a2cc3c08c3ac cat: support cat with explicit paths in subrepos
Matt Harbison <matt_harbison@yahoo.com>
parents: 20970
diff changeset
   624
    @annotatesubrepoerror
12166
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   625
    def status(self, rev2, **opts):
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   626
        try:
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   627
            rev1 = self._state[1]
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   628
            ctx1 = self._repo[rev1]
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   629
            ctx2 = self._repo[rev2]
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   630
            return self._repo.status(ctx1, ctx2, **opts)
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   631
        except error.RepoLookupError, inst:
12503
b4711585a455 subrepo: improve lookup error messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 12323
diff changeset
   632
            self._repo.ui.warn(_('warning: error "%s" in subrepository "%s"\n')
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   633
                               % (inst, subrelpath(self)))
22914
c95db3208a33 status: update various other methods to return new class
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22695
diff changeset
   634
            return scmutil.status([], [], [], [], [], [], [])
12166
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   635
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   636
    @annotatesubrepoerror
18006
0c10cf819146 subrepo: add argument to "diff()" to pass "ui" of caller side (issue3712) (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17895
diff changeset
   637
    def diff(self, ui, diffopts, node2, match, prefix, **opts):
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   638
        try:
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   639
            node1 = node.bin(self._state[1])
12209
affec9fb56ef subrepos: handle diff nodeids in subrepos, not before
Patrick Mezard <pmezard@gmail.com>
parents: 12176
diff changeset
   640
            # We currently expect node2 to come from substate and be
affec9fb56ef subrepos: handle diff nodeids in subrepos, not before
Patrick Mezard <pmezard@gmail.com>
parents: 12176
diff changeset
   641
            # in hex format
12210
21eb85e9ea94 subrepo: handle diff with working copy
Martin Geisler <mg@lazybytes.net>
parents: 12209
diff changeset
   642
            if node2 is not None:
21eb85e9ea94 subrepo: handle diff with working copy
Martin Geisler <mg@lazybytes.net>
parents: 12209
diff changeset
   643
                node2 = node.bin(node2)
18006
0c10cf819146 subrepo: add argument to "diff()" to pass "ui" of caller side (issue3712) (API)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17895
diff changeset
   644
            cmdutil.diffordiffstat(ui, self._repo, diffopts,
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   645
                                   node1, node2, match,
17968
a9f4a6076740 subrepo: use posixpath when diffing, for consistent paths
Bryan O'Sullivan <bryano@fb.com>
parents: 17895
diff changeset
   646
                                   prefix=posixpath.join(prefix, self._path),
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   647
                                   listsubrepos=True, **opts)
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   648
        except error.RepoLookupError, inst:
12503
b4711585a455 subrepo: improve lookup error messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 12323
diff changeset
   649
            self._repo.ui.warn(_('warning: error "%s" in subrepository "%s"\n')
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   650
                               % (inst, subrelpath(self)))
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   651
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   652
    @annotatesubrepoerror
17108
1894dac619de subrepo: propagate matcher to subrepos when archiving
Matt Harbison <matt_harbison@yahoo.com>
parents: 17036
diff changeset
   653
    def archive(self, ui, archiver, prefix, match=None):
15286
4be845e3932c subrepo: pull revisions on demand when archiving hg subrepos
Martin Geisler <mg@aragost.com>
parents: 15234
diff changeset
   654
        self._get(self._state + ('hg',))
18967
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18964
diff changeset
   655
        total = abstractsubrepo.archive(self, ui, archiver, prefix, match)
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   656
        rev = self._state[1]
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   657
        ctx = self._repo[rev]
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   658
        for subpath in ctx.substate:
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   659
            s = subrepo(ctx, subpath)
17108
1894dac619de subrepo: propagate matcher to subrepos when archiving
Matt Harbison <matt_harbison@yahoo.com>
parents: 17036
diff changeset
   660
            submatch = matchmod.narrowmatcher(subpath, match)
18967
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18964
diff changeset
   661
            total += s.archive(
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18964
diff changeset
   662
                ui, archiver, os.path.join(prefix, self._path), submatch)
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18964
diff changeset
   663
        return total
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   664
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   665
    @annotatesubrepoerror
13174
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   666
    def dirty(self, ignoreupdate=False):
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   667
        r = self._state[1]
13174
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   668
        if r == '' and not ignoreupdate: # no state recorded
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   669
            return True
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   670
        w = self._repo[None]
14316
d5b525697ddb extensions: drop maxlength from enabled and disabled
Matt Mackall <mpm@selenic.com>
parents: 14312
diff changeset
   671
        if r != w.p1().hex() and not ignoreupdate:
13325
7ebdfa37842e subrepo: clarify comments in dirty() methods
Kevin Bullock <kbullock@ringworld.org>
parents: 13324
diff changeset
   672
            # different version checked out
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   673
            return True
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   674
        return w.dirty() # working directory changed
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   675
16072
bcb973abcc0b subrepo: add basestate method
Matt Mackall <mpm@selenic.com>
parents: 16022
diff changeset
   676
    def basestate(self):
bcb973abcc0b subrepo: add basestate method
Matt Mackall <mpm@selenic.com>
parents: 16022
diff changeset
   677
        return self._repo['.'].hex()
bcb973abcc0b subrepo: add basestate method
Matt Mackall <mpm@selenic.com>
parents: 16022
diff changeset
   678
12162
af8c4929931c localrepo: add auditor attribute which knows about subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12060
diff changeset
   679
    def checknested(self, path):
af8c4929931c localrepo: add auditor attribute which knows about subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12060
diff changeset
   680
        return self._repo._checknested(self._repo.wjoin(path))
af8c4929931c localrepo: add auditor attribute which knows about subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12060
diff changeset
   681
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   682
    @annotatesubrepoerror
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   683
    def commit(self, text, user, date):
14898
95ced9f5bf29 subrepo: don't commit in subrepo if it's clean
Kevin Bullock <kbullock@ringworld.org>
parents: 14820
diff changeset
   684
        # don't bother committing in the subrepo if it's only been
95ced9f5bf29 subrepo: don't commit in subrepo if it's clean
Kevin Bullock <kbullock@ringworld.org>
parents: 14820
diff changeset
   685
        # updated
95ced9f5bf29 subrepo: don't commit in subrepo if it's clean
Kevin Bullock <kbullock@ringworld.org>
parents: 14820
diff changeset
   686
        if not self.dirty(True):
95ced9f5bf29 subrepo: don't commit in subrepo if it's clean
Kevin Bullock <kbullock@ringworld.org>
parents: 14820
diff changeset
   687
            return self._repo['.'].hex()
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   688
        self._repo.ui.debug("committing subrepo %s\n" % subrelpath(self))
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   689
        n = self._repo.commit(text, user, date)
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   690
        if not n:
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   691
            return self._repo['.'].hex() # different version checked out
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   692
        return node.hex(n)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   693
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   694
    @annotatesubrepoerror
20176
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   695
    def phase(self, state):
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   696
        return self._repo[state].phase()
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   697
4c96c50ef937 subrepo: check phase of state in each subrepositories before committing
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20108
diff changeset
   698
    @annotatesubrepoerror
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   699
    def remove(self):
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   700
        # 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
   701
        # local-only history
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   702
        self._repo.ui.note(_('removing subrepo %s\n') % subrelpath(self))
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   703
        hg.clean(self._repo, node.nullid, False)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   704
9507
5987183d6e59 subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents: 9186
diff changeset
   705
    def _get(self, state):
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
   706
        source, revision, kind = state
20317
d6939f29b3b3 subrepo: do not try to get hidden revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20176
diff changeset
   707
        if revision in self._repo.unfiltered():
20319
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   708
            return True
20318
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   709
        self._repo._subsource = source
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   710
        srcurl = _abssource(self._repo)
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   711
        other = hg.peer(self._repo, {}, srcurl)
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   712
        if len(self._repo) == 0:
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   713
            self._repo.ui.status(_('cloning subrepo %s from %s\n')
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   714
                                 % (subrelpath(self), srcurl))
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   715
            parentrepo = self._repo._subparent
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   716
            shutil.rmtree(self._repo.path)
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   717
            other, cloned = hg.clone(self._repo._subparent.baseui, {},
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   718
                                     other, self._repo.root,
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   719
                                     update=False)
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   720
            self._repo = cloned.local()
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   721
            self._initrepo(parentrepo, source, create=True)
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   722
            self._cachestorehash(srcurl)
20317
d6939f29b3b3 subrepo: do not try to get hidden revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20176
diff changeset
   723
        else:
20318
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   724
            self._repo.ui.status(_('pulling subrepo %s from %s\n')
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   725
                                 % (subrelpath(self), srcurl))
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   726
            cleansub = self.storeclean(srcurl)
22695
15a70ca40b22 subrepo: use exchange.pull
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22657
diff changeset
   727
            exchange.pull(self._repo, other)
20318
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   728
            if cleansub:
c5aef7a66607 subrepo: remove unnecessary else clause in hgsubrepo._get
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20317
diff changeset
   729
                # keep the repo clean after pull
18939
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   730
                self._cachestorehash(srcurl)
20319
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   731
        return False
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   732
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   733
    @annotatesubrepoerror
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 13287
diff changeset
   734
    def get(self, state, overwrite=False):
20319
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   735
        inrepo = self._get(state)
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
   736
        source, revision, kind = state
20319
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   737
        repo = self._repo
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   738
        repo.ui.debug("getting subrepo %s\n" % self._path)
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   739
        if inrepo:
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   740
            urepo = repo.unfiltered()
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   741
            ctx = urepo[revision]
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   742
            if ctx.hidden():
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   743
                urepo.ui.warn(
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   744
                    _('revision %s in subrepo %s is hidden\n') \
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   745
                    % (revision[0:12], self._path))
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   746
                repo = urepo
427d672c0e4e subrepo: make it possible to update to hidden subrepo revisions
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 20318
diff changeset
   747
        hg.updaterepo(repo, revision, overwrite)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   748
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   749
    @annotatesubrepoerror
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   750
    def merge(self, state):
9507
5987183d6e59 subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents: 9186
diff changeset
   751
        self._get(state)
9781
eccc8aacd6f9 subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   752
        cur = self._repo['.']
eccc8aacd6f9 subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   753
        dst = self._repo[state[1]]
10251
a19d2993385d subrepo: fix merging of already merged subrepos (issue1986)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10068
diff changeset
   754
        anc = dst.ancestor(cur)
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   755
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   756
        def mergefunc():
16196
8ae7626d8bf1 subrepo: fix for merge inconsistencies
Friedrich Kastner-Masilko <kastner_masilko@at.festo.com>
parents: 16022
diff changeset
   757
            if anc == cur and dst.branch() == cur.branch():
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   758
                self._repo.ui.debug("updating subrepo %s\n" % subrelpath(self))
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   759
                hg.update(self._repo, state[1])
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   760
            elif anc == dst:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   761
                self._repo.ui.debug("skipping subrepo %s\n" % subrelpath(self))
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   762
            else:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   763
                self._repo.ui.debug("merging subrepo %s\n" % subrelpath(self))
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   764
                hg.merge(self._repo, state[1], remind=False)
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   765
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   766
        wctx = self._repo[None]
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   767
        if self.dirty():
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   768
            if anc != dst:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   769
                if _updateprompt(self._repo.ui, self, wctx.dirty(), cur, dst):
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   770
                    mergefunc()
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   771
            else:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   772
                mergefunc()
9781
eccc8aacd6f9 subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   773
        else:
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   774
            mergefunc()
8815
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   775
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   776
    @annotatesubrepoerror
15708
309e49491253 push: propagate --new-branch and --ssh options when pushing subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15614
diff changeset
   777
    def push(self, opts):
309e49491253 push: propagate --new-branch and --ssh options when pushing subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15614
diff changeset
   778
        force = opts.get('force')
309e49491253 push: propagate --new-branch and --ssh options when pushing subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15614
diff changeset
   779
        newbranch = opts.get('new_branch')
309e49491253 push: propagate --new-branch and --ssh options when pushing subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15614
diff changeset
   780
        ssh = opts.get('ssh')
309e49491253 push: propagate --new-branch and --ssh options when pushing subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15614
diff changeset
   781
8815
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   782
        # push subrepos depth-first for coherent ordering
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   783
        c = self._repo['']
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   784
        subs = c.substate # only repos that are committed
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   785
        for s in sorted(subs):
16022
04604d1a9fc3 push: more precise failure check on subrepo push
Matt Mackall <mpm@selenic.com>
parents: 15912
diff changeset
   786
            if c.sub(s).push(opts) == 0:
11067
49e14ec67144 subrepo: propagate and catch push failures
Matt Mackall <mpm@selenic.com>
parents: 10954
diff changeset
   787
                return False
8815
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   788
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   789
        dsturl = _abssource(self._repo, True)
18940
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
   790
        if not force:
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
   791
            if self.storeclean(dsturl):
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
   792
                self._repo.ui.status(
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
   793
                    _('no changes made to subrepo %s since last push to %s\n')
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
   794
                    % (subrelpath(self), dsturl))
798bdb7f1517 subrepo: do not push mercurial subrepos whose store is clean
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18939
diff changeset
   795
                return None
11111
d2da9e6dd13e subrepo: print pushing url
Edouard Gomez <ed.gomez@free.fr>
parents: 11109
diff changeset
   796
        self._repo.ui.status(_('pushing subrepo %s to %s\n') %
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   797
            (subrelpath(self), dsturl))
17874
2ba70eec1cf0 peer: subrepo isolation, pass repo instead of repo.ui to hg.peer
Simon Heimberg <simohe@besonet.ch>
parents: 17873
diff changeset
   798
        other = hg.peer(self._repo, {'ssh': ssh}, dsturl)
22619
f6cf96804d27 push: `exchange.push` instead of `localrepo.push`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22590
diff changeset
   799
        res = exchange.push(self._repo, other, force, newbranch=newbranch)
18939
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   800
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   801
        # the repo is now clean
aab0c14c20d0 subrepo: implement "storeclean" method for mercurial subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18937
diff changeset
   802
        self._cachestorehash(dsturl)
22619
f6cf96804d27 push: `exchange.push` instead of `localrepo.push`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22590
diff changeset
   803
        return res.cgresult
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
   804
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   805
    @annotatesubrepoerror
12272
42ecd56399d7 outgoing: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12270
diff changeset
   806
    def outgoing(self, ui, dest, opts):
42ecd56399d7 outgoing: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12270
diff changeset
   807
        return hg.outgoing(ui, self._repo, _abssource(self._repo, True), opts)
42ecd56399d7 outgoing: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12270
diff changeset
   808
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   809
    @annotatesubrepoerror
12274
c02e1ed3d407 incoming: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12272
diff changeset
   810
    def incoming(self, ui, source, opts):
c02e1ed3d407 incoming: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12272
diff changeset
   811
        return hg.incoming(ui, self._repo, _abssource(self._repo, False), opts)
c02e1ed3d407 incoming: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12272
diff changeset
   812
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   813
    @annotatesubrepoerror
12322
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   814
    def files(self):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   815
        rev = self._state[1]
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   816
        ctx = self._repo[rev]
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   817
        return ctx.manifest()
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   818
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   819
    def filedata(self, name):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   820
        rev = self._state[1]
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   821
        return self._repo[rev][name].data()
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   822
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   823
    def fileflags(self, name):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   824
        rev = self._state[1]
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   825
        ctx = self._repo[rev]
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   826
        return ctx.flags(name)
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   827
15410
9e99d2bbb1b1 add: support adding explicit files in subrepos
David M. Carr <david@carrclan.us>
parents: 15287
diff changeset
   828
    def walk(self, match):
9e99d2bbb1b1 add: support adding explicit files in subrepos
David M. Carr <david@carrclan.us>
parents: 15287
diff changeset
   829
        ctx = self._repo[None]
9e99d2bbb1b1 add: support adding explicit files in subrepos
David M. Carr <david@carrclan.us>
parents: 15287
diff changeset
   830
        return ctx.walk(match)
12322
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   831
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   832
    @annotatesubrepoerror
15912
2bd54ffaa27e forget: fix subrepo recursion for explicit path handling
David M. Carr <david@carrclan.us>
parents: 15911
diff changeset
   833
    def forget(self, ui, match, prefix):
2bd54ffaa27e forget: fix subrepo recursion for explicit path handling
David M. Carr <david@carrclan.us>
parents: 15911
diff changeset
   834
        return cmdutil.forget(ui, self._repo, match,
2bd54ffaa27e forget: fix subrepo recursion for explicit path handling
David M. Carr <david@carrclan.us>
parents: 15911
diff changeset
   835
                              os.path.join(prefix, self._path), True)
12322
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   836
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
   837
    @annotatesubrepoerror
23325
4165cfd67519 remove: recurse into subrepositories with --subrepos/-S flag
Matt Harbison <matt_harbison@yahoo.com>
parents: 22927
diff changeset
   838
    def removefiles(self, ui, matcher, prefix, after, force, subrepos):
4165cfd67519 remove: recurse into subrepositories with --subrepos/-S flag
Matt Harbison <matt_harbison@yahoo.com>
parents: 22927
diff changeset
   839
        return cmdutil.remove(ui, self._repo, matcher,
4165cfd67519 remove: recurse into subrepositories with --subrepos/-S flag
Matt Harbison <matt_harbison@yahoo.com>
parents: 22927
diff changeset
   840
                              os.path.join(prefix, self._path), after, force,
4165cfd67519 remove: recurse into subrepositories with --subrepos/-S flag
Matt Harbison <matt_harbison@yahoo.com>
parents: 22927
diff changeset
   841
                              subrepos)
4165cfd67519 remove: recurse into subrepositories with --subrepos/-S flag
Matt Harbison <matt_harbison@yahoo.com>
parents: 22927
diff changeset
   842
4165cfd67519 remove: recurse into subrepositories with --subrepos/-S flag
Matt Harbison <matt_harbison@yahoo.com>
parents: 22927
diff changeset
   843
    @annotatesubrepoerror
16429
71dcce391a44 revert: add support for reverting subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16197
diff changeset
   844
    def revert(self, ui, substate, *pats, **opts):
16430
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   845
        # reverting a subrepo is a 2 step process:
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   846
        # 1. if the no_backup is not set, revert all modified
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   847
        #    files inside the subrepo
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   848
        # 2. update the subrepo to the revision specified in
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   849
        #    the corresponding substate dictionary
16429
71dcce391a44 revert: add support for reverting subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16197
diff changeset
   850
        ui.status(_('reverting subrepo %s\n') % substate[0])
16430
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   851
        if not opts.get('no_backup'):
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   852
            # Revert all files on the subrepo, creating backups
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   853
            # Note that this will not recursively revert subrepos
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   854
            # We could do it if there was a set:subrepos() predicate
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   855
            opts = opts.copy()
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   856
            opts['date'] = None
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   857
            opts['rev'] = substate[1]
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   858
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   859
            pats = []
18943
27e8dfc2c338 subrepo: fix exception on revert when "all" option is omitted
Yuya Nishihara <yuya@tcha.org>
parents: 18940
diff changeset
   860
            if not opts.get('all'):
16430
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   861
                pats = ['set:modified()']
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   862
            self.filerevert(ui, *pats, **opts)
16429
71dcce391a44 revert: add support for reverting subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16197
diff changeset
   863
71dcce391a44 revert: add support for reverting subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16197
diff changeset
   864
        # Update the repo to the revision specified in the given substate
71dcce391a44 revert: add support for reverting subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16197
diff changeset
   865
        self.get(substate, overwrite=True)
71dcce391a44 revert: add support for reverting subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16197
diff changeset
   866
16430
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   867
    def filerevert(self, ui, *pats, **opts):
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   868
        ctx = self._repo[opts['rev']]
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   869
        parents = self._repo.dirstate.parents()
18943
27e8dfc2c338 subrepo: fix exception on revert when "all" option is omitted
Yuya Nishihara <yuya@tcha.org>
parents: 18940
diff changeset
   870
        if opts.get('all'):
16430
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   871
            pats = ['set:modified()']
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   872
        else:
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   873
            pats = []
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   874
        cmdutil.revert(ui, self._repo, ctx, parents, *pats, **opts)
6883c2363f44 revert: add support for reverting subrepos without --no-backup and/or --all
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 16429
diff changeset
   875
21400
78a60daacea8 subrepo: add shortid() method to subrepo classes
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21041
diff changeset
   876
    def shortid(self, revid):
78a60daacea8 subrepo: add shortid() method to subrepo classes
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21041
diff changeset
   877
        return revid[:12]
78a60daacea8 subrepo: add shortid() method to subrepo classes
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21041
diff changeset
   878
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   879
class svnsubrepo(abstractsubrepo):
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   880
    def __init__(self, ctx, path, state):
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   881
        self._path = path
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   882
        self._state = state
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   883
        self._ctx = ctx
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   884
        self._ui = ctx._repo.ui
15190
6dc67dced8c1 subrepo: improve error message when svn isn't found
Matt Mackall <mpm@selenic.com>
parents: 15150
diff changeset
   885
        self._exe = util.findexe('svn')
6dc67dced8c1 subrepo: improve error message when svn isn't found
Matt Mackall <mpm@selenic.com>
parents: 15150
diff changeset
   886
        if not self._exe:
6dc67dced8c1 subrepo: improve error message when svn isn't found
Matt Mackall <mpm@selenic.com>
parents: 15150
diff changeset
   887
            raise util.Abort(_("'svn' executable not found for subrepo '%s'")
6dc67dced8c1 subrepo: improve error message when svn isn't found
Matt Mackall <mpm@selenic.com>
parents: 15150
diff changeset
   888
                             % self._path)
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   889
14664
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
   890
    def _svncommand(self, commands, filename='', failok=False):
15190
6dc67dced8c1 subrepo: improve error message when svn isn't found
Matt Mackall <mpm@selenic.com>
parents: 15150
diff changeset
   891
        cmd = [self._exe]
14506
733af5d9f6b2 subrepo: make stdin for svn a pipe for non-interactive use (issue2759)
Augie Fackler <durin42@gmail.com>
parents: 14505
diff changeset
   892
        extrakw = {}
733af5d9f6b2 subrepo: make stdin for svn a pipe for non-interactive use (issue2759)
Augie Fackler <durin42@gmail.com>
parents: 14505
diff changeset
   893
        if not self._ui.interactive():
733af5d9f6b2 subrepo: make stdin for svn a pipe for non-interactive use (issue2759)
Augie Fackler <durin42@gmail.com>
parents: 14505
diff changeset
   894
            # Making stdin be a pipe should prevent svn from behaving
733af5d9f6b2 subrepo: make stdin for svn a pipe for non-interactive use (issue2759)
Augie Fackler <durin42@gmail.com>
parents: 14505
diff changeset
   895
            # interactively even if we can't pass --non-interactive.
733af5d9f6b2 subrepo: make stdin for svn a pipe for non-interactive use (issue2759)
Augie Fackler <durin42@gmail.com>
parents: 14505
diff changeset
   896
            extrakw['stdin'] = subprocess.PIPE
733af5d9f6b2 subrepo: make stdin for svn a pipe for non-interactive use (issue2759)
Augie Fackler <durin42@gmail.com>
parents: 14505
diff changeset
   897
            # Starting in svn 1.5 --non-interactive is a global flag
733af5d9f6b2 subrepo: make stdin for svn a pipe for non-interactive use (issue2759)
Augie Fackler <durin42@gmail.com>
parents: 14505
diff changeset
   898
            # instead of being per-command, but we need to support 1.4 so
733af5d9f6b2 subrepo: make stdin for svn a pipe for non-interactive use (issue2759)
Augie Fackler <durin42@gmail.com>
parents: 14505
diff changeset
   899
            # we have to be intelligent about what commands take
733af5d9f6b2 subrepo: make stdin for svn a pipe for non-interactive use (issue2759)
Augie Fackler <durin42@gmail.com>
parents: 14505
diff changeset
   900
            # --non-interactive.
733af5d9f6b2 subrepo: make stdin for svn a pipe for non-interactive use (issue2759)
Augie Fackler <durin42@gmail.com>
parents: 14505
diff changeset
   901
            if commands[0] in ('update', 'checkout', 'commit'):
733af5d9f6b2 subrepo: make stdin for svn a pipe for non-interactive use (issue2759)
Augie Fackler <durin42@gmail.com>
parents: 14505
diff changeset
   902
                cmd.append('--non-interactive')
14025
1052b1421a48 subrepo: tell Subversion when we are non-interactive (issue2759)
Augie Fackler <durin42@gmail.com>
parents: 13912
diff changeset
   903
        cmd.extend(commands)
14050
9e8a9d45945c subrepo: handle svn tracked/unknown directory collisions
Patrick Mezard <pmezard@gmail.com>
parents: 14025
diff changeset
   904
        if filename is not None:
9e8a9d45945c subrepo: handle svn tracked/unknown directory collisions
Patrick Mezard <pmezard@gmail.com>
parents: 14025
diff changeset
   905
            path = os.path.join(self._ctx._repo.origroot, self._path, filename)
9e8a9d45945c subrepo: handle svn tracked/unknown directory collisions
Patrick Mezard <pmezard@gmail.com>
parents: 14025
diff changeset
   906
            cmd.append(path)
10199
c2e2a5e6c36b subrepo: force en_US.UTF-8 locale when calling svn
Patrick Mezard <pmezard@gmail.com>
parents: 10197
diff changeset
   907
        env = dict(os.environ)
10271
9b38bec5dc29 subrepo: make svn use C locale for portability
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   908
        # Avoid localized output, preserve current locale for everything else.
17705
6929b9c70be9 subrepo: setting LC_MESSAGES only works if LC_ALL is empty or unset
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17441
diff changeset
   909
        lc_all = env.get('LC_ALL')
6929b9c70be9 subrepo: setting LC_MESSAGES only works if LC_ALL is empty or unset
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17441
diff changeset
   910
        if lc_all:
6929b9c70be9 subrepo: setting LC_MESSAGES only works if LC_ALL is empty or unset
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17441
diff changeset
   911
            env['LANG'] = lc_all
6929b9c70be9 subrepo: setting LC_MESSAGES only works if LC_ALL is empty or unset
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17441
diff changeset
   912
            del env['LC_ALL']
10271
9b38bec5dc29 subrepo: make svn use C locale for portability
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   913
        env['LC_MESSAGES'] = 'C'
13108
dcaad69cfd6a subrepo: use subprocess.Popen without the shell
Eric Eisner <ede@mit.edu>
parents: 13107
diff changeset
   914
        p = subprocess.Popen(cmd, bufsize=-1, close_fds=util.closefds,
13014
d1c52354b0a9 subrepo: use subprocess directly to avoid python 2.6 bug
Patrick Mezard <pmezard@gmail.com>
parents: 13013
diff changeset
   915
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE,
14506
733af5d9f6b2 subrepo: make stdin for svn a pipe for non-interactive use (issue2759)
Augie Fackler <durin42@gmail.com>
parents: 14505
diff changeset
   916
                              universal_newlines=True, env=env, **extrakw)
13014
d1c52354b0a9 subrepo: use subprocess directly to avoid python 2.6 bug
Patrick Mezard <pmezard@gmail.com>
parents: 13013
diff changeset
   917
        stdout, stderr = p.communicate()
d1c52354b0a9 subrepo: use subprocess directly to avoid python 2.6 bug
Patrick Mezard <pmezard@gmail.com>
parents: 13013
diff changeset
   918
        stderr = stderr.strip()
14664
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
   919
        if not failok:
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
   920
            if p.returncode:
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
   921
                raise util.Abort(stderr or 'exited with code %d' % p.returncode)
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
   922
            if stderr:
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
   923
                self._ui.warn(stderr + '\n')
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
   924
        return stdout, stderr
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   925
14050
9e8a9d45945c subrepo: handle svn tracked/unknown directory collisions
Patrick Mezard <pmezard@gmail.com>
parents: 14025
diff changeset
   926
    @propertycache
9e8a9d45945c subrepo: handle svn tracked/unknown directory collisions
Patrick Mezard <pmezard@gmail.com>
parents: 14025
diff changeset
   927
    def _svnversion(self):
17707
35674bd95200 subrepo, hghave: use "svn --version --quiet" to determine version number
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17706
diff changeset
   928
        output, err = self._svncommand(['--version', '--quiet'], filename=None)
35674bd95200 subrepo, hghave: use "svn --version --quiet" to determine version number
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17706
diff changeset
   929
        m = re.search(r'^(\d+)\.(\d+)', output)
14050
9e8a9d45945c subrepo: handle svn tracked/unknown directory collisions
Patrick Mezard <pmezard@gmail.com>
parents: 14025
diff changeset
   930
        if not m:
9e8a9d45945c subrepo: handle svn tracked/unknown directory collisions
Patrick Mezard <pmezard@gmail.com>
parents: 14025
diff changeset
   931
            raise util.Abort(_('cannot retrieve svn tool version'))
9e8a9d45945c subrepo: handle svn tracked/unknown directory collisions
Patrick Mezard <pmezard@gmail.com>
parents: 14025
diff changeset
   932
        return (int(m.group(1)), int(m.group(2)))
9e8a9d45945c subrepo: handle svn tracked/unknown directory collisions
Patrick Mezard <pmezard@gmail.com>
parents: 14025
diff changeset
   933
13287
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   934
    def _wcrevs(self):
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   935
        # Get the working directory revision as well as the last
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   936
        # commit revision so we can compare the subrepo state with
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   937
        # both. We used to store the working directory one.
14664
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
   938
        output, err = self._svncommand(['info', '--xml'])
10272
886858b834da subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents: 10271
diff changeset
   939
        doc = xml.dom.minidom.parseString(output)
886858b834da subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents: 10271
diff changeset
   940
        entries = doc.getElementsByTagName('entry')
13287
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   941
        lastrev, rev = '0', '0'
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   942
        if entries:
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   943
            rev = str(entries[0].getAttribute('revision')) or '0'
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   944
            commits = entries[0].getElementsByTagName('commit')
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   945
            if commits:
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   946
                lastrev = str(commits[0].getAttribute('revision')) or '0'
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   947
        return (lastrev, rev)
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   948
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   949
    def _wcrev(self):
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   950
        return self._wcrevs()[0]
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   951
10273
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   952
    def _wcchanged(self):
16530
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
   953
        """Return (changes, extchanges, missing) where changes is True
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
   954
        if the working directory was changed, extchanges is
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
   955
        True if any of these changes concern an external entry and missing
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
   956
        is True if any change is a missing entry.
10273
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   957
        """
14664
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
   958
        output, err = self._svncommand(['status', '--xml'])
16530
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
   959
        externals, changes, missing = [], [], []
10272
886858b834da subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents: 10271
diff changeset
   960
        doc = xml.dom.minidom.parseString(output)
10273
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   961
        for e in doc.getElementsByTagName('entry'):
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   962
            s = e.getElementsByTagName('wc-status')
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   963
            if not s:
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   964
                continue
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   965
            item = s[0].getAttribute('item')
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   966
            props = s[0].getAttribute('props')
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   967
            path = e.getAttribute('path')
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   968
            if item == 'external':
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   969
                externals.append(path)
16530
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
   970
            elif item == 'missing':
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
   971
                missing.append(path)
10273
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   972
            if (item not in ('', 'normal', 'unversioned', 'external')
14994
a115b5ee9c63 subrepo: handle adding svn subrepo with a svn:external file in it (issue2931)
Vasily Titskiy <qehgt0@gmail.com>
parents: 14898
diff changeset
   973
                or props not in ('', 'none', 'normal')):
10273
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   974
                changes.append(path)
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   975
        for path in changes:
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   976
            for ext in externals:
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   977
                if path == ext or path.startswith(ext + os.sep):
16530
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
   978
                    return True, True, bool(missing)
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
   979
        return bool(changes), False, bool(missing)
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   980
13174
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   981
    def dirty(self, ignoreupdate=False):
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   982
        if not self._wcchanged()[0]:
13288
9c3bfba3f48d Merge with stable
Patrick Mezard <pmezard@gmail.com>
parents: 13242 13287
diff changeset
   983
            if self._state[1] in self._wcrevs() or ignoreupdate:
13174
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   984
                return False
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   985
        return True
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   986
16072
bcb973abcc0b subrepo: add basestate method
Matt Mackall <mpm@selenic.com>
parents: 16022
diff changeset
   987
    def basestate(self):
16554
ae2664ee0223 subrepo/svn: fix checked out rev number retrieval (issue2968)
Patrick Mezard <patrick@mezard.eu>
parents: 16530
diff changeset
   988
        lastrev, rev = self._wcrevs()
ae2664ee0223 subrepo/svn: fix checked out rev number retrieval (issue2968)
Patrick Mezard <patrick@mezard.eu>
parents: 16530
diff changeset
   989
        if lastrev != rev:
ae2664ee0223 subrepo/svn: fix checked out rev number retrieval (issue2968)
Patrick Mezard <patrick@mezard.eu>
parents: 16530
diff changeset
   990
            # Last committed rev is not the same than rev. We would
ae2664ee0223 subrepo/svn: fix checked out rev number retrieval (issue2968)
Patrick Mezard <patrick@mezard.eu>
parents: 16530
diff changeset
   991
            # like to take lastrev but we do not know if the subrepo
ae2664ee0223 subrepo/svn: fix checked out rev number retrieval (issue2968)
Patrick Mezard <patrick@mezard.eu>
parents: 16530
diff changeset
   992
            # URL exists at lastrev.  Test it and fallback to rev it
ae2664ee0223 subrepo/svn: fix checked out rev number retrieval (issue2968)
Patrick Mezard <patrick@mezard.eu>
parents: 16530
diff changeset
   993
            # is not there.
ae2664ee0223 subrepo/svn: fix checked out rev number retrieval (issue2968)
Patrick Mezard <patrick@mezard.eu>
parents: 16530
diff changeset
   994
            try:
17035
ba0286e149aa subrepo/svn: make rev number retrieval compatible with svn 1.5 (issue2968)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17025
diff changeset
   995
                self._svncommand(['list', '%s@%s' % (self._state[0], lastrev)])
16554
ae2664ee0223 subrepo/svn: fix checked out rev number retrieval (issue2968)
Patrick Mezard <patrick@mezard.eu>
parents: 16530
diff changeset
   996
                return lastrev
ae2664ee0223 subrepo/svn: fix checked out rev number retrieval (issue2968)
Patrick Mezard <patrick@mezard.eu>
parents: 16530
diff changeset
   997
            except error.Abort:
ae2664ee0223 subrepo/svn: fix checked out rev number retrieval (issue2968)
Patrick Mezard <patrick@mezard.eu>
parents: 16530
diff changeset
   998
                pass
ae2664ee0223 subrepo/svn: fix checked out rev number retrieval (issue2968)
Patrick Mezard <patrick@mezard.eu>
parents: 16530
diff changeset
   999
        return rev
16072
bcb973abcc0b subrepo: add basestate method
Matt Mackall <mpm@selenic.com>
parents: 16022
diff changeset
  1000
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
  1001
    @annotatesubrepoerror
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1002
    def commit(self, text, user, date):
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1003
        # user and date are out of our hands since svn is centralized
16530
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
  1004
        changed, extchanged, missing = self._wcchanged()
10273
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
  1005
        if not changed:
16554
ae2664ee0223 subrepo/svn: fix checked out rev number retrieval (issue2968)
Patrick Mezard <patrick@mezard.eu>
parents: 16530
diff changeset
  1006
            return self.basestate()
10273
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
  1007
        if extchanged:
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
  1008
            # Do not try to commit externals
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
  1009
            raise util.Abort(_('cannot commit svn externals'))
16530
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
  1010
        if missing:
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
  1011
            # svn can commit with missing entries but aborting like hg
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
  1012
            # seems a better approach.
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
  1013
            raise util.Abort(_('cannot commit missing svn entries'))
14664
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
  1014
        commitinfo, err = self._svncommand(['commit', '-m', text])
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1015
        self._ui.status(commitinfo)
12060
63eab3b74ba6 subrepo: use [0-9] instead of [\d] in svn subrepo regex
Martin Geisler <mg@lazybytes.net>
parents: 11961
diff changeset
  1016
        newrev = re.search('Committed revision ([0-9]+).', commitinfo)
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1017
        if not newrev:
16529
3d5d204a08c7 subrepo/svn: abort on commit with missing file (issue3029)
Patrick Mezard <patrick@mezard.eu>
parents: 16527
diff changeset
  1018
            if not commitinfo.strip():
3d5d204a08c7 subrepo/svn: abort on commit with missing file (issue3029)
Patrick Mezard <patrick@mezard.eu>
parents: 16527
diff changeset
  1019
                # Sometimes, our definition of "changed" differs from
3d5d204a08c7 subrepo/svn: abort on commit with missing file (issue3029)
Patrick Mezard <patrick@mezard.eu>
parents: 16527
diff changeset
  1020
                # svn one. For instance, svn ignores missing files
3d5d204a08c7 subrepo/svn: abort on commit with missing file (issue3029)
Patrick Mezard <patrick@mezard.eu>
parents: 16527
diff changeset
  1021
                # when committing. If there are only missing files, no
3d5d204a08c7 subrepo/svn: abort on commit with missing file (issue3029)
Patrick Mezard <patrick@mezard.eu>
parents: 16527
diff changeset
  1022
                # commit is made, no output and no error code.
3d5d204a08c7 subrepo/svn: abort on commit with missing file (issue3029)
Patrick Mezard <patrick@mezard.eu>
parents: 16527
diff changeset
  1023
                raise util.Abort(_('failed to commit svn changes'))
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1024
            raise util.Abort(commitinfo.splitlines()[-1])
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1025
        newrev = newrev.groups()[0]
14664
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
  1026
        self._ui.status(self._svncommand(['update', '-r', newrev])[0])
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1027
        return newrev
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1028
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
  1029
    @annotatesubrepoerror
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1030
    def remove(self):
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1031
        if self.dirty():
10299
e768941f14c1 subrepo: fix errors reported by pylint
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10273
diff changeset
  1032
            self._ui.warn(_('not removing repo %s because '
20869
9658a79968c6 i18n: fix "% inside _()" problems
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20868
diff changeset
  1033
                            'it has changes.\n') % self._path)
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1034
            return
10510
f77f3383c666 i18n: mark more strings for translation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10457
diff changeset
  1035
        self._ui.note(_('removing subrepo %s\n') % self._path)
13013
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
  1036
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
  1037
        def onerror(function, path, excinfo):
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
  1038
            if function is not os.remove:
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
  1039
                raise
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
  1040
            # read-only files cannot be unlinked under Windows
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
  1041
            s = os.stat(path)
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
  1042
            if (s.st_mode & stat.S_IWRITE) != 0:
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
  1043
                raise
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
  1044
            os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE)
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
  1045
            os.remove(path)
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
  1046
13015
82ca0c43bc44 subrepo: prune empty directories when removing svn subrepo
Patrick Mezard <pmezard@gmail.com>
parents: 13014
diff changeset
  1047
        path = self._ctx._repo.wjoin(self._path)
82ca0c43bc44 subrepo: prune empty directories when removing svn subrepo
Patrick Mezard <pmezard@gmail.com>
parents: 13014
diff changeset
  1048
        shutil.rmtree(path, onerror=onerror)
82ca0c43bc44 subrepo: prune empty directories when removing svn subrepo
Patrick Mezard <pmezard@gmail.com>
parents: 13014
diff changeset
  1049
        try:
82ca0c43bc44 subrepo: prune empty directories when removing svn subrepo
Patrick Mezard <pmezard@gmail.com>
parents: 13014
diff changeset
  1050
            os.removedirs(os.path.dirname(path))
82ca0c43bc44 subrepo: prune empty directories when removing svn subrepo
Patrick Mezard <pmezard@gmail.com>
parents: 13014
diff changeset
  1051
        except OSError:
82ca0c43bc44 subrepo: prune empty directories when removing svn subrepo
Patrick Mezard <pmezard@gmail.com>
parents: 13014
diff changeset
  1052
            pass
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1053
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
  1054
    @annotatesubrepoerror
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 13287
diff changeset
  1055
    def get(self, state, overwrite=False):
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 13287
diff changeset
  1056
        if overwrite:
13332
927e3940bfc3 subrepo: fix update -C with svn subrepos when cwd != repo.root
Patrick Mezard <pmezard@gmail.com>
parents: 13322
diff changeset
  1057
            self._svncommand(['revert', '--recursive'])
14050
9e8a9d45945c subrepo: handle svn tracked/unknown directory collisions
Patrick Mezard <pmezard@gmail.com>
parents: 14025
diff changeset
  1058
        args = ['checkout']
9e8a9d45945c subrepo: handle svn tracked/unknown directory collisions
Patrick Mezard <pmezard@gmail.com>
parents: 14025
diff changeset
  1059
        if self._svnversion >= (1, 5):
9e8a9d45945c subrepo: handle svn tracked/unknown directory collisions
Patrick Mezard <pmezard@gmail.com>
parents: 14025
diff changeset
  1060
            args.append('--force')
14820
7ef125fa9b35 subrepo: correct revision in svn checkout
Eli Carter <eli.carter@tektronix.com>
parents: 14766
diff changeset
  1061
        # The revision must be specified at the end of the URL to properly
7ef125fa9b35 subrepo: correct revision in svn checkout
Eli Carter <eli.carter@tektronix.com>
parents: 14766
diff changeset
  1062
        # update to a directory which has since been deleted and recreated.
7ef125fa9b35 subrepo: correct revision in svn checkout
Eli Carter <eli.carter@tektronix.com>
parents: 14766
diff changeset
  1063
        args.append('%s@%s' % (state[0], state[1]))
14664
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
  1064
        status, err = self._svncommand(args, failok=True)
21567
5900bc09e684 subrepo: avoid sanitizing ".hg/hgrc" in meta data area for non-hg subrepos
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21566
diff changeset
  1065
        _sanitize(self._ui, self._ctx._repo.wjoin(self._path), '.svn')
12060
63eab3b74ba6 subrepo: use [0-9] instead of [\d] in svn subrepo regex
Martin Geisler <mg@lazybytes.net>
parents: 11961
diff changeset
  1066
        if not re.search('Checked out revision [0-9]+.', status):
14664
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
  1067
            if ('is already a working copy for a different URL' in err
16530
e37199a1f9d4 subrepo/svn: improve error message on missing files
Patrick Mezard <patrick@mezard.eu>
parents: 16529
diff changeset
  1068
                and (self._wcchanged()[:2] == (False, False))):
14664
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
  1069
                # obstructed but clean working copy, so just blow it away.
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
  1070
                self.remove()
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
  1071
                self.get(state, overwrite=False)
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
  1072
                return
0ae98cd2a83f svn subrepos: work around checkout obstructions (issue2752)
Augie Fackler <durin42@gmail.com>
parents: 14556
diff changeset
  1073
            raise util.Abort((status or err).splitlines()[-1])
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1074
        self._ui.status(status)
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1075
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
  1076
    @annotatesubrepoerror
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1077
    def merge(self, state):
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1078
        old = self._state[1]
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1079
        new = state[1]
16555
4955e7bf085c subrepo/svn: cache _wcrev() value in merge()
Patrick Mezard <patrick@mezard.eu>
parents: 16554
diff changeset
  1080
        wcrev = self._wcrev()
4955e7bf085c subrepo/svn: cache _wcrev() value in merge()
Patrick Mezard <patrick@mezard.eu>
parents: 16554
diff changeset
  1081
        if new != wcrev:
4955e7bf085c subrepo/svn: cache _wcrev() value in merge()
Patrick Mezard <patrick@mezard.eu>
parents: 16554
diff changeset
  1082
            dirty = old == wcrev or self._wcchanged()[0]
4955e7bf085c subrepo/svn: cache _wcrev() value in merge()
Patrick Mezard <patrick@mezard.eu>
parents: 16554
diff changeset
  1083
            if _updateprompt(self._ui, self, dirty, wcrev, new):
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1084
                self.get(state, False)
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1085
15708
309e49491253 push: propagate --new-branch and --ssh options when pushing subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15614
diff changeset
  1086
    def push(self, opts):
11455
3827728b54e2 subrepo: fix silent push failure for SVN (issue2241)
Matt Mackall <mpm@selenic.com>
parents: 11117
diff changeset
  1087
        # push is a no-op for SVN
3827728b54e2 subrepo: fix silent push failure for SVN (issue2241)
Matt Mackall <mpm@selenic.com>
parents: 11117
diff changeset
  1088
        return True
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1089
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
  1090
    @annotatesubrepoerror
12322
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
  1091
    def files(self):
16450
c9c8c9053119 archive: make it work with svn subrepos (issue3308)
Patrick Mezard <patrick@mezard.eu>
parents: 16196
diff changeset
  1092
        output = self._svncommand(['list', '--recursive', '--xml'])[0]
c9c8c9053119 archive: make it work with svn subrepos (issue3308)
Patrick Mezard <patrick@mezard.eu>
parents: 16196
diff changeset
  1093
        doc = xml.dom.minidom.parseString(output)
c9c8c9053119 archive: make it work with svn subrepos (issue3308)
Patrick Mezard <patrick@mezard.eu>
parents: 16196
diff changeset
  1094
        paths = []
c9c8c9053119 archive: make it work with svn subrepos (issue3308)
Patrick Mezard <patrick@mezard.eu>
parents: 16196
diff changeset
  1095
        for e in doc.getElementsByTagName('entry'):
c9c8c9053119 archive: make it work with svn subrepos (issue3308)
Patrick Mezard <patrick@mezard.eu>
parents: 16196
diff changeset
  1096
            kind = str(e.getAttribute('kind'))
c9c8c9053119 archive: make it work with svn subrepos (issue3308)
Patrick Mezard <patrick@mezard.eu>
parents: 16196
diff changeset
  1097
            if kind != 'file':
c9c8c9053119 archive: make it work with svn subrepos (issue3308)
Patrick Mezard <patrick@mezard.eu>
parents: 16196
diff changeset
  1098
                continue
c9c8c9053119 archive: make it work with svn subrepos (issue3308)
Patrick Mezard <patrick@mezard.eu>
parents: 16196
diff changeset
  1099
            name = ''.join(c.data for c
c9c8c9053119 archive: make it work with svn subrepos (issue3308)
Patrick Mezard <patrick@mezard.eu>
parents: 16196
diff changeset
  1100
                           in e.getElementsByTagName('name')[0].childNodes
c9c8c9053119 archive: make it work with svn subrepos (issue3308)
Patrick Mezard <patrick@mezard.eu>
parents: 16196
diff changeset
  1101
                           if c.nodeType == c.TEXT_NODE)
17441
cb12d3ce5607 subrepo: encode unicode path names (issue3610)
Bryan O'Sullivan <bryano@fb.com>
parents: 17191
diff changeset
  1102
            paths.append(name.encode('utf-8'))
16450
c9c8c9053119 archive: make it work with svn subrepos (issue3308)
Patrick Mezard <patrick@mezard.eu>
parents: 16196
diff changeset
  1103
        return paths
12322
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
  1104
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
  1105
    def filedata(self, name):
16450
c9c8c9053119 archive: make it work with svn subrepos (issue3308)
Patrick Mezard <patrick@mezard.eu>
parents: 16196
diff changeset
  1106
        return self._svncommand(['cat'], name)[0]
12322
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
  1107
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
  1108
13106
c869bd9e1193 subrepo: gitsubrepo should inherit from abstractsubrepo
Eric Eisner <ede@mit.edu>
parents: 13097
diff changeset
  1109
class gitsubrepo(abstractsubrepo):
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1110
    def __init__(self, ctx, path, state):
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1111
        self._state = state
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1112
        self._ctx = ctx
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
  1113
        self._path = path
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
  1114
        self._relpath = os.path.join(reporelpath(ctx._repo), path)
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
  1115
        self._abspath = ctx._repo.wjoin(path)
13460
64bb8e586a92 subrepo: expand relative sources for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13432
diff changeset
  1116
        self._subparent = ctx._repo
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1117
        self._ui = ctx._repo.ui
17024
33b057778cd2 subrepo: warn user if Git is not version 1.6.0 or higher
Benjamin Pollack <benjamin@bitquabit.com>
parents: 16596
diff changeset
  1118
        self._ensuregit()
33b057778cd2 subrepo: warn user if Git is not version 1.6.0 or higher
Benjamin Pollack <benjamin@bitquabit.com>
parents: 16596
diff changeset
  1119
33b057778cd2 subrepo: warn user if Git is not version 1.6.0 or higher
Benjamin Pollack <benjamin@bitquabit.com>
parents: 16596
diff changeset
  1120
    def _ensuregit(self):
17025
8ad08dcab7d9 subrepo: support Git being named "git.cmd" on Windows (issue3173)
Benjamin Pollack <benjamin@bitquabit.com>
parents: 17024
diff changeset
  1121
        try:
8ad08dcab7d9 subrepo: support Git being named "git.cmd" on Windows (issue3173)
Benjamin Pollack <benjamin@bitquabit.com>
parents: 17024
diff changeset
  1122
            self._gitexecutable = 'git'
8ad08dcab7d9 subrepo: support Git being named "git.cmd" on Windows (issue3173)
Benjamin Pollack <benjamin@bitquabit.com>
parents: 17024
diff changeset
  1123
            out, err = self._gitnodir(['--version'])
8ad08dcab7d9 subrepo: support Git being named "git.cmd" on Windows (issue3173)
Benjamin Pollack <benjamin@bitquabit.com>
parents: 17024
diff changeset
  1124
        except OSError, e:
8ad08dcab7d9 subrepo: support Git being named "git.cmd" on Windows (issue3173)
Benjamin Pollack <benjamin@bitquabit.com>
parents: 17024
diff changeset
  1125
            if e.errno != 2 or os.name != 'nt':
8ad08dcab7d9 subrepo: support Git being named "git.cmd" on Windows (issue3173)
Benjamin Pollack <benjamin@bitquabit.com>
parents: 17024
diff changeset
  1126
                raise
8ad08dcab7d9 subrepo: support Git being named "git.cmd" on Windows (issue3173)
Benjamin Pollack <benjamin@bitquabit.com>
parents: 17024
diff changeset
  1127
            self._gitexecutable = 'git.cmd'
8ad08dcab7d9 subrepo: support Git being named "git.cmd" on Windows (issue3173)
Benjamin Pollack <benjamin@bitquabit.com>
parents: 17024
diff changeset
  1128
            out, err = self._gitnodir(['--version'])
20840
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1129
        versionstatus = self._checkversion(out)
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1130
        if versionstatus == 'unknown':
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1131
            self._ui.warn(_('cannot retrieve git version\n'))
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1132
        elif versionstatus == 'abort':
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1133
            raise util.Abort(_('git subrepo requires at least 1.6.0 or later'))
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1134
        elif versionstatus == 'warning':
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1135
            self._ui.warn(_('git subrepo requires at least 1.6.0 or later\n'))
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1136
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1137
    @staticmethod
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1138
    def _checkversion(out):
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1139
        '''ensure git version is new enough
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1140
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1141
        >>> _checkversion = gitsubrepo._checkversion
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1142
        >>> _checkversion('git version 1.6.0')
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1143
        'ok'
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1144
        >>> _checkversion('git version 1.8.5')
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1145
        'ok'
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1146
        >>> _checkversion('git version 1.4.0')
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1147
        'abort'
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1148
        >>> _checkversion('git version 1.5.0')
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1149
        'warning'
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1150
        >>> _checkversion('git version 1.9-rc0')
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1151
        'ok'
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1152
        >>> _checkversion('git version 1.9.0.265.g81cdec2')
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1153
        'ok'
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1154
        >>> _checkversion('git version 1.9.0.GIT')
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1155
        'ok'
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1156
        >>> _checkversion('git version 12345')
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1157
        'unknown'
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1158
        >>> _checkversion('no')
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1159
        'unknown'
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1160
        '''
20815
6a2acb0d9352 subrepo: only retrieve the first two components of the Git version
Siddharth Agarwal <sid0@fb.com>
parents: 20319
diff changeset
  1161
        m = re.search(r'^git version (\d+)\.(\d+)', out)
17024
33b057778cd2 subrepo: warn user if Git is not version 1.6.0 or higher
Benjamin Pollack <benjamin@bitquabit.com>
parents: 16596
diff changeset
  1162
        if not m:
20840
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1163
            return 'unknown'
20816
0c32fafd4b3b subrepo: convert matched string to integer before comparing Git version
Siddharth Agarwal <sid0@fb.com>
parents: 20815
diff changeset
  1164
        version = (int(m.group(1)), int(m.group(2)))
17024
33b057778cd2 subrepo: warn user if Git is not version 1.6.0 or higher
Benjamin Pollack <benjamin@bitquabit.com>
parents: 16596
diff changeset
  1165
        # git 1.4.0 can't work at all, but 1.5.X can in at least some cases,
33b057778cd2 subrepo: warn user if Git is not version 1.6.0 or higher
Benjamin Pollack <benjamin@bitquabit.com>
parents: 16596
diff changeset
  1166
        # despite the docstring comment.  For now, error on 1.4.0, warn on
33b057778cd2 subrepo: warn user if Git is not version 1.6.0 or higher
Benjamin Pollack <benjamin@bitquabit.com>
parents: 16596
diff changeset
  1167
        # 1.5.0 but attempt to continue.
20815
6a2acb0d9352 subrepo: only retrieve the first two components of the Git version
Siddharth Agarwal <sid0@fb.com>
parents: 20319
diff changeset
  1168
        if version < (1, 5):
20840
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1169
            return 'abort'
20815
6a2acb0d9352 subrepo: only retrieve the first two components of the Git version
Siddharth Agarwal <sid0@fb.com>
parents: 20319
diff changeset
  1170
        elif version < (1, 6):
20840
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1171
            return 'warning'
308344d80fe5 subrepo: factor out Git version check to add doctests
Siddharth Agarwal <sid0@fb.com>
parents: 20818
diff changeset
  1172
        return 'ok'
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1173
13095
49c7e875482d subrepo: use environment variable instead of git commit's --date
Eric Eisner <ede@mit.edu>
parents: 13094
diff changeset
  1174
    def _gitcommand(self, commands, env=None, stream=False):
49c7e875482d subrepo: use environment variable instead of git commit's --date
Eric Eisner <ede@mit.edu>
parents: 13094
diff changeset
  1175
        return self._gitdir(commands, env=env, stream=stream)[0]
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1176
13095
49c7e875482d subrepo: use environment variable instead of git commit's --date
Eric Eisner <ede@mit.edu>
parents: 13094
diff changeset
  1177
    def _gitdir(self, commands, env=None, stream=False):
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
  1178
        return self._gitnodir(commands, env=env, stream=stream,
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
  1179
                              cwd=self._abspath)
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1180
13095
49c7e875482d subrepo: use environment variable instead of git commit's --date
Eric Eisner <ede@mit.edu>
parents: 13094
diff changeset
  1181
    def _gitnodir(self, commands, env=None, stream=False, cwd=None):
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1182
        """Calls the git command
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1183
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17191
diff changeset
  1184
        The methods tries to call the git command. versions prior to 1.6.0
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1185
        are not supported and very probably fail.
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1186
        """
13110
cad35f06c031 subrepo: show git command with --debug
Eric Eisner <ede@mit.edu>
parents: 13109
diff changeset
  1187
        self._ui.debug('%s: git %s\n' % (self._relpath, ' '.join(commands)))
13111
560b8001f765 subrepo: silence git output when ui.quiet is set
Eric Eisner <ede@mit.edu>
parents: 13110
diff changeset
  1188
        # unless ui.quiet is set, print git's stderr,
560b8001f765 subrepo: silence git output when ui.quiet is set
Eric Eisner <ede@mit.edu>
parents: 13110
diff changeset
  1189
        # which is mostly progress and useful info
560b8001f765 subrepo: silence git output when ui.quiet is set
Eric Eisner <ede@mit.edu>
parents: 13110
diff changeset
  1190
        errpipe = None
560b8001f765 subrepo: silence git output when ui.quiet is set
Eric Eisner <ede@mit.edu>
parents: 13110
diff changeset
  1191
        if self._ui.quiet:
560b8001f765 subrepo: silence git output when ui.quiet is set
Eric Eisner <ede@mit.edu>
parents: 13110
diff changeset
  1192
            errpipe = open(os.devnull, 'w')
17025
8ad08dcab7d9 subrepo: support Git being named "git.cmd" on Windows (issue3173)
Benjamin Pollack <benjamin@bitquabit.com>
parents: 17024
diff changeset
  1193
        p = subprocess.Popen([self._gitexecutable] + commands, bufsize=-1,
8ad08dcab7d9 subrepo: support Git being named "git.cmd" on Windows (issue3173)
Benjamin Pollack <benjamin@bitquabit.com>
parents: 17024
diff changeset
  1194
                             cwd=cwd, env=env, close_fds=util.closefds,
13111
560b8001f765 subrepo: silence git output when ui.quiet is set
Eric Eisner <ede@mit.edu>
parents: 13110
diff changeset
  1195
                             stdout=subprocess.PIPE, stderr=errpipe)
13027
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
  1196
        if stream:
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
  1197
            return p.stdout, None
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
  1198
13085
b4814f1f415c subrepo: strip gitcommand output
Eric Eisner <ede@mit.edu>
parents: 13029
diff changeset
  1199
        retdata = p.stdout.read().strip()
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1200
        # wait for the child to exit to avoid race condition.
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1201
        p.wait()
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1202
13107
3bc237b0eaea subrepo: treat git error code 1 as success
Eric Eisner <ede@mit.edu>
parents: 13106
diff changeset
  1203
        if p.returncode != 0 and p.returncode != 1:
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1204
            # there are certain error codes that are ok
13110
cad35f06c031 subrepo: show git command with --debug
Eric Eisner <ede@mit.edu>
parents: 13109
diff changeset
  1205
            command = commands[0]
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
  1206
            if command in ('cat-file', 'symbolic-ref'):
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1207
                return retdata, p.returncode
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1208
            # for all others, abort
13110
cad35f06c031 subrepo: show git command with --debug
Eric Eisner <ede@mit.edu>
parents: 13109
diff changeset
  1209
            raise util.Abort('git %s error %d in %s' %
cad35f06c031 subrepo: show git command with --debug
Eric Eisner <ede@mit.edu>
parents: 13109
diff changeset
  1210
                             (command, p.returncode, self._relpath))
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1211
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1212
        return retdata, p.returncode
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1213
13553
dea6efdd7ec4 subrepo: don't crash when git repo is missing
Eric Eisner <ede@mit.edu>
parents: 13531
diff changeset
  1214
    def _gitmissing(self):
dea6efdd7ec4 subrepo: don't crash when git repo is missing
Eric Eisner <ede@mit.edu>
parents: 13531
diff changeset
  1215
        return not os.path.exists(os.path.join(self._abspath, '.git'))
dea6efdd7ec4 subrepo: don't crash when git repo is missing
Eric Eisner <ede@mit.edu>
parents: 13531
diff changeset
  1216
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1217
    def _gitstate(self):
13085
b4814f1f415c subrepo: strip gitcommand output
Eric Eisner <ede@mit.edu>
parents: 13029
diff changeset
  1218
        return self._gitcommand(['rev-parse', 'HEAD'])
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1219
13152
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
  1220
    def _gitcurrentbranch(self):
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
  1221
        current, err = self._gitdir(['symbolic-ref', 'HEAD', '--quiet'])
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
  1222
        if err:
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
  1223
            current = None
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
  1224
        return current
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
  1225
13569
3ab3b892d223 subrepo: show the source that git pulls
Eric Eisner <ede@mit.edu>
parents: 13560
diff changeset
  1226
    def _gitremote(self, remote):
3ab3b892d223 subrepo: show the source that git pulls
Eric Eisner <ede@mit.edu>
parents: 13560
diff changeset
  1227
        out = self._gitcommand(['remote', 'show', '-n', remote])
3ab3b892d223 subrepo: show the source that git pulls
Eric Eisner <ede@mit.edu>
parents: 13560
diff changeset
  1228
        line = out.split('\n')[1]
3ab3b892d223 subrepo: show the source that git pulls
Eric Eisner <ede@mit.edu>
parents: 13560
diff changeset
  1229
        i = line.index('URL: ') + len('URL: ')
3ab3b892d223 subrepo: show the source that git pulls
Eric Eisner <ede@mit.edu>
parents: 13560
diff changeset
  1230
        return line[i:]
3ab3b892d223 subrepo: show the source that git pulls
Eric Eisner <ede@mit.edu>
parents: 13560
diff changeset
  1231
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1232
    def _githavelocally(self, revision):
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1233
        out, code = self._gitdir(['cat-file', '-e', revision])
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1234
        return code == 0
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1235
13029
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
  1236
    def _gitisancestor(self, r1, r2):
13085
b4814f1f415c subrepo: strip gitcommand output
Eric Eisner <ede@mit.edu>
parents: 13029
diff changeset
  1237
        base = self._gitcommand(['merge-base', r1, r2])
13029
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
  1238
        return base == r1
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
  1239
14440
96f1c1b14154 subrepo: bare git repos considered dirty
Paul Molodowitch <pm@stanfordalumni.org>
parents: 14417
diff changeset
  1240
    def _gitisbare(self):
96f1c1b14154 subrepo: bare git repos considered dirty
Paul Molodowitch <pm@stanfordalumni.org>
parents: 14417
diff changeset
  1241
        return self._gitcommand(['config', '--bool', 'core.bare']) == 'true'
96f1c1b14154 subrepo: bare git repos considered dirty
Paul Molodowitch <pm@stanfordalumni.org>
parents: 14417
diff changeset
  1242
15531
0810ccc51f0a subrepo: fix git status false positive (issue3109)
Eric Roshan Eisner <ede@alum.mit.edu>
parents: 15498
diff changeset
  1243
    def _gitupdatestat(self):
0810ccc51f0a subrepo: fix git status false positive (issue3109)
Eric Roshan Eisner <ede@alum.mit.edu>
parents: 15498
diff changeset
  1244
        """This must be run before git diff-index.
0810ccc51f0a subrepo: fix git status false positive (issue3109)
Eric Roshan Eisner <ede@alum.mit.edu>
parents: 15498
diff changeset
  1245
        diff-index only looks at changes to file stat;
0810ccc51f0a subrepo: fix git status false positive (issue3109)
Eric Roshan Eisner <ede@alum.mit.edu>
parents: 15498
diff changeset
  1246
        this command looks at file contents and updates the stat."""
0810ccc51f0a subrepo: fix git status false positive (issue3109)
Eric Roshan Eisner <ede@alum.mit.edu>
parents: 15498
diff changeset
  1247
        self._gitcommand(['update-index', '-q', '--refresh'])
0810ccc51f0a subrepo: fix git status false positive (issue3109)
Eric Roshan Eisner <ede@alum.mit.edu>
parents: 15498
diff changeset
  1248
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1249
    def _gitbranchmap(self):
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1250
        '''returns 2 things:
13086
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
  1251
        a map from git branch to revision
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1252
        a map from revision to branches'''
13086
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
  1253
        branch2rev = {}
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
  1254
        rev2branch = {}
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1255
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
  1256
        out = self._gitcommand(['for-each-ref', '--format',
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1257
                                '%(objectname) %(refname)'])
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1258
        for line in out.split('\n'):
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1259
            revision, ref = line.split(' ')
13465
fa88fabc1d66 subrepo: disallow all unknown git ref types
Eric Eisner <ede@mit.edu>
parents: 13460
diff changeset
  1260
            if (not ref.startswith('refs/heads/') and
fa88fabc1d66 subrepo: disallow all unknown git ref types
Eric Eisner <ede@mit.edu>
parents: 13460
diff changeset
  1261
                not ref.startswith('refs/remotes/')):
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1262
                continue
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
  1263
            if ref.startswith('refs/remotes/') and ref.endswith('/HEAD'):
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1264
                continue # ignore remote/HEAD redirects
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
  1265
            branch2rev[ref] = revision
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
  1266
            rev2branch.setdefault(revision, []).append(ref)
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1267
        return branch2rev, rev2branch
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1268
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1269
    def _gittracking(self, branches):
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1270
        'return map of remote branch to local tracking branch'
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1271
        # assumes no more than one local tracking branch for each remote
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1272
        tracking = {}
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1273
        for b in branches:
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1274
            if b.startswith('refs/remotes/'):
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1275
                continue
15234
5d700b7edd85 subrepo: fix git branch tracking logic (issue2920)
Eric Roshan Eisner <ede@alum.mit.edu>
parents: 15208
diff changeset
  1276
            bname = b.split('/', 2)[2]
5d700b7edd85 subrepo: fix git branch tracking logic (issue2920)
Eric Roshan Eisner <ede@alum.mit.edu>
parents: 15208
diff changeset
  1277
            remote = self._gitcommand(['config', 'branch.%s.remote' % bname])
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1278
            if remote:
15234
5d700b7edd85 subrepo: fix git branch tracking logic (issue2920)
Eric Roshan Eisner <ede@alum.mit.edu>
parents: 15208
diff changeset
  1279
                ref = self._gitcommand(['config', 'branch.%s.merge' % bname])
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1280
                tracking['refs/remotes/%s/%s' %
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1281
                         (remote, ref.split('/', 2)[2])] = b
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1282
        return tracking
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1283
13460
64bb8e586a92 subrepo: expand relative sources for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13432
diff changeset
  1284
    def _abssource(self, source):
13692
a7c9735307bd subrepo: recognize scp-style paths as git URLs
Eric Eisner <ede@mit.edu>
parents: 13559
diff changeset
  1285
        if '://' not in source:
a7c9735307bd subrepo: recognize scp-style paths as git URLs
Eric Eisner <ede@mit.edu>
parents: 13559
diff changeset
  1286
            # recognize the scp syntax as an absolute source
a7c9735307bd subrepo: recognize scp-style paths as git URLs
Eric Eisner <ede@mit.edu>
parents: 13559
diff changeset
  1287
            colon = source.find(':')
a7c9735307bd subrepo: recognize scp-style paths as git URLs
Eric Eisner <ede@mit.edu>
parents: 13559
diff changeset
  1288
            if colon != -1 and '/' not in source[:colon]:
a7c9735307bd subrepo: recognize scp-style paths as git URLs
Eric Eisner <ede@mit.edu>
parents: 13559
diff changeset
  1289
                return source
13460
64bb8e586a92 subrepo: expand relative sources for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13432
diff changeset
  1290
        self._subsource = source
64bb8e586a92 subrepo: expand relative sources for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13432
diff changeset
  1291
        return _abssource(self)
64bb8e586a92 subrepo: expand relative sources for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13432
diff changeset
  1292
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
  1293
    def _fetch(self, source, revision):
13553
dea6efdd7ec4 subrepo: don't crash when git repo is missing
Eric Eisner <ede@mit.edu>
parents: 13531
diff changeset
  1294
        if self._gitmissing():
13525
c12088259f64 subrepo: show the source that git clones
Eric Eisner <ede@mit.edu>
parents: 13466
diff changeset
  1295
            source = self._abssource(source)
c12088259f64 subrepo: show the source that git clones
Eric Eisner <ede@mit.edu>
parents: 13466
diff changeset
  1296
            self._ui.status(_('cloning subrepo %s from %s\n') %
c12088259f64 subrepo: show the source that git clones
Eric Eisner <ede@mit.edu>
parents: 13466
diff changeset
  1297
                            (self._relpath, source))
c12088259f64 subrepo: show the source that git clones
Eric Eisner <ede@mit.edu>
parents: 13466
diff changeset
  1298
            self._gitnodir(['clone', source, self._abspath])
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
  1299
        if self._githavelocally(revision):
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
  1300
            return
13569
3ab3b892d223 subrepo: show the source that git pulls
Eric Eisner <ede@mit.edu>
parents: 13560
diff changeset
  1301
        self._ui.status(_('pulling subrepo %s from %s\n') %
3ab3b892d223 subrepo: show the source that git pulls
Eric Eisner <ede@mit.edu>
parents: 13560
diff changeset
  1302
                        (self._relpath, self._gitremote('origin')))
13466
f2295f7cd468 subrepo: only attempt pulling from git's origin
Eric Eisner <ede@mit.edu>
parents: 13465
diff changeset
  1303
        # try only origin: the originally cloned repo
13097
c922aacf6f1f subrepo: drop arguments unsupported by old git
Eric Eisner <ede@mit.edu>
parents: 13096
diff changeset
  1304
        self._gitcommand(['fetch'])
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
  1305
        if not self._githavelocally(revision):
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
  1306
            raise util.Abort(_("revision %s does not exist in subrepo %s\n") %
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
  1307
                               (revision, self._relpath))
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
  1308
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
  1309
    @annotatesubrepoerror
13179
b512a7074349 subrepo: support ignoreupdate in gitsubrepo's dirty()
Eric Eisner <ede@mit.edu>
parents: 13178
diff changeset
  1310
    def dirty(self, ignoreupdate=False):
13553
dea6efdd7ec4 subrepo: don't crash when git repo is missing
Eric Eisner <ede@mit.edu>
parents: 13531
diff changeset
  1311
        if self._gitmissing():
14469
2fdea636f254 subrepo: don't crash when git .hgsubstate is empty (issue2716)
Eric Eisner <ede@alum.mit.edu>
parents: 14205
diff changeset
  1312
            return self._state[1] != ''
14440
96f1c1b14154 subrepo: bare git repos considered dirty
Paul Molodowitch <pm@stanfordalumni.org>
parents: 14417
diff changeset
  1313
        if self._gitisbare():
96f1c1b14154 subrepo: bare git repos considered dirty
Paul Molodowitch <pm@stanfordalumni.org>
parents: 14417
diff changeset
  1314
            return True
13179
b512a7074349 subrepo: support ignoreupdate in gitsubrepo's dirty()
Eric Eisner <ede@mit.edu>
parents: 13178
diff changeset
  1315
        if not ignoreupdate and self._state[1] != self._gitstate():
13325
7ebdfa37842e subrepo: clarify comments in dirty() methods
Kevin Bullock <kbullock@ringworld.org>
parents: 13324
diff changeset
  1316
            # different version checked out
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1317
            return True
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1318
        # check for staged changes or modified files; ignore untracked files
15531
0810ccc51f0a subrepo: fix git status false positive (issue3109)
Eric Roshan Eisner <ede@alum.mit.edu>
parents: 15498
diff changeset
  1319
        self._gitupdatestat()
13153
dca5488f0e4f subrepo: use low-level git-diff-index for dirty()
Eric Eisner <ede@mit.edu>
parents: 13152
diff changeset
  1320
        out, code = self._gitdir(['diff-index', '--quiet', 'HEAD'])
dca5488f0e4f subrepo: use low-level git-diff-index for dirty()
Eric Eisner <ede@mit.edu>
parents: 13152
diff changeset
  1321
        return code == 1
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1322
16072
bcb973abcc0b subrepo: add basestate method
Matt Mackall <mpm@selenic.com>
parents: 16022
diff changeset
  1323
    def basestate(self):
bcb973abcc0b subrepo: add basestate method
Matt Mackall <mpm@selenic.com>
parents: 16022
diff changeset
  1324
        return self._gitstate()
bcb973abcc0b subrepo: add basestate method
Matt Mackall <mpm@selenic.com>
parents: 16022
diff changeset
  1325
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
  1326
    @annotatesubrepoerror
13323
d8d478f9ee0f merge with stable
Martin Geisler <mg@aragost.com>
parents: 13288 13322
diff changeset
  1327
    def get(self, state, overwrite=False):
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
  1328
        source, revision, kind = state
14469
2fdea636f254 subrepo: don't crash when git .hgsubstate is empty (issue2716)
Eric Eisner <ede@alum.mit.edu>
parents: 14205
diff changeset
  1329
        if not revision:
2fdea636f254 subrepo: don't crash when git .hgsubstate is empty (issue2716)
Eric Eisner <ede@alum.mit.edu>
parents: 14205
diff changeset
  1330
            self.remove()
2fdea636f254 subrepo: don't crash when git .hgsubstate is empty (issue2716)
Eric Eisner <ede@alum.mit.edu>
parents: 14205
diff changeset
  1331
            return
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
  1332
        self._fetch(source, revision)
12996
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1333
        # if the repo was set to be bare, unbare it
14440
96f1c1b14154 subrepo: bare git repos considered dirty
Paul Molodowitch <pm@stanfordalumni.org>
parents: 14417
diff changeset
  1334
        if self._gitisbare():
12996
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1335
            self._gitcommand(['config', 'core.bare', 'false'])
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1336
            if self._gitstate() == revision:
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1337
                self._gitcommand(['reset', '--hard', 'HEAD'])
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1338
                return
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1339
        elif self._gitstate() == revision:
13324
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1340
            if overwrite:
13927
518344d02761 subrepo: trailing whitespace cleanup
Augie Fackler <durin42@gmail.com>
parents: 13913
diff changeset
  1341
                # first reset the index to unmark new files for commit, because
13324
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1342
                # reset --hard will otherwise throw away files added for commit,
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1343
                # not just unmark them.
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1344
                self._gitcommand(['reset', 'HEAD'])
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1345
                self._gitcommand(['reset', '--hard', 'HEAD'])
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1346
            return
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1347
        branch2rev, rev2branch = self._gitbranchmap()
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1348
13324
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1349
        def checkout(args):
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1350
            cmd = ['checkout']
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1351
            if overwrite:
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1352
                # first reset the index to unmark new files for commit, because
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1353
                # the -f option will otherwise throw away files added for
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1354
                # commit, not just unmark them.
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1355
                self._gitcommand(['reset', 'HEAD'])
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1356
                cmd.append('-f')
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1357
            self._gitcommand(cmd + args)
21567
5900bc09e684 subrepo: avoid sanitizing ".hg/hgrc" in meta data area for non-hg subrepos
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21566
diff changeset
  1358
            _sanitize(self._ui, self._abspath, '.git')
13324
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1359
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1360
        def rawcheckout():
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1361
            # no branch to checkout, check it out with no branch
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
  1362
            self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
  1363
                          self._relpath)
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
  1364
            self._ui.warn(_('check out a git branch if you intend '
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
  1365
                            'to make changes\n'))
13324
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1366
            checkout(['-q', revision])
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1367
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1368
        if revision not in rev2branch:
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1369
            rawcheckout()
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1370
            return
13086
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
  1371
        branches = rev2branch[revision]
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1372
        firstlocalbranch = None
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1373
        for b in branches:
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
  1374
            if b == 'refs/heads/master':
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1375
                # master trumps all other branches
13324
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1376
                checkout(['refs/heads/master'])
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1377
                return
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
  1378
            if not firstlocalbranch and not b.startswith('refs/remotes/'):
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1379
                firstlocalbranch = b
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1380
        if firstlocalbranch:
13324
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1381
            checkout([firstlocalbranch])
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1382
            return
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1383
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1384
        tracking = self._gittracking(branch2rev.keys())
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1385
        # choose a remote branch already tracked if possible
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1386
        remote = branches[0]
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1387
        if remote not in tracking:
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1388
            for b in branches:
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1389
                if b in tracking:
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1390
                    remote = b
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1391
                    break
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1392
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1393
        if remote not in tracking:
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1394
            # create a new local tracking branch
19012
811e253226c3 subrepo: clone of git sub-repository creates incorrect git branch (issue3870)
pozheg <pozheg@gmail.com>
parents: 18967
diff changeset
  1395
            local = remote.split('/', 3)[3]
13324
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1396
            checkout(['-b', local, remote])
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1397
        elif self._gitisancestor(branch2rev[tracking[remote]], remote):
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1398
            # When updating to a tracked remote branch,
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1399
            # if the local tracking branch is downstream of it,
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1400
            # a normal `git pull` would have performed a "fast-forward merge"
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1401
            # which is equivalent to updating the local branch to the remote.
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1402
            # Since we are only looking at branching at update, we need to
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1403
            # detect this situation and perform this action lazily.
13152
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
  1404
            if tracking[remote] != self._gitcurrentbranch():
13324
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
  1405
                checkout([tracking[remote]])
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1406
            self._gitcommand(['merge', '--ff', remote])
21567
5900bc09e684 subrepo: avoid sanitizing ".hg/hgrc" in meta data area for non-hg subrepos
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21566
diff changeset
  1407
            _sanitize(self._ui, self._abspath, '.git')
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1408
        else:
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1409
            # a real merge would be required, just checkout the revision
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
  1410
            rawcheckout()
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
  1411
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
  1412
    @annotatesubrepoerror
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1413
    def commit(self, text, user, date):
13553
dea6efdd7ec4 subrepo: don't crash when git repo is missing
Eric Eisner <ede@mit.edu>
parents: 13531
diff changeset
  1414
        if self._gitmissing():
dea6efdd7ec4 subrepo: don't crash when git repo is missing
Eric Eisner <ede@mit.edu>
parents: 13531
diff changeset
  1415
            raise util.Abort(_("subrepo %s is missing") % self._relpath)
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1416
        cmd = ['commit', '-a', '-m', text]
13095
49c7e875482d subrepo: use environment variable instead of git commit's --date
Eric Eisner <ede@mit.edu>
parents: 13094
diff changeset
  1417
        env = os.environ.copy()
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1418
        if user:
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1419
            cmd += ['--author', user]
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1420
        if date:
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1421
            # git's date parser silently ignores when seconds < 1e9
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1422
            # convert to ISO8601
13095
49c7e875482d subrepo: use environment variable instead of git commit's --date
Eric Eisner <ede@mit.edu>
parents: 13094
diff changeset
  1423
            env['GIT_AUTHOR_DATE'] = util.datestr(date,
49c7e875482d subrepo: use environment variable instead of git commit's --date
Eric Eisner <ede@mit.edu>
parents: 13094
diff changeset
  1424
                                                  '%Y-%m-%dT%H:%M:%S %1%2')
49c7e875482d subrepo: use environment variable instead of git commit's --date
Eric Eisner <ede@mit.edu>
parents: 13094
diff changeset
  1425
        self._gitcommand(cmd, env=env)
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1426
        # make sure commit works otherwise HEAD might not exist under certain
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1427
        # circumstances
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1428
        return self._gitstate()
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1429
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
  1430
    @annotatesubrepoerror
12994
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
  1431
    def merge(self, state):
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
  1432
        source, revision, kind = state
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
  1433
        self._fetch(source, revision)
13085
b4814f1f415c subrepo: strip gitcommand output
Eric Eisner <ede@mit.edu>
parents: 13029
diff changeset
  1434
        base = self._gitcommand(['merge-base', revision, self._state[1]])
15531
0810ccc51f0a subrepo: fix git status false positive (issue3109)
Eric Roshan Eisner <ede@alum.mit.edu>
parents: 15498
diff changeset
  1435
        self._gitupdatestat()
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1436
        out, code = self._gitdir(['diff-index', '--quiet', 'HEAD'])
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1437
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1438
        def mergefunc():
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1439
            if base == revision:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1440
                self.get(state) # fast forward merge
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1441
            elif base != self._state[1]:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1442
                self._gitcommand(['merge', '--no-commit', revision])
21567
5900bc09e684 subrepo: avoid sanitizing ".hg/hgrc" in meta data area for non-hg subrepos
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21566
diff changeset
  1443
            _sanitize(self._ui, self._abspath, '.git')
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1444
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1445
        if self.dirty():
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1446
            if self._gitstate() != revision:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1447
                dirty = self._gitstate() == self._state[1] or code != 0
13432
5a5bd7614401 subrepo: break long line found by check-code
Martin Geisler <mg@aragost.com>
parents: 13428
diff changeset
  1448
                if _updateprompt(self._ui, self, dirty,
5a5bd7614401 subrepo: break long line found by check-code
Martin Geisler <mg@aragost.com>
parents: 13428
diff changeset
  1449
                                 self._state[1][:7], revision[:7]):
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1450
                    mergefunc()
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1451
        else:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
  1452
            mergefunc()
12994
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
  1453
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
  1454
    @annotatesubrepoerror
15708
309e49491253 push: propagate --new-branch and --ssh options when pushing subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15614
diff changeset
  1455
    def push(self, opts):
309e49491253 push: propagate --new-branch and --ssh options when pushing subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15614
diff changeset
  1456
        force = opts.get('force')
309e49491253 push: propagate --new-branch and --ssh options when pushing subrepos
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 15614
diff changeset
  1457
14469
2fdea636f254 subrepo: don't crash when git .hgsubstate is empty (issue2716)
Eric Eisner <ede@alum.mit.edu>
parents: 14205
diff changeset
  1458
        if not self._state[1]:
2fdea636f254 subrepo: don't crash when git .hgsubstate is empty (issue2716)
Eric Eisner <ede@alum.mit.edu>
parents: 14205
diff changeset
  1459
            return True
13553
dea6efdd7ec4 subrepo: don't crash when git repo is missing
Eric Eisner <ede@mit.edu>
parents: 13531
diff changeset
  1460
        if self._gitmissing():
dea6efdd7ec4 subrepo: don't crash when git repo is missing
Eric Eisner <ede@mit.edu>
parents: 13531
diff changeset
  1461
            raise util.Abort(_("subrepo %s is missing") % self._relpath)
13029
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
  1462
        # if a branch in origin contains the revision, nothing to do
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
  1463
        branch2rev, rev2branch = self._gitbranchmap()
13109
53341289eaf8 subrepo: speed up git push logic
Eric Eisner <ede@mit.edu>
parents: 13108
diff changeset
  1464
        if self._state[1] in rev2branch:
53341289eaf8 subrepo: speed up git push logic
Eric Eisner <ede@mit.edu>
parents: 13108
diff changeset
  1465
            for b in rev2branch[self._state[1]]:
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
  1466
                if b.startswith('refs/remotes/origin/'):
13109
53341289eaf8 subrepo: speed up git push logic
Eric Eisner <ede@mit.edu>
parents: 13108
diff changeset
  1467
                    return True
13086
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
  1468
        for b, revision in branch2rev.iteritems():
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
  1469
            if b.startswith('refs/remotes/origin/'):
13086
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
  1470
                if self._gitisancestor(self._state[1], revision):
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
  1471
                    return True
13029
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
  1472
        # otherwise, try to push the currently checked out branch
12994
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
  1473
        cmd = ['push']
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
  1474
        if force:
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
  1475
            cmd.append('--force')
13152
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
  1476
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
  1477
        current = self._gitcurrentbranch()
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1478
        if current:
13029
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
  1479
            # determine if the current branch is even useful
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
  1480
            if not self._gitisancestor(self._state[1], current):
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
  1481
                self._ui.warn(_('unrelated git branch checked out '
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
  1482
                                'in subrepo %s\n') % self._relpath)
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
  1483
                return False
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
  1484
            self._ui.status(_('pushing branch %s of subrepo %s\n') %
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
  1485
                            (current.split('/', 2)[2], self._relpath))
20970
70312c95f2f7 subrepo: check return code for git push (issue4223)
Matt Mackall <mpm@selenic.com>
parents: 20870
diff changeset
  1486
            ret = self._gitdir(cmd + ['origin', current])
70312c95f2f7 subrepo: check return code for git push (issue4223)
Matt Mackall <mpm@selenic.com>
parents: 20870
diff changeset
  1487
            return ret[1] == 0
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1488
        else:
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1489
            self._ui.warn(_('no branch checked out in subrepo %s\n'
17140
54714fc4ae33 subrepo: add missing newline in Git warning message
Martin Geisler <mg@aragost.com>
parents: 17035
diff changeset
  1490
                            'cannot push revision %s\n') %
13029
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
  1491
                          (self._relpath, self._state[1]))
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
  1492
            return False
12994
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
  1493
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
  1494
    @annotatesubrepoerror
12996
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1495
    def remove(self):
13553
dea6efdd7ec4 subrepo: don't crash when git repo is missing
Eric Eisner <ede@mit.edu>
parents: 13531
diff changeset
  1496
        if self._gitmissing():
dea6efdd7ec4 subrepo: don't crash when git repo is missing
Eric Eisner <ede@mit.edu>
parents: 13531
diff changeset
  1497
            return
12996
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1498
        if self.dirty():
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1499
            self._ui.warn(_('not removing repo %s because '
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
  1500
                            'it has changes.\n') % self._relpath)
12996
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1501
            return
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1502
        # we can't fully delete the repository as it may contain
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1503
        # local-only history
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
  1504
        self._ui.note(_('removing subrepo %s\n') % self._relpath)
12996
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1505
        self._gitcommand(['config', 'core.bare', 'true'])
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
  1506
        for f in os.listdir(self._abspath):
12996
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1507
            if f == '.git':
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1508
                continue
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
  1509
            path = os.path.join(self._abspath, f)
12996
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1510
            if os.path.isdir(path) and not os.path.islink(path):
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1511
                shutil.rmtree(path)
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1512
            else:
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1513
                os.remove(path)
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
  1514
17108
1894dac619de subrepo: propagate matcher to subrepos when archiving
Matt Harbison <matt_harbison@yahoo.com>
parents: 17036
diff changeset
  1515
    def archive(self, ui, archiver, prefix, match=None):
18967
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18964
diff changeset
  1516
        total = 0
13027
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
  1517
        source, revision = self._state
14469
2fdea636f254 subrepo: don't crash when git .hgsubstate is empty (issue2716)
Eric Eisner <ede@alum.mit.edu>
parents: 14205
diff changeset
  1518
        if not revision:
18967
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18964
diff changeset
  1519
            return total
13027
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
  1520
        self._fetch(source, revision)
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
  1521
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
  1522
        # Parse git's native archive command.
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
  1523
        # This should be much faster than manually traversing the trees
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
  1524
        # and objects with many subprocess calls.
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
  1525
        tarstream = self._gitcommand(['archive', revision], stream=True)
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
  1526
        tar = tarfile.open(fileobj=tarstream, mode='r|')
13144
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
  1527
        relpath = subrelpath(self)
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
  1528
        ui.progress(_('archiving (%s)') % relpath, 0, unit=_('files'))
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
  1529
        for i, info in enumerate(tar):
13180
a79e0688a5ee subrepo: fix git archive parsing of directories and symfiles
Eric Eisner <ede@mit.edu>
parents: 13179
diff changeset
  1530
            if info.isdir():
a79e0688a5ee subrepo: fix git archive parsing of directories and symfiles
Eric Eisner <ede@mit.edu>
parents: 13179
diff changeset
  1531
                continue
17108
1894dac619de subrepo: propagate matcher to subrepos when archiving
Matt Harbison <matt_harbison@yahoo.com>
parents: 17036
diff changeset
  1532
            if match and not match(info.name):
1894dac619de subrepo: propagate matcher to subrepos when archiving
Matt Harbison <matt_harbison@yahoo.com>
parents: 17036
diff changeset
  1533
                continue
13180
a79e0688a5ee subrepo: fix git archive parsing of directories and symfiles
Eric Eisner <ede@mit.edu>
parents: 13179
diff changeset
  1534
            if info.issym():
a79e0688a5ee subrepo: fix git archive parsing of directories and symfiles
Eric Eisner <ede@mit.edu>
parents: 13179
diff changeset
  1535
                data = info.linkname
a79e0688a5ee subrepo: fix git archive parsing of directories and symfiles
Eric Eisner <ede@mit.edu>
parents: 13179
diff changeset
  1536
            else:
a79e0688a5ee subrepo: fix git archive parsing of directories and symfiles
Eric Eisner <ede@mit.edu>
parents: 13179
diff changeset
  1537
                data = tar.extractfile(info).read()
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
  1538
            archiver.addfile(os.path.join(prefix, self._path, info.name),
13180
a79e0688a5ee subrepo: fix git archive parsing of directories and symfiles
Eric Eisner <ede@mit.edu>
parents: 13179
diff changeset
  1539
                             info.mode, info.issym(), data)
18967
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18964
diff changeset
  1540
            total += 1
13144
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
  1541
            ui.progress(_('archiving (%s)') % relpath, i + 1,
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
  1542
                        unit=_('files'))
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
  1543
        ui.progress(_('archiving (%s)') % relpath, None)
18967
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18964
diff changeset
  1544
        return total
13144
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
  1545
13027
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
  1546
18109
9e3910db4e78 subrepo: append subrepo path to subrepo error messages
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18031
diff changeset
  1547
    @annotatesubrepoerror
13182
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1548
    def status(self, rev2, **opts):
14469
2fdea636f254 subrepo: don't crash when git .hgsubstate is empty (issue2716)
Eric Eisner <ede@alum.mit.edu>
parents: 14205
diff changeset
  1549
        rev1 = self._state[1]
2fdea636f254 subrepo: don't crash when git .hgsubstate is empty (issue2716)
Eric Eisner <ede@alum.mit.edu>
parents: 14205
diff changeset
  1550
        if self._gitmissing() or not rev1:
13553
dea6efdd7ec4 subrepo: don't crash when git repo is missing
Eric Eisner <ede@mit.edu>
parents: 13531
diff changeset
  1551
            # if the repo is missing, return no results
dea6efdd7ec4 subrepo: don't crash when git repo is missing
Eric Eisner <ede@mit.edu>
parents: 13531
diff changeset
  1552
            return [], [], [], [], [], [], []
13182
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1553
        modified, added, removed = [], [], []
15531
0810ccc51f0a subrepo: fix git status false positive (issue3109)
Eric Roshan Eisner <ede@alum.mit.edu>
parents: 15498
diff changeset
  1554
        self._gitupdatestat()
13182
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1555
        if rev2:
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1556
            command = ['diff-tree', rev1, rev2]
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1557
        else:
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1558
            command = ['diff-index', rev1]
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1559
        out = self._gitcommand(command)
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1560
        for line in out.split('\n'):
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1561
            tab = line.find('\t')
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1562
            if tab == -1:
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1563
                continue
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1564
            status, f = line[tab - 1], line[tab + 1:]
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1565
            if status == 'M':
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1566
                modified.append(f)
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1567
            elif status == 'A':
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1568
                added.append(f)
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1569
            elif status == 'D':
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1570
                removed.append(f)
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1571
22927
7d754b7acd55 subrepo: use separate instances of empty lists in status
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22914
diff changeset
  1572
        deleted, unknown, ignored, clean = [], [], [], []
23411
2d86f4e38c08 subrepo: add status support for ignored files in git subrepos
Mathias De Maré <mathias.demare@gmail.com>
parents: 23373
diff changeset
  1573
2d86f4e38c08 subrepo: add status support for ignored files in git subrepos
Mathias De Maré <mathias.demare@gmail.com>
parents: 23373
diff changeset
  1574
        if not rev2:
2d86f4e38c08 subrepo: add status support for ignored files in git subrepos
Mathias De Maré <mathias.demare@gmail.com>
parents: 23373
diff changeset
  1575
            command = ['ls-files', '--others', '--exclude-standard']
2d86f4e38c08 subrepo: add status support for ignored files in git subrepos
Mathias De Maré <mathias.demare@gmail.com>
parents: 23373
diff changeset
  1576
            out = self._gitcommand(command)
2d86f4e38c08 subrepo: add status support for ignored files in git subrepos
Mathias De Maré <mathias.demare@gmail.com>
parents: 23373
diff changeset
  1577
            for line in out.split('\n'):
2d86f4e38c08 subrepo: add status support for ignored files in git subrepos
Mathias De Maré <mathias.demare@gmail.com>
parents: 23373
diff changeset
  1578
                if len(line) == 0:
2d86f4e38c08 subrepo: add status support for ignored files in git subrepos
Mathias De Maré <mathias.demare@gmail.com>
parents: 23373
diff changeset
  1579
                    continue
2d86f4e38c08 subrepo: add status support for ignored files in git subrepos
Mathias De Maré <mathias.demare@gmail.com>
parents: 23373
diff changeset
  1580
                unknown.append(line)
2d86f4e38c08 subrepo: add status support for ignored files in git subrepos
Mathias De Maré <mathias.demare@gmail.com>
parents: 23373
diff changeset
  1581
22914
c95db3208a33 status: update various other methods to return new class
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22695
diff changeset
  1582
        return scmutil.status(modified, added, removed, deleted,
c95db3208a33 status: update various other methods to return new class
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22695
diff changeset
  1583
                              unknown, ignored, clean)
13182
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
  1584
21400
78a60daacea8 subrepo: add shortid() method to subrepo classes
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21041
diff changeset
  1585
    def shortid(self, revid):
78a60daacea8 subrepo: add shortid() method to subrepo classes
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21041
diff changeset
  1586
        return revid[:7]
78a60daacea8 subrepo: add shortid() method to subrepo classes
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 21041
diff changeset
  1587
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
  1588
types = {
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
  1589
    'hg': hgsubrepo,
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
  1590
    'svn': svnsubrepo,
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
  1591
    'git': gitsubrepo,
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
  1592
    }