--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/commit.py Wed Jul 22 22:09:38 2020 -0400
@@ -0,0 +1,354 @@
+# commit.py - fonction to perform commit
+#
+# 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 weakref
+
+from .i18n import _
+from .node import (
+ hex,
+ nullid,
+ nullrev,
+)
+
+from . import (
+ context,
+ mergestate,
+ metadata,
+ phases,
+ scmutil,
+ subrepoutil,
+)
+
+
+def commitctx(repo, ctx, error=False, origctx=None):
+ """Add a new revision to the target repository.
+ Revision information is passed via the context argument.
+
+ ctx.files() should list all files involved in this commit, i.e.
+ modified/added/removed files. On merge, it may be wider than the
+ ctx.files() to be committed, since any file nodes derived directly
+ from p1 or p2 are excluded from the committed ctx.files().
+
+ origctx is for convert to work around the problem that bug
+ fixes to the files list in changesets change hashes. For
+ convert to be the identity, it can pass an origctx and this
+ function will use the same files list when it makes sense to
+ do so.
+ """
+ repo = repo.unfiltered()
+
+ p1, p2 = ctx.p1(), ctx.p2()
+ user = ctx.user()
+
+ if repo.filecopiesmode == b'changeset-sidedata':
+ writechangesetcopy = True
+ writefilecopymeta = True
+ writecopiesto = None
+ else:
+ writecopiesto = repo.ui.config(b'experimental', b'copies.write-to')
+ writefilecopymeta = writecopiesto != b'changeset-only'
+ writechangesetcopy = writecopiesto in (
+ b'changeset-only',
+ b'compatibility',
+ )
+ p1copies, p2copies = None, None
+ if writechangesetcopy:
+ p1copies = ctx.p1copies()
+ p2copies = ctx.p2copies()
+ filesadded, filesremoved = None, None
+ with repo.lock(), repo.transaction(b"commit") as tr:
+ trp = weakref.proxy(tr)
+
+ if ctx.manifestnode():
+ # reuse an existing manifest revision
+ repo.ui.debug(b'reusing known manifest\n')
+ mn = ctx.manifestnode()
+ files = ctx.files()
+ if writechangesetcopy:
+ filesadded = ctx.filesadded()
+ filesremoved = ctx.filesremoved()
+ elif not ctx.files():
+ repo.ui.debug(b'reusing manifest from p1 (no file change)\n')
+ mn = p1.manifestnode()
+ files = []
+ else:
+ m1ctx = p1.manifestctx()
+ m2ctx = p2.manifestctx()
+ mctx = m1ctx.copy()
+
+ m = mctx.read()
+ m1 = m1ctx.read()
+ m2 = m2ctx.read()
+
+ # check in files
+ added = []
+ filesadded = []
+ removed = list(ctx.removed())
+ touched = []
+ linkrev = len(repo)
+ repo.ui.note(_(b"committing files:\n"))
+ uipathfn = scmutil.getuipathfn(repo)
+ for f in sorted(ctx.modified() + ctx.added()):
+ repo.ui.note(uipathfn(f) + b"\n")
+ try:
+ fctx = ctx[f]
+ if fctx is None:
+ removed.append(f)
+ else:
+ added.append(f)
+ m[f], is_touched = _filecommit(
+ repo, fctx, m1, m2, linkrev, trp, writefilecopymeta,
+ )
+ if is_touched:
+ touched.append(f)
+ if writechangesetcopy and is_touched == 'added':
+ filesadded.append(f)
+ m.setflag(f, fctx.flags())
+ except OSError:
+ repo.ui.warn(_(b"trouble committing %s!\n") % uipathfn(f))
+ raise
+ except IOError as inst:
+ errcode = getattr(inst, 'errno', errno.ENOENT)
+ if error or errcode and errcode != errno.ENOENT:
+ repo.ui.warn(
+ _(b"trouble committing %s!\n") % uipathfn(f)
+ )
+ raise
+
+ # update manifest
+ removed = [f for f in removed if f in m1 or f in m2]
+ drop = sorted([f for f in removed if f in m])
+ for f in drop:
+ del m[f]
+ if p2.rev() != nullrev:
+ rf = metadata.get_removal_filter(ctx, (p1, p2, m1, m2))
+ removed = [f for f in removed if not rf(f)]
+
+ touched.extend(removed)
+
+ if writechangesetcopy:
+ filesremoved = removed
+
+ files = touched
+ md = None
+ if not files:
+ # if no "files" actually changed in terms of the changelog,
+ # try hard to detect unmodified manifest entry so that the
+ # exact same commit can be reproduced later on convert.
+ md = m1.diff(m, scmutil.matchfiles(repo, ctx.files()))
+ if not files and md:
+ repo.ui.debug(
+ b'not reusing manifest (no file change in '
+ b'changelog, but manifest differs)\n'
+ )
+ if files or md:
+ repo.ui.note(_(b"committing manifest\n"))
+ # we're using narrowmatch here since it's already applied at
+ # other stages (such as dirstate.walk), so we're already
+ # ignoring things outside of narrowspec in most cases. The
+ # one case where we might have files outside the narrowspec
+ # at this point is merges, and we already error out in the
+ # case where the merge has files outside of the narrowspec,
+ # so this is safe.
+ mn = mctx.write(
+ trp,
+ linkrev,
+ p1.manifestnode(),
+ p2.manifestnode(),
+ added,
+ drop,
+ match=repo.narrowmatch(),
+ )
+ else:
+ repo.ui.debug(
+ b'reusing manifest from p1 (listed files '
+ b'actually unchanged)\n'
+ )
+ mn = p1.manifestnode()
+
+ if writecopiesto == b'changeset-only':
+ # If writing only to changeset extras, use None to indicate that
+ # no entry should be written. If writing to both, write an empty
+ # entry to prevent the reader from falling back to reading
+ # filelogs.
+ p1copies = p1copies or None
+ p2copies = p2copies or None
+ filesadded = filesadded or None
+ filesremoved = filesremoved or None
+
+ if origctx and origctx.manifestnode() == mn:
+ files = origctx.files()
+
+ # update changelog
+ repo.ui.note(_(b"committing changelog\n"))
+ repo.changelog.delayupdate(tr)
+ n = repo.changelog.add(
+ mn,
+ files,
+ ctx.description(),
+ trp,
+ p1.node(),
+ p2.node(),
+ user,
+ ctx.date(),
+ ctx.extra().copy(),
+ p1copies,
+ p2copies,
+ filesadded,
+ filesremoved,
+ )
+ xp1, xp2 = p1.hex(), p2 and p2.hex() or b''
+ repo.hook(
+ b'pretxncommit', throw=True, node=hex(n), parent1=xp1, parent2=xp2,
+ )
+ # set the new commit is proper phase
+ targetphase = subrepoutil.newcommitphase(repo.ui, ctx)
+ if targetphase:
+ # retract boundary do not alter parent changeset.
+ # if a parent have higher the resulting phase will
+ # be compliant anyway
+ #
+ # if minimal phase was 0 we don't need to retract anything
+ phases.registernew(repo, tr, targetphase, [n])
+ return n
+
+
+def _filecommit(
+ repo, fctx, manifest1, manifest2, linkrev, tr, includecopymeta,
+):
+ """
+ commit an individual file as part of a larger transaction
+
+ input:
+
+ fctx: a file context with the content we are trying to commit
+ manifest1: manifest of changeset first parent
+ manifest2: manifest of changeset second parent
+ linkrev: revision number of the changeset being created
+ tr: current transation
+ individual: boolean, set to False to skip storing the copy data
+ (only used by the Google specific feature of using
+ changeset extra as copy source of truth).
+
+ output: (filenode, touched)
+
+ filenode: the filenode that should be used by this changeset
+ touched: one of: None, 'added' or 'modified'
+ """
+
+ fname = fctx.path()
+ fparent1 = manifest1.get(fname, nullid)
+ fparent2 = manifest2.get(fname, nullid)
+ touched = None
+ if fparent1 == fparent2 == nullid:
+ touched = 'added'
+
+ if isinstance(fctx, context.filectx):
+ # This block fast path most comparisons which are usually done. It
+ # assumes that bare filectx is used and no merge happened, hence no
+ # need to create a new file revision in this case.
+ node = fctx.filenode()
+ if node in [fparent1, fparent2]:
+ repo.ui.debug(b'reusing %s filelog entry\n' % fname)
+ if (
+ fparent1 != nullid and manifest1.flags(fname) != fctx.flags()
+ ) or (
+ fparent2 != nullid and manifest2.flags(fname) != fctx.flags()
+ ):
+ touched = 'modified'
+ return node, touched
+
+ flog = repo.file(fname)
+ meta = {}
+ cfname = fctx.copysource()
+ fnode = None
+
+ if cfname and cfname != fname:
+ # Mark the new revision of this file as a copy of another
+ # file. This copy data will effectively act as a parent
+ # of this new revision. If this is a merge, the first
+ # parent will be the nullid (meaning "look up the copy data")
+ # and the second one will be the other parent. For example:
+ #
+ # 0 --- 1 --- 3 rev1 changes file foo
+ # \ / rev2 renames foo to bar and changes it
+ # \- 2 -/ rev3 should have bar with all changes and
+ # should record that bar descends from
+ # bar in rev2 and foo in rev1
+ #
+ # this allows this merge to succeed:
+ #
+ # 0 --- 1 --- 3 rev4 reverts the content change from rev2
+ # \ / merging rev3 and rev4 should use bar@rev2
+ # \- 2 --- 4 as the merge base
+ #
+
+ cnode = manifest1.get(cfname)
+ newfparent = fparent2
+
+ if manifest2: # branch merge
+ if fparent2 == nullid or cnode is None: # copied on remote side
+ if cfname in manifest2:
+ cnode = manifest2[cfname]
+ newfparent = fparent1
+
+ # Here, we used to search backwards through history to try to find
+ # where the file copy came from if the source of a copy was not in
+ # the parent directory. However, this doesn't actually make sense to
+ # do (what does a copy from something not in your working copy even
+ # mean?) and it causes bugs (eg, issue4476). Instead, we will warn
+ # the user that copy information was dropped, so if they didn't
+ # expect this outcome it can be fixed, but this is the correct
+ # behavior in this circumstance.
+
+ if cnode:
+ repo.ui.debug(b" %s: copy %s:%s\n" % (fname, cfname, hex(cnode)))
+ if includecopymeta:
+ meta[b"copy"] = cfname
+ meta[b"copyrev"] = hex(cnode)
+ fparent1, fparent2 = nullid, newfparent
+ else:
+ repo.ui.warn(
+ _(
+ b"warning: can't find ancestor for '%s' "
+ b"copied from '%s'!\n"
+ )
+ % (fname, cfname)
+ )
+
+ elif fparent1 == nullid:
+ fparent1, fparent2 = fparent2, nullid
+ elif fparent2 != nullid:
+ # is one parent an ancestor of the other?
+ fparentancestors = flog.commonancestorsheads(fparent1, fparent2)
+ if fparent1 in fparentancestors:
+ fparent1, fparent2 = fparent2, nullid
+ elif fparent2 in fparentancestors:
+ fparent2 = nullid
+ elif not fparentancestors:
+ # TODO: this whole if-else might be simplified much more
+ ms = mergestate.mergestate.read(repo)
+ if (
+ fname in ms
+ and ms[fname] == mergestate.MERGE_RECORD_MERGED_OTHER
+ ):
+ fparent1, fparent2 = fparent2, nullid
+
+ # is the file changed?
+ text = fctx.data()
+ if fparent2 != nullid or meta or flog.cmp(fparent1, text):
+ if touched is None: # do not overwrite added
+ touched = 'modified'
+ fnode = flog.add(text, meta, tr, linkrev, fparent1, fparent2)
+ # are just the flags changed during merge?
+ elif fname in manifest1 and manifest1.flags(fname) != fctx.flags():
+ touched = 'modified'
+ fnode = fparent1
+ else:
+ fnode = fparent1
+ return fnode, touched
--- a/mercurial/debugcommands.py Tue Jul 21 01:04:19 2020 +0200
+++ b/mercurial/debugcommands.py Wed Jul 22 22:09:38 2020 -0400
@@ -1668,8 +1668,8 @@
fm.data(re2=bool(util._re2))
# templates
- p = templater.templatepaths()
- fm.write(b'templatedirs', b'checking templates (%s)...\n', b' '.join(p))
+ p = templater.templatedir()
+ fm.write(b'templatedirs', b'checking templates (%s)...\n', p)
fm.condwrite(not p, b'', _(b" no template directories found\n"))
if p:
m = templater.templatepath(b"map-cmdline.default")
--- a/mercurial/hgweb/hgwebdir_mod.py Tue Jul 21 01:04:19 2020 +0200
+++ b/mercurial/hgweb/hgwebdir_mod.py Wed Jul 22 22:09:38 2020 -0400
@@ -414,10 +414,8 @@
fname = req.qsparams[b'static']
static = self.ui.config(b"web", b"static", untrusted=False)
if not static:
- tp = self.templatepath or templater.templatepaths()
- if isinstance(tp, bytes):
- tp = [tp]
- static = [os.path.join(p, b'static') for p in tp]
+ tp = self.templatepath or templater.templatedir()
+ static = [os.path.join(tp, b'static')]
staticfile(static, fname, res)
return res.sendresponse()
--- a/mercurial/hgweb/webcommands.py Tue Jul 21 01:04:19 2020 +0200
+++ b/mercurial/hgweb/webcommands.py Wed Jul 22 22:09:38 2020 -0400
@@ -1319,10 +1319,8 @@
# readable by the user running the CGI script
static = web.config(b"web", b"static", untrusted=False)
if not static:
- tp = web.templatepath or templater.templatepaths()
- if isinstance(tp, bytes):
- tp = [tp]
- static = [os.path.join(p, b'static') for p in tp]
+ tp = web.templatepath or templater.templatedir()
+ static = [os.path.join(tp, b'static')]
staticfile(static, fname, web.res)
return web.res.sendresponse()
--- a/mercurial/localrepo.py Tue Jul 21 01:04:19 2020 +0200
+++ b/mercurial/localrepo.py Wed Jul 22 22:09:38 2020 -0400
@@ -32,6 +32,7 @@
bundle2,
changegroup,
color,
+ commit,
context,
dirstate,
dirstateguard,
@@ -46,7 +47,6 @@
match as matchmod,
mergestate as mergestatemod,
mergeutil,
- metadata,
namespaces,
narrowspec,
obsolete,
@@ -2771,140 +2771,6 @@
"""Returns the wlock if it's held, or None if it's not."""
return self._currentlock(self._wlockref)
- def _filecommit(
- self,
- fctx,
- manifest1,
- manifest2,
- linkrev,
- tr,
- changelist,
- includecopymeta,
- ):
- """
- commit an individual file as part of a larger transaction
-
- input:
-
- fctx: a file context with the content we are trying to commit
- manifest1: manifest of changeset first parent
- manifest2: manifest of changeset second parent
- linkrev: revision number of the changeset being created
- tr: current transation
- changelist: list of file being changed (modified inplace)
- individual: boolean, set to False to skip storing the copy data
- (only used by the Google specific feature of using
- changeset extra as copy source of truth).
-
- output:
-
- The resulting filenode
- """
-
- fname = fctx.path()
- fparent1 = manifest1.get(fname, nullid)
- fparent2 = manifest2.get(fname, nullid)
- if isinstance(fctx, context.filectx):
- node = fctx.filenode()
- if node in [fparent1, fparent2]:
- self.ui.debug(b'reusing %s filelog entry\n' % fname)
- if (
- fparent1 != nullid
- and manifest1.flags(fname) != fctx.flags()
- ) or (
- fparent2 != nullid
- and manifest2.flags(fname) != fctx.flags()
- ):
- changelist.append(fname)
- return node
-
- flog = self.file(fname)
- meta = {}
- cfname = fctx.copysource()
- if cfname and cfname != fname:
- # Mark the new revision of this file as a copy of another
- # file. This copy data will effectively act as a parent
- # of this new revision. If this is a merge, the first
- # parent will be the nullid (meaning "look up the copy data")
- # and the second one will be the other parent. For example:
- #
- # 0 --- 1 --- 3 rev1 changes file foo
- # \ / rev2 renames foo to bar and changes it
- # \- 2 -/ rev3 should have bar with all changes and
- # should record that bar descends from
- # bar in rev2 and foo in rev1
- #
- # this allows this merge to succeed:
- #
- # 0 --- 1 --- 3 rev4 reverts the content change from rev2
- # \ / merging rev3 and rev4 should use bar@rev2
- # \- 2 --- 4 as the merge base
- #
-
- cnode = manifest1.get(cfname)
- newfparent = fparent2
-
- if manifest2: # branch merge
- if fparent2 == nullid or cnode is None: # copied on remote side
- if cfname in manifest2:
- cnode = manifest2[cfname]
- newfparent = fparent1
-
- # Here, we used to search backwards through history to try to find
- # where the file copy came from if the source of a copy was not in
- # the parent directory. However, this doesn't actually make sense to
- # do (what does a copy from something not in your working copy even
- # mean?) and it causes bugs (eg, issue4476). Instead, we will warn
- # the user that copy information was dropped, so if they didn't
- # expect this outcome it can be fixed, but this is the correct
- # behavior in this circumstance.
-
- if cnode:
- self.ui.debug(
- b" %s: copy %s:%s\n" % (fname, cfname, hex(cnode))
- )
- if includecopymeta:
- meta[b"copy"] = cfname
- meta[b"copyrev"] = hex(cnode)
- fparent1, fparent2 = nullid, newfparent
- else:
- self.ui.warn(
- _(
- b"warning: can't find ancestor for '%s' "
- b"copied from '%s'!\n"
- )
- % (fname, cfname)
- )
-
- elif fparent1 == nullid:
- fparent1, fparent2 = fparent2, nullid
- elif fparent2 != nullid:
- # is one parent an ancestor of the other?
- fparentancestors = flog.commonancestorsheads(fparent1, fparent2)
- if fparent1 in fparentancestors:
- fparent1, fparent2 = fparent2, nullid
- elif fparent2 in fparentancestors:
- fparent2 = nullid
- elif not fparentancestors:
- # TODO: this whole if-else might be simplified much more
- ms = mergestatemod.mergestate.read(self)
- if (
- fname in ms
- and ms[fname] == mergestatemod.MERGE_RECORD_MERGED_OTHER
- ):
- fparent1, fparent2 = fparent2, nullid
-
- # is the file changed?
- text = fctx.data()
- if fparent2 != nullid or meta or flog.cmp(fparent1, text):
- changelist.append(fname)
- return flog.add(text, meta, tr, linkrev, fparent1, fparent2)
- # are just the flags changed during merge?
- elif fname in manifest1 and manifest1.flags(fname) != fctx.flags():
- changelist.append(fname)
-
- return fparent1
-
def checkcommitpatterns(self, wctx, match, status, fail):
"""check for commit arguments that aren't committable"""
if match.isexact() or match.prefix():
@@ -3062,203 +2928,7 @@
@unfilteredmethod
def commitctx(self, ctx, error=False, origctx=None):
- """Add a new revision to current repository.
- Revision information is passed via the context argument.
-
- ctx.files() should list all files involved in this commit, i.e.
- modified/added/removed files. On merge, it may be wider than the
- ctx.files() to be committed, since any file nodes derived directly
- from p1 or p2 are excluded from the committed ctx.files().
-
- origctx is for convert to work around the problem that bug
- fixes to the files list in changesets change hashes. For
- convert to be the identity, it can pass an origctx and this
- function will use the same files list when it makes sense to
- do so.
- """
-
- p1, p2 = ctx.p1(), ctx.p2()
- user = ctx.user()
-
- if self.filecopiesmode == b'changeset-sidedata':
- writechangesetcopy = True
- writefilecopymeta = True
- writecopiesto = None
- else:
- writecopiesto = self.ui.config(b'experimental', b'copies.write-to')
- writefilecopymeta = writecopiesto != b'changeset-only'
- writechangesetcopy = writecopiesto in (
- b'changeset-only',
- b'compatibility',
- )
- p1copies, p2copies = None, None
- if writechangesetcopy:
- p1copies = ctx.p1copies()
- p2copies = ctx.p2copies()
- filesadded, filesremoved = None, None
- with self.lock(), self.transaction(b"commit") as tr:
- trp = weakref.proxy(tr)
-
- if ctx.manifestnode():
- # reuse an existing manifest revision
- self.ui.debug(b'reusing known manifest\n')
- mn = ctx.manifestnode()
- files = ctx.files()
- if writechangesetcopy:
- filesadded = ctx.filesadded()
- filesremoved = ctx.filesremoved()
- elif ctx.files():
- m1ctx = p1.manifestctx()
- m2ctx = p2.manifestctx()
- mctx = m1ctx.copy()
-
- m = mctx.read()
- m1 = m1ctx.read()
- m2 = m2ctx.read()
-
- # check in files
- added = []
- changed = []
- removed = list(ctx.removed())
- linkrev = len(self)
- self.ui.note(_(b"committing files:\n"))
- uipathfn = scmutil.getuipathfn(self)
- for f in sorted(ctx.modified() + ctx.added()):
- self.ui.note(uipathfn(f) + b"\n")
- try:
- fctx = ctx[f]
- if fctx is None:
- removed.append(f)
- else:
- added.append(f)
- m[f] = self._filecommit(
- fctx,
- m1,
- m2,
- linkrev,
- trp,
- changed,
- writefilecopymeta,
- )
- m.setflag(f, fctx.flags())
- except OSError:
- self.ui.warn(
- _(b"trouble committing %s!\n") % uipathfn(f)
- )
- raise
- except IOError as inst:
- errcode = getattr(inst, 'errno', errno.ENOENT)
- if error or errcode and errcode != errno.ENOENT:
- self.ui.warn(
- _(b"trouble committing %s!\n") % uipathfn(f)
- )
- raise
-
- # update manifest
- removed = [f for f in removed if f in m1 or f in m2]
- drop = sorted([f for f in removed if f in m])
- for f in drop:
- del m[f]
- if p2.rev() != nullrev:
- rf = metadata.get_removal_filter(ctx, (p1, p2, m1, m2))
- removed = [f for f in removed if not rf(f)]
-
- files = changed + removed
- md = None
- if not files:
- # if no "files" actually changed in terms of the changelog,
- # try hard to detect unmodified manifest entry so that the
- # exact same commit can be reproduced later on convert.
- md = m1.diff(m, scmutil.matchfiles(self, ctx.files()))
- if not files and md:
- self.ui.debug(
- b'not reusing manifest (no file change in '
- b'changelog, but manifest differs)\n'
- )
- if files or md:
- self.ui.note(_(b"committing manifest\n"))
- # we're using narrowmatch here since it's already applied at
- # other stages (such as dirstate.walk), so we're already
- # ignoring things outside of narrowspec in most cases. The
- # one case where we might have files outside the narrowspec
- # at this point is merges, and we already error out in the
- # case where the merge has files outside of the narrowspec,
- # so this is safe.
- mn = mctx.write(
- trp,
- linkrev,
- p1.manifestnode(),
- p2.manifestnode(),
- added,
- drop,
- match=self.narrowmatch(),
- )
-
- if writechangesetcopy:
- filesadded = [
- f for f in changed if not (f in m1 or f in m2)
- ]
- filesremoved = removed
- else:
- self.ui.debug(
- b'reusing manifest from p1 (listed files '
- b'actually unchanged)\n'
- )
- mn = p1.manifestnode()
- else:
- self.ui.debug(b'reusing manifest from p1 (no file change)\n')
- mn = p1.manifestnode()
- files = []
-
- if writecopiesto == b'changeset-only':
- # If writing only to changeset extras, use None to indicate that
- # no entry should be written. If writing to both, write an empty
- # entry to prevent the reader from falling back to reading
- # filelogs.
- p1copies = p1copies or None
- p2copies = p2copies or None
- filesadded = filesadded or None
- filesremoved = filesremoved or None
-
- if origctx and origctx.manifestnode() == mn:
- files = origctx.files()
-
- # update changelog
- self.ui.note(_(b"committing changelog\n"))
- self.changelog.delayupdate(tr)
- n = self.changelog.add(
- mn,
- files,
- ctx.description(),
- trp,
- p1.node(),
- p2.node(),
- user,
- ctx.date(),
- ctx.extra().copy(),
- p1copies,
- p2copies,
- filesadded,
- filesremoved,
- )
- xp1, xp2 = p1.hex(), p2 and p2.hex() or b''
- self.hook(
- b'pretxncommit',
- throw=True,
- node=hex(n),
- parent1=xp1,
- parent2=xp2,
- )
- # set the new commit is proper phase
- targetphase = subrepoutil.newcommitphase(self.ui, ctx)
- if targetphase:
- # retract boundary do not alter parent changeset.
- # if a parent have higher the resulting phase will
- # be compliant anyway
- #
- # if minimal phase was 0 we don't need to retract anything
- phases.registernew(self, tr, targetphase, [n])
- return n
+ return commit.commitctx(self, ctx, error=error, origctx=origctx)
@unfilteredmethod
def destroying(self):
--- a/mercurial/templater.py Tue Jul 21 01:04:19 2020 +0200
+++ b/mercurial/templater.py Wed Jul 22 22:09:38 2020 -0400
@@ -800,10 +800,10 @@
def stylelist():
- paths = templatepaths()
- if not paths:
+ path = templatedir()
+ if not path:
return _(b'no templates found, try `hg debuginstall` for more info')
- dirlist = os.listdir(paths[0])
+ dirlist = os.listdir(path)
stylelist = []
for file in dirlist:
split = file.split(b".")
@@ -823,7 +823,7 @@
)
base = os.path.dirname(mapfile)
- conf = config.config(includepaths=templatepaths())
+ conf = config.config(includepaths=[templatedir()])
conf.read(mapfile, remap={b'': b'templates'})
cache = {}
@@ -837,15 +837,13 @@
# fallback check in template paths
if not os.path.exists(path):
- for p in templatepaths():
- p2 = util.normpath(os.path.join(p, val))
- if os.path.isfile(p2):
- path = p2
- break
+ p2 = util.normpath(os.path.join(templatedir(), val))
+ if os.path.isfile(p2):
+ path = p2
+ else:
p3 = util.normpath(os.path.join(p2, b"map"))
if os.path.isfile(p3):
path = p3
- break
cache, tmap, aliases = _readmapfile(path)
@@ -1045,26 +1043,21 @@
return stream
-def templatepaths():
- '''return locations used for template files.'''
- pathsrel = [b'templates']
- paths = [
- os.path.normpath(os.path.join(resourceutil.datapath, f))
- for f in pathsrel
- ]
- return [p for p in paths if os.path.isdir(p)]
+def templatedir():
+ '''return the directory used for template files, or None.'''
+ path = os.path.normpath(os.path.join(resourceutil.datapath, b'templates'))
+ return path if os.path.isdir(path) else None
def templatepath(name):
'''return location of template file. returns None if not found.'''
- for p in templatepaths():
- f = os.path.join(p, name)
- if os.path.exists(f):
- return f
+ f = os.path.join(templatedir(), name)
+ if f and os.path.exists(f):
+ return f
return None
-def stylemap(styles, paths=None):
+def stylemap(styles, path=None):
"""Return path to mapfile for a given style.
Searches mapfile in the following locations:
@@ -1073,10 +1066,8 @@
3. templatepath/map
"""
- if paths is None:
- paths = templatepaths()
- elif isinstance(paths, bytes):
- paths = [paths]
+ if path is None:
+ path = templatedir()
if isinstance(styles, bytes):
styles = [styles]
@@ -1094,10 +1085,9 @@
locations = [os.path.join(style, b'map'), b'map-' + style]
locations.append(b'map')
- for path in paths:
- for location in locations:
- mapfile = os.path.join(path, location)
- if os.path.isfile(mapfile):
- return style, mapfile
+ for location in locations:
+ mapfile = os.path.join(path, location)
+ if os.path.isfile(mapfile):
+ return style, mapfile
- raise RuntimeError(b"No hgweb templates found in %r" % paths)
+ raise RuntimeError(b"No hgweb templates found in %r" % path)
--- a/tests/test-annotate.t Tue Jul 21 01:04:19 2020 +0200
+++ b/tests/test-annotate.t Wed Jul 22 22:09:38 2020 -0400
@@ -479,26 +479,24 @@
$ cat > ../legacyrepo.py <<EOF
> from __future__ import absolute_import
- > from mercurial import error, node
- > def reposetup(ui, repo):
- > class legacyrepo(repo.__class__):
- > def _filecommit(self, fctx, manifest1, manifest2,
- > linkrev, tr, changelist, includecopymeta):
- > fname = fctx.path()
- > text = fctx.data()
- > flog = self.file(fname)
- > fparent1 = manifest1.get(fname, node.nullid)
- > fparent2 = manifest2.get(fname, node.nullid)
- > meta = {}
- > copy = fctx.copysource()
- > if copy and copy != fname:
- > raise error.Abort('copying is not supported')
- > if fparent2 != node.nullid:
- > changelist.append(fname)
- > return flog.add(text, meta, tr, linkrev,
- > fparent1, fparent2)
- > raise error.Abort('only merging is supported')
- > repo.__class__ = legacyrepo
+ > from mercurial import commit, error, extensions, node
+ > def _filecommit(orig, repo, fctx, manifest1, manifest2,
+ > linkrev, tr, includecopymeta):
+ > fname = fctx.path()
+ > text = fctx.data()
+ > flog = repo.file(fname)
+ > fparent1 = manifest1.get(fname, node.nullid)
+ > fparent2 = manifest2.get(fname, node.nullid)
+ > meta = {}
+ > copy = fctx.copysource()
+ > if copy and copy != fname:
+ > raise error.Abort('copying is not supported')
+ > if fparent2 != node.nullid:
+ > return flog.add(text, meta, tr, linkrev,
+ > fparent1, fparent2), 'modified'
+ > raise error.Abort('only merging is supported')
+ > def uisetup(ui):
+ > extensions.wrapfunction(commit, '_filecommit', _filecommit)
> EOF
$ cat > baz <<EOF
--- a/tests/test-fastannotate-hg.t Tue Jul 21 01:04:19 2020 +0200
+++ b/tests/test-fastannotate-hg.t Wed Jul 22 22:09:38 2020 -0400
@@ -481,26 +481,25 @@
and its ancestor by overriding "repo._filecommit".
$ cat > ../legacyrepo.py <<EOF
- > from mercurial import error, node
- > def reposetup(ui, repo):
- > class legacyrepo(repo.__class__):
- > def _filecommit(self, fctx, manifest1, manifest2,
- > linkrev, tr, changelist, includecopymeta):
- > fname = fctx.path()
- > text = fctx.data()
- > flog = self.file(fname)
- > fparent1 = manifest1.get(fname, node.nullid)
- > fparent2 = manifest2.get(fname, node.nullid)
- > meta = {}
- > copy = fctx.renamed()
- > if copy and copy[0] != fname:
- > raise error.Abort('copying is not supported')
- > if fparent2 != node.nullid:
- > changelist.append(fname)
- > return flog.add(text, meta, tr, linkrev,
- > fparent1, fparent2)
- > raise error.Abort('only merging is supported')
- > repo.__class__ = legacyrepo
+ > from __future__ import absolute_import
+ > from mercurial import commit, error, extensions, node
+ > def _filecommit(orig, repo, fctx, manifest1, manifest2,
+ > linkrev, tr, includecopymeta):
+ > fname = fctx.path()
+ > text = fctx.data()
+ > flog = repo.file(fname)
+ > fparent1 = manifest1.get(fname, node.nullid)
+ > fparent2 = manifest2.get(fname, node.nullid)
+ > meta = {}
+ > copy = fctx.copysource()
+ > if copy and copy != fname:
+ > raise error.Abort('copying is not supported')
+ > if fparent2 != node.nullid:
+ > return flog.add(text, meta, tr, linkrev,
+ > fparent1, fparent2), 'modified'
+ > raise error.Abort('only merging is supported')
+ > def uisetup(ui):
+ > extensions.wrapfunction(commit, '_filecommit', _filecommit)
> EOF
$ cat > baz <<EOF