##// END OF EJS Templates
scmutil: introduce function to check whether repo uses treemanifest or not...
scmutil: introduce function to check whether repo uses treemanifest or not In an upcoming patch, I wanted to check whether current repo uses treemanifest or not. I looked for a function and found that at all places we manually check for the requirement in repo requirements. I guess having a dedicated function for that is much better. Differential Revision: https://phab.mercurial-scm.org/D8981

File last commit:

r45935:8c466bcb default
r46126:dfe58565 default
Show More
subrepo.py
2051 lines | 70.0 KiB | text/x-python | PythonLexer
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 # subrepo.py - sub-repository classes and factory
Matt Mackall
subrepo: introduce basic state parsing
r8812 #
David Soria Parra
subrepo: correct copyright
r10324 # Copyright 2009-2010 Matt Mackall <mpm@selenic.com>
Matt Mackall
subrepo: introduce basic state parsing
r8812 #
# This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Matt Mackall
subrepo: introduce basic state parsing
r8812
Gregory Szorc
subrepo: use absolute_import
r25980 from __future__ import absolute_import
Matt Harbison
addremove: automatically process a subrepository's subrepos...
r23540 import copy
Gregory Szorc
subrepo: use absolute_import
r25980 import errno
import os
import re
import stat
import subprocess
import sys
import tarfile
Augie Fackler
subrepo: move import of xml.minidom.dom to its own line for check-code
r19788 import xml.dom.minidom
Gregory Szorc
subrepo: use absolute_import
r25980
from .i18n import _
from . import (
cmdutil,
Pulkit Goyal
py3: replace os.environ with encoding.environ (part 2 of 5)
r30635 encoding,
Gregory Szorc
subrepo: use absolute_import
r25980 error,
exchange,
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 logcmdutil,
Gregory Szorc
subrepo: use absolute_import
r25980 match as matchmod,
node,
pathutil,
phases,
Pulkit Goyal
py3: replace os.sep with pycompat.ossep (part 3 of 4)
r30615 pycompat,
Gregory Szorc
subrepo: use absolute_import
r25980 scmutil,
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 subrepoutil,
Gregory Szorc
subrepo: use absolute_import
r25980 util,
Pierre-Yves David
vfs: use 'vfs' module directly in 'mercurial.subrepo'...
r31236 vfs as vfsmod,
Gregory Szorc
subrepo: use absolute_import
r25980 )
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 from .utils import (
dateutil,
Augie Fackler
core: migrate uses of hashlib.sha1 to hashutil.sha1...
r44517 hashutil,
Yuya Nishihara
procutil: bulk-replace function calls to point to new module
r37138 procutil,
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 stringutil,
)
Gregory Szorc
subrepo: use absolute_import
r25980
Abderrahim Kitouni
subrepo: use hg.repository instead of creating localrepo directly...
r9092 hg = None
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 reporelpath = subrepoutil.reporelpath
subrelpath = subrepoutil.subrelpath
_abssource = subrepoutil._abssource
Patrick Mezard
subrepo: handle svn tracked/unknown directory collisions...
r14050 propertycache = util.propertycache
Matt Mackall
commit: recurse into subrepositories
r8813
Augie Fackler
formatting: blacken the codebase...
r43346
Angel Ezquerra
subrepo: do not push mercurial subrepos whose store is clean...
r18940 def _expandedabspath(path):
'''
get a path or url and if it is a path expand it and return an absolute path
'''
expandedpath = util.urllocalpath(util.expandpath(path))
u = util.url(expandedpath)
if not u.scheme:
path = util.normpath(os.path.abspath(u.path))
return path
Angel Ezquerra
subrepo: introduce storeclean helper functions...
r18936
Augie Fackler
formatting: blacken the codebase...
r43346
Angel Ezquerra
subrepo: introduce storeclean helper functions...
r18936 def _getstorehashcachename(remotepath):
'''get a unique filename for the store hash cache of a remote repository'''
Augie Fackler
core: migrate uses of hashlib.sha1 to hashutil.sha1...
r44517 return node.hex(hashutil.sha1(_expandedabspath(remotepath)).digest())[0:12]
Angel Ezquerra
subrepo: introduce storeclean helper functions...
r18936
Augie Fackler
formatting: blacken the codebase...
r43346
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 class SubrepoAbort(error.Abort):
"""Exception class used to avoid handling a subrepo error more than once"""
Augie Fackler
formatting: blacken the codebase...
r43346
Angel Ezquerra
subrepo: add subrepo property to SubrepoAbort exceptions...
r18263 def __init__(self, *args, **kw):
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 self.subrepo = kw.pop('subrepo', None)
self.cause = kw.pop('cause', None)
Brendan Cully
subrepo: fix python2.4 compatibility after 9aa6bee6e9f9...
r18296 error.Abort.__init__(self, *args, **kw)
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109
Augie Fackler
formatting: blacken the codebase...
r43346
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 def annotatesubrepoerror(func):
def decoratedmethod(self, *args, **kargs):
try:
res = func(self, *args, **kargs)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except SubrepoAbort as ex:
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 # This exception has already been handled
raise ex
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except error.Abort as ex:
Angel Ezquerra
subrepo: add subrepo property to SubrepoAbort exceptions...
r18263 subrepo = subrelpath(self)
Augie Fackler
formatting: blacken the codebase...
r43346 errormsg = (
stringutil.forcebytestr(ex)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 + b' '
+ _(b'(in subrepository "%s")') % subrepo
Augie Fackler
formatting: blacken the codebase...
r43346 )
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 # avoid handling this exception by raising a SubrepoAbort exception
Augie Fackler
formatting: blacken the codebase...
r43346 raise SubrepoAbort(
errormsg, hint=ex.hint, subrepo=subrepo, cause=sys.exc_info()
)
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 return res
Augie Fackler
formatting: blacken the codebase...
r43346
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 return decoratedmethod
Augie Fackler
formatting: blacken the codebase...
r43346
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417 def _updateprompt(ui, sub, dirty, local, remote):
if dirty:
Augie Fackler
formatting: blacken the codebase...
r43346 msg = _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b' subrepository sources for %s differ\n'
b'you can use (l)ocal source (%s) or (r)emote source (%s).\n'
b'what do you want to do?'
b'$$ &Local $$ &Remote'
Augie Fackler
formatting: blacken the codebase...
r43346 ) % (subrelpath(sub), local, remote)
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417 else:
Augie Fackler
formatting: blacken the codebase...
r43346 msg = _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b' subrepository sources for %s differ (in checked out '
b'version)\n'
b'you can use (l)ocal source (%s) or (r)emote source (%s).\n'
b'what do you want to do?'
b'$$ &Local $$ &Remote'
Augie Fackler
formatting: blacken the codebase...
r43346 ) % (subrelpath(sub), local, remote)
Matt Mackall
ui: merge prompt text components into a singe string...
r19226 return ui.promptchoice(msg, 0)
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417
Augie Fackler
formatting: blacken the codebase...
r43346
FUJIWARA Katsunori
subrepo: pass wvfs to _sanitize instead of absolute path to a subrepository...
r24724 def _sanitize(ui, vfs, ignore):
FUJIWARA Katsunori
subrepo: use vfs.walk instead of os.walk...
r24726 for dirname, dirs, names in vfs.walk():
FUJIWARA Katsunori
subrepo: avoid sanitizing ".hg/hgrc" in meta data area for non-hg subrepos...
r21567 for i, d in enumerate(dirs):
if d.lower() == ignore:
del dirs[i]
break
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if vfs.basename(dirname).lower() != b'.hg':
FUJIWARA Katsunori
subrepo: make "_sanitize()" work...
r21564 continue
Matt Mackall
subrepo: sanitize non-hg subrepos
r20104 for f in names:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if f.lower() == b'hgrc':
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"warning: removing potentially hostile 'hgrc' "
b"in '%s'\n"
Augie Fackler
formatting: blacken the codebase...
r43346 )
% vfs.join(dirname)
)
FUJIWARA Katsunori
subrepo: use vfs.walk instead of os.walk...
r24726 vfs.unlink(vfs.reljoin(dirname, f))
Matt Mackall
subrepo: sanitize non-hg subrepos
r20104
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
subrepo: disallow symlink traversal across subrepo mount point (SEC)...
r34985 def _auditsubrepopath(repo, path):
Yuya Nishihara
subrepo: reject potentially unsafe subrepo paths (BC) (SEC)...
r41551 # sanity check for potentially unsafe paths such as '~' and '$FOO'
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if path.startswith(b'~') or b'$' in path or util.expandpath(path) != path:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'subrepo path contains illegal component: %s') % path
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
subrepo: disallow symlink traversal across subrepo mount point (SEC)...
r34985 # auditor doesn't check if the path itself is a symlink
pathutil.pathauditor(repo.root)(path)
if repo.wvfs.islink(path):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"subrepo '%s' traverses symbolic link") % path)
Yuya Nishihara
subrepo: disallow symlink traversal across subrepo mount point (SEC)...
r34985
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
subrepo: use per-type config options to enable subrepos...
r34990 SUBREPO_ALLOWED_DEFAULTS = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'hg': True,
b'git': False,
b'svn': False,
Gregory Szorc
subrepo: use per-type config options to enable subrepos...
r34990 }
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
subrepo: add config option to reject any subrepo operations (SEC)...
r34986 def _checktype(ui, kind):
Gregory Szorc
subrepo: use per-type config options to enable subrepos...
r34990 # subrepos.allowed is a master kill switch. If disabled, subrepos are
# disabled period.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not ui.configbool(b'subrepos', b'allowed', True):
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'subrepos not enabled'),
hint=_(b"see 'hg help config.subrepos' for details"),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
subrepo: use per-type config options to enable subrepos...
r34990
default = SUBREPO_ALLOWED_DEFAULTS.get(kind, False)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not ui.configbool(b'subrepos', b'%s:allowed' % kind, default):
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s subrepos not allowed') % kind,
hint=_(b"see 'hg help config.subrepos' for details"),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
subrepo: use per-type config options to enable subrepos...
r34990
Yuya Nishihara
subrepo: add config option to reject any subrepo operations (SEC)...
r34986 if kind not in types:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'unknown subrepo type %s') % kind)
Yuya Nishihara
subrepo: add config option to reject any subrepo operations (SEC)...
r34986
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
verify: don't init subrepo when missing one is referenced (issue5128) (API)...
r29021 def subrepo(ctx, path, allowwdir=False, allowcreate=True):
Mads Kiilerich
subrepo: docstrings
r11571 """return instance of the right subrepo class for subrepo in path"""
Matt Mackall
commit: recurse into subrepositories
r8813 # subrepo inherently violates our import layering rules
# because it wants to make repo objects from deep inside the stack
# so we manually delay the circular imports to not break
# scripts that don't use our demand-loading
Abderrahim Kitouni
subrepo: use hg.repository instead of creating localrepo directly...
r9092 global hg
Gregory Szorc
subrepo: use absolute_import
r25980 from . import hg as h
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
subrepo: add update/merge logic
r8814 hg = h
Matt Mackall
commit: recurse into subrepositories
r8813
Yuya Nishihara
subrepo: add config option to reject any subrepo operations (SEC)...
r34986 repo = ctx.repo()
_auditsubrepopath(repo, path)
Dov Feldstern
subrepo: make subrepo.subrepo(<not a subrepo path>) fail...
r16756 state = ctx.substate[path]
Yuya Nishihara
subrepo: add config option to reject any subrepo operations (SEC)...
r34986 _checktype(repo.ui, state[2])
Matt Harbison
subrepo: allow a representation of the working directory subrepo...
r25600 if allowwdir:
state = (state[0], ctx.subrev(path), state[2])
Matt Harbison
verify: don't init subrepo when missing one is referenced (issue5128) (API)...
r29021 return types[state[2]](ctx, path, state[:2], allowcreate)
Matt Mackall
commit: recurse into subrepositories
r8813
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
subrepo: introduce the nullsubrepo() method...
r25416 def nullsubrepo(ctx, path, pctx):
"""return an empty subrepo in pctx for the extant subrepo in ctx"""
# subrepo inherently violates our import layering rules
# because it wants to make repo objects from deep inside the stack
# so we manually delay the circular imports to not break
# scripts that don't use our demand-loading
global hg
Gregory Szorc
subrepo: use absolute_import
r25980 from . import hg as h
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
subrepo: introduce the nullsubrepo() method...
r25416 hg = h
Yuya Nishihara
subrepo: add config option to reject any subrepo operations (SEC)...
r34986 repo = ctx.repo()
_auditsubrepopath(repo, path)
Matt Harbison
subrepo: introduce the nullsubrepo() method...
r25416 state = ctx.substate[path]
Yuya Nishihara
subrepo: add config option to reject any subrepo operations (SEC)...
r34986 _checktype(repo.ui, state[2])
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 subrev = b''
if state[2] == b'hg':
subrev = b"0" * 40
Matt Harbison
verify: don't init subrepo when missing one is referenced (issue5128) (API)...
r29021 return types[state[2]](pctx, path, (state[0], subrev), True)
Matt Harbison
subrepo: introduce the nullsubrepo() method...
r25416
Augie Fackler
formatting: blacken the codebase...
r43346
Martin Geisler
subrepo: add abstract superclass for subrepo classes
r11559 # subrepo classes need to implement the following abstract class:
Augie Fackler
formatting: blacken the codebase...
r43346
Martin Geisler
subrepo: add abstract superclass for subrepo classes
r11559 class abstractsubrepo(object):
FUJIWARA Katsunori
subrepo: change arguments of abstractsubrepo.__init__ (API)...
r24671 def __init__(self, ctx, path):
"""Initialize abstractsubrepo part
``ctx`` is the context referring this subrepository in the
parent repository.
Mads Kiilerich
spelling: trivial spell checking
r26781 ``path`` is the path to this subrepository as seen from
FUJIWARA Katsunori
subrepo: change arguments of abstractsubrepo.__init__ (API)...
r24671 innermost repository.
"""
self.ui = ctx.repo().ui
self._ctx = ctx
self._path = path
Matt Harbison
subrepo: store the ui object in the base class...
r23536
Matt Harbison
serve: add support for Mercurial subrepositories...
r32005 def addwebdirpath(self, serverpath, webconf):
"""Add the hgwebdir entries for this subrepo, and any of its subrepos.
``serverpath`` is the path component of the URL for this repo.
``webconf`` is the dictionary of hgwebdir entries.
"""
pass
Angel Ezquerra
subrepo: introduce storeclean method...
r18937 def storeclean(self, path):
"""
returns true if the repository has not changed since it was last
cloned from or pushed to a given repository.
"""
return False
Matt Harbison
subrepo: consider the parent repo dirty when a file is missing...
r33364 def dirty(self, ignoreupdate=False, missing=False):
Kevin Bullock
mq: update .hgsubstate if subrepos are clean (issue2499)...
r13174 """returns true if the dirstate of the subrepo is dirty or does not
match current stored state. If ignoreupdate is true, only check
Matt Harbison
subrepo: consider the parent repo dirty when a file is missing...
r33364 whether the subrepo has uncommitted changes in its dirstate. If missing
is true, check for deleted files.
Martin Geisler
subrepo: add abstract superclass for subrepo classes
r11559 """
raise NotImplementedError
Matt Harbison
subrepo: consider the parent repo dirty when a file is missing...
r33364 def dirtyreason(self, ignoreupdate=False, missing=False):
FUJIWARA Katsunori
subrepo: add dirtyreason to centralize composing dirty reason message...
r24470 """return reason string if it is ``dirty()``
Returned string should have enough information for the message
of exception.
This returns None, otherwise.
"""
Matt Harbison
subrepo: consider the parent repo dirty when a file is missing...
r33364 if self.dirty(ignoreupdate=ignoreupdate, missing=missing):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return _(b'uncommitted changes in subrepository "%s"') % subrelpath(
Augie Fackler
formatting: blacken the codebase...
r43346 self
)
FUJIWARA Katsunori
subrepo: add dirtyreason to centralize composing dirty reason message...
r24470
Valters Vingolds
rebase: provide detailed hint to abort message if working dir is not clean...
r30755 def bailifchanged(self, ignoreupdate=False, hint=None):
FUJIWARA Katsunori
subrepo: add bailifchanged to centralize raising Abort if subrepo is dirty...
r24471 """raise Abort if subrepository is ``dirty()``
"""
Augie Fackler
formatting: blacken the codebase...
r43346 dirtyreason = self.dirtyreason(ignoreupdate=ignoreupdate, missing=True)
FUJIWARA Katsunori
subrepo: add bailifchanged to centralize raising Abort if subrepo is dirty...
r24471 if dirtyreason:
Valters Vingolds
rebase: provide detailed hint to abort message if working dir is not clean...
r30755 raise error.Abort(dirtyreason, hint=hint)
FUJIWARA Katsunori
subrepo: add bailifchanged to centralize raising Abort if subrepo is dirty...
r24471
Matt Mackall
subrepo: add basestate method...
r16072 def basestate(self):
"""current working directory base state, disregarding .hgsubstate
state and working directory modifications"""
raise NotImplementedError
Brodie Rao
subrepos: add missing self argument to abstractsubrepo.checknested
r12506 def checknested(self, path):
Martin Geisler
localrepo: add auditor attribute which knows about subrepos
r12162 """check if path is a subrepository within this repository"""
return False
Martin Geisler
subrepo: add abstract superclass for subrepo classes
r11559 def commit(self, text, user, date):
"""commit the current changes to the subrepo with the given
log message. Use given user and date if possible. Return the
new state of the subrepo.
"""
raise NotImplementedError
FUJIWARA Katsunori
subrepo: check phase of state in each subrepositories before committing...
r20176 def phase(self, state):
"""returns phase of specified state in the subrepository.
"""
return phases.public
Martin Geisler
subrepo: add abstract superclass for subrepo classes
r11559 def remove(self):
"""remove the subrepo
Matt Mackall
commit: recurse into subrepositories
r8813
Martin Geisler
subrepo: add abstract superclass for subrepo classes
r11559 (should verify the dirstate is not dirty first)
"""
raise NotImplementedError
Erik Zielke
subrepo: make update -C clean the working directory for svn subrepos...
r13322 def get(self, state, overwrite=False):
Martin Geisler
subrepo: add abstract superclass for subrepo classes
r11559 """run whatever commands are needed to put the subrepo into
this state
"""
raise NotImplementedError
Erik Zielke
subrepo: remove argument introduced by mistake in c19b9282d3a7
r13413 def merge(self, state):
Martin Geisler
subrepo: add abstract superclass for subrepo classes
r11559 """merge currently-saved state with the new state."""
raise NotImplementedError
Angel Ezquerra
push: propagate --new-branch and --ssh options when pushing subrepos...
r15708 def push(self, opts):
Martin Geisler
Merge with stable
r11572 """perform whatever action is analogous to 'hg push'
Martin Geisler
subrepo: add abstract superclass for subrepo classes
r11559
This may be a no-op on some systems.
"""
raise NotImplementedError
Martin von Zweigbergk
add: pass around uipathfn and use instead of m.rel() (API)...
r41799 def add(self, ui, match, prefix, uipathfn, explicitonly, **opts):
Martin Geisler
add: recurse into subrepositories with --subrepos/-S flag
r12270 return []
Martin Geisler
subrepo: add abstract superclass for subrepo classes
r11559
Martin von Zweigbergk
addremove: pass around uipathfn and use instead of m.uipath() (API)...
r41801 def addremove(self, matcher, prefix, uipathfn, opts):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.warn(b"%s: %s" % (prefix, _(b"addremove is not supported")))
Matt Harbison
commit: propagate --addremove to subrepos if -S is specified (issue3759)...
r23537 return 1
Yuya Nishihara
cat: add formatter support...
r32578 def cat(self, match, fm, fntemplate, prefix, **opts):
Matt Harbison
cat: support cat with explicit paths in subrepos...
r21041 return 1
Martin Geisler
status: recurse into subrepositories with --subrepos/-S flag
r12166 def status(self, rev2, **opts):
Martin von Zweigbergk
status: update various other methods to return new class
r22914 return scmutil.status([], [], [], [], [], [], [])
Martin Geisler
status: recurse into subrepositories with --subrepos/-S flag
r12166
FUJIWARA Katsunori
subrepo: add argument to "diff()" to pass "ui" of caller side (issue3712) (API)...
r18006 def diff(self, ui, diffopts, node2, match, prefix, **opts):
Martin Geisler
diff: recurse into subrepositories with --subrepos/-S flag
r12167 pass
Martin Geisler
outgoing: recurse into subrepositories with --subrepos/-S flag...
r12272 def outgoing(self, ui, dest, opts):
return 1
Martin Geisler
incoming: recurse into subrepositories with --subrepos/-S flag...
r12274 def incoming(self, ui, source, opts):
return 1
Martin Geisler
subrepo: introduce files and filedata methods for subrepo classes
r12322 def files(self):
"""return filename iterator"""
raise NotImplementedError
Matt Harbison
subrepo: run the repo decoders when archiving...
r31099 def filedata(self, name, decode):
"""return file data, optionally passed through repo decoders"""
Martin Geisler
subrepo: introduce files and filedata methods for subrepo classes
r12322 raise NotImplementedError
def fileflags(self, name):
"""return file flags"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b''
Martin Geisler
subrepo: introduce files and filedata methods for subrepo classes
r12322
Matt Harbison
match: resolve filesets against the passed `cwd`, not the current one...
r44461 def matchfileset(self, cwd, expr, badfn=None):
Matt Harbison
subrepo: introduce getfileset()...
r25121 """Resolve the fileset expression for this repo"""
Martin von Zweigbergk
match: delete unused root and cwd arguments from {always,never,exact}() (API)...
r41825 return matchmod.never(badfn=badfn)
Matt Harbison
subrepo: introduce getfileset()...
r25121
Martin von Zweigbergk
subrepo: use root-repo-relative path from `hg files` with ui.relative-paths=no...
r41914 def printfiles(self, ui, m, uipathfn, fm, fmt, subrepos):
Matt Harbison
subrepo: add basic support to hgsubrepo for the files command...
r24413 """handle the files command for this subrepo"""
return 1
Matt Harbison
subrepo: run the repo decoders when archiving...
r31099 def archive(self, archiver, prefix, match=None, decode=True):
Matt Harbison
subrepo: propagate matcher to subrepos when archiving...
r17108 if match is not None:
files = [f for f in self.files() if match(f)]
else:
files = self.files()
Martin Geisler
subrepo: add progress bar support to archive
r13144 total = len(files)
relpath = subrelpath(self)
Augie Fackler
formatting: blacken the codebase...
r43346 progress = self.ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'archiving (%s)') % relpath, unit=_(b'files'), total=total
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martin von Zweigbergk
subrepo: use progress helper...
r38398 progress.update(0)
for name in files:
Martin Geisler
subrepo: add support for 'hg archive'
r12323 flags = self.fileflags(name)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 mode = b'x' in flags and 0o755 or 0o644
symlink = b'l' in flags
Augie Fackler
formatting: blacken the codebase...
r43346 archiver.addfile(
prefix + name, mode, symlink, self.filedata(name, decode)
)
Martin von Zweigbergk
subrepo: use progress helper...
r38398 progress.increment()
progress.complete()
Angel Ezquerra
archive: raise error.Abort if the file pattern matches no files...
r18967 return total
Martin Geisler
subrepo: add support for 'hg archive'
r12323
David M. Carr
add: support adding explicit files in subrepos...
r15410 def walk(self, match):
'''
walk recursively through the directory tree, finding all files
matched by the match function
'''
Martin Geisler
subrepo: add support for 'hg archive'
r12323
Martin von Zweigbergk
forget: pass around uipathfn and use instead of m.rel() (API)...
r41802 def forget(self, match, prefix, uipathfn, dryrun, interactive):
Patrick Mezard
subrepo: fix default implementation of forget() (issue3404)
r16527 return ([], [])
Martin Geisler
subrepo: add support for 'hg archive'
r12323
Augie Fackler
formatting: blacken the codebase...
r43346 def removefiles(
self,
matcher,
prefix,
uipathfn,
after,
force,
subrepos,
dryrun,
warnings,
):
Matt Harbison
remove: recurse into subrepositories with --subrepos/-S flag...
r23325 """remove the matched files from the subrepository and the filesystem,
possibly by force and/or after the file has been removed from the
filesystem. Return 0 on success, 1 on any warning.
"""
Augie Fackler
formatting: blacken the codebase...
r43346 warnings.append(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"warning: removefiles not implemented (%s)") % self._path
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
remove: recurse into subrepositories with --subrepos/-S flag...
r23325 return 1
Matt Harbison
subrepo: drop the 'ui' parameter to revert()...
r23579 def revert(self, substate, *pats, **opts):
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s: reverting %s subrepos is unsupported\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (substate[0], substate[2])
)
Angel Ezquerra
revert: add support for reverting subrepos...
r16429 return []
Angel Ezquerra
subrepo: add shortid() method to subrepo classes...
r21400 def shortid(self, revid):
return revid
Matt Harbison
subrepo: implement 'unshare' for Mercurial subrepos...
r34880 def unshare(self):
'''
convert this repository from shared to normal storage.
'''
Matt Harbison
exchange: ensure all outgoing subrepo references are present before pushing...
r44365 def verify(self, onpush=False):
"""verify the revision of this repository that is held in `_state` is
present and not hidden. Return 0 on success or warning, 1 on any
error. In the case of ``onpush``, warnings or errors will raise an
exception if the result of pushing would be a broken remote repository.
"""
Matt Harbison
verify: check the subrepository references in .hgsubstate...
r25591 return 0
FUJIWARA Katsunori
subrepo: add wvfs field to access the working directory via vfs...
r24672 @propertycache
def wvfs(self):
"""return vfs to access the working directory of this subrepository
"""
Pierre-Yves David
vfs: use 'vfs' module directly in 'mercurial.subrepo'...
r31236 return vfsmod.vfs(self._ctx.repo().wvfs.join(self._path))
FUJIWARA Katsunori
subrepo: add wvfs field to access the working directory via vfs...
r24672
FUJIWARA Katsunori
subrepo: add _relpath field to centralize subrelpath logic...
r24673 @propertycache
def _relpath(self):
"""return path to this subrepository as seen from outermost repository
"""
Matt Harbison
subrepo: backout 93b0e0db7929 to restore reporelpath()...
r24785 return self.wvfs.reljoin(reporelpath(self._ctx.repo()), self._path)
FUJIWARA Katsunori
subrepo: add _relpath field to centralize subrelpath logic...
r24673
Augie Fackler
formatting: blacken the codebase...
r43346
Martin Geisler
subrepo: add abstract superclass for subrepo classes
r11559 class hgsubrepo(abstractsubrepo):
Matt Harbison
verify: don't init subrepo when missing one is referenced (issue5128) (API)...
r29021 def __init__(self, ctx, path, state, allowcreate):
FUJIWARA Katsunori
subrepo: change arguments of abstractsubrepo.__init__ (API)...
r24671 super(hgsubrepo, self).__init__(ctx, path)
Matt Mackall
commit: recurse into subrepositories
r8813 self._state = state
Matt Harbison
subrepo: replace 'ctx._repo' with 'ctx.repo()'
r24302 r = ctx.repo()
Matt Harbison
subrepo: avoid false unsafe path detection on Windows...
r41747 root = r.wjoin(util.localpath(path))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 create = allowcreate and not r.wvfs.exists(b'%s/.hg' % path)
Yuya Nishihara
subrepo: prohibit variable expansion on creation of hg subrepo (SEC)...
r41550 # repository constructor does expand variables in path, which is
# unsafe since subrepo path might come from untrusted source.
if os.path.realpath(util.expandpath(root)) != root:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'subrepo path contains illegal component: %s') % path
Augie Fackler
formatting: blacken the codebase...
r43346 )
FUJIWARA Katsunori
subrepo: isolate configuration between each repositories in subrepo tree...
r17873 self._repo = hg.repository(r.baseui, root, create=create)
Yuya Nishihara
subrepo: prohibit variable expansion on creation of hg subrepo (SEC)...
r41550 if self._repo.root != root:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.ProgrammingError(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'failed to reject unsafe subrepo '
b'path: %s (expanded to %s)' % (root, self._repo.root)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
subrepo: propagate the --hidden option to hg subrepositories...
r24877
# Propagate the parent's --hidden option
if r is r.unfiltered():
self._repo = self._repo.unfiltered()
Matt Harbison
subrepo: reset 'self.ui' to the subrepo copy of 'ui' in the hgsubrepo class...
r23573 self.ui = self._repo.ui
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for s, k in [(b'ui', b'commitsubrepos')]:
FUJIWARA Katsunori
subrepo: isolate configuration between each repositories in subrepo tree...
r17873 v = r.ui.config(s, k)
if v:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.setconfig(s, k, v, b'subrepo')
Matt Mackall
subrepo: mark internal-only option
r25848 # internal config: ui._usedassubrepo
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.setconfig(b'ui', b'_usedassubrepo', b'True', b'subrepo')
Martin Geisler
subrepo: create subrepos using clone instead of pull...
r14281 self._initrepo(r, state[0], create)
Matt Harbison
serve: add support for Mercurial subrepositories...
r32005 @annotatesubrepoerror
def addwebdirpath(self, serverpath, webconf):
cmdutil.addwebdirpath(self._repo, subrelpath(self), webconf)
Angel Ezquerra
subrepo: implement "storeclean" method for mercurial subrepos...
r18939 def storeclean(self, path):
Bryan O'Sullivan
with: use context manager in subrepo storeclean
r27844 with self._repo.lock():
FUJIWARA Katsunori
subrepo: ensure "lock.release()" execution at the end of "storeclean()"...
r21885 return self._storeclean(path)
def _storeclean(self, path):
Angel Ezquerra
subrepo: implement "storeclean" method for mercurial subrepos...
r18939 clean = True
itercache = self._calcstorehash(path)
Pierre-Yves David
subrepo: further replacement of try/except with 'next'...
r25172 for filehash in self._readstorehashcache(path):
if filehash != next(itercache, None):
clean = False
break
if clean:
# if not empty:
Angel Ezquerra
subrepo: implement "storeclean" method for mercurial subrepos...
r18939 # the cached and current pull states have a different size
Pierre-Yves David
subrepo: further replacement of try/except with 'next'...
r25172 clean = next(itercache, None) is None
Angel Ezquerra
subrepo: implement "storeclean" method for mercurial subrepos...
r18939 return clean
def _calcstorehash(self, remotepath):
'''calculate a unique "store hash"
This method is used to to detect when there are changes that may
require a push to a given remote path.'''
# sort the files that will be hashed in increasing (likely) file size
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 filelist = (b'bookmarks', b'store/phaseroots', b'store/00changelog.i')
yield b'# %s\n' % _expandedabspath(remotepath)
FUJIWARA Katsunori
subrepo: replace "_calcfilehash" invocation by "vfs.tryread"...
r23365 vfs = self._repo.vfs
Angel Ezquerra
subrepo: implement "storeclean" method for mercurial subrepos...
r18939 for relname in filelist:
Augie Fackler
core: migrate uses of hashlib.sha1 to hashutil.sha1...
r44517 filehash = node.hex(hashutil.sha1(vfs.tryread(relname)).digest())
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 yield b'%s = %s\n' % (relname, filehash)
Angel Ezquerra
subrepo: implement "storeclean" method for mercurial subrepos...
r18939
FUJIWARA Katsunori
subrepo: add "_cachestorehashvfs" to handle cache store hash files via vfs...
r23367 @propertycache
def _cachestorehashvfs(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return vfsmod.vfs(self._repo.vfs.join(b'cache/storehash'))
FUJIWARA Katsunori
subrepo: add "_cachestorehashvfs" to handle cache store hash files via vfs...
r23367
Angel Ezquerra
subrepo: implement "storeclean" method for mercurial subrepos...
r18939 def _readstorehashcache(self, remotepath):
'''read the store hash cache for a given remote repository'''
FUJIWARA Katsunori
subrepo: replace direct file APIs around "readlines" by "vfs.tryreadlines"...
r23369 cachefile = _getstorehashcachename(remotepath)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._cachestorehashvfs.tryreadlines(cachefile, b'r')
Angel Ezquerra
subrepo: implement "storeclean" method for mercurial subrepos...
r18939
def _cachestorehash(self, remotepath):
'''cache the current store hash
Each remote repo requires its own store hash cache, because a subrepo
store may be "clean" versus a given remote repo, but not versus another
'''
FUJIWARA Katsunori
subrepo: replace direct file APIs around "writelines" by "vfs.writelines"...
r23372 cachefile = _getstorehashcachename(remotepath)
Bryan O'Sullivan
with: use context manager in subrepo _cachestorehash
r27843 with self._repo.lock():
FUJIWARA Katsunori
subrepo: ensure "lock.release()" execution at the end of "_cachestorehash()"...
r21886 storehash = list(self._calcstorehash(remotepath))
FUJIWARA Katsunori
subrepo: replace direct file APIs around "writelines" by "vfs.writelines"...
r23372 vfs = self._cachestorehashvfs
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 vfs.writelines(cachefile, storehash, mode=b'wb', notindexed=True)
Angel Ezquerra
subrepo: implement "storeclean" method for mercurial subrepos...
r18939
Matt Harbison
subrepo: introduce hgsubrepo._getctx()...
r25572 def _getctx(self):
'''fetch the context for this subrepo revision, possibly a workingctx
'''
if self._ctx.rev() is None:
return self._repo[None] # workingctx if parent is workingctx
else:
rev = self._state[1]
return self._repo[rev]
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Martin Geisler
subrepo: create subrepos using clone instead of pull...
r14281 def _initrepo(self, parentrepo, source, create):
self._repo._subparent = parentrepo
self._repo._subsource = source
Matt Mackall
commit: recurse into subrepositories
r8813
Benoit Boissinot
subrepo: keep ui and hgrc in sync when creating new repo
r10666 if create:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 lines = [b'[paths]\n']
Benoit Boissinot
subrepo: keep ui and hgrc in sync when creating new repo
r10666
def addpathconfig(key, value):
Mads Kiilerich
subrepo: abort instead of pushing/pulling to the repo itself...
r12753 if value:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 lines.append(b'%s = %s\n' % (key, value))
self.ui.setconfig(b'paths', key, value, b'subrepo')
Benoit Boissinot
subrepo: keep ui and hgrc in sync when creating new repo
r10666
Mads Kiilerich
subrepo: abort instead of pushing/pulling to the repo itself...
r12753 defpath = _abssource(self._repo, abort=False)
defpushpath = _abssource(self._repo, True, abort=False)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 addpathconfig(b'default', defpath)
Edouard Gomez
subrepo: fix hgrc paths section during subrepo pulling...
r10697 if defpath != defpushpath:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 addpathconfig(b'default-push', defpushpath)
FUJIWARA Katsunori
subrepo: ensure "close()" execution at the end of "_initrepo()"...
r21891
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._repo.vfs.write(b'hgrc', util.tonativeeol(b''.join(lines)))
Benoit Boissinot
subrepo: keep ui and hgrc in sync when creating new repo
r10666
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Martin von Zweigbergk
add: pass around uipathfn and use instead of m.rel() (API)...
r41799 def add(self, ui, match, prefix, uipathfn, explicitonly, **opts):
Augie Fackler
formatting: blacken the codebase...
r43346 return cmdutil.add(
ui, self._repo, match, prefix, uipathfn, explicitonly, **opts
)
Martin Geisler
add: recurse into subrepositories with --subrepos/-S flag
r12270
Matt Harbison
subrepo: annotate addremove with @annotatesubrepoerror
r24132 @annotatesubrepoerror
Martin von Zweigbergk
addremove: pass around uipathfn and use instead of m.uipath() (API)...
r41801 def addremove(self, m, prefix, uipathfn, opts):
Matt Harbison
addremove: automatically process a subrepository's subrepos...
r23540 # In the same way as sub directories are processed, once in a subrepo,
# always entry any of its subrepos. Don't corrupt the options that will
# be used to process sibling subrepos however.
opts = copy.copy(opts)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 opts[b'subrepos'] = True
Martin von Zweigbergk
addremove: pass around uipathfn and use instead of m.uipath() (API)...
r41801 return scmutil.addremove(self._repo, m, prefix, uipathfn, opts)
Matt Harbison
commit: propagate --addremove to subrepos if -S is specified (issue3759)...
r23537
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Yuya Nishihara
cat: add formatter support...
r32578 def cat(self, match, fm, fntemplate, prefix, **opts):
Matt Harbison
cat: support cat with explicit paths in subrepos...
r21041 rev = self._state[1]
ctx = self._repo[rev]
Augie Fackler
formatting: blacken the codebase...
r43346 return cmdutil.cat(
self.ui, self._repo, ctx, match, fm, fntemplate, prefix, **opts
)
Matt Harbison
cat: support cat with explicit paths in subrepos...
r21041
@annotatesubrepoerror
Martin Geisler
status: recurse into subrepositories with --subrepos/-S flag
r12166 def status(self, rev2, **opts):
try:
rev1 = self._state[1]
ctx1 = self._repo[rev1]
ctx2 = self._repo[rev2]
return self._repo.status(ctx1, ctx2, **opts)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except error.RepoLookupError as inst:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'warning: error "%s" in subrepository "%s"\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (inst, subrelpath(self))
)
Martin von Zweigbergk
status: update various other methods to return new class
r22914 return scmutil.status([], [], [], [], [], [], [])
Martin Geisler
status: recurse into subrepositories with --subrepos/-S flag
r12166
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
FUJIWARA Katsunori
subrepo: add argument to "diff()" to pass "ui" of caller side (issue3712) (API)...
r18006 def diff(self, ui, diffopts, node2, match, prefix, **opts):
Martin Geisler
diff: recurse into subrepositories with --subrepos/-S flag
r12167 try:
node1 = node.bin(self._state[1])
Patrick Mezard
subrepos: handle diff nodeids in subrepos, not before...
r12209 # We currently expect node2 to come from substate and be
# in hex format
Martin Geisler
subrepo: handle diff with working copy...
r12210 if node2 is not None:
node2 = node.bin(node2)
Augie Fackler
formatting: blacken the codebase...
r43346 logcmdutil.diffordiffstat(
ui,
self._repo,
diffopts,
Augie Fackler
cleanup: avoid extra node/ctx conversions in logcmdutil.diffordiffstat...
r45340 self._repo[node1],
self._repo[node2],
Augie Fackler
formatting: blacken the codebase...
r43346 match,
prefix=prefix,
listsubrepos=True,
**opts
)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except error.RepoLookupError as inst:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'warning: error "%s" in subrepository "%s"\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (inst, subrelpath(self))
)
Martin Geisler
diff: recurse into subrepositories with --subrepos/-S flag
r12167
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Matt Harbison
subrepo: run the repo decoders when archiving...
r31099 def archive(self, archiver, prefix, match=None, decode=True):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._get(self._state + (b'hg',))
Matt Harbison
archive: call the storage prefetch hook
r35943 files = self.files()
if match:
files = [f for f in files if match(f)]
Martin Geisler
subrepo: add support for 'hg archive'
r12323 rev = self._state[1]
ctx = self._repo[rev]
Augie Fackler
formatting: blacken the codebase...
r43346 scmutil.prefetchfiles(
Rodrigo Damazio Bovendorp
scmutil: allowing different files to be prefetched per revision...
r45632 self._repo, [(ctx.rev(), scmutil.matchfiles(self._repo, files))]
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
archive: call the storage prefetch hook
r35943 total = abstractsubrepo.archive(self, archiver, prefix, match)
Martin Geisler
subrepo: add support for 'hg archive'
r12323 for subpath in ctx.substate:
Matt Harbison
archive: support 'wdir()'...
r25601 s = subrepo(ctx, subpath, True)
Martin von Zweigbergk
match: rename "narrowmatcher" to "subdirmatcher" (API)...
r28017 submatch = matchmod.subdirmatcher(subpath, match)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 subprefix = prefix + subpath + b'/'
Augie Fackler
formatting: blacken the codebase...
r43346 total += s.archive(archiver, subprefix, submatch, decode)
Angel Ezquerra
archive: raise error.Abort if the file pattern matches no files...
r18967 return total
Martin Geisler
subrepo: add support for 'hg archive'
r12323
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Matt Harbison
subrepo: consider the parent repo dirty when a file is missing...
r33364 def dirty(self, ignoreupdate=False, missing=False):
Matt Mackall
commit: recurse into subrepositories
r8813 r = self._state[1]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if r == b'' and not ignoreupdate: # no state recorded
Matt Mackall
commit: recurse into subrepositories
r8813 return True
w = self._repo[None]
Matt Mackall
extensions: drop maxlength from enabled and disabled...
r14316 if r != w.p1().hex() and not ignoreupdate:
Kevin Bullock
subrepo: clarify comments in dirty() methods...
r13325 # different version checked out
Matt Mackall
commit: recurse into subrepositories
r8813 return True
Augie Fackler
formatting: blacken the codebase...
r43346 return w.dirty(missing=missing) # working directory changed
Matt Mackall
commit: recurse into subrepositories
r8813
Matt Mackall
subrepo: add basestate method...
r16072 def basestate(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._repo[b'.'].hex()
Matt Mackall
subrepo: add basestate method...
r16072
Martin Geisler
localrepo: add auditor attribute which knows about subrepos
r12162 def checknested(self, path):
return self._repo._checknested(self._repo.wjoin(path))
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Matt Mackall
commit: recurse into subrepositories
r8813 def commit(self, text, user, date):
Kevin Bullock
subrepo: don't commit in subrepo if it's clean...
r14898 # don't bother committing in the subrepo if it's only been
# updated
if not self.dirty(True):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._repo[b'.'].hex()
self.ui.debug(b"committing subrepo %s\n" % subrelpath(self))
Matt Mackall
commit: recurse into subrepositories
r8813 n = self._repo.commit(text, user, date)
if not n:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._repo[b'.'].hex() # different version checked out
Matt Mackall
commit: recurse into subrepositories
r8813 return node.hex(n)
Matt Mackall
subrepo: add update/merge logic
r8814
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
FUJIWARA Katsunori
subrepo: check phase of state in each subrepositories before committing...
r20176 def phase(self, state):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._repo[state or b'.'].phase()
FUJIWARA Katsunori
subrepo: check phase of state in each subrepositories before committing...
r20176
@annotatesubrepoerror
Matt Mackall
subrepo: add update/merge logic
r8814 def remove(self):
# we can't fully delete the repository as it may contain
# local-only history
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.note(_(b'removing subrepo %s\n') % subrelpath(self))
Matt Mackall
subrepo: add update/merge logic
r8814 hg.clean(self._repo, node.nullid, False)
Matt Mackall
subrepo: add auto-pull for merge
r9507 def _get(self, state):
Augie Fackler
subrepo: add table-based dispatch for subrepo types
r10177 source, revision, kind = state
Matt Harbison
subrepo: share instead of clone if the parent repo is shared (issue5675) (BC)...
r34816 parentrepo = self._repo._subparent
Angel Ezquerra
subrepo: do not try to get hidden revisions...
r20317 if revision in self._repo.unfiltered():
Matt Harbison
subrepo: share instead of clone if the parent repo is shared (issue5675) (BC)...
r34816 # Allow shared subrepos tracked at null to setup the sharedpath
if len(self._repo) != 0 or not parentrepo.shared():
return True
Angel Ezquerra
subrepo: remove unnecessary else clause in hgsubrepo._get...
r20318 self._repo._subsource = source
srcurl = _abssource(self._repo)
Matt Harbison
subrepo: print the status line before creating the peer for better diagnostics...
r40691
# Defer creating the peer until after the status message is logged, in
# case there are network problems.
getpeer = lambda: hg.peer(self._repo, {}, srcurl)
Angel Ezquerra
subrepo: remove unnecessary else clause in hgsubrepo._get...
r20318 if len(self._repo) == 0:
FUJIWARA Katsunori
subrepo: use vfs.rmtree instead of shutil.rmtree...
r24690 # use self._repo.vfs instead of self.wvfs to remove .hg only
self._repo.vfs.rmtree()
Matt Harbison
subrepo: don't attempt to share remote sources (issue5793)...
r36705
# A remote subrepo could be shared if there is a local copy
# relative to the parent's share source. But clone pooling doesn't
# assemble the repos in a tree, so that can't be consistently done.
# A simpler option is for the user to configure clone pooling, and
# work with that.
if parentrepo.shared() and hg.islocal(srcurl):
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'sharing subrepo %s from %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (subrelpath(self), srcurl)
)
shared = hg.share(
self._repo._subparent.baseui,
getpeer(),
self._repo.root,
update=False,
bookmarks=False,
)
Matt Harbison
subrepo: share instead of clone if the parent repo is shared (issue5675) (BC)...
r34816 self._repo = shared.local()
else:
Matt Harbison
subrepo: activate clone pooling to enable sharing with remote URLs...
r36706 # TODO: find a common place for this and this code in the
# share.py wrap of the clone command.
if parentrepo.shared():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 pool = self.ui.config(b'share', b'pool')
Matt Harbison
subrepo: activate clone pooling to enable sharing with remote URLs...
r36706 if pool:
pool = util.expandpath(pool)
shareopts = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'pool': pool,
b'mode': self.ui.config(b'share', b'poolnaming'),
Matt Harbison
subrepo: activate clone pooling to enable sharing with remote URLs...
r36706 }
else:
shareopts = {}
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'cloning subrepo %s from %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (subrelpath(self), util.hidepassword(srcurl))
)
other, cloned = hg.clone(
self._repo._subparent.baseui,
{},
getpeer(),
self._repo.root,
update=False,
shareopts=shareopts,
)
Matt Harbison
subrepo: share instead of clone if the parent repo is shared (issue5675) (BC)...
r34816 self._repo = cloned.local()
Angel Ezquerra
subrepo: remove unnecessary else clause in hgsubrepo._get...
r20318 self._initrepo(parentrepo, source, create=True)
self._cachestorehash(srcurl)
Angel Ezquerra
subrepo: do not try to get hidden revisions...
r20317 else:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'pulling subrepo %s from %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (subrelpath(self), util.hidepassword(srcurl))
)
Angel Ezquerra
subrepo: remove unnecessary else clause in hgsubrepo._get...
r20318 cleansub = self.storeclean(srcurl)
Matt Harbison
subrepo: print the status line before creating the peer for better diagnostics...
r40691 exchange.pull(self._repo, getpeer())
Angel Ezquerra
subrepo: remove unnecessary else clause in hgsubrepo._get...
r20318 if cleansub:
# keep the repo clean after pull
Angel Ezquerra
subrepo: implement "storeclean" method for mercurial subrepos...
r18939 self._cachestorehash(srcurl)
Angel Ezquerra
subrepo: make it possible to update to hidden subrepo revisions...
r20319 return False
Matt Mackall
subrepo: add update/merge logic
r8814
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Erik Zielke
subrepo: make update -C clean the working directory for svn subrepos...
r13322 def get(self, state, overwrite=False):
Angel Ezquerra
subrepo: make it possible to update to hidden subrepo revisions...
r20319 inrepo = self._get(state)
Augie Fackler
subrepo: add table-based dispatch for subrepo types
r10177 source, revision, kind = state
Angel Ezquerra
subrepo: make it possible to update to hidden subrepo revisions...
r20319 repo = self._repo
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"getting subrepo %s\n" % self._path)
Angel Ezquerra
subrepo: make it possible to update to hidden subrepo revisions...
r20319 if inrepo:
urepo = repo.unfiltered()
ctx = urepo[revision]
if ctx.hidden():
urepo.ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'revision %s in subrepository "%s" is hidden\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (revision[0:12], self._path)
)
Angel Ezquerra
subrepo: make it possible to update to hidden subrepo revisions...
r20319 repo = urepo
hg.updaterepo(repo, revision, overwrite)
Matt Mackall
subrepo: add update/merge logic
r8814
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Matt Mackall
subrepo: add update/merge logic
r8814 def merge(self, state):
Matt Mackall
subrepo: add auto-pull for merge
r9507 self._get(state)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cur = self._repo[b'.']
Matt Mackall
subrepo: do a linear update when appropriate
r9781 dst = self._repo[state[1]]
Benoit Boissinot
subrepo: fix merging of already merged subrepos (issue1986)...
r10251 anc = dst.ancestor(cur)
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417
def mergefunc():
Friedrich Kastner-Masilko
subrepo: fix for merge inconsistencies...
r16196 if anc == cur and dst.branch() == cur.branch():
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'updating subrepository "%s"\n' % subrelpath(self)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417 hg.update(self._repo, state[1])
elif anc == dst:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'skipping subrepository "%s"\n' % subrelpath(self)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.debug(
b'merging subrepository "%s"\n' % subrelpath(self)
)
Martin von Zweigbergk
merge: make hg.merge() take a context instead of a node...
r44916 hg.merge(dst, remind=False)
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417
wctx = self._repo[None]
if self.dirty():
if anc != dst:
Matt Harbison
subrepo: use 'self.ui' instead of 'self._repo.ui'...
r23574 if _updateprompt(self.ui, self, wctx.dirty(), cur, dst):
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417 mergefunc()
else:
mergefunc()
Matt Mackall
subrepo: do a linear update when appropriate
r9781 else:
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417 mergefunc()
Matt Mackall
subrepo: basic push support
r8815
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Angel Ezquerra
push: propagate --new-branch and --ssh options when pushing subrepos...
r15708 def push(self, opts):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 force = opts.get(b'force')
newbranch = opts.get(b'new_branch')
ssh = opts.get(b'ssh')
Angel Ezquerra
push: propagate --new-branch and --ssh options when pushing subrepos...
r15708
Matt Mackall
subrepo: basic push support
r8815 # push subrepos depth-first for coherent ordering
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 c = self._repo[b'.']
Augie Fackler
formatting: blacken the codebase...
r43346 subs = c.substate # only repos that are committed
Matt Mackall
subrepo: basic push support
r8815 for s in sorted(subs):
Matt Mackall
push: more precise failure check on subrepo push...
r16022 if c.sub(s).push(opts) == 0:
Matt Mackall
subrepo: propagate and catch push failures
r11067 return False
Matt Mackall
subrepo: basic push support
r8815
dsturl = _abssource(self._repo, True)
Angel Ezquerra
subrepo: do not push mercurial subrepos whose store is clean...
r18940 if not force:
if self.storeclean(dsturl):
Matt Harbison
subrepo: use 'self.ui' instead of 'self._repo.ui'...
r23574 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'no changes made to subrepo %s since last push to %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (subrelpath(self), util.hidepassword(dsturl))
)
Angel Ezquerra
subrepo: do not push mercurial subrepos whose store is clean...
r18940 return None
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'pushing subrepo %s to %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (subrelpath(self), util.hidepassword(dsturl))
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 other = hg.peer(self._repo, {b'ssh': ssh}, dsturl)
Pierre-Yves David
push: `exchange.push` instead of `localrepo.push`...
r22619 res = exchange.push(self._repo, other, force, newbranch=newbranch)
Angel Ezquerra
subrepo: implement "storeclean" method for mercurial subrepos...
r18939
# the repo is now clean
self._cachestorehash(dsturl)
Pierre-Yves David
push: `exchange.push` instead of `localrepo.push`...
r22619 return res.cgresult
Augie Fackler
subrepo: add table-based dispatch for subrepo types
r10177
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Martin Geisler
outgoing: recurse into subrepositories with --subrepos/-S flag...
r12272 def outgoing(self, ui, dest, opts):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'rev' in opts or b'branch' in opts:
Matt Harbison
subrepo: don't pass the outer repo's --rev or --branch to subrepo outgoing()...
r24875 opts = copy.copy(opts)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 opts.pop(b'rev', None)
opts.pop(b'branch', None)
Martin Geisler
outgoing: recurse into subrepositories with --subrepos/-S flag...
r12272 return hg.outgoing(ui, self._repo, _abssource(self._repo, True), opts)
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Martin Geisler
incoming: recurse into subrepositories with --subrepos/-S flag...
r12274 def incoming(self, ui, source, opts):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'rev' in opts or b'branch' in opts:
Matt Harbison
subrepo: don't pass the outer repo's --rev or --branch to subrepo incoming()...
r24876 opts = copy.copy(opts)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 opts.pop(b'rev', None)
opts.pop(b'branch', None)
Martin Geisler
incoming: recurse into subrepositories with --subrepos/-S flag...
r12274 return hg.incoming(ui, self._repo, _abssource(self._repo, False), opts)
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Martin Geisler
subrepo: introduce files and filedata methods for subrepo classes
r12322 def files(self):
rev = self._state[1]
ctx = self._repo[rev]
Matt Harbison
subrepo: return only the manifest keys from hgsubrepo.files()...
r24173 return ctx.manifest().keys()
Martin Geisler
subrepo: introduce files and filedata methods for subrepo classes
r12322
Matt Harbison
subrepo: run the repo decoders when archiving...
r31099 def filedata(self, name, decode):
Martin Geisler
subrepo: introduce files and filedata methods for subrepo classes
r12322 rev = self._state[1]
Matt Harbison
subrepo: run the repo decoders when archiving...
r31099 data = self._repo[rev][name].data()
if decode:
data = self._repo.wwritedata(name, data)
return data
Martin Geisler
subrepo: introduce files and filedata methods for subrepo classes
r12322
def fileflags(self, name):
rev = self._state[1]
ctx = self._repo[rev]
return ctx.flags(name)
Matt Harbison
subrepo: add basic support to hgsubrepo for the files command...
r24413 @annotatesubrepoerror
Martin von Zweigbergk
subrepo: use root-repo-relative path from `hg files` with ui.relative-paths=no...
r41914 def printfiles(self, ui, m, uipathfn, fm, fmt, subrepos):
Matt Harbison
subrepo: add basic support to hgsubrepo for the files command...
r24413 # If the parent context is a workingctx, use the workingctx here for
# consistency.
if self._ctx.rev() is None:
ctx = self._repo[None]
else:
rev = self._state[1]
ctx = self._repo[rev]
Martin von Zweigbergk
subrepo: use root-repo-relative path from `hg files` with ui.relative-paths=no...
r41914 return cmdutil.files(ui, ctx, m, uipathfn, fm, fmt, subrepos)
Matt Harbison
subrepo: add basic support to hgsubrepo for the files command...
r24413
Matt Harbison
subrepo: introduce getfileset()...
r25121 @annotatesubrepoerror
Matt Harbison
match: resolve filesets against the passed `cwd`, not the current one...
r44461 def matchfileset(self, cwd, expr, badfn=None):
Matt Harbison
subrepo: introduce getfileset()...
r25121 if self._ctx.rev() is None:
Martin von Zweigbergk
match: delete unused root and cwd arguments from {always,never,exact}() (API)...
r41825 ctx = self._repo[None]
Matt Harbison
subrepo: introduce getfileset()...
r25121 else:
rev = self._state[1]
Martin von Zweigbergk
match: delete unused root and cwd arguments from {always,never,exact}() (API)...
r41825 ctx = self._repo[rev]
Matt Harbison
subrepo: introduce getfileset()...
r25121
Matt Harbison
match: resolve filesets against the passed `cwd`, not the current one...
r44461 matchers = [ctx.matchfileset(cwd, expr, badfn=badfn)]
Matt Harbison
subrepo: introduce getfileset()...
r25121
for subpath in ctx.substate:
sub = ctx.sub(subpath)
try:
Matt Harbison
match: resolve filesets against the passed `cwd`, not the current one...
r44461 sm = sub.matchfileset(cwd, expr, badfn=badfn)
Martin von Zweigbergk
match: delete unused root and cwd arguments to constructors (API)...
r41824 pm = matchmod.prefixdirmatcher(subpath, sm, badfn=badfn)
Yuya Nishihara
fileset: restrict getfileset() to not return a computed set (API)...
r38631 matchers.append(pm)
Matt Harbison
subrepo: introduce getfileset()...
r25121 except error.LookupError:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"skipping missing subrepository: %s\n")
Augie Fackler
formatting: blacken the codebase...
r43346 % self.wvfs.reljoin(reporelpath(self), subpath)
)
Yuya Nishihara
fileset: restrict getfileset() to not return a computed set (API)...
r38631 if len(matchers) == 1:
return matchers[0]
return matchmod.unionmatcher(matchers)
Matt Harbison
subrepo: introduce getfileset()...
r25121
David M. Carr
add: support adding explicit files in subrepos...
r15410 def walk(self, match):
ctx = self._repo[None]
return ctx.walk(match)
Martin Geisler
subrepo: introduce files and filedata methods for subrepo classes
r12322
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Martin von Zweigbergk
forget: pass around uipathfn and use instead of m.rel() (API)...
r41802 def forget(self, match, prefix, uipathfn, dryrun, interactive):
Augie Fackler
formatting: blacken the codebase...
r43346 return cmdutil.forget(
self.ui,
self._repo,
match,
prefix,
uipathfn,
True,
dryrun=dryrun,
interactive=interactive,
)
Martin Geisler
subrepo: introduce files and filedata methods for subrepo classes
r12322
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Augie Fackler
formatting: blacken the codebase...
r43346 def removefiles(
self,
matcher,
prefix,
uipathfn,
after,
force,
subrepos,
dryrun,
warnings,
):
return cmdutil.remove(
self.ui,
self._repo,
matcher,
prefix,
uipathfn,
after,
force,
subrepos,
dryrun,
)
Matt Harbison
remove: recurse into subrepositories with --subrepos/-S flag...
r23325
@annotatesubrepoerror
Matt Harbison
subrepo: drop the 'ui' parameter to revert()...
r23579 def revert(self, substate, *pats, **opts):
Angel Ezquerra
revert: add support for reverting subrepos without --no-backup and/or --all...
r16430 # reverting a subrepo is a 2 step process:
# 1. if the no_backup is not set, revert all modified
# files inside the subrepo
# 2. update the subrepo to the revision specified in
# the corresponding substate dictionary
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.status(_(b'reverting subrepo %s\n') % substate[0])
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if not opts.get('no_backup'):
Angel Ezquerra
revert: add support for reverting subrepos without --no-backup and/or --all...
r16430 # Revert all files on the subrepo, creating backups
# Note that this will not recursively revert subrepos
# We could do it if there was a set:subrepos() predicate
opts = opts.copy()
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 opts['date'] = None
opts['rev'] = substate[1]
Angel Ezquerra
revert: add support for reverting subrepos without --no-backup and/or --all...
r16430
Matt Harbison
subrepo: drop the 'ui' parameter to revert()...
r23579 self.filerevert(*pats, **opts)
Angel Ezquerra
revert: add support for reverting subrepos...
r16429
# Update the repo to the revision specified in the given substate
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if not opts.get('dry_run'):
Matt Harbison
revert: display full subrepo output with --dry-run...
r24134 self.get(substate, overwrite=True)
Angel Ezquerra
revert: add support for reverting subrepos...
r16429
Matt Harbison
subrepo: drop the 'ui' parameter to revert()...
r23579 def filerevert(self, *pats, **opts):
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 ctx = self._repo[opts['rev']]
if opts.get('all'):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 pats = [b'set:modified()']
Angel Ezquerra
revert: add support for reverting subrepos without --no-backup and/or --all...
r16430 else:
pats = []
Martin von Zweigbergk
revert: remove dangerous `parents` argument from `cmdutil.revert()`...
r45935 cmdutil.revert(self.ui, self._repo, ctx, *pats, **opts)
Angel Ezquerra
revert: add support for reverting subrepos without --no-backup and/or --all...
r16430
Angel Ezquerra
subrepo: add shortid() method to subrepo classes...
r21400 def shortid(self, revid):
return revid[:12]
Matt Harbison
subrepo: implement 'unshare' for Mercurial subrepos...
r34880 @annotatesubrepoerror
def unshare(self):
# subrepo inherently violates our import layering rules
# because it wants to make repo objects from deep inside the stack
# so we manually delay the circular imports to not break
# scripts that don't use our demand-loading
global hg
from . import hg as h
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
subrepo: implement 'unshare' for Mercurial subrepos...
r34880 hg = h
# Nothing prevents a user from sharing in a repo, and then making that a
# subrepo. Alternately, the previous unshare attempt may have failed
# part way through. So recurse whether or not this layer is shared.
if self._repo.shared():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.status(_(b"unsharing subrepo '%s'\n") % self._relpath)
Matt Harbison
subrepo: implement 'unshare' for Mercurial subrepos...
r34880
hg.unshare(self.ui, self._repo)
Matt Harbison
exchange: ensure all outgoing subrepo references are present before pushing...
r44365 def verify(self, onpush=False):
Matt Harbison
verify: check the subrepository references in .hgsubstate...
r25591 try:
rev = self._state[1]
ctx = self._repo.unfiltered()[rev]
if ctx.hidden():
# Since hidden revisions aren't pushed/pulled, it seems worth an
# explicit warning.
Matt Harbison
exchange: ensure all outgoing subrepo references are present before pushing...
r44365 msg = _(b"subrepo '%s' is hidden in revision %s") % (
self._relpath,
node.short(self._ctx.node()),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
exchange: ensure all outgoing subrepo references are present before pushing...
r44365
if onpush:
raise error.Abort(msg)
else:
self._repo.ui.warn(b'%s\n' % msg)
Matt Harbison
verify: check the subrepository references in .hgsubstate...
r25591 return 0
except error.RepoLookupError:
# A missing subrepo revision may be a case of needing to pull it, so
Matt Harbison
exchange: ensure all outgoing subrepo references are present before pushing...
r44365 # don't treat this as an error for `hg verify`.
msg = _(b"subrepo '%s' not found in revision %s") % (
self._relpath,
node.short(self._ctx.node()),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
exchange: ensure all outgoing subrepo references are present before pushing...
r44365
if onpush:
raise error.Abort(msg)
else:
self._repo.ui.warn(b'%s\n' % msg)
Matt Harbison
verify: check the subrepository references in .hgsubstate...
r25591 return 0
FUJIWARA Katsunori
subrepo: add wvfs field to access the working directory via vfs...
r24672 @propertycache
def wvfs(self):
Mads Kiilerich
spelling: trivial spell checking
r26781 """return own wvfs for efficiency and consistency
FUJIWARA Katsunori
subrepo: add wvfs field to access the working directory via vfs...
r24672 """
return self._repo.wvfs
Matt Harbison
subrepo: calculate _relpath for hgsubrepo based on self instead of parent...
r24786 @propertycache
def _relpath(self):
"""return path to this subrepository as seen from outermost repository
"""
# Keep consistent dir separators by avoiding vfs.join(self._path)
return reporelpath(self._repo)
Augie Fackler
formatting: blacken the codebase...
r43346
Martin Geisler
subrepo: add abstract superclass for subrepo classes
r11559 class svnsubrepo(abstractsubrepo):
Matt Harbison
verify: don't init subrepo when missing one is referenced (issue5128) (API)...
r29021 def __init__(self, ctx, path, state, allowcreate):
FUJIWARA Katsunori
subrepo: change arguments of abstractsubrepo.__init__ (API)...
r24671 super(svnsubrepo, self).__init__(ctx, path)
Augie Fackler
subrepo: Subversion support
r10178 self._state = state
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._exe = procutil.findexe(b'svn')
Matt Mackall
subrepo: improve error message when svn isn't found...
r15190 if not self._exe:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"'svn' executable not found for subrepo '%s'") % self._path
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
subrepo: Subversion support
r10178
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 def _svncommand(self, commands, filename=b'', failok=False):
Matt Mackall
subrepo: improve error message when svn isn't found...
r15190 cmd = [self._exe]
Augie Fackler
subrepo: make stdin for svn a pipe for non-interactive use (issue2759)...
r14506 extrakw = {}
Matt Harbison
subrepo: rename the '_ui' member to 'ui'...
r23572 if not self.ui.interactive():
Augie Fackler
subrepo: make stdin for svn a pipe for non-interactive use (issue2759)...
r14506 # Making stdin be a pipe should prevent svn from behaving
# interactively even if we can't pass --non-interactive.
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 extrakw['stdin'] = subprocess.PIPE
Augie Fackler
subrepo: make stdin for svn a pipe for non-interactive use (issue2759)...
r14506 # Starting in svn 1.5 --non-interactive is a global flag
# instead of being per-command, but we need to support 1.4 so
# we have to be intelligent about what commands take
# --non-interactive.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if commands[0] in (b'update', b'checkout', b'commit'):
cmd.append(b'--non-interactive')
Augie Fackler
subrepo: tell Subversion when we are non-interactive (issue2759)...
r14025 cmd.extend(commands)
Patrick Mezard
subrepo: handle svn tracked/unknown directory collisions...
r14050 if filename is not None:
Augie Fackler
formatting: blacken the codebase...
r43346 path = self.wvfs.reljoin(
self._ctx.repo().origroot, self._path, filename
)
Patrick Mezard
subrepo: handle svn tracked/unknown directory collisions...
r14050 cmd.append(path)
Pulkit Goyal
py3: replace os.environ with encoding.environ (part 2 of 5)
r30635 env = dict(encoding.environ)
Patrick Mezard
subrepo: make svn use C locale for portability...
r10271 # Avoid localized output, preserve current locale for everything else.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 lc_all = env.get(b'LC_ALL')
Thomas Arendsen Hein
subrepo: setting LC_MESSAGES only works if LC_ALL is empty or unset...
r17705 if lc_all:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 env[b'LANG'] = lc_all
del env[b'LC_ALL']
env[b'LC_MESSAGES'] = b'C'
Augie Fackler
formatting: blacken the codebase...
r43346 p = subprocess.Popen(
pycompat.rapply(procutil.tonativestr, cmd),
bufsize=-1,
close_fds=procutil.closefds,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=procutil.tonativeenv(env),
**extrakw
)
Yuya Nishihara
py3: don't use universal_newlines in svnsubrepo...
r41658 stdout, stderr = map(util.fromnativeeol, p.communicate())
Patrick Mezard
subrepo: use subprocess directly to avoid python 2.6 bug...
r13014 stderr = stderr.strip()
Augie Fackler
svn subrepos: work around checkout obstructions (issue2752)...
r14664 if not failok:
if p.returncode:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 stderr or b'exited with code %d' % p.returncode
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
svn subrepos: work around checkout obstructions (issue2752)...
r14664 if stderr:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.warn(stderr + b'\n')
Augie Fackler
svn subrepos: work around checkout obstructions (issue2752)...
r14664 return stdout, stderr
Augie Fackler
subrepo: Subversion support
r10178
Patrick Mezard
subrepo: handle svn tracked/unknown directory collisions...
r14050 @propertycache
def _svnversion(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output, err = self._svncommand(
[b'--version', b'--quiet'], filename=None
)
Yuya Nishihara
py3: fix type of regex literals in subrepo.py
r34070 m = re.search(br'^(\d+)\.(\d+)', output)
Patrick Mezard
subrepo: handle svn tracked/unknown directory collisions...
r14050 if not m:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'cannot retrieve svn tool version'))
Patrick Mezard
subrepo: handle svn tracked/unknown directory collisions...
r14050 return (int(m.group(1)), int(m.group(2)))
Jordi Gutiérrez Hermoso
svnsubrepo: add new method _svnmissing...
r35679 def _svnmissing(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return not self.wvfs.exists(b'.svn')
Jordi Gutiérrez Hermoso
svnsubrepo: add new method _svnmissing...
r35679
Patrick Mezard
subrepo: compare svn subrepo state to last committed revision...
r13287 def _wcrevs(self):
# Get the working directory revision as well as the last
# commit revision so we can compare the subrepo state with
# both. We used to store the working directory one.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output, err = self._svncommand([b'info', b'--xml'])
Patrick Mezard
subrepo: svn xml output is much easier to parse...
r10272 doc = xml.dom.minidom.parseString(output)
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 entries = doc.getElementsByTagName('entry')
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 lastrev, rev = b'0', b'0'
Patrick Mezard
subrepo: compare svn subrepo state to last committed revision...
r13287 if entries:
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 rev = pycompat.bytestr(entries[0].getAttribute('revision')) or b'0'
commits = entries[0].getElementsByTagName('commit')
Patrick Mezard
subrepo: compare svn subrepo state to last committed revision...
r13287 if commits:
Augie Fackler
formatting: blacken the codebase...
r43346 lastrev = (
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 pycompat.bytestr(commits[0].getAttribute('revision'))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 or b'0'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Patrick Mezard
subrepo: compare svn subrepo state to last committed revision...
r13287 return (lastrev, rev)
def _wcrev(self):
return self._wcrevs()[0]
Augie Fackler
subrepo: Subversion support
r10178
Patrick Mezard
subrepo: handle svn externals and meta changes (issue1982)...
r10273 def _wcchanged(self):
Patrick Mezard
subrepo/svn: improve error message on missing files...
r16530 """Return (changes, extchanges, missing) where changes is True
if the working directory was changed, extchanges is
True if any of these changes concern an external entry and missing
is True if any change is a missing entry.
Patrick Mezard
subrepo: handle svn externals and meta changes (issue1982)...
r10273 """
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output, err = self._svncommand([b'status', b'--xml'])
Patrick Mezard
subrepo/svn: improve error message on missing files...
r16530 externals, changes, missing = [], [], []
Patrick Mezard
subrepo: svn xml output is much easier to parse...
r10272 doc = xml.dom.minidom.parseString(output)
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 for e in doc.getElementsByTagName('entry'):
s = e.getElementsByTagName('wc-status')
Patrick Mezard
subrepo: handle svn externals and meta changes (issue1982)...
r10273 if not s:
continue
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 item = s[0].getAttribute('item')
props = s[0].getAttribute('props')
path = e.getAttribute('path').encode('utf8')
if item == 'external':
Patrick Mezard
subrepo: handle svn externals and meta changes (issue1982)...
r10273 externals.append(path)
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 elif item == 'missing':
Patrick Mezard
subrepo/svn: improve error message on missing files...
r16530 missing.append(path)
Augie Fackler
formatting: blacken the codebase...
r43346 if item not in (
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 '',
'normal',
'unversioned',
'external',
) or props not in ('', 'none', 'normal'):
Patrick Mezard
subrepo: handle svn externals and meta changes (issue1982)...
r10273 changes.append(path)
for path in changes:
for ext in externals:
Pulkit Goyal
py3: replace os.sep with pycompat.ossep (part 3 of 4)
r30615 if path == ext or path.startswith(ext + pycompat.ossep):
Patrick Mezard
subrepo/svn: improve error message on missing files...
r16530 return True, True, bool(missing)
return bool(changes), False, bool(missing)
Augie Fackler
subrepo: Subversion support
r10178
Jordi Gutiérrez Hermoso
svnsubrepo: decorate dirty method with annotatesubrepoerror...
r35678 @annotatesubrepoerror
Matt Harbison
subrepo: consider the parent repo dirty when a file is missing...
r33364 def dirty(self, ignoreupdate=False, missing=False):
Jordi Gutiérrez Hermoso
svnsubrepo: check if subrepo is missing when checking dirty state (issue5657)...
r35694 if self._svnmissing():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._state[1] != b''
Matt Harbison
subrepo: consider the parent repo dirty when a file is missing...
r33364 wcchanged = self._wcchanged()
changed = wcchanged[0] or (missing and wcchanged[2])
if not changed:
Patrick Mezard
Merge with stable
r13288 if self._state[1] in self._wcrevs() or ignoreupdate:
Kevin Bullock
mq: update .hgsubstate if subrepos are clean (issue2499)...
r13174 return False
Augie Fackler
subrepo: Subversion support
r10178 return True
Matt Mackall
subrepo: add basestate method...
r16072 def basestate(self):
Patrick Mezard
subrepo/svn: fix checked out rev number retrieval (issue2968)...
r16554 lastrev, rev = self._wcrevs()
if lastrev != rev:
# Last committed rev is not the same than rev. We would
# like to take lastrev but we do not know if the subrepo
# URL exists at lastrev. Test it and fallback to rev it
# is not there.
try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._svncommand(
[b'list', b'%s@%s' % (self._state[0], lastrev)]
)
Patrick Mezard
subrepo/svn: fix checked out rev number retrieval (issue2968)...
r16554 return lastrev
except error.Abort:
pass
return rev
Matt Mackall
subrepo: add basestate method...
r16072
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Augie Fackler
subrepo: Subversion support
r10178 def commit(self, text, user, date):
# user and date are out of our hands since svn is centralized
Patrick Mezard
subrepo/svn: improve error message on missing files...
r16530 changed, extchanged, missing = self._wcchanged()
Patrick Mezard
subrepo: handle svn externals and meta changes (issue1982)...
r10273 if not changed:
Patrick Mezard
subrepo/svn: fix checked out rev number retrieval (issue2968)...
r16554 return self.basestate()
Patrick Mezard
subrepo: handle svn externals and meta changes (issue1982)...
r10273 if extchanged:
# Do not try to commit externals
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'cannot commit svn externals'))
Patrick Mezard
subrepo/svn: improve error message on missing files...
r16530 if missing:
# svn can commit with missing entries but aborting like hg
# seems a better approach.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'cannot commit missing svn entries'))
commitinfo, err = self._svncommand([b'commit', b'-m', text])
Matt Harbison
subrepo: rename the '_ui' member to 'ui'...
r23572 self.ui.status(commitinfo)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 newrev = re.search(b'Committed revision ([0-9]+).', commitinfo)
Augie Fackler
subrepo: Subversion support
r10178 if not newrev:
Patrick Mezard
subrepo/svn: abort on commit with missing file (issue3029)...
r16529 if not commitinfo.strip():
# Sometimes, our definition of "changed" differs from
# svn one. For instance, svn ignores missing files
# when committing. If there are only missing files, no
# commit is made, no output and no error code.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'failed to commit svn changes'))
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(commitinfo.splitlines()[-1])
Augie Fackler
subrepo: Subversion support
r10178 newrev = newrev.groups()[0]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.status(self._svncommand([b'update', b'-r', newrev])[0])
Augie Fackler
subrepo: Subversion support
r10178 return newrev
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Augie Fackler
subrepo: Subversion support
r10178 def remove(self):
if self.dirty():
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 _(b'not removing repo %s because it has changes.\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % self._path
)
Augie Fackler
subrepo: Subversion support
r10178 return
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.note(_(b'removing subrepo %s\n') % self._path)
Patrick Mezard
subrepo: fix removing read-only svn files on Windows
r13013
FUJIWARA Katsunori
subrepo: use vfs.rmtree instead of shutil.rmtree...
r24690 self.wvfs.rmtree(forcibly=True)
Patrick Mezard
subrepo: prune empty directories when removing svn subrepo
r13015 try:
FUJIWARA Katsunori
subrepo: use vfs.dirname instead of os.path.dirname...
r25773 pwvfs = self._ctx.repo().wvfs
pwvfs.removedirs(pwvfs.dirname(self._path))
Patrick Mezard
subrepo: prune empty directories when removing svn subrepo
r13015 except OSError:
pass
Augie Fackler
subrepo: Subversion support
r10178
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Erik Zielke
subrepo: make update -C clean the working directory for svn subrepos...
r13322 def get(self, state, overwrite=False):
if overwrite:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._svncommand([b'revert', b'--recursive'])
args = [b'checkout']
Patrick Mezard
subrepo: handle svn tracked/unknown directory collisions...
r14050 if self._svnversion >= (1, 5):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 args.append(b'--force')
Eli Carter
subrepo: correct revision in svn checkout...
r14820 # The revision must be specified at the end of the URL to properly
# update to a directory which has since been deleted and recreated.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 args.append(b'%s@%s' % (state[0], state[1]))
Sean Farley
subrepo: add tests for svn rogue ssh urls (SEC)...
r33730
# SEC: check that the ssh url is safe
util.checksafessh(state[0])
Augie Fackler
svn subrepos: work around checkout obstructions (issue2752)...
r14664 status, err = self._svncommand(args, failok=True)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _sanitize(self.ui, self.wvfs, b'.svn')
if not re.search(b'Checked out revision [0-9]+.', status):
if b'is already a working copy for a different URL' in err and (
Augie Fackler
formatting: blacken the codebase...
r43346 self._wcchanged()[:2] == (False, False)
):
Augie Fackler
svn subrepos: work around checkout obstructions (issue2752)...
r14664 # obstructed but clean working copy, so just blow it away.
self.remove()
self.get(state, overwrite=False)
return
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort((status or err).splitlines()[-1])
Matt Harbison
subrepo: rename the '_ui' member to 'ui'...
r23572 self.ui.status(status)
Augie Fackler
subrepo: Subversion support
r10178
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Augie Fackler
subrepo: Subversion support
r10178 def merge(self, state):
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417 old = self._state[1]
new = state[1]
Patrick Mezard
subrepo/svn: cache _wcrev() value in merge()
r16555 wcrev = self._wcrev()
if new != wcrev:
dirty = old == wcrev or self._wcchanged()[0]
Matt Harbison
subrepo: rename the '_ui' member to 'ui'...
r23572 if _updateprompt(self.ui, self, dirty, wcrev, new):
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417 self.get(state, False)
Augie Fackler
subrepo: Subversion support
r10178
Angel Ezquerra
push: propagate --new-branch and --ssh options when pushing subrepos...
r15708 def push(self, opts):
Matt Mackall
subrepo: fix silent push failure for SVN (issue2241)
r11455 # push is a no-op for SVN
return True
Augie Fackler
subrepo: Subversion support
r10178
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Martin Geisler
subrepo: introduce files and filedata methods for subrepo classes
r12322 def files(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output = self._svncommand([b'list', b'--recursive', b'--xml'])[0]
Patrick Mezard
archive: make it work with svn subrepos (issue3308)...
r16450 doc = xml.dom.minidom.parseString(output)
paths = []
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 for e in doc.getElementsByTagName('entry'):
kind = pycompat.bytestr(e.getAttribute('kind'))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if kind != b'file':
Patrick Mezard
archive: make it work with svn subrepos (issue3308)...
r16450 continue
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 name = ''.join(
Augie Fackler
formatting: blacken the codebase...
r43346 c.data
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 for c in e.getElementsByTagName('name')[0].childNodes
Augie Fackler
formatting: blacken the codebase...
r43346 if c.nodeType == c.TEXT_NODE
)
Augie Fackler
subrepo: clean up lingering bytes/str issues in svn support...
r41635 paths.append(name.encode('utf8'))
Patrick Mezard
archive: make it work with svn subrepos (issue3308)...
r16450 return paths
Martin Geisler
subrepo: introduce files and filedata methods for subrepo classes
r12322
Matt Harbison
subrepo: run the repo decoders when archiving...
r31099 def filedata(self, name, decode):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._svncommand([b'cat'], name)[0]
Martin Geisler
subrepo: introduce files and filedata methods for subrepo classes
r12322
Eric Eisner
subrepo: gitsubrepo should inherit from abstractsubrepo
r13106 class gitsubrepo(abstractsubrepo):
Matt Harbison
verify: don't init subrepo when missing one is referenced (issue5128) (API)...
r29021 def __init__(self, ctx, path, state, allowcreate):
FUJIWARA Katsunori
subrepo: change arguments of abstractsubrepo.__init__ (API)...
r24671 super(gitsubrepo, self).__init__(ctx, path)
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 self._state = state
Matt Harbison
subrepo: replace 'ctx._repo' with 'ctx.repo()'
r24302 self._abspath = ctx.repo().wjoin(path)
self._subparent = ctx.repo()
Benjamin Pollack
subrepo: warn user if Git is not version 1.6.0 or higher
r17024 self._ensuregit()
def _ensuregit(self):
Benjamin Pollack
subrepo: support Git being named "git.cmd" on Windows (issue3173)...
r17025 try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._gitexecutable = b'git'
out, err = self._gitnodir([b'--version'])
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except OSError as e:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 genericerror = _(b"error executing git for subrepo '%s': %s")
notfoundhint = _(b"check git is installed and in your PATH")
Mason Malone
subrepo: better error messages in _ensuregit...
r27935 if e.errno != errno.ENOENT:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
genericerror % (self._path, encoding.strtolocal(e.strerror))
)
Jun Wu
codemod: use pycompat.iswindows...
r34646 elif pycompat.iswindows:
Mason Malone
subrepo: better error messages in _ensuregit...
r27935 try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._gitexecutable = b'git.cmd'
out, err = self._gitnodir([b'--version'])
Mason Malone
subrepo: better error messages in _ensuregit...
r27935 except OSError as e2:
if e2.errno == errno.ENOENT:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"couldn't find 'git' or 'git.cmd'"
b" for subrepo '%s'"
Augie Fackler
formatting: blacken the codebase...
r43346 )
% self._path,
hint=notfoundhint,
)
Mason Malone
subrepo: better error messages in _ensuregit...
r27935 else:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
genericerror
% (self._path, encoding.strtolocal(e2.strerror))
)
Mason Malone
subrepo: better error messages in _ensuregit...
r27935 else:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"couldn't find git for subrepo '%s'") % self._path,
Augie Fackler
formatting: blacken the codebase...
r43346 hint=notfoundhint,
)
Siddharth Agarwal
subrepo: factor out Git version check to add doctests...
r20840 versionstatus = self._checkversion(out)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if versionstatus == b'unknown':
self.ui.warn(_(b'cannot retrieve git version\n'))
elif versionstatus == b'abort':
raise error.Abort(
_(b'git subrepo requires at least 1.6.0 or later')
)
elif versionstatus == b'warning':
self.ui.warn(_(b'git subrepo requires at least 1.6.0 or later\n'))
Siddharth Agarwal
subrepo: factor out Git version check to add doctests...
r20840
@staticmethod
Mathias De Maré
subrepo: move git version check into a separate method...
r23521 def _gitversion(out):
Yuya Nishihara
py3: fix type of regex literals in subrepo.py
r34070 m = re.search(br'^git version (\d+)\.(\d+)\.(\d+)', out)
Mathias De Maré
subrepo: extend git version check to 3 digits...
r23522 if m:
return (int(m.group(1)), int(m.group(2)), int(m.group(3)))
Yuya Nishihara
py3: fix type of regex literals in subrepo.py
r34070 m = re.search(br'^git version (\d+)\.(\d+)', out)
Mathias De Maré
subrepo: move git version check into a separate method...
r23521 if m:
Mathias De Maré
subrepo: extend git version check to 3 digits...
r23522 return (int(m.group(1)), int(m.group(2)), 0)
Mathias De Maré
subrepo: move git version check into a separate method...
r23521
return -1
@staticmethod
Siddharth Agarwal
subrepo: factor out Git version check to add doctests...
r20840 def _checkversion(out):
'''ensure git version is new enough
>>> _checkversion = gitsubrepo._checkversion
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> _checkversion(b'git version 1.6.0')
Siddharth Agarwal
subrepo: factor out Git version check to add doctests...
r20840 'ok'
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> _checkversion(b'git version 1.8.5')
Siddharth Agarwal
subrepo: factor out Git version check to add doctests...
r20840 'ok'
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> _checkversion(b'git version 1.4.0')
Siddharth Agarwal
subrepo: factor out Git version check to add doctests...
r20840 'abort'
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> _checkversion(b'git version 1.5.0')
Siddharth Agarwal
subrepo: factor out Git version check to add doctests...
r20840 'warning'
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> _checkversion(b'git version 1.9-rc0')
Siddharth Agarwal
subrepo: factor out Git version check to add doctests...
r20840 'ok'
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> _checkversion(b'git version 1.9.0.265.g81cdec2')
Siddharth Agarwal
subrepo: factor out Git version check to add doctests...
r20840 'ok'
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> _checkversion(b'git version 1.9.0.GIT')
Siddharth Agarwal
subrepo: factor out Git version check to add doctests...
r20840 'ok'
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> _checkversion(b'git version 12345')
Siddharth Agarwal
subrepo: factor out Git version check to add doctests...
r20840 'unknown'
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> _checkversion(b'no')
Siddharth Agarwal
subrepo: factor out Git version check to add doctests...
r20840 'unknown'
'''
Mathias De Maré
subrepo: move git version check into a separate method...
r23521 version = gitsubrepo._gitversion(out)
Benjamin Pollack
subrepo: warn user if Git is not version 1.6.0 or higher
r17024 # git 1.4.0 can't work at all, but 1.5.X can in at least some cases,
# despite the docstring comment. For now, error on 1.4.0, warn on
# 1.5.0 but attempt to continue.
Mathias De Maré
subrepo: move git version check into a separate method...
r23521 if version == -1:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b'unknown'
Mathias De Maré
subrepo: extend git version check to 3 digits...
r23522 if version < (1, 5, 0):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b'abort'
Mathias De Maré
subrepo: extend git version check to 3 digits...
r23522 elif version < (1, 6, 0):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b'warning'
return b'ok'
Eric Eisner
subrepo: support for adding a git subrepo...
r12992
Eric Eisner
subrepo: use environment variable instead of git commit's --date...
r13095 def _gitcommand(self, commands, env=None, stream=False):
return self._gitdir(commands, env=env, stream=stream)[0]
Eric Eisner
subrepo: support for adding a git subrepo...
r12992
Eric Eisner
subrepo: use environment variable instead of git commit's --date...
r13095 def _gitdir(self, commands, env=None, stream=False):
Augie Fackler
formatting: blacken the codebase...
r43346 return self._gitnodir(
commands, env=env, stream=stream, cwd=self._abspath
)
Eric Eisner
subrepo: support for adding a git subrepo...
r12992
Eric Eisner
subrepo: use environment variable instead of git commit's --date...
r13095 def _gitnodir(self, commands, env=None, stream=False, cwd=None):
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 """Calls the git command
Mads Kiilerich
fix trivial spelling errors
r17424 The methods tries to call the git command. versions prior to 1.6.0
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 are not supported and very probably fail.
"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.debug(b'%s: git %s\n' % (self._relpath, b' '.join(commands)))
Mateusz Kwapich
subrepo: set GIT_ALLOW_PROTOCOL to limit git clone protocols (SEC)...
r28658 if env is None:
Pulkit Goyal
py3: replace os.environ with encoding.environ (part 2 of 5)
r30635 env = encoding.environ.copy()
Matt Mackall
subrepo: disable localizations when calling Git (issue5176)...
r28949 # disable localization for Git output (issue5176)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 env[b'LC_ALL'] = b'C'
Mateusz Kwapich
subrepo: set GIT_ALLOW_PROTOCOL to limit git clone protocols (SEC)...
r28658 # fix for Git CVE-2015-7545
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'GIT_ALLOW_PROTOCOL' not in env:
env[b'GIT_ALLOW_PROTOCOL'] = b'file:git:http:https:ssh'
Eric Eisner
subrepo: silence git output when ui.quiet is set
r13111 # unless ui.quiet is set, print git's stderr,
# which is mostly progress and useful info
errpipe = None
Matt Harbison
subrepo: rename the '_ui' member to 'ui'...
r23572 if self.ui.quiet:
Kyle Lippincott
subrepo: use pycompat.open directly instead of importing open from pycompat...
r44228 errpipe = pycompat.open(os.devnull, b'w')
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if self.ui._colormode and len(commands) and commands[0] == b"diff":
Pierre-Yves David
color: move git-subrepo support into the subrepo module...
r31102 # insert the argument in the front,
# the end of git diff arguments is used for paths
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 commands.insert(1, b'--color')
Augie Fackler
formatting: blacken the codebase...
r43346 p = subprocess.Popen(
pycompat.rapply(
procutil.tonativestr, [self._gitexecutable] + commands
),
bufsize=-1,
cwd=pycompat.rapply(procutil.tonativestr, cwd),
env=procutil.tonativeenv(env),
close_fds=procutil.closefds,
stdout=subprocess.PIPE,
stderr=errpipe,
)
Eric Eisner
subrepo: archive git subrepos
r13027 if stream:
return p.stdout, None
Eric Eisner
subrepo: strip gitcommand output
r13085 retdata = p.stdout.read().strip()
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 # wait for the child to exit to avoid race condition.
p.wait()
Eric Eisner
subrepo: treat git error code 1 as success...
r13107 if p.returncode != 0 and p.returncode != 1:
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 # there are certain error codes that are ok
Eric Eisner
subrepo: show git command with --debug...
r13110 command = commands[0]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if command in (b'cat-file', b'symbolic-ref'):
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 return retdata, p.returncode
# for all others, abort
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'git %s error %d in %s')
Augie Fackler
formatting: blacken the codebase...
r43346 % (command, p.returncode, self._relpath)
)
Eric Eisner
subrepo: support for adding a git subrepo...
r12992
return retdata, p.returncode
Eric Eisner
subrepo: don't crash when git repo is missing
r13553 def _gitmissing(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return not self.wvfs.exists(b'.git')
Eric Eisner
subrepo: don't crash when git repo is missing
r13553
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 def _gitstate(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._gitcommand([b'rev-parse', b'HEAD'])
Eric Eisner
subrepo: support for adding a git subrepo...
r12992
Eric Eisner
subrepo: defer determination of git's current branch
r13152 def _gitcurrentbranch(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 current, err = self._gitdir([b'symbolic-ref', b'HEAD', b'--quiet'])
Eric Eisner
subrepo: defer determination of git's current branch
r13152 if err:
current = None
return current
Eric Eisner
subrepo: show the source that git pulls
r13569 def _gitremote(self, remote):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 out = self._gitcommand([b'remote', b'show', b'-n', remote])
line = out.split(b'\n')[1]
i = line.index(b'URL: ') + len(b'URL: ')
Eric Eisner
subrepo: show the source that git pulls
r13569 return line[i:]
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 def _githavelocally(self, revision):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 out, code = self._gitdir([b'cat-file', b'-e', revision])
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 return code == 0
Eric Eisner
subrepo: lazier git push logic...
r13029 def _gitisancestor(self, r1, r2):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 base = self._gitcommand([b'merge-base', r1, r2])
Eric Eisner
subrepo: lazier git push logic...
r13029 return base == r1
Paul Molodowitch
subrepo: bare git repos considered dirty...
r14440 def _gitisbare(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._gitcommand([b'config', b'--bool', b'core.bare']) == b'true'
Paul Molodowitch
subrepo: bare git repos considered dirty...
r14440
Eric Roshan Eisner
subrepo: fix git status false positive (issue3109)...
r15531 def _gitupdatestat(self):
"""This must be run before git diff-index.
diff-index only looks at changes to file stat;
this command looks at file contents and updates the stat."""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._gitcommand([b'update-index', b'-q', b'--refresh'])
Eric Roshan Eisner
subrepo: fix git status false positive (issue3109)...
r15531
Eric Eisner
subrepo: update and merge works with any git branch
r12995 def _gitbranchmap(self):
Eric Eisner
subrepo: backout 519ac79d680b...
r13178 '''returns 2 things:
Eric Eisner
subrepo: return both mapping directions from gitbranchmap
r13086 a map from git branch to revision
Eric Eisner
subrepo: backout 519ac79d680b...
r13178 a map from revision to branches'''
Eric Eisner
subrepo: return both mapping directions from gitbranchmap
r13086 branch2rev = {}
rev2branch = {}
Eric Eisner
subrepo: backout 519ac79d680b...
r13178
Augie Fackler
formatting: blacken the codebase...
r43346 out = self._gitcommand(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 [b'for-each-ref', b'--format', b'%(objectname) %(refname)']
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for line in out.split(b'\n'):
revision, ref = line.split(b' ')
if not ref.startswith(b'refs/heads/') and not ref.startswith(
b'refs/remotes/'
Augie Fackler
formatting: blacken the codebase...
r43346 ):
Eric Eisner
subrepo: update and merge works with any git branch
r12995 continue
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if ref.startswith(b'refs/remotes/') and ref.endswith(b'/HEAD'):
Augie Fackler
formatting: blacken the codebase...
r43346 continue # ignore remote/HEAD redirects
Eric Eisner
subrepo: use low-level git-for-each-ref command in branchmap...
r13150 branch2rev[ref] = revision
rev2branch.setdefault(revision, []).append(ref)
Eric Eisner
subrepo: backout 519ac79d680b...
r13178 return branch2rev, rev2branch
def _gittracking(self, branches):
Matt Harbison
cleanup: fix docstring formatting...
r44226 """return map of remote branch to local tracking branch"""
Eric Eisner
subrepo: backout 519ac79d680b...
r13178 # assumes no more than one local tracking branch for each remote
tracking = {}
for b in branches:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b.startswith(b'refs/remotes/'):
Eric Eisner
subrepo: backout 519ac79d680b...
r13178 continue
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 bname = b.split(b'/', 2)[2]
remote = self._gitcommand([b'config', b'branch.%s.remote' % bname])
Eric Eisner
subrepo: backout 519ac79d680b...
r13178 if remote:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ref = self._gitcommand([b'config', b'branch.%s.merge' % bname])
Augie Fackler
formatting: blacken the codebase...
r43346 tracking[
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'refs/remotes/%s/%s' % (remote, ref.split(b'/', 2)[2])
Augie Fackler
formatting: blacken the codebase...
r43346 ] = b
Eric Eisner
subrepo: backout 519ac79d680b...
r13178 return tracking
Eric Eisner
subrepo: lazily update git's local tracking branches...
r13087
Eric Eisner
subrepo: expand relative sources for git subrepos
r13460 def _abssource(self, source):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'://' not in source:
Eric Eisner
subrepo: recognize scp-style paths as git URLs
r13692 # recognize the scp syntax as an absolute source
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 colon = source.find(b':')
if colon != -1 and b'/' not in source[:colon]:
Eric Eisner
subrepo: recognize scp-style paths as git URLs
r13692 return source
Eric Eisner
subrepo: expand relative sources for git subrepos
r13460 self._subsource = source
return _abssource(self)
Eric Eisner
subrepo: cloning and updating of git subrepos...
r12993 def _fetch(self, source, revision):
Eric Eisner
subrepo: don't crash when git repo is missing
r13553 if self._gitmissing():
Sean Farley
subrepo: add tests for git rogue ssh urls (SEC)...
r33731 # SEC: check for safe ssh url
util.checksafessh(source)
Eric Eisner
subrepo: show the source that git clones
r13525 source = self._abssource(source)
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'cloning subrepo %s from %s\n') % (self._relpath, source)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._gitnodir([b'clone', source, self._abspath])
Eric Eisner
subrepo: cloning and updating of git subrepos...
r12993 if self._githavelocally(revision):
return
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'pulling subrepo %s from %s\n')
% (self._relpath, self._gitremote(b'origin'))
Augie Fackler
formatting: blacken the codebase...
r43346 )
Eric Eisner
subrepo: only attempt pulling from git's origin...
r13466 # try only origin: the originally cloned repo
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._gitcommand([b'fetch'])
Eric Eisner
subrepo: cloning and updating of git subrepos...
r12993 if not self._githavelocally(revision):
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 _(b'revision %s does not exist in subrepository "%s"\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (revision, self._relpath)
)
Eric Eisner
subrepo: cloning and updating of git subrepos...
r12993
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Matt Harbison
subrepo: consider the parent repo dirty when a file is missing...
r33364 def dirty(self, ignoreupdate=False, missing=False):
Eric Eisner
subrepo: don't crash when git repo is missing
r13553 if self._gitmissing():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._state[1] != b''
Paul Molodowitch
subrepo: bare git repos considered dirty...
r14440 if self._gitisbare():
return True
Eric Eisner
subrepo: support ignoreupdate in gitsubrepo's dirty()
r13179 if not ignoreupdate and self._state[1] != self._gitstate():
Kevin Bullock
subrepo: clarify comments in dirty() methods...
r13325 # different version checked out
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 return True
# check for staged changes or modified files; ignore untracked files
Eric Roshan Eisner
subrepo: fix git status false positive (issue3109)...
r15531 self._gitupdatestat()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 out, code = self._gitdir([b'diff-index', b'--quiet', b'HEAD'])
Eric Eisner
subrepo: use low-level git-diff-index for dirty()...
r13153 return code == 1
Eric Eisner
subrepo: support for adding a git subrepo...
r12992
Matt Mackall
subrepo: add basestate method...
r16072 def basestate(self):
return self._gitstate()
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Martin Geisler
merge with stable
r13323 def get(self, state, overwrite=False):
Eric Eisner
subrepo: cloning and updating of git subrepos...
r12993 source, revision, kind = state
Eric Eisner
subrepo: don't crash when git .hgsubstate is empty (issue2716)
r14469 if not revision:
self.remove()
return
Eric Eisner
subrepo: cloning and updating of git subrepos...
r12993 self._fetch(source, revision)
Eric Eisner
subrepo: removing (and restoring) git subrepo state
r12996 # if the repo was set to be bare, unbare it
Paul Molodowitch
subrepo: bare git repos considered dirty...
r14440 if self._gitisbare():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._gitcommand([b'config', b'core.bare', b'false'])
Eric Eisner
subrepo: removing (and restoring) git subrepo state
r12996 if self._gitstate() == revision:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._gitcommand([b'reset', b'--hard', b'HEAD'])
Eric Eisner
subrepo: removing (and restoring) git subrepo state
r12996 return
elif self._gitstate() == revision:
Erik Zielke
subrepo: make update -C clean the working directory for git subrepos...
r13324 if overwrite:
Augie Fackler
subrepo: trailing whitespace cleanup
r13927 # first reset the index to unmark new files for commit, because
Erik Zielke
subrepo: make update -C clean the working directory for git subrepos...
r13324 # reset --hard will otherwise throw away files added for commit,
# not just unmark them.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._gitcommand([b'reset', b'HEAD'])
self._gitcommand([b'reset', b'--hard', b'HEAD'])
Eric Eisner
subrepo: update and merge works with any git branch
r12995 return
Eric Eisner
subrepo: backout 519ac79d680b...
r13178 branch2rev, rev2branch = self._gitbranchmap()
Eric Eisner
subrepo: lazily update git's local tracking branches...
r13087
Erik Zielke
subrepo: make update -C clean the working directory for git subrepos...
r13324 def checkout(args):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd = [b'checkout']
Erik Zielke
subrepo: make update -C clean the working directory for git subrepos...
r13324 if overwrite:
# first reset the index to unmark new files for commit, because
# the -f option will otherwise throw away files added for
# commit, not just unmark them.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._gitcommand([b'reset', b'HEAD'])
cmd.append(b'-f')
Erik Zielke
subrepo: make update -C clean the working directory for git subrepos...
r13324 self._gitcommand(cmd + args)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _sanitize(self.ui, self.wvfs, b'.git')
Erik Zielke
subrepo: make update -C clean the working directory for git subrepos...
r13324
Eric Eisner
subrepo: lazily update git's local tracking branches...
r13087 def rawcheckout():
Eric Eisner
subrepo: update and merge works with any git branch
r12995 # no branch to checkout, check it out with no branch
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 _(b'checking out detached HEAD in subrepository "%s"\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % self._relpath
)
self.ui.warn(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 _(b'check out a git branch if you intend to make changes\n')
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 checkout([b'-q', revision])
Eric Eisner
subrepo: lazily update git's local tracking branches...
r13087
if revision not in rev2branch:
rawcheckout()
Eric Eisner
subrepo: update and merge works with any git branch
r12995 return
Eric Eisner
subrepo: return both mapping directions from gitbranchmap
r13086 branches = rev2branch[revision]
Eric Eisner
subrepo: update and merge works with any git branch
r12995 firstlocalbranch = None
for b in branches:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b == b'refs/heads/master':
Eric Eisner
subrepo: update and merge works with any git branch
r12995 # master trumps all other branches
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 checkout([b'refs/heads/master'])
Eric Eisner
subrepo: update and merge works with any git branch
r12995 return
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not firstlocalbranch and not b.startswith(b'refs/remotes/'):
Eric Eisner
subrepo: update and merge works with any git branch
r12995 firstlocalbranch = b
if firstlocalbranch:
Erik Zielke
subrepo: make update -C clean the working directory for git subrepos...
r13324 checkout([firstlocalbranch])
Eric Eisner
subrepo: lazily update git's local tracking branches...
r13087 return
Eric Eisner
subrepo: backout 519ac79d680b...
r13178 tracking = self._gittracking(branch2rev.keys())
Eric Eisner
subrepo: lazily update git's local tracking branches...
r13087 # choose a remote branch already tracked if possible
remote = branches[0]
if remote not in tracking:
for b in branches:
if b in tracking:
remote = b
break
if remote not in tracking:
# create a new local tracking branch
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 local = remote.split(b'/', 3)[3]
checkout([b'-b', local, remote])
Eric Eisner
subrepo: lazily update git's local tracking branches...
r13087 elif self._gitisancestor(branch2rev[tracking[remote]], remote):
# When updating to a tracked remote branch,
# if the local tracking branch is downstream of it,
# a normal `git pull` would have performed a "fast-forward merge"
# which is equivalent to updating the local branch to the remote.
# Since we are only looking at branching at update, we need to
# detect this situation and perform this action lazily.
Eric Eisner
subrepo: defer determination of git's current branch
r13152 if tracking[remote] != self._gitcurrentbranch():
Erik Zielke
subrepo: make update -C clean the working directory for git subrepos...
r13324 checkout([tracking[remote]])
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._gitcommand([b'merge', b'--ff', remote])
_sanitize(self.ui, self.wvfs, b'.git')
Eric Eisner
subrepo: lazily update git's local tracking branches...
r13087 else:
# a real merge would be required, just checkout the revision
rawcheckout()
Eric Eisner
subrepo: cloning and updating of git subrepos...
r12993
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 def commit(self, text, user, date):
Eric Eisner
subrepo: don't crash when git repo is missing
r13553 if self._gitmissing():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"subrepo %s is missing") % self._relpath)
cmd = [b'commit', b'-a', b'-m', text]
Pulkit Goyal
py3: replace os.environ with encoding.environ (part 2 of 5)
r30635 env = encoding.environ.copy()
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 if user:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd += [b'--author', user]
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 if date:
# git's date parser silently ignores when seconds < 1e9
# convert to ISO8601
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 env[b'GIT_AUTHOR_DATE'] = dateutil.datestr(
date, b'%Y-%m-%dT%H:%M:%S %1%2'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Eric Eisner
subrepo: use environment variable instead of git commit's --date...
r13095 self._gitcommand(cmd, env=env)
Eric Eisner
subrepo: support for adding a git subrepo...
r12992 # make sure commit works otherwise HEAD might not exist under certain
# circumstances
return self._gitstate()
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Eric Eisner
subrepo: allow git subrepos to push and merge...
r12994 def merge(self, state):
source, revision, kind = state
self._fetch(source, revision)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 base = self._gitcommand([b'merge-base', revision, self._state[1]])
Eric Roshan Eisner
subrepo: fix git status false positive (issue3109)...
r15531 self._gitupdatestat()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 out, code = self._gitdir([b'diff-index', b'--quiet', b'HEAD'])
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417
def mergefunc():
if base == revision:
Augie Fackler
formatting: blacken the codebase...
r43346 self.get(state) # fast forward merge
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417 elif base != self._state[1]:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._gitcommand([b'merge', b'--no-commit', revision])
_sanitize(self.ui, self.wvfs, b'.git')
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417
if self.dirty():
if self._gitstate() != revision:
dirty = self._gitstate() == self._state[1] or code != 0
Augie Fackler
formatting: blacken the codebase...
r43346 if _updateprompt(
self.ui, self, dirty, self._state[1][:7], revision[:7]
):
Erik Zielke
subrepos: prompt on conflicts on update with dirty subrepos...
r13417 mergefunc()
else:
mergefunc()
Eric Eisner
subrepo: allow git subrepos to push and merge...
r12994
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Angel Ezquerra
push: propagate --new-branch and --ssh options when pushing subrepos...
r15708 def push(self, opts):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 force = opts.get(b'force')
Angel Ezquerra
push: propagate --new-branch and --ssh options when pushing subrepos...
r15708
Eric Eisner
subrepo: don't crash when git .hgsubstate is empty (issue2716)
r14469 if not self._state[1]:
return True
Eric Eisner
subrepo: don't crash when git repo is missing
r13553 if self._gitmissing():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"subrepo %s is missing") % self._relpath)
Eric Eisner
subrepo: lazier git push logic...
r13029 # if a branch in origin contains the revision, nothing to do
Eric Eisner
subrepo: backout 519ac79d680b...
r13178 branch2rev, rev2branch = self._gitbranchmap()
Eric Eisner
subrepo: speed up git push logic...
r13109 if self._state[1] in rev2branch:
for b in rev2branch[self._state[1]]:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b.startswith(b'refs/remotes/origin/'):
Eric Eisner
subrepo: speed up git push logic...
r13109 return True
Gregory Szorc
py3: finish porting iteritems() to pycompat and remove source transformer...
r43376 for b, revision in pycompat.iteritems(branch2rev):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b.startswith(b'refs/remotes/origin/'):
Eric Eisner
subrepo: return both mapping directions from gitbranchmap
r13086 if self._gitisancestor(self._state[1], revision):
return True
Eric Eisner
subrepo: lazier git push logic...
r13029 # otherwise, try to push the currently checked out branch
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd = [b'push']
Eric Eisner
subrepo: allow git subrepos to push and merge...
r12994 if force:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd.append(b'--force')
Eric Eisner
subrepo: defer determination of git's current branch
r13152
current = self._gitcurrentbranch()
Eric Eisner
subrepo: update and merge works with any git branch
r12995 if current:
Eric Eisner
subrepo: lazier git push logic...
r13029 # determine if the current branch is even useful
if not self._gitisancestor(self._state[1], current):
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'unrelated git branch checked out '
b'in subrepository "%s"\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% self._relpath
)
Eric Eisner
subrepo: lazier git push logic...
r13029 return False
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'pushing branch %s of subrepository "%s"\n')
% (current.split(b'/', 2)[2], self._relpath)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ret = self._gitdir(cmd + [b'origin', current])
Matt Mackall
subrepo: check return code for git push (issue4223)
r20970 return ret[1] == 0
Eric Eisner
subrepo: update and merge works with any git branch
r12995 else:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'no branch checked out in subrepository "%s"\n'
b'cannot push revision %s\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% (self._relpath, self._state[1])
)
Eric Eisner
subrepo: update and merge works with any git branch
r12995 return False
Eric Eisner
subrepo: allow git subrepos to push and merge...
r12994
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Martin von Zweigbergk
add: pass around uipathfn and use instead of m.rel() (API)...
r41799 def add(self, ui, match, prefix, uipathfn, explicitonly, **opts):
Mathias De Maré
subrepos: support adding files in git subrepos...
r24174 if self._gitmissing():
return []
Matt Harbison
subrepo: don't exclude files in .hgignore when adding to git...
r24182
Martin von Zweigbergk
subrepo: access status members by name instead of by position...
r40378 s = self.status(None, unknown=True, clean=True)
Mathias De Maré
subrepos: support adding files in git subrepos...
r24174
Matt Harbison
subrepo: warn when adding already tracked files in gitsubrepo...
r24183 tracked = set()
# dirstates 'amn' warn, 'r' is added again
Martin von Zweigbergk
subrepo: access status members by name instead of by position...
r40378 for l in (s.modified, s.added, s.deleted, s.clean):
Matt Harbison
subrepo: warn when adding already tracked files in gitsubrepo...
r24183 tracked.update(l)
Matt Harbison
subrepo: don't exclude files in .hgignore when adding to git...
r24182 # Unknown files not of interest will be rejected by the matcher
Martin von Zweigbergk
subrepo: access status members by name instead of by position...
r40378 files = s.unknown
Matt Harbison
subrepo: don't exclude files in .hgignore when adding to git...
r24182 files.extend(match.files())
Matt Harbison
subrepo: warn when adding already tracked files in gitsubrepo...
r24183 rejected = []
Matt Harbison
subrepo: don't exclude files in .hgignore when adding to git...
r24182 files = [f for f in sorted(set(files)) if match(f)]
Mathias De Maré
subrepos: support adding files in git subrepos...
r24174 for f in files:
exact = match.exact(f)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 command = [b"add"]
Mathias De Maré
subrepos: support adding files in git subrepos...
r24174 if exact:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 command.append(b"-f") # should be added, even if ignored
Mathias De Maré
subrepos: support adding files in git subrepos...
r24174 if ui.verbose or not exact:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'adding %s\n') % uipathfn(f))
Matt Harbison
subrepo: warn when adding already tracked files in gitsubrepo...
r24183
if f in tracked: # hg prints 'adding' even if already tracked
if exact:
rejected.append(f)
continue
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if not opts.get('dry_run'):
Mathias De Maré
subrepos: support adding files in git subrepos...
r24174 self._gitcommand(command + [f])
Matt Harbison
subrepo: warn when adding already tracked files in gitsubrepo...
r24183
for f in rejected:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.warn(_(b"%s already tracked!\n") % uipathfn(f))
Matt Harbison
subrepo: warn when adding already tracked files in gitsubrepo...
r24183
return rejected
Mathias De Maré
subrepos: support adding files in git subrepos...
r24174
@annotatesubrepoerror
Eric Eisner
subrepo: removing (and restoring) git subrepo state
r12996 def remove(self):
Eric Eisner
subrepo: don't crash when git repo is missing
r13553 if self._gitmissing():
return
Eric Eisner
subrepo: removing (and restoring) git subrepo state
r12996 if self.dirty():
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 _(b'not removing repo %s because it has changes.\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % self._relpath
)
Eric Eisner
subrepo: removing (and restoring) git subrepo state
r12996 return
# we can't fully delete the repository as it may contain
# local-only history
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.note(_(b'removing subrepo %s\n') % self._relpath)
self._gitcommand([b'config', b'core.bare', b'true'])
FUJIWARA Katsunori
subrepo: use vfs.readdir instead of os.listdir to avoid expensive stat calls...
r24688 for f, kind in self.wvfs.readdir():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if f == b'.git':
Eric Eisner
subrepo: removing (and restoring) git subrepo state
r12996 continue
FUJIWARA Katsunori
subrepo: use vfs.readdir instead of os.listdir to avoid expensive stat calls...
r24688 if kind == stat.S_IFDIR:
FUJIWARA Katsunori
subrepo: use vfs.rmtree instead of shutil.rmtree...
r24690 self.wvfs.rmtree(f)
Eric Eisner
subrepo: removing (and restoring) git subrepo state
r12996 else:
FUJIWARA Katsunori
subrepo: use vfs.unlink instead of os.remove...
r24691 self.wvfs.unlink(f)
Eric Eisner
subrepo: removing (and restoring) git subrepo state
r12996
Matt Harbison
subrepo: run the repo decoders when archiving...
r31099 def archive(self, archiver, prefix, match=None, decode=True):
Angel Ezquerra
archive: raise error.Abort if the file pattern matches no files...
r18967 total = 0
Eric Eisner
subrepo: archive git subrepos
r13027 source, revision = self._state
Eric Eisner
subrepo: don't crash when git .hgsubstate is empty (issue2716)
r14469 if not revision:
Angel Ezquerra
archive: raise error.Abort if the file pattern matches no files...
r18967 return total
Eric Eisner
subrepo: archive git subrepos
r13027 self._fetch(source, revision)
# Parse git's native archive command.
# This should be much faster than manually traversing the trees
# and objects with many subprocess calls.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tarstream = self._gitcommand([b'archive', revision], stream=True)
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 tar = tarfile.open(fileobj=tarstream, mode='r|')
Martin Geisler
subrepo: add progress bar support to archive
r13144 relpath = subrelpath(self)
Augie Fackler
formatting: blacken the codebase...
r43346 progress = self.ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'archiving (%s)') % relpath, unit=_(b'files')
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martin von Zweigbergk
subrepo: use progress helper...
r38398 progress.update(0)
for info in tar:
Eric Eisner
subrepo: fix git archive parsing of directories and symfiles
r13180 if info.isdir():
continue
Augie Fackler
subrepo: bytes/str cleanups on Git support...
r41624 bname = pycompat.fsencode(info.name)
if match and not match(bname):
Matt Harbison
subrepo: propagate matcher to subrepos when archiving...
r17108 continue
Eric Eisner
subrepo: fix git archive parsing of directories and symfiles
r13180 if info.issym():
data = info.linkname
else:
data = tar.extractfile(info).read()
Martin von Zweigbergk
subrepo: adjust subrepo prefix before calling subrepo.archive() (API)...
r41780 archiver.addfile(prefix + bname, info.mode, info.issym(), data)
Angel Ezquerra
archive: raise error.Abort if the file pattern matches no files...
r18967 total += 1
Martin von Zweigbergk
subrepo: use progress helper...
r38398 progress.increment()
progress.complete()
Angel Ezquerra
archive: raise error.Abort if the file pattern matches no files...
r18967 return total
Martin Geisler
subrepo: add progress bar support to archive
r13144
Angel Ezquerra
subrepo: append subrepo path to subrepo error messages...
r18109 @annotatesubrepoerror
Yuya Nishihara
cat: add formatter support...
r32578 def cat(self, match, fm, fntemplate, prefix, **opts):
Mathias De Maré
subrepo: add 'cat' support for git subrepos...
r23991 rev = self._state[1]
if match.anypats():
Augie Fackler
formatting: blacken the codebase...
r43346 return 1 # No support for include/exclude yet
Mathias De Maré
subrepo: add 'cat' support for git subrepos...
r23991
if not match.files():
return 1
Yuya Nishihara
cat: add formatter support...
r32578 # TODO: add support for non-plain formatter (see cmdutil.cat())
Mathias De Maré
subrepo: add 'cat' support for git subrepos...
r23991 for f in match.files():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output = self._gitcommand([b"show", b"%s:%s" % (rev, f)])
Augie Fackler
formatting: blacken the codebase...
r43346 fp = cmdutil.makefileobj(
self._ctx, fntemplate, pathname=self.wvfs.reljoin(prefix, f)
)
Mathias De Maré
subrepo: add 'cat' support for git subrepos...
r23991 fp.write(output)
fp.close()
return 0
@annotatesubrepoerror
Eric Eisner
subrepo: basic support for status of git subrepos
r13182 def status(self, rev2, **opts):
Eric Eisner
subrepo: don't crash when git .hgsubstate is empty (issue2716)
r14469 rev1 = self._state[1]
if self._gitmissing() or not rev1:
Eric Eisner
subrepo: don't crash when git repo is missing
r13553 # if the repo is missing, return no results
Matt Harbison
subrepo: always return scmutil.status() from gitsubrepo.status()...
r24210 return scmutil.status([], [], [], [], [], [], [])
Eric Eisner
subrepo: basic support for status of git subrepos
r13182 modified, added, removed = [], [], []
Eric Roshan Eisner
subrepo: fix git status false positive (issue3109)...
r15531 self._gitupdatestat()
Eric Eisner
subrepo: basic support for status of git subrepos
r13182 if rev2:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 command = [b'diff-tree', b'--no-renames', b'-r', rev1, rev2]
Eric Eisner
subrepo: basic support for status of git subrepos
r13182 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 command = [b'diff-index', b'--no-renames', rev1]
Eric Eisner
subrepo: basic support for status of git subrepos
r13182 out = self._gitcommand(command)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for line in out.split(b'\n'):
tab = line.find(b'\t')
Eric Eisner
subrepo: basic support for status of git subrepos
r13182 if tab == -1:
continue
Augie Fackler
formatting: blacken the codebase...
r43346 status, f = line[tab - 1 : tab], line[tab + 1 :]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if status == b'M':
Eric Eisner
subrepo: basic support for status of git subrepos
r13182 modified.append(f)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif status == b'A':
Eric Eisner
subrepo: basic support for status of git subrepos
r13182 added.append(f)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif status == b'D':
Eric Eisner
subrepo: basic support for status of git subrepos
r13182 removed.append(f)
Martin von Zweigbergk
subrepo: use separate instances of empty lists in status...
r22927 deleted, unknown, ignored, clean = [], [], [], []
Mathias De Maré
subrepo: add status support for ignored files in git subrepos...
r23411
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 command = [b'status', b'--porcelain', b'-z']
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if opts.get('unknown'):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 command += [b'--untracked-files=all']
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if opts.get('ignored'):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 command += [b'--ignored']
Mathias De Maré
subrepo: add status support for ignored and clean files in git subrepos
r24256 out = self._gitcommand(command)
changedfiles = set()
changedfiles.update(modified)
changedfiles.update(added)
changedfiles.update(removed)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for line in out.split(b'\0'):
Mathias De Maré
subrepo: add status support for ignored and clean files in git subrepos
r24256 if not line:
continue
st = line[0:2]
Augie Fackler
formatting: blacken the codebase...
r43346 # moves and copies show 2 files on one line
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if line.find(b'\0') >= 0:
filename1, filename2 = line[3:].split(b'\0')
Mathias De Maré
subrepo: add status support for ignored and clean files in git subrepos
r24256 else:
filename1 = line[3:]
filename2 = None
changedfiles.add(filename1)
if filename2:
changedfiles.add(filename2)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if st == b'??':
Mathias De Maré
subrepo: add status support for ignored and clean files in git subrepos
r24256 unknown.append(filename1)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif st == b'!!':
Mathias De Maré
subrepo: add status support for ignored and clean files in git subrepos
r24256 ignored.append(filename1)
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if opts.get('clean'):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 out = self._gitcommand([b'ls-files'])
for f in out.split(b'\n'):
Mathias De Maré
subrepo: add status support for ignored and clean files in git subrepos
r24256 if not f in changedfiles:
clean.append(f)
Mathias De Maré
subrepo: add status support for ignored files in git subrepos...
r23411
Augie Fackler
formatting: blacken the codebase...
r43346 return scmutil.status(
modified, added, removed, deleted, unknown, ignored, clean
)
Eric Eisner
subrepo: basic support for status of git subrepos
r13182
Mathias De Maré
subrepo: add partial diff support for git subrepos...
r23523 @annotatesubrepoerror
def diff(self, ui, diffopts, node2, match, prefix, **opts):
node1 = self._state[1]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd = [b'diff', b'--no-renames']
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if opts['stat']:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd.append(b'--stat')
Mathias De Maré
subrepo: add partial diff support for git subrepos...
r23523 else:
# for Git, this also implies '-p'
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd.append(b'-U%d' % diffopts.context)
Mathias De Maré
subrepo: add partial diff support for git subrepos...
r23523
if diffopts.noprefix:
Augie Fackler
formatting: blacken the codebase...
r43346 cmd.extend(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 [b'--src-prefix=%s/' % prefix, b'--dst-prefix=%s/' % prefix]
Augie Fackler
formatting: blacken the codebase...
r43346 )
Mathias De Maré
subrepo: add partial diff support for git subrepos...
r23523 else:
Augie Fackler
formatting: blacken the codebase...
r43346 cmd.extend(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 [b'--src-prefix=a/%s/' % prefix, b'--dst-prefix=b/%s/' % prefix]
Augie Fackler
formatting: blacken the codebase...
r43346 )
Mathias De Maré
subrepo: add partial diff support for git subrepos...
r23523
if diffopts.ignorews:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd.append(b'--ignore-all-space')
Mathias De Maré
subrepo: add partial diff support for git subrepos...
r23523 if diffopts.ignorewsamount:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd.append(b'--ignore-space-change')
Augie Fackler
formatting: blacken the codebase...
r43346 if (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._gitversion(self._gitcommand([b'--version'])) >= (1, 8, 4)
Augie Fackler
formatting: blacken the codebase...
r43346 and diffopts.ignoreblanklines
):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd.append(b'--ignore-blank-lines')
Mathias De Maré
subrepo: add partial diff support for git subrepos...
r23523
cmd.append(node1)
if node2:
cmd.append(node2)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output = b""
Mathias De Maré
subrepo: add partial diff support for git subrepos...
r23523 if match.always():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output += self._gitcommand(cmd) + b'\n'
Mathias De Maré
subrepo: add include/exclude support for diffing git subrepos...
r24778 else:
Augie Fackler
subrepo: use field names instead of field numbers on scmutil.status...
r44050 st = self.status(node2)
files = [
f
for sublist in (st.modified, st.added, st.removed)
for f in sublist
]
Mathias De Maré
subrepo: add include/exclude support for diffing git subrepos...
r24778 for f in files:
if match(f):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output += self._gitcommand(cmd + [b'--', f]) + b'\n'
Mathias De Maré
subrepo: correctly add newline for git subrepo diffs...
r23938
if output.strip():
ui.write(output)
Mathias De Maré
subrepo: add partial diff support for git subrepos...
r23523
Mathias De Maré
subrepo: add forgotten annotation for reverting git subrepos...
r23679 @annotatesubrepoerror
Matt Mackall
subrepo: fix git subrepo ui argument
r23580 def revert(self, substate, *pats, **opts):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.status(_(b'reverting subrepo %s\n') % substate[0])
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if not opts.get('no_backup'):
Mathias De Maré
subrepo: add full revert support for git subrepos...
r23678 status = self.status(None)
names = status.modified
for name in names:
Martin von Zweigbergk
subrepo: migrate to scmutil.backuppath()...
r41752 # backuppath() expects a path relative to the parent repo (the
# repo that ui.origbackuppath is relative to)
parentname = os.path.join(self._path, name)
Augie Fackler
formatting: blacken the codebase...
r43346 bakname = scmutil.backuppath(
self.ui, self._subparent, parentname
)
self.ui.note(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'saving current version of %s as %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (name, os.path.relpath(bakname))
)
Martin von Zweigbergk
subrepo: migrate to scmutil.backuppath()...
r41752 util.rename(self.wvfs.join(name), bakname)
Mathias De Maré
subrepo: add revert support without backup for git subrepos...
r23550
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if not opts.get('dry_run'):
Matt Harbison
revert: display full subrepo output with --dry-run...
r24134 self.get(substate, overwrite=True)
Mathias De Maré
subrepo: add revert support without backup for git subrepos...
r23550 return []
Angel Ezquerra
subrepo: add shortid() method to subrepo classes...
r21400 def shortid(self, revid):
return revid[:7]
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
subrepo: add table-based dispatch for subrepo types
r10177 types = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'hg': hgsubrepo,
b'svn': svnsubrepo,
b'git': gitsubrepo,
Augie Fackler
formatting: blacken the codebase...
r43346 }