mercurial/subrepo.py
author Erik Zielke <ez@aragost.com>
Wed, 09 Feb 2011 10:53:09 +0100
changeset 13417 0748e18be470
parent 13413 fa921dcd9993
child 13428 5ef29e0dd418
permissions -rw-r--r--
subrepos: prompt on conflicts on update with dirty subrepos Consider a repository with a single subrepository. The changesets in the main repository reference the subrepository changesets like this: m0 -> s0 m1 -> s1 m2 -> s2 Starting from a state (m1, s0), doing 'hg update m2' in the main repository will yield a conflict: the subrepo is at revision s0 but the target revision says it should be at revision s2. Before this change, Mercurial would do (m1, s0) -> (m2, s2) and thus ignore the conflict between the working copy and the target revision. With this change, the user is prompted to resolve the conflict by choosing which revision he wants. This is consistent with 'hg merge', which also prompts the user when it detects conflicts in the merged .hgsubstate files. The prompt looks like this: $ hg update tip subrepository sources for my-subrepo differ use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9)?
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
11109
a2bc2f2d77a9 subrepo: normalize path part of URLs so that pulling subrepos from webdir works
Edouard Gomez <ed.gomez@free.fr>
parents: 11078
diff changeset
     8
import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath
13027
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
     9
import stat, subprocess, tarfile
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    10
from i18n import _
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
    11
import config, util, node, error, cmdutil
9092
9aebeea7ac00 subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents: 9049
diff changeset
    12
hg = None
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    13
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
    14
nullstate = ('', '', 'empty')
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
11775
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
    16
def state(ctx, ui):
11571
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
    17
    """return a state dict, mapping subrepo paths configured in .hgsub
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
    18
    to tuple: (source from .hgsub, revision from .hgsubstate, kind
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
    19
    (key in types dict))
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
    20
    """
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
    p = config.config()
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
    def read(f, sections=None, remap=None):
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
        if f in ctx:
13017
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    24
            try:
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    25
                data = ctx[f].data()
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    26
            except IOError, err:
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    27
                if err.errno != errno.ENOENT:
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    28
                    raise
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    29
                # 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
    30
                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
    31
                return
d0e21c5fde41 subrepo: handle missing subrepo spec file as removed
Patrick Mezard <pmezard@gmail.com>
parents: 13015
diff changeset
    32
            p.parse(f, data, sections, remap, read)
10174
65b6dc44cdbf subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents: 10069
diff changeset
    33
        else:
65b6dc44cdbf subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents: 10069
diff changeset
    34
            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
    35
65b6dc44cdbf subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents: 10069
diff changeset
    36
    if '.hgsub' in ctx:
65b6dc44cdbf subrepo: fix includes support in .hgsub
Matt Mackall <mpm@selenic.com>
parents: 10069
diff changeset
    37
        read('.hgsub')
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
11775
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
    39
    for path, src in ui.configitems('subpaths'):
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
    40
        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
    41
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
    rev = {}
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
    if '.hgsubstate' in ctx:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    44
        try:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
            for l in ctx['.hgsubstate'].data().splitlines():
9752
a22cdd5e56b7 subrepo: more robust split for .hgsubstate parsing
Matt Mackall <mpm@selenic.com>
parents: 9508
diff changeset
    46
                revision, path = l.split(" ", 1)
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
                rev[path] = revision
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
        except IOError, err:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
            if err.errno != errno.ENOENT:
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
                raise
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
    state = {}
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
    for path, src in p[''].items():
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
    54
        kind = 'hg'
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
    55
        if src.startswith('['):
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
    56
            if ']' not in src:
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
    57
                raise util.Abort(_('missing ] in subrepo source'))
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
    58
            kind, src = src.split(']', 1)
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
    59
            kind = kind[1:]
11775
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
    60
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
    61
        for pattern, repl in p.items('subpaths'):
11961
f3075ffa6b30 subrepos: handle backslashes in subpaths
Martin Geisler <mg@lazybytes.net>
parents: 11775
diff changeset
    62
            # 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
    63
            # does a string decode.
f3075ffa6b30 subrepos: handle backslashes in subpaths
Martin Geisler <mg@lazybytes.net>
parents: 11775
diff changeset
    64
            repl = repl.encode('string-escape')
f3075ffa6b30 subrepos: handle backslashes in subpaths
Martin Geisler <mg@lazybytes.net>
parents: 11775
diff changeset
    65
            # 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
    66
            # 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
    67
            # extra escapes are needed because re.sub string decodes.
f3075ffa6b30 subrepos: handle backslashes in subpaths
Martin Geisler <mg@lazybytes.net>
parents: 11775
diff changeset
    68
            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
    69
            try:
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
    70
                src = re.sub(pattern, repl, src, 1)
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
    71
            except re.error, e:
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
    72
                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
    73
                                 % (p.source('subpaths', pattern), e))
a8614c5a5e9a subrepos: support remapping of .hgsub source paths
Martin Geisler <mg@lazybytes.net>
parents: 11572
diff changeset
    74
10457
4f38d03d4975 subrepo: make sure that the source path is stripped
David Soria Parra <dsp@php.net>
parents: 10378
diff changeset
    75
        state[path] = (src.strip(), rev.get(path, ''), kind)
8812
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
859f841937d0 subrepo: introduce basic state parsing
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    77
    return state
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    78
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    79
def writestate(repo, state):
11571
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
    80
    """rewrite .hgsubstate in (outer) repo with these subrepo states"""
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    81
    repo.wwrite('.hgsubstate',
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    82
                ''.join(['%s %s\n' % (state[s][1], s)
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    83
                         for s in sorted(state)]), '')
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
    84
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 13287
diff changeset
    85
def submerge(repo, wctx, mctx, actx, overwrite):
11571
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
    86
    """delegated from merge.applyupdates: merging of .hgsubstate file
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
    87
    in working context, merging context and ancestor context"""
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    88
    if mctx == actx: # backwards?
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    89
        actx = wctx.p1()
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    90
    s1 = wctx.substate
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    91
    s2 = mctx.substate
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    92
    sa = actx.substate
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    93
    sm = {}
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
    94
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
    95
    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
    96
9779
58a6f3f4d553 subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents: 9752
diff changeset
    97
    def debug(s, msg, r=""):
58a6f3f4d553 subrepo: add some debug output to submerge
Matt Mackall <mpm@selenic.com>
parents: 9752
diff changeset
    98
        if r:
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
    99
            r = "%s:%s:%s" % r
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   100
        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
   101
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   102
    for s, l in s1.items():
11470
34e33d50c26b subrepo: correctly handle update -C with modified subrepos (issue2022)
Matt Mackall <mpm@selenic.com>
parents: 11463
diff changeset
   103
        a = sa.get(s, nullstate)
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   104
        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
   105
        if wctx.sub(s).dirty():
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   106
            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
   107
        if wctx == actx: # overwrite
