##// END OF EJS Templates
interfaces: mark a few dirstate methods abstract...
interfaces: mark a few dirstate methods abstract I'm not sure what's going on here, but when enabling pytype checking on this package, it spits out the following errors: File "/mnt/c/Users/Matt/hg/mercurial/interfaces/dirstate.py", line 136, in changing_parents: bad return type [bad-return-type] Expected: Iterator Actually returned: None Attributes of protocol Iterator are not implemented on None: __next__ File "/mnt/c/Users/Matt/hg/mercurial/interfaces/dirstate.py", line 145, in changing_files: bad return type [bad-return-type] Expected: Iterator Actually returned: None Attributes of protocol Iterator are not implemented on None: __next__ I guess technically that's true, because these methods only have a doc comment, and don't explicitly return something or unconditionally raise an error. The strange thing is that both before and after this change, the *.pyi file that is generated is unchanged, and contains: def changing_files(self, repo) -> contextlib._GeneratorContextManager: ... def changing_parents(self, repo) -> contextlib._GeneratorContextManager: ... I'm not sure if the `@abstractmethod` should be the most inner or most outer decoration. We'll roll the dice with being the innermost, because that's how `@abstractproperty` says it should be used in conjunction with `@property`. We should probably make all of the methods without an actual body abstract, like was done for some `mercurial.wireprototypes` classes in fd200f5bcaea. But let's hold off for now and do that enmass later.

File last commit:

