##// END OF EJS Templates
mergetools: add new conflict marker format with diffs in...
mergetools: add new conflict marker format with diffs in I use 3-way conflict markers. Often when I resolve them, I manually compare one the base with one side and apply the differences to the other side. That can be hard when the conflict marker is large. This patch introduces a new type of conflict marker, which I'm hoping will make it easier to resolve conflicts. The new format uses `<<<<<<<` and `>>>>>>>` to open and close the markers, just like our existing 2-way and 3-way conflict markers. Instead of having 2 or 3 snapshots (left+right or left+base+right), it has a sequence of diffs. A diff looks like this: ``` ------- base +++++++ left a -b +c d ``` A diff that adds one side ("diff from nothing") has a `=======` header instead and does not have have `+` prefixed on its lines. A regular 3-way merge can be viewed as adding one side plus a diff between the base and the other side. It thus has two ways of being represented, depending on which side is being diffed: ``` <<<<<<< ======= left contents on left ------- base +++++++ right contents on -left +right >>>>>>> ``` or ``` <<<<<<< ------- base +++++++ left contents on -right +left ======= right contents on right >>>>>>> ``` I've made it so the new merge tool tries to pick a version that has the most common lines (no difference in the example above). I've called the new tool "mergediff" to stick to the convention of starting with "merge" if the tool tries a regular 3-way merge. The idea came from my pet VCS (placeholder name `jj`), which has support for octopus merges and other ways of ending up with merges of more than 3 versions. I wanted to be able to represent such conflicts in the working copy and therefore thought of this format (although I have not yet implemented it in my VCS). I then attended a meeting with Larry McVoy, who said BitKeeper has an option (`bk smerge -g`) for showing a similar format, which reminded me to actually attempt this in Mercurial. Differential Revision: https://phab.mercurial-scm.org/D9551

File last commit:

r45817:668af67b default
r46724:bdc2bf68 default
Show More
subrepoutil.py
459 lines | 15.9 KiB | text/x-python | PythonLexer
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 # subrepoutil.py - sub-repository operations and substate handling
#
# Copyright 2009-2010 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from __future__ import absolute_import
import errno
import os
import posixpath
import re
from .i18n import _
Gregory Szorc
py3: manually import getattr where it is needed...
r43359 from .pycompat import getattr
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 from . import (
config,
error,
filemerge,
pathutil,
phases,
Gregory Szorc
py3: finish porting iteritems() to pycompat and remove source transformer...
r43376 pycompat,
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 util,
)
Augie Fackler
formatting: blacken the codebase...
r43346 from .utils import stringutil
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026
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
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 def state(ctx, ui):
"""return a state dict, mapping subrepo paths configured in .hgsub
to tuple: (source from .hgsub, revision from .hgsubstate, kind
(key in types dict))
"""
p = config.config()
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()
except IOError as err:
if err.errno != errno.ENOENT:
raise
# 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
except IOError as err:
if err.errno != errno.ENOENT:
raise
def remap(src):
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:
src = re.sub(pattern, repl, src, 1)
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 = {}
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for path, src in p[b''].items():
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
if not util.url(src).isabs():
parent = _abssource(repo, abort=False)
if parent:
parent = util.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
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 def writestate(repo, state):
"""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
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 def submerge(repo, wctx, mctx, actx, overwrite, labels=None):
"""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
py3: finish porting iteritems() to pycompat and remove source transformer...
r43376 for s, l in sorted(pycompat.iteritems(s1)):
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
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 def precommit(ui, wctx, status, match, force=False):
"""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
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 def reporelpath(repo):
"""return path to this (sub)repo as seen from outermost repo"""
parent = repo
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 while util.safehasattr(parent, b'_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
def subrelpath(sub):
"""return path to this subrepo as seen from outermost repo"""
return sub._relpath
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 def _abssource(repo, push=False, abort=True):
"""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."""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if util.safehasattr(repo, b'_subparent'):
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 source = util.url(repo._subsource)
if source.isabs():
return bytes(source)
source.path = posixpath.normpath(source.path)
parent = _abssource(repo._subparent, push, abort=False)
if parent:
parent = util.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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if util.safehasattr(repo, b'_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
if util.hasdriveletter(path):
if len(path) == 2 or path[2:3] not in br'\/':
path = os.path.abspath(path)
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
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 def newcommitphase(ui, ctx):
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