34e33d50c26b subrepo: correctly handle update -C with modified subrepos (issue2022)
Matt Mackall <mpm@selenic.com>
parents: 11463
diff changeset
   108
            a = ld
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   109
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   110
        if s in s2:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   111
            r = s2[s]
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   112
            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
   113
                sm[s] = l
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   114
                continue
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   115
            elif ld == a: # other side changed
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   116
                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
   117
                wctx.sub(s).get(r, overwrite)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   118
                sm[s] = r
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   119
            elif ld[0] != r[0]: # sources differ
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8997
diff changeset
   120
                if repo.ui.promptchoice(
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   121
                    _(' subrepository sources for %s differ\n'
8908
105343f9f744 Fix warning: Seen unexpected token "%"
Dongsheng Song <dongsheng.song@gmail.com>
parents: 8815
diff changeset
   122
                      'use (l)ocal source (%s) or (r)emote source (%s)?')
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   123
                      % (s, l[0], r[0]),
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8997
diff changeset
   124
                      (_('&Local'), _('&Remote')), 0):
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   125
                    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
   126
                    wctx.sub(s).get(r, overwrite)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   127
                    sm[s] = r
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   128
            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
   129
                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
   130
                wctx.sub(s).get(r, overwrite)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   131
                sm[s] = r
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   132
            else:
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   133
                debug(s, "both sides changed, merge with", r)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   134
                wctx.sub(s).merge(r)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   135
                sm[s] = l
11463
f0ea93557133 subrepo: fix recording of + in .hgsubstate (issue2217)
Matt Mackall <mpm@selenic.com>
parents: 11455
diff changeset
   136
        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
   137
            debug(s, "remote removed, remove")
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   138
            wctx.sub(s).remove()
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   139
        else:
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8997
diff changeset
   140
            if repo.ui.promptchoice(
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   141
                _(' local changed subrepository %s which remote removed\n'
8908
105343f9f744 Fix warning: Seen unexpected token "%"
Dongsheng Song <dongsheng.song@gmail.com>
parents: 8815
diff changeset
   142
                  'use (c)hanged version or (d)elete?') % s,
9049
38b5d5e0efab filemerge, subrepo: correct indention
Martin Geisler <mg@lazybytes.net>
parents: 9048
diff changeset
   143
                (_('&Changed'), _('&Delete')), 0):
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   144
                debug(s, "prompt remove")
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   145
                wctx.sub(s).remove()
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   146
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   147
    for s, r in s2.items():
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   148
        if s in s1:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   149
            continue
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   150
        elif s not in sa:
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   151
            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
   152
            mctx.sub(s).get(r)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   153
            sm[s] = r
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   154
        elif r != sa[s]:
9048
86b4a9b0ddda ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents: 8997
diff changeset
   155
            if repo.ui.promptchoice(
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   156
                _(' remote changed subrepository %s which local removed\n'
8908
105343f9f744 Fix warning: Seen unexpected token "%"
Dongsheng Song <dongsheng.song@gmail.com>
parents: 8815
diff changeset
   157
                  'use (c)hanged version or (d)elete?') % s,
9049
38b5d5e0efab filemerge, subrepo: correct indention
Martin Geisler <mg@lazybytes.net>
parents: 9048
diff changeset
   158
                (_('&Changed'), _('&Delete')), 0) == 0:
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   159
                debug(s, "prompt recreate", r)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   160
                wctx.sub(s).get(r)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   161
                sm[s] = r
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   162
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   163
    # record merged .hgsubstate
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   164
    writestate(repo, sm)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   165
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   166
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
   167
    if dirty:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   168
        msg = (_(' subrepository sources for %s differ\n'
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   169
                 'use (l)ocal source (%s) or (r)emote source (%s)?\n')
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   170
               % (subrelpath(sub), local, remote))
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   171
    else:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   172
        msg = (_(' subrepository sources for %s differ (in checked out version)\n'
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   173
                 'use (l)ocal source (%s) or (r)emote source (%s)?\n')
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   174
               % (subrelpath(sub), local, remote))
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   175
    return ui.promptchoice(msg, (_('&Local'), _('&Remote')), 0)
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   176
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   177
def reporelpath(repo):
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   178
    """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
   179
    parent = repo
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   180
    while hasattr(parent, '_subparent'):
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   181
        parent = parent._subparent
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   182
    return repo.root[len(parent.root)+1:]
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   183
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   184
def subrelpath(sub):
11571
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
   185
    """return path to this subrepo as seen from outermost repo"""
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
   186
    if hasattr(sub, '_relpath'):
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
   187
        return sub._relpath
11112
4a9bee613737 subrepo: print paths relative to upper repo root for push/pull/commit
Edouard Gomez <ed.gomez@free.fr>
parents: 11111
diff changeset
   188
    if not hasattr(sub, '_repo'):
4a9bee613737 subrepo: print paths relative to upper repo root for push/pull/commit
Edouard Gomez <ed.gomez@free.fr>
parents: 11111
diff changeset
   189
        return sub._path
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   190
    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
   191
12753
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   192
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
   193
    """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
   194
    or on the top repo config. Abort or return None if no source found."""
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   195
    if hasattr(repo, '_subparent'):
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   196
        source = repo._subsource
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   197
        if source.startswith('/') or '://' in source:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   198
            return source
12753
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   199
        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
   200
        if parent:
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   201
            if '://' in parent:
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   202
                if parent[-1] == '/':
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   203
                    parent = parent[:-1]
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   204
                r = urlparse.urlparse(parent + '/' + source)
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   205
                r = urlparse.urlunparse((r[0], r[1],
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   206
                                         posixpath.normpath(r[2]),
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   207
                                         r[3], r[4], r[5]))
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   208
                return r
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   209
            else: # plain file system path
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   210
                return posixpath.normpath(os.path.join(parent, repo._subsource))
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   211
    else: # recursion reached top repo
12852
5dbff89cf107 subrepo: propagate non-default pull/push path to relative subrepos (issue1852)
Mads Kiilerich <mads@kiilerich.com>
parents: 12799
diff changeset
   212
        if hasattr(repo, '_subtoppath'):
5dbff89cf107 subrepo: propagate non-default pull/push path to relative subrepos (issue1852)
Mads Kiilerich <mads@kiilerich.com>
parents: 12799
diff changeset
   213
            return repo._subtoppath
12753
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   214
        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
   215
            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
   216
        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
   217
            return 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
   218
    if abort:
12770
614f0d8724ab check-code: find trailing whitespace
Martin Geisler <mg@lazybytes.net>
parents: 12753
diff changeset
   219
        raise util.Abort(_("default path for subrepository %s not found") %
12753
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   220
            reporelpath(repo))
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   221
12176
ecab10820983 subrepos: add function for iterating over ctx subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12167
diff changeset
   222
def itersubrepos(ctx1, ctx2):
ecab10820983 subrepos: add function for iterating over ctx subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12167
diff changeset
   223
    """find subrepos in ctx1 or ctx2"""
ecab10820983 subrepos: add function for iterating over ctx subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12167
diff changeset
   224
    # Create a (subpath, ctx) mapping where we prefer subpaths from
ecab10820983 subrepos: add function for iterating over ctx subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12167
diff changeset
   225
    # ctx1. The subpaths from ctx2 are important when the .hgsub file
ecab10820983 subrepos: add function for iterating over ctx subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12167
diff changeset
   226
    # has been modified (in ctx2) but not yet committed (in ctx1).
ecab10820983 subrepos: add function for iterating over ctx subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12167
diff changeset
   227
    subpaths = dict.fromkeys(ctx2.substate, ctx2)
ecab10820983 subrepos: add function for iterating over ctx subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12167
diff changeset
   228
    subpaths.update(dict.fromkeys(ctx1.substate, ctx1))
ecab10820983 subrepos: add function for iterating over ctx subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12167
diff changeset
   229
    for subpath, ctx in sorted(subpaths.iteritems()):
ecab10820983 subrepos: add function for iterating over ctx subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12167
diff changeset
   230
        yield subpath, ctx.sub(subpath)
ecab10820983 subrepos: add function for iterating over ctx subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12167
diff changeset
   231
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   232
def subrepo(ctx, path):
11571
636554d58665 subrepo: docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 11470
diff changeset
   233
    """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
   234
    # subrepo inherently violates our import layering rules
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   235
    # 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
   236
    # so we manually delay the circular imports to not break
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   237
    # 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
   238
    global hg