r52756:f4733654 default
r53328:2c8c46c3 default
Show More
subrepoutil.py
545 lines | 17.8 KiB | text/x-python | PythonLexer
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 # subrepoutil.py - sub-repository operations and substate handling
#
Raphaël Gomès
contributor: change mentions of mpm to olivia...
r47575 # Copyright 2009-2010 Olivia Mackall <olivia@selenic.com>
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 #
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Matt Harbison
typing: add `from __future__ import annotations` to most files...
r52756 from __future__ import annotations
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
import os
import posixpath
import re
pytype: import typing directly...
r52178 import typing
from typing import (
Any,
Dict,
List,
Optional,
Set,
Tuple,
)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
from .i18n import _
from . import (
config,
error,
filemerge,
pathutil,
phases,
util,
)
urlutil: extract `url` related code from `util` into the new module...
r47669 from .utils import (
stringutil,
urlutil,
)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
pytype: import typing directly...
r52178 # keeps pyflakes happy
assert [
Any,
Dict,
List,
Optional,
Set,
Tuple,
]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 nullstate = (b'', b'', b'empty')
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
pytype: import typing directly...
r52178 if typing.TYPE_CHECKING:
Matt Harbison
typing: add type annotations to the public methods of mercurial/subrepoutil.py...
r47389 from . import (
context,
localrepo,
match as matchmod,
scmutil,
subrepo,
ui as uimod,
)
pytype: import typing directly...
r52178 # keeps pyflakes happy
assert [
context,
localrepo,
matchmod,
scmutil,
subrepo,
uimod,
]
Substate = Dict[bytes, Tuple[bytes, bytes, bytes]]
Matt Harbison
typing: add type annotations to the public methods of mercurial/subrepoutil.py...
r47389
Augie Fackler
formatting: blacken the codebase...
r43346
pytype: move some type comment to proper annotation...
r52180 def state(ctx: "context.changectx", ui: "uimod.ui") -> Substate:
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 """return a state dict, mapping subrepo paths configured in .hgsub
to tuple: (source from .hgsub, revision from .hgsubstate, kind
(key in types dict))
"""
pytype: drop the last inline type comment...
r52182 p: config.config = config.config()
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 repo = ctx.repo()
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
config: remove now-unused `abs` argument from `include` callback...
r45817 def read(f, sections=None, remap=None):
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 if f in ctx:
try:
data = ctx[f].data()
Manuel Jacob
py3: catch FileNotFoundError instead of checking errno == ENOENT
r50201 except FileNotFoundError:
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 # handle missing subrepo spec files as removed
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"warning: subrepo spec file \'%s\' not found\n")
Augie Fackler
formatting: blacken the codebase...
r43346 % repo.pathto(f)
)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 return
p.parse(f, data, sections, remap, read)
else:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"subrepo spec file \'%s\' not found") % repo.pathto(f)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'.hgsub' in ctx:
Martin von Zweigbergk
config: remove now-unused `abs` argument from `include` callback...
r45817 read(b'.hgsub')
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for path, src in ui.configitems(b'subpaths'):
p.set(b'subpaths', path, src, ui.configsource(b'subpaths', path))
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
rev = {}
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'.hgsubstate' in ctx:
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for i, l in enumerate(ctx[b'.hgsubstate'].data().splitlines()):
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 l = l.lstrip()
if not l:
continue
try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 revision, path = l.split(b" ", 1)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 except ValueError:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"invalid subrepository revision "
b"specifier in \'%s\' line %d"
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 % (repo.pathto(b'.hgsubstate'), (i + 1))
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 rev[path] = revision
Manuel Jacob
py3: catch FileNotFoundError instead of checking errno == ENOENT
r50201 except FileNotFoundError:
pass
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
pytype: move some type comment to proper annotation...
r52180 def remap(src: bytes) -> bytes:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for pattern, repl in p.items(b'subpaths'):
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 # Turn r'C:\foo\bar' into r'C:\\foo\\bar' since re.sub
# does a string decode.
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 repl = stringutil.escapestr(repl)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 # However, we still want to allow back references to go
# through unharmed, so we turn r'\\1' into r'\1'. Again,
# extra escapes are needed because re.sub string decodes.
repl = re.sub(br'\\\\([0-9]+)', br'\\\1', repl)
try:
Mads Kiilerich
subrepoutil: pass re.sub 'count' argument by name...
r52640 src = re.sub(pattern, repl, src, count=1)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 except re.error as e:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"bad subrepository pattern in %s: %s")
Augie Fackler
formatting: blacken the codebase...
r43346 % (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 p.source(b'subpaths', pattern),
Augie Fackler
formatting: blacken the codebase...
r43346 stringutil.forcebytestr(e),
)
)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 return src
state = {}
pytype: drop the last inline type comment...
r52182 for path, src in p.items(b''):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 kind = b'hg'
if src.startswith(b'['):
if b']' not in src:
raise error.Abort(_(b'missing ] in subrepository source'))
kind, src = src.split(b']', 1)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 kind = kind[1:]
Augie Fackler
formatting: blacken the codebase...
r43346 src = src.lstrip() # strip any extra whitespace after ']'
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
urlutil: extract `url` related code from `util` into the new module...
r47669 if not urlutil.url(src).isabs():
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 parent = _abssource(repo, abort=False)
if parent:
urlutil: extract `url` related code from `util` into the new module...
r47669 parent = urlutil.url(parent)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 parent.path = posixpath.join(parent.path or b'', src)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 parent.path = posixpath.normpath(parent.path)
Pulkit Goyal
py3: use bytes() instead of str() on util.url()...
r37604 joined = bytes(parent)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 # Remap the full joined path and use it if it changes,
# else remap the original source.
remapped = remap(joined)
if remapped == joined:
src = remap(src)
else:
src = remapped
src = remap(src)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 state[util.pconvert(path)] = (src.strip(), rev.get(path, b''), kind)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
return state
Augie Fackler
formatting: blacken the codebase...
r43346
pytype: move some type comment to proper annotation...
r52180 def writestate(repo: "localrepo.localrepository", state: Substate) -> None:
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 """rewrite .hgsubstate in (outer) repo with these subrepo states"""
Augie Fackler
formatting: blacken the codebase...
r43346 lines = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'%s %s\n' % (state[s][1], s)
Augie Fackler
formatting: blacken the codebase...
r43346 for s in sorted(state)
if state[s][1] != nullstate[1]
]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.wwrite(b'.hgsubstate', b''.join(lines), b'')
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
Augie Fackler
formatting: blacken the codebase...
r43346
pytype: move some type comment to proper annotation...
r52180 def submerge(
repo: "localrepo.localrepository",
wctx: "context.workingctx",
mctx: "context.changectx",
actx: "context.changectx",
overwrite: bool,
labels: Optional[Any] = None,
) -> Substate:
Matt Harbison
typing: add type annotations to the public methods of mercurial/subrepoutil.py...
r47389 # TODO: type the `labels` arg
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 """delegated from merge.applyupdates: merging of .hgsubstate file
in working context, merging context and ancestor context"""
Augie Fackler
formatting: blacken the codebase...
r43346 if mctx == actx: # backwards?
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 actx = wctx.p1()
s1 = wctx.substate
s2 = mctx.substate
sa = actx.substate
sm = {}
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b"subrepo merge %s %s %s\n" % (wctx, mctx, actx))
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 def debug(s, msg, r=b""):
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 if r:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 r = b"%s:%s:%s" % r
repo.ui.debug(b" subrepo %s: %s %s\n" % (s, msg, r))
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
promptssrc = filemerge.partextras(labels)
Gregory Szorc
global: bulk replace simple pycompat.iteritems(x) with x.items()...
r49768 for s, l in sorted(s1.items()):
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 a = sa.get(s, nullstate)
Augie Fackler
formatting: blacken the codebase...
r43346 ld = l # local state with possible dirty flag for compares
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 if wctx.sub(s).dirty():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ld = (l[0], l[1] + b"+")
Augie Fackler
formatting: blacken the codebase...
r43346 if wctx == actx: # overwrite
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 a = ld
prompts = promptssrc.copy()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prompts[b's'] = s
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 if s in s2:
r = s2[s]
Augie Fackler
formatting: blacken the codebase...
r43346 if ld == r or r == a: # no change or local is newer
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 sm[s] = l
continue
Augie Fackler
formatting: blacken the codebase...
r43346 elif ld == a: # other side changed
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 debug(s, b"other changed, get", r)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 wctx.sub(s).get(r, overwrite)
sm[s] = r
Augie Fackler
formatting: blacken the codebase...
r43346 elif ld[0] != r[0]: # sources differ
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prompts[b'lo'] = l[0]
prompts[b'ro'] = r[0]
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 if repo.ui.promptchoice(
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b' subrepository sources for %(s)s differ\n'
b'you can use (l)ocal%(l)s source (%(lo)s)'
b' or (r)emote%(o)s source (%(ro)s).\n'
b'what do you want to do?'
b'$$ &Local $$ &Remote'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% prompts,
0,
):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 debug(s, b"prompt changed, get", r)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 wctx.sub(s).get(r, overwrite)
sm[s] = r
Augie Fackler
formatting: blacken the codebase...
r43346 elif ld[1] == a[1]: # local side is unchanged
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 debug(s, b"other side changed, get", r)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 wctx.sub(s).get(r, overwrite)
sm[s] = r
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 debug(s, b"both sides changed")
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 srepo = wctx.sub(s)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prompts[b'sl'] = srepo.shortid(l[1])
prompts[b'sr'] = srepo.shortid(r[1])
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 option = repo.ui.promptchoice(
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b' subrepository %(s)s diverged (local revision: %(sl)s, '
b'remote revision: %(sr)s)\n'
b'you can (m)erge, keep (l)ocal%(l)s or keep '
b'(r)emote%(o)s.\n'
b'what do you want to do?'
b'$$ &Merge $$ &Local $$ &Remote'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% prompts,
0,
)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 if option == 0:
wctx.sub(s).merge(r)
sm[s] = l
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 debug(s, b"merge with", r)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 elif option == 1:
sm[s] = l
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 debug(s, b"keep local subrepo revision", l)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 else:
wctx.sub(s).get(r, overwrite)
sm[s] = r
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 debug(s, b"get remote subrepo revision", r)
Augie Fackler
formatting: blacken the codebase...
r43346 elif ld == a: # remote removed, local unchanged
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 debug(s, b"remote removed, remove")
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 wctx.sub(s).remove()
Augie Fackler
formatting: blacken the codebase...
r43346 elif a == nullstate: # not present in remote or ancestor
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 debug(s, b"local added, keep")
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 sm[s] = l
continue
else:
if repo.ui.promptchoice(
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b' local%(l)s changed subrepository %(s)s'
b' which remote%(o)s removed\n'
b'use (c)hanged version or (d)elete?'
b'$$ &Changed $$ &Delete'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% prompts,
0,
):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 debug(s, b"prompt remove")
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 wctx.sub(s).remove()
for s, r in sorted(s2.items()):
if s in s1:
continue
elif s not in sa:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 debug(s, b"remote added, get", r)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 mctx.sub(s).get(r)
sm[s] = r
elif r != sa[s]:
prompts = promptssrc.copy()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prompts[b's'] = s
Augie Fackler
formatting: blacken the codebase...
r43346 if (
repo.ui.promptchoice(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b' remote%(o)s changed subrepository %(s)s'
b' which local%(l)s removed\n'
b'use (c)hanged version or (d)elete?'
b'$$ &Changed $$ &Delete'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% prompts,
0,
)
== 0
):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 debug(s, b"prompt recreate", r)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 mctx.sub(s).get(r)
sm[s] = r
# record merged .hgsubstate
writestate(repo, sm)
return sm
Augie Fackler
formatting: blacken the codebase...
r43346
pytype: move some type comment to proper annotation...
r52180 def precommit(
ui: "uimod.ui",
wctx: "context.workingcommitctx",
status: "scmutil.status",
match: "matchmod.basematcher",
force: bool = False,
) -> Tuple[List[bytes], Set[bytes], Substate]:
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 """Calculate .hgsubstate changes that should be applied before committing
Returns (subs, commitsubs, newstate) where
- subs: changed subrepos (including dirty ones)
- commitsubs: dirty subrepos which the caller needs to commit recursively
- newstate: new state dict which the caller must write to .hgsubstate
This also updates the given status argument.
"""
subs = []
commitsubs = set()
newstate = wctx.substate.copy()
# only manage subrepos and .hgsubstate if .hgsub is present
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'.hgsub' in wctx:
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 # we'll decide whether to track this ourselves, thanks
for c in status.modified, status.added, status.removed:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'.hgsubstate' in c:
c.remove(b'.hgsubstate')
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
# compare current state to last committed state
# build new substate based on last committed state
oldstate = wctx.p1().substate
for s in sorted(newstate.keys()):
if not match(s):
# ignore working copy, use old state if present
if s in oldstate:
newstate[s] = oldstate[s]
continue
if not force:
raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"commit with new subrepo %s excluded") % s
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 dirtyreason = wctx.sub(s).dirtyreason(True)
if dirtyreason:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not ui.configbool(b'ui', b'commitsubrepos'):
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
dirtyreason,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 hint=_(b"use --subrepos for recursive commit"),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 subs.append(s)
commitsubs.add(s)
else:
bs = wctx.sub(s).basestate()
newstate[s] = (newstate[s][0], bs, newstate[s][2])
if oldstate.get(s, (None, None, None))[1] != bs:
subs.append(s)
# check for removed subrepos
for p in wctx.parents():
r = [s for s in p.substate if s not in newstate]
subs += [s for s in r if match(s)]
if subs:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not match(b'.hgsub') and b'.hgsub' in (
Augie Fackler
formatting: blacken the codebase...
r43346 wctx.modified() + wctx.added()
):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"can't commit subrepos without .hgsub"))
status.modified.insert(0, b'.hgsubstate')
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif b'.hgsub' in status.removed:
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 # clean up .hgsubstate when .hgsub is removed
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'.hgsubstate' in wctx and b'.hgsubstate' not in (
Augie Fackler
formatting: blacken the codebase...
r43346 status.modified + status.added + status.removed
):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 status.removed.insert(0, b'.hgsubstate')
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
return subs, commitsubs, newstate
Augie Fackler
formatting: blacken the codebase...
r43346
subrepo: introduce a `repo_rel_or_abs_source` function...
r47691 def repo_rel_or_abs_source(repo):
"""return the source of this repo
Either absolute or relative the outermost repo"""
parent = repo
chunks = []
safehasattr: drop usage in favor of hasattr...
r51821 while hasattr(parent, '_subparent'):
subrepo: introduce a `repo_rel_or_abs_source` function...
r47691 source = urlutil.url(parent._subsource)
chunks.append(bytes(source))
if source.isabs():
break
parent = parent._subparent
chunks.reverse()
path = posixpath.join(*chunks)
Felipe Resende
subrepo: fix normalizing paths with scheme...
r52404 matchscheme = re.compile(b'^[a-zA-Z0-9+.\\-]+:').match
if matchscheme(path):
scheme, path = path.split(b':', 1)
if path.startswith(b'//'):
path = path[2:]
sep = b'//'
else:
sep = b''
normalized_path = scheme + b':' + sep + posixpath.normpath(path)
else:
normalized_path = posixpath.normpath(path)
return normalized_path
subrepo: introduce a `repo_rel_or_abs_source` function...
r47691
pytype: move some type comment to proper annotation...
r52180 def reporelpath(repo: "localrepo.localrepository") -> bytes:
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 """return path to this (sub)repo as seen from outermost repo"""
parent = repo
safehasattr: drop usage in favor of hasattr...
r51821 while hasattr(parent, '_subparent'):
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 parent = parent._subparent
Augie Fackler
formatting: blacken the codebase...
r43346 return repo.root[len(pathutil.normasprefix(parent.root)) :]
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
pytype: move some type comment to proper annotation...
r52180 def subrelpath(sub: "subrepo.abstractsubrepo") -> bytes:
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 """return path to this subrepo as seen from outermost repo"""
return sub._relpath
Augie Fackler
formatting: blacken the codebase...
r43346
pytype: move some type comment to proper annotation...
r52180 def _abssource(
repo: "localrepo.localrepository",
push: bool = False,
abort: bool = True,
) -> Optional[bytes]:
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 """return pull/push path of repo - either based on parent repo .hgsub info
or on the top repo config. Abort or return None if no source found."""
safehasattr: drop usage in favor of hasattr...
r51821 if hasattr(repo, '_subparent'):
urlutil: extract `url` related code from `util` into the new module...
r47669 source = urlutil.url(repo._subsource)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 if source.isabs():
return bytes(source)
source.path = posixpath.normpath(source.path)
parent = _abssource(repo._subparent, push, abort=False)
if parent:
urlutil: extract `url` related code from `util` into the new module...
r47669 parent = urlutil.url(util.pconvert(parent))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 parent.path = posixpath.join(parent.path or b'', source.path)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 parent.path = posixpath.normpath(parent.path)
return bytes(parent)
Augie Fackler
formatting: blacken the codebase...
r43346 else: # recursion reached top repo
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 path = None
safehasattr: drop usage in favor of hasattr...
r51821 if hasattr(repo, '_subtoppath'):
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 path = repo._subtoppath
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif push and repo.ui.config(b'paths', b'default-push'):
path = repo.ui.config(b'paths', b'default-push')
elif repo.ui.config(b'paths', b'default'):
path = repo.ui.config(b'paths', b'default')
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 elif repo.shared():
# chop off the .hg component to get the default path form. This has
# already run through vfsmod.vfs(..., realpath=True), so it doesn't
# have problems with 'C:'
return os.path.dirname(repo.sharedpath)
if path:
# issue5770: 'C:\' and 'C:' are not equivalent paths. The former is
# as expected: an absolute path to the root of the C: drive. The
# latter is a relative path, and works like so:
#
# C:\>cd C:\some\path
# C:\>D:
# D:\>python -c "import os; print os.path.abspath('C:')"
# C:\some\path
#
# D:\>python -c "import os; print os.path.abspath('C:relative')"
# C:\some\path\relative
urlutil: extract `url` related code from `util` into the new module...
r47669 if urlutil.hasdriveletter(path):
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 if len(path) == 2 or path[2:3] not in br'\/':
windows: use abspath in subrepoutil...
r48429 path = util.abspath(path)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 return path
if abort:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"default path for subrepository not found"))
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
Augie Fackler
formatting: blacken the codebase...
r43346
pytype: move some type comment to proper annotation...
r52180 def newcommitphase(ui: "uimod.ui", ctx: "context.changectx") -> int:
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 commitphase = phases.newcommitphase(ui)
substate = getattr(ctx, "substate", None)
if not substate:
return commitphase
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 check = ui.config(b'phases', b'checksubrepos')
if check not in (b'ignore', b'follow', b'abort'):
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'invalid phases.checksubrepos configuration: %s') % check
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if check == b'ignore':
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 return commitphase
maxphase = phases.public
maxsub = None
for s in sorted(substate):
sub = ctx.sub(s)
subphase = sub.phase(substate[s][1])
if maxphase < subphase:
maxphase = subphase
maxsub = s
if commitphase < maxphase:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if check == b'abort':
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"can't commit in %s phase"
b" conflicting %s from subrepository %s"
Augie Fackler
formatting: blacken the codebase...
r43346 )
% (
phases.phasenames[commitphase],
phases.phasenames[maxphase],
maxsub,
)
)
ui.warn(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"warning: changes are committed in"
b" %s phase from subrepository %s\n"
Augie Fackler
formatting: blacken the codebase...
r43346 )
% (phases.phasenames[maxphase], maxsub)
)
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 return maxphase
return commitphase