9aebeea7ac00 subrepo: use hg.repository instead of creating localrepo directly
Abderrahim Kitouni <a.kitouni@gmail.com>
parents: 9049
diff changeset
   239
    import hg as h
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   240
    hg = h
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   241
8997
70f5d3be5917 subrepo: audit subrepo paths
Matt Mackall <mpm@selenic.com>
parents: 8908
diff changeset
   242
    util.path_auditor(ctx._repo.root)(path)
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   243
    state = ctx.substate.get(path, nullstate)
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
   244
    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
   245
        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
   246
    return types[state[2]](ctx, path, state[:2])
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   247
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   248
# 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
   249
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   250
class abstractsubrepo(object):
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   251
13174
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   252
    def dirty(self, ignoreupdate=False):
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   253
        """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
   254
        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
   255
        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
   256
        """
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   257
        raise NotImplementedError
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   258
12506
e7d45e41338c subrepos: add missing self argument to abstractsubrepo.checknested
Brodie Rao <brodie@bitheap.org>
parents: 12503
diff changeset
   259
    def checknested(self, path):
12162
af8c4929931c localrepo: add auditor attribute which knows about subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12060
diff changeset
   260
        """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
   261
        return False
af8c4929931c localrepo: add auditor attribute which knows about subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12060
diff changeset
   262
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   263
    def commit(self, text, user, date):
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   264
        """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
   265
        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
   266
        new state of the subrepo.
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   267
        """
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   268
        raise NotImplementedError
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   269
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   270
    def remove(self):
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   271
        """remove the subrepo
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   272
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   273
        (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
   274
        """
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   275
        raise NotImplementedError
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   276
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 13287
diff changeset
   277
    def get(self, state, overwrite=False):
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   278
        """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
   279
        this state
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   280
        """
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   281
        raise NotImplementedError
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   282
13413
fa921dcd9993 subrepo: remove argument introduced by mistake in c19b9282d3a7
Erik Zielke <ez@aragost.com>
parents: 13333
diff changeset
   283
    def merge(self, state):
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   284
        """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
   285
        raise NotImplementedError
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   286
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   287
    def push(self, force):
11572
324bad1dc230 Merge with stable
Martin Geisler <mg@lazybytes.net>
parents: 11560 11571
diff changeset
   288
        """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
   289
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   290
        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
   291
        """
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   292
        raise NotImplementedError
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   293
12270
166b9866580a add: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12210
diff changeset
   294
    def add(self, ui, match, dryrun, prefix):
166b9866580a add: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12210
diff changeset
   295
        return []
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   296
12166
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   297
    def status(self, rev2, **opts):
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   298
        return [], [], [], [], [], [], []
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   299
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   300
    def diff(self, diffopts, node2, match, prefix, **opts):
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   301
        pass
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   302
12272
42ecd56399d7 outgoing: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12270
diff changeset
   303
    def outgoing(self, ui, dest, opts):
42ecd56399d7 outgoing: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12270
diff changeset
   304
        return 1
42ecd56399d7 outgoing: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12270
diff changeset
   305
12274
c02e1ed3d407 incoming: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12272
diff changeset
   306
    def incoming(self, ui, source, opts):
c02e1ed3d407 incoming: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12272
diff changeset
   307
        return 1
c02e1ed3d407 incoming: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12272
diff changeset
   308
12322
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   309
    def files(self):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   310
        """return filename iterator"""
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   311
        raise NotImplementedError
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   312
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   313
    def filedata(self, name):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   314
        """return file data"""
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   315
        raise NotImplementedError
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   316
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   317
    def fileflags(self, name):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   318
        """return file flags"""
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   319
        return ''
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   320
13144
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   321
    def archive(self, ui, archiver, prefix):
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   322
        files = self.files()
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   323
        total = len(files)
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   324
        relpath = subrelpath(self)
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   325
        ui.progress(_('archiving (%s)') % relpath, 0,
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   326
                    unit=_('files'), total=total)
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   327
        for i, name in enumerate(files):
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   328
            flags = self.fileflags(name)
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   329
            mode = 'x' in flags and 0755 or 0644
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   330
            symlink = 'l' in flags
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   331
            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
   332
                             mode, symlink, self.filedata(name))
13144
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   333
            ui.progress(_('archiving (%s)') % relpath, i + 1,
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   334
                        unit=_('files'), total=total)
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   335
        ui.progress(_('archiving (%s)') % relpath, None)
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   336
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   337
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   338
class hgsubrepo(abstractsubrepo):
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   339
    def __init__(self, ctx, path, state):
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   340
        self._path = path
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   341
        self._state = state
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   342
        r = ctx._repo
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   343
        root = r.wjoin(path)
10666
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   344
        create = False
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   345
        if not os.path.exists(os.path.join(root, '.hg')):
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   346
            create = True
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   347
            util.makedirs(root)
10666
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   348
        self._repo = hg.repository(r.ui, root, create=create)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   349
        self._repo._subparent = r
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   350
        self._repo._subsource = state[0]
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   351
10666
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   352
        if create:
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   353
            fp = self._repo.opener("hgrc", "w", text=True)
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   354
            fp.write('[paths]\n')
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   355
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   356
            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
   357
                if value:
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   358
                    fp.write('%s = %s\n' % (key, value))
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   359
                    self._repo.ui.setconfig('paths', key, value)
10666
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   360
12753
ef5eaf53f4f7 subrepo: abort instead of pushing/pulling to the repo itself
Mads Kiilerich <mads@kiilerich.com>
parents: 12752
diff changeset
   361
            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
   362
            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
   363
            addpathconfig('default', defpath)
10697
c90d923fff64 subrepo: fix hgrc paths section during subrepo pulling
Edouard Gomez <ed.gomez@free.fr>
parents: 10666
diff changeset
   364
            if defpath != defpushpath:
c90d923fff64 subrepo: fix hgrc paths section during subrepo pulling
Edouard Gomez <ed.gomez@free.fr>
parents: 10666
diff changeset
   365
                addpathconfig('default-push', defpushpath)
10666
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   366
            fp.close()
4c50a90b90fc subrepo: keep ui and hgrc in sync when creating new repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10665
diff changeset
   367
12270
166b9866580a add: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12210
diff changeset
   368
    def add(self, ui, match, dryrun, prefix):
166b9866580a add: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12210
diff changeset
   369
        return cmdutil.add(ui, self._repo, match, dryrun, True,
166b9866580a add: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12210
diff changeset
   370
                           os.path.join(prefix, self._path))
166b9866580a add: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12210
diff changeset
   371
12166
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   372
    def status(self, rev2, **opts):
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   373
        try:
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   374
            rev1 = self._state[1]
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   375
            ctx1 = self._repo[rev1]
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   376
            ctx2 = self._repo[rev2]
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   377
            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
   378
        except error.RepoLookupError, inst:
12503
b4711585a455 subrepo: improve lookup error messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 12323
diff changeset
   379
            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
   380
                               % (inst, subrelpath(self)))
12166
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   381
            return [], [], [], [], [], [], []
441a74b8def1 status: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12162
diff changeset
   382
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   383
    def diff(self, diffopts, node2, match, prefix, **opts):
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   384
        try:
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   385
            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
   386
            # 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
   387
            # in hex format
12210
21eb85e9ea94 subrepo: handle diff with working copy
Martin Geisler <mg@lazybytes.net>
parents: 12209
diff changeset
   388
            if node2 is not None:
21eb85e9ea94 subrepo: handle diff with working copy
Martin Geisler <mg@lazybytes.net>
parents: 12209
diff changeset
   389
                node2 = node.bin(node2)
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   390
            cmdutil.diffordiffstat(self._repo.ui, self._repo, diffopts,
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   391
                                   node1, node2, match,
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   392
                                   prefix=os.path.join(prefix, self._path),
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   393
                                   listsubrepos=True, **opts)
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   394
        except error.RepoLookupError, inst:
12503
b4711585a455 subrepo: improve lookup error messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 12323
diff changeset
   395
            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
   396
                               % (inst, subrelpath(self)))
12167
d2c5b0927c28 diff: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12166
diff changeset
   397
13144
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   398
    def archive(self, ui, archiver, prefix):
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   399
        abstractsubrepo.archive(self, ui, archiver, prefix)
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   400
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   401
        rev = self._state[1]
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   402
        ctx = self._repo[rev]
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   403
        for subpath in ctx.substate:
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   404
            s = subrepo(ctx, subpath)
13144
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   405
            s.archive(ui, archiver, os.path.join(prefix, self._path))
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12322
diff changeset
   406
13174
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   407
    def dirty(self, ignoreupdate=False):
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   408
        r = self._state[1]
13174
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   409
        if r == '' and not ignoreupdate: # no state recorded
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   410
            return True
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   411
        w = self._repo[None]
13174
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   412
        if w.p1() != self._repo[r] and not ignoreupdate:
13325
7ebdfa37842e subrepo: clarify comments in dirty() methods
Kevin Bullock <kbullock@ringworld.org>
parents: 13324
diff changeset
   413
            # different version checked out
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   414
            return True
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   415
        return w.dirty() # working directory changed
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   416
12162
af8c4929931c localrepo: add auditor attribute which knows about subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12060
diff changeset
   417
    def checknested(self, path):
af8c4929931c localrepo: add auditor attribute which knows about subrepos
Martin Geisler <mg@lazybytes.net>
parents: 12060
diff changeset
   418
        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
   419
8813
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   420
    def commit(self, text, user, date):
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   421
        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
   422
        n = self._repo.commit(text, user, date)
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   423
        if not n:
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   424
            return self._repo['.'].hex() # different version checked out
db3c1ab0e632 commit: recurse into subrepositories
Matt Mackall <mpm@selenic.com>
parents: 8812
diff changeset
   425
        return node.hex(n)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   426
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   427
    def remove(self):
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   428
        # 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
   429
        # local-only history
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   430
        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
   431
        hg.clean(self._repo, node.nullid, False)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   432
9507
5987183d6e59 subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents: 9186
diff changeset
   433
    def _get(self, state):
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
   434
        source, revision, kind = state
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   435
        try:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   436
            self._repo.lookup(revision)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   437
        except error.RepoError:
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   438
            self._repo._subsource = source
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   439
            srcurl = _abssource(self._repo)
10671
001ffc2b3d22 subrepo: wrap long line
Martin Geisler <mg@lazybytes.net>
parents: 10670
diff changeset
   440
            self._repo.ui.status(_('pulling subrepo %s from %s\n')
12752
18b5b6392fcf subrepo: rename relpath to subrelpath and introduce reporelpath
Mads Kiilerich <mads@kiilerich.com>
parents: 12506
diff changeset
   441
                                 % (subrelpath(self), srcurl))
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   442
            other = hg.repository(self._repo.ui, srcurl)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   443
            self._repo.pull(other)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   444
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 13287
diff changeset
   445
    def get(self, state, overwrite=False):
9507
5987183d6e59 subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents: 9186
diff changeset
   446
        self._get(state)
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
   447
        source, revision, kind = state
9782
c1c40511c276 subrepo: add more debugging output, lose _ markers
Matt Mackall <mpm@selenic.com>
parents: 9781
diff changeset
   448
        self._repo.ui.debug("getting subrepo %s\n" % self._path)
8814
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   449
        hg.clean(self._repo, revision, False)
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   450
ab668c92a036 subrepo: add update/merge logic
Matt Mackall <mpm@selenic.com>
parents: 8813
diff changeset
   451
    def merge(self, state):
9507
5987183d6e59 subrepo: add auto-pull for merge
Matt Mackall <mpm@selenic.com>
parents: 9186
diff changeset
   452
        self._get(state)
9781
eccc8aacd6f9 subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   453
        cur = self._repo['.']
eccc8aacd6f9 subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   454
        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
   455
        anc = dst.ancestor(cur)
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   456
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   457
        def mergefunc():
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   458
            if anc == cur:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   459
                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
   460
                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
   461
            elif anc == dst:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   462
                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
   463
            else:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   464
                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
   465
                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
   466
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   467
        wctx = self._repo[None]
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   468
        if self.dirty():
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   469
            if anc != dst:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   470
                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
   471
                    mergefunc()
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   472
            else:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   473
                mergefunc()
9781
eccc8aacd6f9 subrepo: do a linear update when appropriate
Matt Mackall <mpm@selenic.com>
parents: 9780
diff changeset
   474
        else:
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   475
            mergefunc()
8815
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   476
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   477
    def push(self, force):
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   478
        # push subrepos depth-first for coherent ordering
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   479
        c = self._repo['']
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   480
        subs = c.substate # only repos that are committed
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   481
        for s in sorted(subs):
11067
49e14ec67144 subrepo: propagate and catch push failures
Matt Mackall <mpm@selenic.com>
parents: 10954
diff changeset
   482
            if not c.sub(s).push(force):
49e14ec67144 subrepo: propagate and catch push failures
Matt Mackall <mpm@selenic.com>
parents: 10954
diff changeset
   483
                return False
8815
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   484
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   485
        dsturl = _abssource(self._repo, True)
11111
d2da9e6dd13e subrepo: print pushing url
Edouard Gomez <ed.gomez@free.fr>
parents: 11109
diff changeset
   486
        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
   487
            (subrelpath(self), dsturl))
8815
e87b0fc4750b subrepo: basic push support
Matt Mackall <mpm@selenic.com>
parents: 8814
diff changeset
   488
        other = hg.repository(self._repo.ui, dsturl)
11067
49e14ec67144 subrepo: propagate and catch push failures
Matt Mackall <mpm@selenic.com>
parents: 10954
diff changeset
   489
        return self._repo.push(other, force)
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
   490
12272
42ecd56399d7 outgoing: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12270
diff changeset
   491
    def outgoing(self, ui, dest, opts):
42ecd56399d7 outgoing: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12270
diff changeset
   492
        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
   493
12274
c02e1ed3d407 incoming: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12272
diff changeset
   494
    def incoming(self, ui, source, opts):
c02e1ed3d407 incoming: recurse into subrepositories with --subrepos/-S flag
Martin Geisler <mg@lazybytes.net>
parents: 12272
diff changeset
   495
        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
   496
12322
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   497
    def files(self):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   498
        rev = self._state[1]
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   499
        ctx = self._repo[rev]
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   500
        return ctx.manifest()
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   501
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   502
    def filedata(self, name):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   503
        rev = self._state[1]
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   504
        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
   505
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   506
    def fileflags(self, name):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   507
        rev = self._state[1]
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   508
        ctx = self._repo[rev]
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   509
        return ctx.flags(name)
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   510
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   511
11559
9d88597470af subrepo: add abstract superclass for subrepo classes
Martin Geisler <mg@lazybytes.net>
parents: 11470
diff changeset
   512
class svnsubrepo(abstractsubrepo):
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   513
    def __init__(self, ctx, path, state):
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   514
        self._path = path
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   515
        self._state = state
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   516
        self._ctx = ctx
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   517
        self._ui = ctx._repo.ui
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   518
11560
ea2cdee9a1fe subrepos: let caller specify a filename for SVN commands
Martin Geisler <mg@lazybytes.net>
parents: 11559
diff changeset
   519
    def _svncommand(self, commands, filename=''):
ea2cdee9a1fe subrepos: let caller specify a filename for SVN commands
Martin Geisler <mg@lazybytes.net>
parents: 11559
diff changeset
   520
        path = os.path.join(self._ctx._repo.origroot, self._path, filename)
10954
33119d0252c1 subrepo: fix repo root path handling in svn subrepo
Brett Cannon <brett@python.org>
parents: 10697
diff changeset
   521
        cmd = ['svn'] + commands + [path]
10199
c2e2a5e6c36b subrepo: force en_US.UTF-8 locale when calling svn
Patrick Mezard <pmezard@gmail.com>
parents: 10197
diff changeset
   522
        env = dict(os.environ)
10271
9b38bec5dc29 subrepo: make svn use C locale for portability
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   523
        # Avoid localized output, preserve current locale for everything else.
9b38bec5dc29 subrepo: make svn use C locale for portability
Patrick Mezard <pmezard@gmail.com>
parents: 10264
diff changeset
   524
        env['LC_MESSAGES'] = 'C'
13108
dcaad69cfd6a subrepo: use subprocess.Popen without the shell
Eric Eisner <ede@mit.edu>
parents: 13107
diff changeset
   525
        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
   526
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE,
d1c52354b0a9 subrepo: use subprocess directly to avoid python 2.6 bug
Patrick Mezard <pmezard@gmail.com>
parents: 13013
diff changeset
   527
                             universal_newlines=True, env=env)
d1c52354b0a9 subrepo: use subprocess directly to avoid python 2.6 bug
Patrick Mezard <pmezard@gmail.com>
parents: 13013
diff changeset
   528
        stdout, stderr = p.communicate()
d1c52354b0a9 subrepo: use subprocess directly to avoid python 2.6 bug
Patrick Mezard <pmezard@gmail.com>
parents: 13013
diff changeset
   529
        stderr = stderr.strip()
d1c52354b0a9 subrepo: use subprocess directly to avoid python 2.6 bug
Patrick Mezard <pmezard@gmail.com>
parents: 13013
diff changeset
   530
        if stderr:
d1c52354b0a9 subrepo: use subprocess directly to avoid python 2.6 bug
Patrick Mezard <pmezard@gmail.com>
parents: 13013
diff changeset
   531
            raise util.Abort(stderr)
d1c52354b0a9 subrepo: use subprocess directly to avoid python 2.6 bug
Patrick Mezard <pmezard@gmail.com>
parents: 13013
diff changeset
   532
        return stdout
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   533
13287
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   534
    def _wcrevs(self):
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   535
        # 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
   536
        # 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
   537
        # both. We used to store the working directory one.
10272
886858b834da subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents: 10271
diff changeset
   538
        output = self._svncommand(['info', '--xml'])
886858b834da subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents: 10271
diff changeset
   539
        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
   540
        entries = doc.getElementsByTagName('entry')
13287
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   541
        lastrev, rev = '0', '0'
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   542
        if entries:
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   543
            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
   544
            commits = entries[0].getElementsByTagName('commit')
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   545
            if commits:
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   546
                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
   547
        return (lastrev, rev)
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   548
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   549
    def _wcrev(self):
d0e0d3d43e14 subrepo: compare svn subrepo state to last committed revision
Patrick Mezard <pmezard@gmail.com>
parents: 13117
diff changeset
   550
        return self._wcrevs()[0]
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   551
10273
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   552
    def _wcchanged(self):
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   553
        """Return (changes, extchanges) where changes is True
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   554
        if the working directory was changed, and extchanges is
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   555
        True if any of these changes concern an external entry.
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   556
        """
10272
886858b834da subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents: 10271
diff changeset
   557
        output = self._svncommand(['status', '--xml'])
10273
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   558
        externals, changes = [], []
10272
886858b834da subrepo: svn xml output is much easier to parse
Patrick Mezard <pmezard@gmail.com>
parents: 10271
diff changeset
   559
        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
   560
        for e in doc.getElementsByTagName('entry'):
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   561
            s = e.getElementsByTagName('wc-status')
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   562
            if not s:
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   563
                continue
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   564
            item = s[0].getAttribute('item')
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   565
            props = s[0].getAttribute('props')
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   566
            path = e.getAttribute('path')
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   567
            if item == 'external':
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   568
                externals.append(path)
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   569
            if (item not in ('', 'normal', 'unversioned', 'external')
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   570
                or props not in ('', 'none')):
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   571
                changes.append(path)
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   572
        for path in changes:
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   573
            for ext in externals:
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   574
                if path == ext or path.startswith(ext + os.sep):
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   575
                    return True, True
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   576
        return bool(changes), False
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   577
13174
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   578
    def dirty(self, ignoreupdate=False):
be7e8e9bc5e5 mq: update .hgsubstate if subrepos are clean (issue2499)
Kevin Bullock <kbullock@ringworld.org>
parents: 13172
diff changeset
   579
        if not self._wcchanged()[0]:
13288
9c3bfba3f48d Merge with stable
Patrick Mezard <pmezard@gmail.com>
parents: 13242 13287
diff changeset
   580
            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
   581
                return False
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   582
        return True
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   583
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   584
    def commit(self, text, user, date):
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   585
        # user and date are out of our hands since svn is centralized
10273
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   586
        changed, extchanged = self._wcchanged()
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   587
        if not changed:
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   588
            return self._wcrev()
10273
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   589
        if extchanged:
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   590
            # Do not try to commit externals
e898bc7810ad subrepo: handle svn externals and meta changes (issue1982)
Patrick Mezard <pmezard@gmail.com>
parents: 10272
diff changeset
   591
            raise util.Abort(_('cannot commit svn externals'))
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   592
        commitinfo = self._svncommand(['commit', '-m', text])
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   593
        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
   594
        newrev = re.search('Committed revision ([0-9]+).', commitinfo)
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   595
        if not newrev:
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   596
            raise util.Abort(commitinfo.splitlines()[-1])
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   597
        newrev = newrev.groups()[0]
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   598
        self._ui.status(self._svncommand(['update', '-r', newrev]))
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   599
        return newrev
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   600
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   601
    def remove(self):
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   602
        if self.dirty():
10299
e768941f14c1 subrepo: fix errors reported by pylint
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10273
diff changeset
   603
            self._ui.warn(_('not removing repo %s because '
e768941f14c1 subrepo: fix errors reported by pylint
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10273
diff changeset
   604
                            'it has changes.\n' % self._path))
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   605
            return
10510
f77f3383c666 i18n: mark more strings for translation
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10457
diff changeset
   606
        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
   607
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
   608
        def onerror(function, path, excinfo):
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
   609
            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
   610
                raise
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
   611
            # 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
   612
            s = os.stat(path)
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
   613
            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
   614
                raise
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
   615
            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
   616
            os.remove(path)
92b0d669637f subrepo: fix removing read-only svn files on Windows
Patrick Mezard <pmezard@gmail.com>
parents: 12930
diff changeset
   617
13015
82ca0c43bc44 subrepo: prune empty directories when removing svn subrepo
Patrick Mezard <pmezard@gmail.com>
parents: 13014
diff changeset
   618
        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
   619
        shutil.rmtree(path, onerror=onerror)
82ca0c43bc44 subrepo: prune empty directories when removing svn subrepo
Patrick Mezard <pmezard@gmail.com>
parents: 13014
diff changeset
   620
        try:
82ca0c43bc44 subrepo: prune empty directories when removing svn subrepo
Patrick Mezard <pmezard@gmail.com>
parents: 13014
diff changeset
   621
            os.removedirs(os.path.dirname(path))
82ca0c43bc44 subrepo: prune empty directories when removing svn subrepo
Patrick Mezard <pmezard@gmail.com>
parents: 13014
diff changeset
   622
        except OSError:
82ca0c43bc44 subrepo: prune empty directories when removing svn subrepo
Patrick Mezard <pmezard@gmail.com>
parents: 13014
diff changeset
   623
            pass
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   624
13322
c19b9282d3a7 subrepo: make update -C clean the working directory for svn subrepos
Erik Zielke <ez@aragost.com>
parents: 13287
diff changeset
   625
    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
   626
        if overwrite:
13332
927e3940bfc3 subrepo: fix update -C with svn subrepos when cwd != repo.root
Patrick Mezard <pmezard@gmail.com>
parents: 13322
diff changeset
   627
            self._svncommand(['revert', '--recursive'])
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   628
        status = self._svncommand(['checkout', state[0], '--revision', state[1]])
12060
63eab3b74ba6 subrepo: use [0-9] instead of [\d] in svn subrepo regex
Martin Geisler <mg@lazybytes.net>
parents: 11961
diff changeset
   629
        if not re.search('Checked out revision [0-9]+.', status):
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   630
            raise util.Abort(status.splitlines()[-1])
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   631
        self._ui.status(status)
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   632
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   633
    def merge(self, state):
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   634
        old = self._state[1]
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   635
        new = state[1]
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   636
        if new != self._wcrev():
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   637
            dirty = old == self._wcrev() or self._wcchanged()[0]
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   638
            if _updateprompt(self._ui, self, dirty, self._wcrev(), new):
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   639
                self.get(state, False)
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   640
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   641
    def push(self, force):
11455
3827728b54e2 subrepo: fix silent push failure for SVN (issue2241)
Matt Mackall <mpm@selenic.com>
parents: 11117
diff changeset
   642
        # 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
   643
        return True
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   644
12322
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   645
    def files(self):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   646
        output = self._svncommand(['list'])
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   647
        # This works because svn forbids \n in filenames.
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   648
        return output.splitlines()
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   649
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   650
    def filedata(self, name):
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   651
        return self._svncommand(['cat'], name)
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   652
510afb31cf99 subrepo: introduce files and filedata methods for subrepo classes
Martin Geisler <mg@aragost.com>
parents: 12274
diff changeset
   653
13106
c869bd9e1193 subrepo: gitsubrepo should inherit from abstractsubrepo
Eric Eisner <ede@mit.edu>
parents: 13097
diff changeset
   654
class gitsubrepo(abstractsubrepo):
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   655
    def __init__(self, ctx, path, state):
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   656
        # TODO add git version check.
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   657
        self._state = state
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   658
        self._ctx = ctx
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
   659
        self._path = path
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
   660
        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
   661
        self._abspath = ctx._repo.wjoin(path)
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   662
        self._ui = ctx._repo.ui
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   663
13095
49c7e875482d subrepo: use environment variable instead of git commit's --date
Eric Eisner <ede@mit.edu>
parents: 13094
diff changeset
   664
    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
   665
        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
   666
13095
49c7e875482d subrepo: use environment variable instead of git commit's --date
Eric Eisner <ede@mit.edu>
parents: 13094
diff changeset
   667
    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
   668
        return self._gitnodir(commands, env=env, stream=stream,
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
   669
                              cwd=self._abspath)
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   670
13095
49c7e875482d subrepo: use environment variable instead of git commit's --date
Eric Eisner <ede@mit.edu>
parents: 13094
diff changeset
   671
    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
   672
        """Calls the git command
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   673
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   674
        The methods tries to call the git command. versions previor to 1.6.0
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   675
        are not supported and very probably fail.
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   676
        """
13110
cad35f06c031 subrepo: show git command with --debug
Eric Eisner <ede@mit.edu>
parents: 13109
diff changeset
   677
        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
   678
        # 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
   679
        # 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
   680
        errpipe = None
560b8001f765 subrepo: silence git output when ui.quiet is set
Eric Eisner <ede@mit.edu>
parents: 13110
diff changeset
   681
        if self._ui.quiet:
560b8001f765 subrepo: silence git output when ui.quiet is set
Eric Eisner <ede@mit.edu>
parents: 13110
diff changeset
   682
            errpipe = open(os.devnull, 'w')
13108
dcaad69cfd6a subrepo: use subprocess.Popen without the shell
Eric Eisner <ede@mit.edu>
parents: 13107
diff changeset
   683
        p = subprocess.Popen(['git'] + commands, bufsize=-1, cwd=cwd, env=env,
13027
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
   684
                             close_fds=util.closefds,
13111
560b8001f765 subrepo: silence git output when ui.quiet is set
Eric Eisner <ede@mit.edu>
parents: 13110
diff changeset
   685
                             stdout=subprocess.PIPE, stderr=errpipe)
13027
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
   686
        if stream:
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
   687
            return p.stdout, None
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
   688
13085
b4814f1f415c subrepo: strip gitcommand output
Eric Eisner <ede@mit.edu>
parents: 13029
diff changeset
   689
        retdata = p.stdout.read().strip()
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   690
        # 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
   691
        p.wait()
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   692
13107
3bc237b0eaea subrepo: treat git error code 1 as success
Eric Eisner <ede@mit.edu>
parents: 13106
diff changeset
   693
        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
   694
            # 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
   695
            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
   696
            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
   697
                return retdata, p.returncode
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   698
            # for all others, abort
13110
cad35f06c031 subrepo: show git command with --debug
Eric Eisner <ede@mit.edu>
parents: 13109
diff changeset
   699
            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
   700
                             (command, p.returncode, self._relpath))
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   701
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   702
        return retdata, p.returncode
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   703
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   704
    def _gitstate(self):
13085
b4814f1f415c subrepo: strip gitcommand output
Eric Eisner <ede@mit.edu>
parents: 13029
diff changeset
   705
        return self._gitcommand(['rev-parse', 'HEAD'])
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   706
13152
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
   707
    def _gitcurrentbranch(self):
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
   708
        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
   709
        if err:
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
   710
            current = None
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
   711
        return current
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
   712
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   713
    def _githavelocally(self, revision):
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   714
        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
   715
        return code == 0
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   716
13029
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
   717
    def _gitisancestor(self, r1, r2):
13085
b4814f1f415c subrepo: strip gitcommand output
Eric Eisner <ede@mit.edu>
parents: 13029
diff changeset
   718
        base = self._gitcommand(['merge-base', r1, r2])
13029
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
   719
        return base == r1
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
   720
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
   721
    def _gitbranchmap(self):
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   722
        '''returns 2 things:
13086
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
   723
        a map from git branch to revision
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   724
        a map from revision to branches'''
13086
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
   725
        branch2rev = {}
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
   726
        rev2branch = {}
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   727
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
   728
        out = self._gitcommand(['for-each-ref', '--format',
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   729
                                '%(objectname) %(refname)'])
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
   730
        for line in out.split('\n'):
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   731
            revision, ref = line.split(' ')
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
   732
            if ref.startswith('refs/tags/'):
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
   733
                continue
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
   734
            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
   735
                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
   736
            branch2rev[ref] = revision
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
   737
            rev2branch.setdefault(revision, []).append(ref)
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   738
        return branch2rev, rev2branch
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   739
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   740
    def _gittracking(self, branches):
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   741
        'return map of remote branch to local tracking branch'
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   742
        # assumes no more than one local tracking branch for each remote
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   743
        tracking = {}
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   744
        for b in branches:
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   745
            if b.startswith('refs/remotes/'):
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   746
                continue
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   747
            remote = self._gitcommand(['config', 'branch.%s.remote' % b])
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   748
            if remote:
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   749
                ref = self._gitcommand(['config', 'branch.%s.merge' % b])
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   750
                tracking['refs/remotes/%s/%s' %
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   751
                         (remote, ref.split('/', 2)[2])] = b
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   752
        return tracking
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   753
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
   754
    def _fetch(self, source, revision):
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
   755
        if not os.path.exists(os.path.join(self._abspath, '.git')):
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
   756
            self._ui.status(_('cloning subrepo %s\n') % self._relpath)
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
   757
            self._gitnodir(['clone', source, self._abspath])
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
   758
        if self._githavelocally(revision):
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
   759
            return
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
   760
        self._ui.status(_('pulling subrepo %s\n') % self._relpath)
13097
c922aacf6f1f subrepo: drop arguments unsupported by old git
Eric Eisner <ede@mit.edu>
parents: 13096
diff changeset
   761
        # first try from origin
c922aacf6f1f subrepo: drop arguments unsupported by old git
Eric Eisner <ede@mit.edu>
parents: 13096
diff changeset
   762
        self._gitcommand(['fetch'])
c922aacf6f1f subrepo: drop arguments unsupported by old git
Eric Eisner <ede@mit.edu>
parents: 13096
diff changeset
   763
        if self._githavelocally(revision):
c922aacf6f1f subrepo: drop arguments unsupported by old git
Eric Eisner <ede@mit.edu>
parents: 13096
diff changeset
   764
            return
c922aacf6f1f subrepo: drop arguments unsupported by old git
Eric Eisner <ede@mit.edu>
parents: 13096
diff changeset
   765
        # then try from known subrepo source
c922aacf6f1f subrepo: drop arguments unsupported by old git
Eric Eisner <ede@mit.edu>
parents: 13096
diff changeset
   766
        self._gitcommand(['fetch', source])
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
   767
        if not self._githavelocally(revision):
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
   768
            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
   769
                               (revision, self._relpath))
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
   770
13179
b512a7074349 subrepo: support ignoreupdate in gitsubrepo's dirty()
Eric Eisner <ede@mit.edu>
parents: 13178
diff changeset
   771
    def dirty(self, ignoreupdate=False):
b512a7074349 subrepo: support ignoreupdate in gitsubrepo's dirty()
Eric Eisner <ede@mit.edu>
parents: 13178
diff changeset
   772
        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
   773
            # different version checked out
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   774
            return True
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   775
        # check for staged changes or modified files; ignore untracked files
13153
dca5488f0e4f subrepo: use low-level git-diff-index for dirty()
Eric Eisner <ede@mit.edu>
parents: 13152
diff changeset
   776
        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
   777
        return code == 1
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   778
13323
d8d478f9ee0f merge with stable
Martin Geisler <mg@aragost.com>
parents: 13288 13322
diff changeset
   779
    def get(self, state, overwrite=False):
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
   780
        source, revision, kind = state
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
   781
        self._fetch(source, revision)
12996
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   782
        # if the repo was set to be bare, unbare it
13085
b4814f1f415c subrepo: strip gitcommand output
Eric Eisner <ede@mit.edu>
parents: 13029
diff changeset
   783
        if self._gitcommand(['config', '--bool', 'core.bare']) == 'true':
12996
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   784
            self._gitcommand(['config', 'core.bare', 'false'])
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   785
            if self._gitstate() == revision:
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   786
                self._gitcommand(['reset', '--hard', 'HEAD'])
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   787
                return
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   788
        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
   789
            if overwrite:
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
   790
                # 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
   791
                # 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
   792
                # 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
   793
                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
   794
                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
   795
            return
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   796
        branch2rev, rev2branch = self._gitbranchmap()
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   797
13324
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
   798
        def checkout(args):
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
   799
            cmd = ['checkout']
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
   800
            if overwrite:
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
   801
                # 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
   802
                # 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
   803
                # 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
   804
                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
   805
                cmd.append('-f')
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
   806
            self._gitcommand(cmd + args)
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
   807
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   808
        def rawcheckout():
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
   809
            # 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
   810
            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
   811
                          self._relpath)
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
   812
            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
   813
                            '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
   814
            checkout(['-q', revision])
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   815
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   816
        if revision not in rev2branch:
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   817
            rawcheckout()
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
   818
            return
13086
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
   819
        branches = rev2branch[revision]
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
   820
        firstlocalbranch = None
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
   821
        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
   822
            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
   823
                # 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
   824
                checkout(['refs/heads/master'])
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
   825
                return
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
   826
            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
   827
                firstlocalbranch = b
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
   828
        if firstlocalbranch:
13324
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
   829
            checkout([firstlocalbranch])
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   830
            return
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   831
13178
c4d857f5405d subrepo: backout 519ac79d680b
Eric Eisner <ede@mit.edu>
parents: 13174
diff changeset
   832
        tracking = self._gittracking(branch2rev.keys())
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   833
        # 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
   834
        remote = branches[0]
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   835
        if remote not in tracking:
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   836
            for b in branches:
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   837
                if b in tracking:
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   838
                    remote = b
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   839
                    break
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   840
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   841
        if remote not in tracking:
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   842
            # create a new local tracking branch
13150
8617b8b74fae subrepo: use low-level git-for-each-ref command in branchmap
Eric Eisner <ede@mit.edu>
parents: 13144
diff changeset
   843
            local = remote.split('/', 2)[2]
13324
e5617047c926 subrepo: make update -C clean the working directory for git subrepos
Erik Zielke <ez@aragost.com>
parents: 13323
diff changeset
   844
            checkout(['-b', local, remote])
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   845
        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
   846
            # 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
   847
            # 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
   848
            # 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
   849
            # 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
   850
            # 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
   851
            # 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
   852
            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
   853
                checkout([tracking[remote]])
13087
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   854
            self._gitcommand(['merge', '--ff', remote])
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   855
        else:
cca0779b4832 subrepo: lazily update git's local tracking branches
Eric Eisner <ede@mit.edu>
parents: 13086
diff changeset
   856
            # 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
   857
            rawcheckout()
12993
a91334380699 subrepo: cloning and updating of git subrepos
Eric Eisner <ede@mit.edu>
parents: 12992
diff changeset
   858
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   859
    def commit(self, text, user, date):
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   860
        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
   861
        env = os.environ.copy()
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   862
        if user:
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   863
            cmd += ['--author', user]
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   864
        if date:
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   865
            # 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
   866
            # convert to ISO8601
13095
49c7e875482d subrepo: use environment variable instead of git commit's --date
Eric Eisner <ede@mit.edu>
parents: 13094
diff changeset
   867
            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
   868
                                                  '%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
   869
        self._gitcommand(cmd, env=env)
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   870
        # 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
   871
        # circumstances
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   872
        return self._gitstate()
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   873
12994
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
   874
    def merge(self, state):
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
   875
        source, revision, kind = state
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
   876
        self._fetch(source, revision)
13085
b4814f1f415c subrepo: strip gitcommand output
Eric Eisner <ede@mit.edu>
parents: 13029
diff changeset
   877
        base = self._gitcommand(['merge-base', revision, self._state[1]])
13417
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   878
        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
   879
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   880
        def mergefunc():
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   881
            if base == revision:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   882
                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
   883
            elif base != self._state[1]:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   884
                self._gitcommand(['merge', '--no-commit', revision])
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   885
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   886
        if self.dirty():
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   887
            if self._gitstate() != revision:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   888
                dirty = self._gitstate() == self._state[1] or code != 0
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   889
                if _updateprompt(self._ui, self, dirty, self._state[1], revision):
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   890
                    mergefunc()
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   891
        else:
0748e18be470 subrepos: prompt on conflicts on update with dirty subrepos
Erik Zielke <ez@aragost.com>
parents: 13413
diff changeset
   892
            mergefunc()
12994
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
   893
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
   894
    def push(self, force):
13029
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
   895
        # 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
   896
        branch2rev, rev2branch = self._gitbranchmap()
13109
53341289eaf8 subrepo: speed up git push logic
Eric Eisner <ede@mit.edu>
parents: 13108
diff changeset
   897
        if self._state[1] in rev2branch:
53341289eaf8 subrepo: speed up git push logic
Eric Eisner <ede@mit.edu>
parents: 13108
diff changeset
   898
            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
   899
                if b.startswith('refs/remotes/origin/'):
13109
53341289eaf8 subrepo: speed up git push logic
Eric Eisner <ede@mit.edu>
parents: 13108
diff changeset
   900
                    return True
13086
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
   901
        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
   902
            if b.startswith('refs/remotes/origin/'):
13086
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
   903
                if self._gitisancestor(self._state[1], revision):
8db85e39d59c subrepo: return both mapping directions from gitbranchmap
Eric Eisner <ede@mit.edu>
parents: 13085
diff changeset
   904
                    return True
13029
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
   905
        # 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
   906
        cmd = ['push']
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
   907
        if force:
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
   908
            cmd.append('--force')
13152
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
   909
70d80907e4b8 subrepo: defer determination of git's current branch
Eric Eisner <ede@mit.edu>
parents: 13151
diff changeset
   910
        current = self._gitcurrentbranch()
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
   911
        if current:
13029
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
   912
            # determine if the current branch is even useful
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
   913
            if not self._gitisancestor(self._state[1], current):
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
   914
                self._ui.warn(_('unrelated git branch checked out '
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
   915
                                'in subrepo %s\n') % self._relpath)
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
   916
                return False
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
   917
            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
   918
                            (current.split('/', 2)[2], self._relpath))
13097
c922aacf6f1f subrepo: drop arguments unsupported by old git
Eric Eisner <ede@mit.edu>
parents: 13096
diff changeset
   919
            self._gitcommand(cmd + ['origin', current])
12995
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
   920
            return True
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
   921
        else:
d90fc91c8377 subrepo: update and merge works with any git branch
Eric Eisner <ede@mit.edu>
parents: 12994
diff changeset
   922
            self._ui.warn(_('no branch checked out in subrepo %s\n'
13029
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
   923
                            'cannot push revision %s') %
f930032aa6d5 subrepo: lazier git push logic
Eric Eisner <ede@mit.edu>
parents: 13027
diff changeset
   924
                          (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
   925
            return False
12994
845c602b8635 subrepo: allow git subrepos to push and merge
Eric Eisner <ede@mit.edu>
parents: 12993
diff changeset
   926
12996
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   927
    def remove(self):
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   928
        if self.dirty():
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   929
            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
   930
                            'it has changes.\n') % self._relpath)
12996
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   931
            return
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   932
        # 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
   933
        # local-only history
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
   934
        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
   935
        self._gitcommand(['config', 'core.bare', 'true'])
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
   936
        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
   937
            if f == '.git':
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   938
                continue
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
   939
            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
   940
            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
   941
                shutil.rmtree(path)
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   942
            else:
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   943
                os.remove(path)
3a42651b0a62 subrepo: removing (and restoring) git subrepo state
Eric Eisner <ede@mit.edu>
parents: 12995
diff changeset
   944
13144
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   945
    def archive(self, ui, archiver, prefix):
13027
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
   946
        source, revision = self._state
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
   947
        self._fetch(source, revision)
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
   948
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
   949
        # Parse git's native archive command.
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
   950
        # This should be much faster than manually traversing the trees
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
   951
        # and objects with many subprocess calls.
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
   952
        tarstream = self._gitcommand(['archive', revision], stream=True)
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
   953
        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
   954
        relpath = subrelpath(self)
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   955
        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
   956
        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
   957
            if info.isdir():
a79e0688a5ee subrepo: fix git archive parsing of directories and symfiles
Eric Eisner <ede@mit.edu>
parents: 13179
diff changeset
   958
                continue
a79e0688a5ee subrepo: fix git archive parsing of directories and symfiles
Eric Eisner <ede@mit.edu>
parents: 13179
diff changeset
   959
            if info.issym():
a79e0688a5ee subrepo: fix git archive parsing of directories and symfiles
Eric Eisner <ede@mit.edu>
parents: 13179
diff changeset
   960
                data = info.linkname
a79e0688a5ee subrepo: fix git archive parsing of directories and symfiles
Eric Eisner <ede@mit.edu>
parents: 13179
diff changeset
   961
            else:
a79e0688a5ee subrepo: fix git archive parsing of directories and symfiles
Eric Eisner <ede@mit.edu>
parents: 13179
diff changeset
   962
                data = tar.extractfile(info).read()
13181
413bef846806 subrepo: fix subrelpath for git subrepos
Eric Eisner <ede@mit.edu>
parents: 13180
diff changeset
   963
            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
   964
                             info.mode, info.issym(), data)
13144
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   965
            ui.progress(_('archiving (%s)') % relpath, i + 1,
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   966
                        unit=_('files'))
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   967
        ui.progress(_('archiving (%s)') % relpath, None)
aae2d5cbde64 subrepo: add progress bar support to archive
Martin Geisler <mg@aragost.com>
parents: 13137
diff changeset
   968
13027
7f2ecb64140d subrepo: archive git subrepos
Eric Eisner <ede@mit.edu>
parents: 13018
diff changeset
   969
13182
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   970
    def status(self, rev2, **opts):
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   971
        rev1 = self._state[1]
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   972
        modified, added, removed = [], [], []
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   973
        if rev2:
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   974
            command = ['diff-tree', rev1, rev2]
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   975
        else:
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   976
            command = ['diff-index', rev1]
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   977
        out = self._gitcommand(command)
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   978
        for line in out.split('\n'):
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   979
            tab = line.find('\t')
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   980
            if tab == -1:
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   981
                continue
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   982
            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
   983
            if status == 'M':
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   984
                modified.append(f)
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   985
            elif status == 'A':
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   986
                added.append(f)
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   987
            elif status == 'D':
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   988
                removed.append(f)
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   989
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   990
        deleted = unknown = ignored = clean = []
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   991
        return modified, added, removed, deleted, unknown, ignored, clean
2537bd17421d subrepo: basic support for status of git subrepos
Eric Eisner <ede@mit.edu>
parents: 13181
diff changeset
   992
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
   993
types = {
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
   994
    'hg': hgsubrepo,
10178
cd477be6f2fc subrepo: Subversion support
Augie Fackler <durin42@gmail.com>
parents: 10177
diff changeset
   995
    'svn': svnsubrepo,
12992
2b73a3279a9f subrepo: support for adding a git subrepo
Eric Eisner <ede@mit.edu>
parents: 12930
diff changeset
   996
    'git': gitsubrepo,
10177
5ca0d220ae21 subrepo: add table-based dispatch for subrepo types
Augie Fackler <durin42@gmail.com>
parents: 10175
diff changeset
   997
    }