##// END OF EJS Templates
revert: remove dangerous `parents` argument from `cmdutil.revert()`...
revert: remove dangerous `parents` argument from `cmdutil.revert()` As we found out the hard way (thanks to spectral@ for figuring it out!), `cmdutil.revert()`'s `parents` argument must be `repo.dirstate.parents()` or things may go wrong. We had an extension that passed in the target commit as the first parent. The `hg split` command from the evolve extension seems to have made the same mistake, but I haven't looked carefully. The problem is that `cmdutil._performrevert()` calls `dirstate.normal()` on reverted files if the commit to revert to equals the first parent. So if you pass in `ctx=foo` and `parents=(foo.node(), nullid)`, then `dirstate.normal()` will be called for the revert files, even though they might not be clean in the working copy. There doesn't seem to be any reason, other than a tiny performance benefit, to passing the `parents` around instead of looking them up again in `cmdutil._performrevert()`, so that's what this patch does. Differential Revision: https://phab.mercurial-scm.org/D8925

File last commit:

r44937:9d2b2df2 default
r45935:8c466bcb default
Show More
transplant.py
929 lines | 30.4 KiB | text/x-python | PythonLexer
Brendan Cully
Add transplant extension
r3714 # Patch transplanting extension for Mercurial
#
Thomas Arendsen Hein
Updated copyright notices and add "and others" to "hg version"
r4635 # Copyright 2006, 2007 Brendan Cully <brendan@kublai.com>
Brendan Cully
Add transplant extension
r3714 #
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # 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.
Brendan Cully
Add transplant extension
r3714
Dirkjan Ochtman
extensions: change descriptions for extensions providing a few commands
r8934 '''command to transplant changesets from another branch
Brendan Cully
Add transplant extension
r3714
Mads Kiilerich
transplant: improve documentation
r19028 This extension allows you to transplant changes to another parent revision,
possibly in another repository. The transplant is done using 'diff' patches.
Brendan Cully
Add transplant extension
r3714
Martin Geisler
transplant: word-wrap help texts at 70 characters
r8000 Transplanted patches are recorded in .hg/transplant/transplants, as a
map from a changeset hash to its hash in the source repository.
Brendan Cully
Add transplant extension
r3714 '''
timeless
transplant: use absolute_import
r28481 from __future__ import absolute_import
Brendan Cully
Add transplant extension
r3714
timeless
transplant: use absolute_import
r28481 import os
Yuya Nishihara
py3: wrap tempfile.mkstemp() to use bytes path...
r38182
Dirkjan Ochtman
transplant: move docstrings before imports (see issue1466)
r7629 from mercurial.i18n import _
Gregory Szorc
py3: manually import pycompat.open into files that need it...
r43355 from mercurial.pycompat import open
timeless
transplant: use absolute_import
r28481 from mercurial import (
bundlerepo,
cmdutil,
error,
exchange,
hg,
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 logcmdutil,
timeless
transplant: use absolute_import
r28481 match,
merge,
node as nodemod,
patch,
Pulkit Goyal
py3: convert the mode argument of os.fdopen to unicodes (2 of 2)
r30925 pycompat,
timeless
transplant: use absolute_import
r28481 registrar,
revlog,
revset,
scmutil,
Yuya Nishihara
revset: import set classes directly from smartset module...
r31023 smartset,
Taapas Agrawal
states: moved cmdutil.unfinishedstates to state.py...
r42729 state as statemod,
timeless
transplant: use absolute_import
r28481 util,
Pierre-Yves David
vfs: use 'vfs' module directly in 'hgext.transplant'...
r31245 vfs as vfsmod,
timeless
transplant: use absolute_import
r28481 )
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 from mercurial.utils import (
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,
)
Dirkjan Ochtman
transplant: move docstrings before imports (see issue1466)
r7629
Augie Fackler
formatting: blacken the codebase...
r43346
Patrick Mezard
transplant: do not rollback on patching error (issue3379)...
r16507 class TransplantError(error.Abort):
pass
Augie Fackler
formatting: blacken the codebase...
r43346
Adrian Buehlmann
transplant: use cmdutil.command decorator
r14308 cmdtable = {}
Yuya Nishihara
registrar: move cmdutil.command to registrar module (API)...
r32337 command = registrar.command(cmdtable)
Augie Fackler
extensions: change magic "shipped with hg" string...
r29841 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
Augie Fackler
extensions: document that `testedwith = 'internal'` is special...
r25186 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
# be specifying the version(s) of Mercurial they are tested with, or
# leave the attribute unspecified.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 testedwith = b'ships-with-hg-core'
Adrian Buehlmann
transplant: use cmdutil.command decorator
r14308
Boris Feld
configitems: register the 'transplant.filter' config
r34470 configtable = {}
configitem = registrar.configitem(configtable)
Augie Fackler
formatting: blacken the codebase...
r43346 configitem(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'transplant', b'filter', default=None,
Boris Feld
configitems: register the 'transplant.filter' config
r34470 )
Augie Fackler
formatting: blacken the codebase...
r43346 configitem(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'transplant', b'log', default=None,
Boris Feld
configitems: register the 'transplant.log' config
r34471 )
Boris Feld
configitems: register the 'transplant.filter' config
r34470
Augie Fackler
formatting: blacken the codebase...
r43346
Benoit Boissinot
use new style classes
r8778 class transplantentry(object):
Brendan Cully
Add transplant extension
r3714 def __init__(self, lnode, rnode):
self.lnode = lnode
self.rnode = rnode
Augie Fackler
formatting: blacken the codebase...
r43346
Benoit Boissinot
use new style classes
r8778 class transplants(object):
Brendan Cully
Add transplant extension
r3714 def __init__(self, path=None, transplantfile=None, opener=None):
self.path = path
self.transplantfile = transplantfile
self.opener = opener
if not opener:
Pierre-Yves David
vfs: use 'vfs' module directly in 'hgext.transplant'...
r31245 self.opener = vfsmod.vfs(self.path)
Peter Arrenbrecht
transplant: maintain list of transplants in dict
r12313 self.transplants = {}
Brendan Cully
Add transplant extension
r3714 self.dirty = False
self.read()
def read(self):
abspath = os.path.join(self.path, self.transplantfile)
if self.transplantfile and os.path.exists(abspath):
Dan Villiom Podlaski Christiansen
prevent transient leaks of file handle by using new helper functions...
r14168 for line in self.opener.read(self.transplantfile).splitlines():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 lnode, rnode = map(revlog.bin, line.split(b':'))
Peter Arrenbrecht
transplant: maintain list of transplants in dict
r12313 list = self.transplants.setdefault(rnode, [])
list.append(transplantentry(lnode, rnode))
Brendan Cully
Add transplant extension
r3714
def write(self):
if self.dirty and self.transplantfile:
if not os.path.isdir(self.path):
os.mkdir(self.path)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fp = self.opener(self.transplantfile, b'w')
Gregory Szorc
py3: define and use pycompat.itervalues()...
r43374 for list in pycompat.itervalues(self.transplants):
Peter Arrenbrecht
transplant: fix var name conflict introduced by 2912881c2a98
r12349 for t in list:
timeless
transplant: switch to using nodemod for hex+short
r28480 l, r = map(nodemod.hex, (t.lnode, t.rnode))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fp.write(l + b':' + r + b'\n')
Brendan Cully
Add transplant extension
r3714 fp.close()
self.dirty = False
def get(self, rnode):
Peter Arrenbrecht
transplant: maintain list of transplants in dict
r12313 return self.transplants.get(rnode) or []
Brendan Cully
Add transplant extension
r3714
def set(self, lnode, rnode):
Peter Arrenbrecht
transplant: maintain list of transplants in dict
r12313 list = self.transplants.setdefault(rnode, [])
list.append(transplantentry(lnode, rnode))
Brendan Cully
Add transplant extension
r3714 self.dirty = True
def remove(self, transplant):
Peter Arrenbrecht
transplant: maintain list of transplants in dict
r12313 list = self.transplants.get(transplant.rnode)
if list:
del list[list.index(transplant)]
self.dirty = True
Brendan Cully
Add transplant extension
r3714
Augie Fackler
formatting: blacken the codebase...
r43346
Benoit Boissinot
use new style classes
r8778 class transplanter(object):
FUJIWARA Katsunori
transplant: use "getcommiteditor()" instead of explicit editor choice...
r21411 def __init__(self, ui, repo, opts):
Brendan Cully
Add transplant extension
r3714 self.ui = ui
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.path = repo.vfs.join(b'transplant')
Pierre-Yves David
vfs: use 'vfs' module directly in 'hgext.transplant'...
r31245 self.opener = vfsmod.vfs(self.path)
Augie Fackler
formatting: blacken the codebase...
r43346 self.transplants = transplants(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.path, b'transplants', opener=self.opener
Augie Fackler
formatting: blacken the codebase...
r43346 )
FUJIWARA Katsunori
transplant: change "editform" to distinguish merge commits from others...
r22252 def getcommiteditor():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 editform = cmdutil.mergeeditform(repo[None], b'transplant')
Augie Fackler
formatting: blacken the codebase...
r43346 return cmdutil.getcommiteditor(
editform=editform, **pycompat.strkwargs(opts)
)
FUJIWARA Katsunori
transplant: change "editform" to distinguish merge commits from others...
r22252 self.getcommiteditor = getcommiteditor
Brendan Cully
Add transplant extension
r3714
def applied(self, repo, node, parent):
'''returns True if a node is already an ancestor of parent
Joshua Redstone
transplant: convert applied() algorithm from nodes to revs...
r17010 or is parent or has already been transplanted'''
if hasnode(repo, parent):
parentrev = repo.changelog.rev(parent)
Brendan Cully
Add transplant extension
r3714 if hasnode(repo, node):
Joshua Redstone
transplant: convert applied() algorithm from nodes to revs...
r17010 rev = repo.changelog.rev(node)
Augie Fackler
formatting: blacken the codebase...
r43346 reachable = repo.changelog.ancestors(
[parentrev], rev, inclusive=True
)
Joshua Redstone
transplant: convert applied() algorithm from nodes to revs...
r17010 if rev in reachable:
Brendan Cully
Add transplant extension
r3714 return True
for t in self.transplants.get(node):
# it might have been stripped
if not hasnode(repo, t.lnode):
self.transplants.remove(t)
return False
Joshua Redstone
transplant: convert applied() algorithm from nodes to revs...
r17010 lnoderev = repo.changelog.rev(t.lnode)
Augie Fackler
formatting: blacken the codebase...
r43346 if lnoderev in repo.changelog.ancestors(
[parentrev], lnoderev, inclusive=True
):
Brendan Cully
Add transplant extension
r3714 return True
return False
Pierre-Yves David
transplant: remove a mutable default argument...
r26346 def apply(self, repo, source, revmap, merges, opts=None):
Brendan Cully
Add transplant extension
r3714 '''apply the revisions in revmap one by one in revision order'''
Pierre-Yves David
transplant: remove a mutable default argument...
r26346 if opts is None:
opts = {}
Matt Mackall
replace util.sort with sorted built-in...
r8209 revs = sorted(revmap)
Martin von Zweigbergk
cleanup: use p1() instead of parents() when we only need the first parent...
r41444 p1 = repo.dirstate.p1()
Brendan Cully
Add transplant extension
r3714 pulls = []
Siddharth Agarwal
transplant: don't honor whitespace and format-changing diffopts...
r23452 diffopts = patch.difffeatureopts(self.ui, opts)
Brendan Cully
Add transplant extension
r3714 diffopts.git = True
FUJIWARA Katsunori
transplant: widen wlock scope of transplant for consitency while processing...
r27289 lock = tr = None
Brendan Cully
Add transplant extension
r3714 try:
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 lock = repo.lock()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tr = repo.transaction(b'transplant')
Brendan Cully
Add transplant extension
r3714 for rev in revs:
node = revmap[rev]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 revstr = b'%d:%s' % (rev, nodemod.short(node))
Brendan Cully
Add transplant extension
r3714
if self.applied(repo, node, p1):
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'skipping already applied revision %s\n') % revstr
Augie Fackler
formatting: blacken the codebase...
r43346 )
Brendan Cully
Add transplant extension
r3714 continue
parents = source.changelog.parents(node)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not (opts.get(b'filter') or opts.get(b'log')):
Martin Geisler
transplant: wrapped long lines
r7744 # If the changeset parent is the same as the
# wdir's parent, just pull it.
Brendan Cully
Add transplant extension
r3714 if parents[0] == p1:
pulls.append(node)
p1 = node
continue
if pulls:
if source != repo:
Pierre-Yves David
transplant: use exchange.pull...
r22699 exchange.pull(repo, source.peer(), heads=pulls)
Augie Fackler
formatting: blacken the codebase...
r43346 merge.update(
repo, pulls[-1], branchmerge=False, force=False
)
Martin von Zweigbergk
cleanup: use p1() instead of parents() when we only need the first parent...
r41444 p1 = repo.dirstate.p1()
Brendan Cully
Add transplant extension
r3714 pulls = []
domerge = False
if node in merges:
Martin Geisler
transplant: wrapped long lines
r7744 # pulling all the merge revs at once would mean we
# couldn't transplant after the latest even if
# transplants before them fail.
Brendan Cully
Add transplant extension
r3714 domerge = True
if not hasnode(repo, node):
Pierre-Yves David
transplant: use exchange.pull...
r22699 exchange.pull(repo, source.peer(), heads=[node])
Brendan Cully
Add transplant extension
r3714
Steven Stallion
transplant: permit merge changesets via --parent...
r16400 skipmerge = False
Brendan Cully
Add transplant extension
r3714 if parents[1] != revlog.nullid:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not opts.get(b'parent'):
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.note(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'skipping merge changeset %d:%s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (rev, nodemod.short(node))
)
Steven Stallion
transplant: permit merge changesets via --parent...
r16400 skipmerge = True
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 parent = source.lookup(opts[b'parent'])
Steven Stallion
transplant: permit merge changesets via --parent...
r16400 if parent not in parents:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s is not a parent of %s')
Augie Fackler
formatting: blacken the codebase...
r43346 % (nodemod.short(parent), nodemod.short(node))
)
Steven Stallion
transplant: permit merge changesets via --parent...
r16400 else:
parent = parents[0]
if skipmerge:
Brendan Cully
Add transplant extension
r3714 patchfile = None
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fd, patchfile = pycompat.mkstemp(prefix=b'hg-transplant-')
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 fp = os.fdopen(fd, 'wb')
Steven Stallion
transplant: permit merge changesets via --parent...
r16400 gen = patch.diff(source, parent, node, opts=diffopts)
Dirkjan Ochtman
patch: turn patch.diff() into a generator...
r7308 for chunk in gen:
fp.write(chunk)
Brendan Cully
Add transplant extension
r3714 fp.close()
del revmap[rev]
if patchfile or domerge:
try:
Patrick Mezard
transplant: do not rollback on patching error (issue3379)...
r16507 try:
Augie Fackler
formatting: blacken the codebase...
r43346 n = self.applyone(
repo,
node,
source.changelog.read(node),
patchfile,
merge=domerge,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 log=opts.get(b'log'),
filter=opts.get(b'filter'),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Patrick Mezard
transplant: do not rollback on patching error (issue3379)...
r16507 except TransplantError:
# Do not rollback, it is up to the user to
# fix the merge or cancel everything
tr.close()
raise
Brendan Cully
transplant: fix ignoring empty changesets (eg after filter)
r4251 if n and domerge:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s merged at %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (revstr, nodemod.short(n))
)
Brendan Cully
transplant: fix ignoring empty changesets (eg after filter)
r4251 elif n:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s transplanted to %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (nodemod.short(node), nodemod.short(n))
)
Brendan Cully
Add transplant extension
r3714 finally:
if patchfile:
os.unlink(patchfile)
Greg Ward
transplant: wrap a transaction around the whole command
r15204 tr.close()
Brendan Cully
Add transplant extension
r3714 if pulls:
Pierre-Yves David
transplant: use exchange.pull...
r22699 exchange.pull(repo, source.peer(), heads=pulls)
Martin von Zweigbergk
update: clarify update() call sites by specifying argument names...
r40402 merge.update(repo, pulls[-1], branchmerge=False, force=False)
Brendan Cully
Add transplant extension
r3714 finally:
self.saveseries(revmap, merges)
self.transplants.write()
Greg Ward
transplant: wrap a transaction around the whole command
r15204 if tr:
tr.release()
FUJIWARA Katsunori
transplant: restore dirstate correctly at unexpected failure...
r25879 if lock:
lock.release()
Brendan Cully
Add transplant extension
r3714
Luke Plant
transplant: added 'HGREVISION' variable to the environment passed to the 'filter' command...
r13579 def filter(self, filter, node, changelog, patchfile):
Brendan Cully
Add transplant extension
r3714 '''arbitrarily rewrite changeset before applying it'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.status(_(b'filtering %s\n') % patchfile)
Brendan Cully
transplant: split filter args into changelog entry and patch
r3759 user, date, msg = (changelog[1], changelog[2], changelog[4])
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fd, headerfile = pycompat.mkstemp(prefix=b'hg-transplant-')
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 fp = os.fdopen(fd, 'wb')
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fp.write(b"# HG changeset patch\n")
fp.write(b"# User %s\n" % user)
fp.write(b"# Date %d %d\n" % date)
fp.write(msg + b'\n')
Brendan Cully
transplant: split filter args into changelog entry and patch
r3759 fp.close()
try:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.system(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'%s %s %s'
Augie Fackler
formatting: blacken the codebase...
r43346 % (
filter,
procutil.shellquote(headerfile),
procutil.shellquote(patchfile),
),
environ={
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'HGUSER': changelog[1],
b'HGREVISION': nodemod.hex(node),
Augie Fackler
formatting: blacken the codebase...
r43346 },
onerr=error.Abort,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 errprefix=_(b'filter failed'),
blockedtag=b'transplant_filter',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 user, date, msg = self.parselog(open(headerfile, b'rb'))[1:4]
Brendan Cully
transplant: split filter args into changelog entry and patch
r3759 finally:
os.unlink(headerfile)
return (user, date, msg)
Brendan Cully
Add transplant extension
r3714
Augie Fackler
formatting: blacken the codebase...
r43346 def applyone(
self, repo, node, cl, patchfile, merge=False, log=False, filter=None
):
Brendan Cully
Add transplant extension
r3714 '''apply the patch in patchfile to the repository as a transplant'''
(manifest, user, (time, timezone), files, message) = cl[:5]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 date = b"%d %d" % (time, timezone)
extra = {b'transplant_source': node}
Brendan Cully
Add transplant extension
r3714 if filter:
Luke Plant
transplant: added 'HGREVISION' variable to the environment passed to the 'filter' command...
r13579 (user, date, message) = self.filter(filter, node, cl, patchfile)
Brendan Cully
Add transplant extension
r3714
if log:
Martin Geisler
do not translate commit messages...
r9183 # we don't translate messages inserted into commits
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 message += b'\n(transplanted from %s)' % nodemod.hex(node)
Brendan Cully
Add transplant extension
r3714
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.status(_(b'applying %s\n') % nodemod.short(node))
self.ui.note(b'%s %s\n%s\n' % (user, date, message))
Brendan Cully
Add transplant extension
r3714
if not patchfile and not merge:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'can only omit patchfile if merging'))
Brendan Cully
Add transplant extension
r3714 if patchfile:
try:
Patrick Mezard
patch: turn patch() touched files dict into a set
r14564 files = set()
Patrick Mezard
patch: remove patch.patch() cwd argument
r14382 patch.patch(self.ui, repo, patchfile, files=files, eolmode=None)
Patrick Mezard
patch: make patch()/internalpatch() always update the dirstate
r14260 files = list(files)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except Exception as inst:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 seriespath = os.path.join(self.path, b'series')
Brendan Cully
transplant: clobber old series when transplant fails
r3757 if os.path.exists(seriespath):
os.unlink(seriespath)
Matt Mackall
misc: replace .parents()[0] with p1()
r13878 p1 = repo.dirstate.p1()
Brendan Cully
Add transplant extension
r3714 p2 = node
Brendan Cully
transplant: preserve filter changes in --continue log
r3725 self.log(user, date, message, p1, p2, merge=merge)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.write(stringutil.forcebytestr(inst) + b'\n')
Augie Fackler
formatting: blacken the codebase...
r43346 raise TransplantError(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'fix up the working directory and run '
b'hg transplant --continue'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Brendan Cully
Add transplant extension
r3714 else:
files = None
if merge:
Martin von Zweigbergk
cleanup: use p1() instead of parents() when we only need the first parent...
r41444 p1 = repo.dirstate.p1()
Patrick Mezard
localrepo: add setparents() to adjust dirstate copies (issue3407)...
r16551 repo.setparents(p1, node)
Martin von Zweigbergk
match: delete unused root and cwd arguments from {always,never,exact}() (API)...
r41825 m = match.always()
Matt Mackall
transplant: use match object rather than files for commit
r8703 else:
Martin von Zweigbergk
match: delete unused root and cwd arguments from {always,never,exact}() (API)...
r41825 m = match.exact(files)
Brendan Cully
Add transplant extension
r3714
Augie Fackler
formatting: blacken the codebase...
r43346 n = repo.commit(
message,
user,
date,
extra=extra,
match=m,
editor=self.getcommiteditor(),
)
Greg Ward
transplant: crash if repo.commit() finds nothing to commit...
r11638 if not n:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'skipping emptied changeset %s\n') % nodemod.short(node)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Patrick Mezard
transplant: handle non-empty patches doing nothing (issue2806)...
r17319 return None
Brendan Cully
Add transplant extension
r3714 if not merge:
self.transplants.set(n, node)
return n
timeless
transplant: only use checkunfinished if not continue
r27677 def canresume(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return os.path.exists(os.path.join(self.path, b'journal'))
timeless
transplant: only use checkunfinished if not continue
r27677
Bryan O'Sullivan
repoview: remove unreachable code...
r18919 def resume(self, repo, source, opts):
Brendan Cully
Add transplant extension
r3714 '''recover last transaction and apply remaining changesets'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if os.path.exists(os.path.join(self.path, b'journal')):
Bryan O'Sullivan
transplant: pass source through to recover
r18926 n, node = self.recover(repo, source, opts)
Pierre-Yves David
transplant: properly skip empty changeset (issue4423)...
r23781 if n:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s transplanted as %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (nodemod.short(node), nodemod.short(n))
)
Pierre-Yves David
transplant: properly skip empty changeset (issue4423)...
r23781 else:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s skipped due to empty diff\n')
% (nodemod.short(node),)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 seriespath = os.path.join(self.path, b'series')
Brendan Cully
Add transplant extension
r3714 if not os.path.exists(seriespath):
Brendan Cully
transplant: log source node when recovering too.
r3758 self.transplants.write()
Brendan Cully
Add transplant extension
r3714 return
nodes, merges = self.readseries()
revmap = {}
for n in nodes:
revmap[source.changelog.rev(n)] = n
os.unlink(seriespath)
self.apply(repo, source, revmap, merges, opts)
Bryan O'Sullivan
transplant: pass source through to recover
r18926 def recover(self, repo, source, opts):
Brendan Cully
Add transplant extension
r3714 '''commit working directory using journal metadata'''
node, user, date, message, parents = self.readlog()
Steven Stallion
transplant: permit merge changesets via --parent...
r16400 merge = False
Brendan Cully
Add transplant extension
r3714
if not user or not date or not message or not parents[0]:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'transplant log file is corrupt'))
Brendan Cully
Add transplant extension
r3714
Steven Stallion
transplant: permit merge changesets via --parent...
r16400 parent = parents[0]
if len(parents) > 1:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'parent'):
parent = source.lookup(opts[b'parent'])
Steven Stallion
transplant: permit merge changesets via --parent...
r16400 if parent not in parents:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s is not a parent of %s')
Augie Fackler
formatting: blacken the codebase...
r43346 % (nodemod.short(parent), nodemod.short(node))
)
Steven Stallion
transplant: permit merge changesets via --parent...
r16400 else:
merge = True
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extra = {b'transplant_source': node}
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
Martin von Zweigbergk
cleanup: use p1() instead of parents() when we only need the first parent...
r41444 p1 = repo.dirstate.p1()
Steven Stallion
transplant: permit merge changesets via --parent...
r16400 if p1 != parent:
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'working directory not at transplant parent %s')
Augie Fackler
formatting: blacken the codebase...
r43346 % nodemod.hex(parent)
)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if merge:
Patrick Mezard
localrepo: add setparents() to adjust dirstate copies (issue3407)...
r16551 repo.setparents(p1, parents[1])
Augie Fackler
transplant: use field names instead of field numbers on scmutil.status...
r44041 st = repo.status()
modified, added, removed, deleted = (
st.modified,
st.added,
st.removed,
st.deleted,
)
Pierre-Yves David
transplant: properly skip empty changeset (issue4423)...
r23781 if merge or modified or added or removed or deleted:
Augie Fackler
formatting: blacken the codebase...
r43346 n = repo.commit(
message,
user,
date,
extra=extra,
editor=self.getcommiteditor(),
)
Pierre-Yves David
transplant: properly skip empty changeset (issue4423)...
r23781 if not n:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'commit failed'))
Pierre-Yves David
transplant: properly skip empty changeset (issue4423)...
r23781 if not merge:
self.transplants.set(n, node)
else:
n = None
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 self.unlog()
Brendan Cully
Add transplant extension
r3714
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 return n, node
finally:
FUJIWARA Katsunori
transplant: widen wlock scope of transplant for consitency while processing...
r27289 # TODO: get rid of this meaningless try/finally enclosing.
# this is kept only to reduce changes in a patch.
pass
Brendan Cully
Add transplant extension
r3714
Taapas Agrawal
transplant: added support for --stop flag...
r43030 def stop(self, ui, repo):
"""logic to stop an interrupted transplant"""
if self.canresume():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 startctx = repo[b'.']
Taapas Agrawal
transplant: added support for --stop flag...
r43030 hg.updaterepo(repo, startctx.node(), overwrite=True)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b"stopped the interrupted transplant\n"))
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"working directory is now at %s\n") % startctx.hex()[:12]
Augie Fackler
formatting: blacken the codebase...
r43346 )
Taapas Agrawal
transplant: added support for --stop flag...
r43030 self.unlog()
return 0
Brendan Cully
Add transplant extension
r3714 def readseries(self):
nodes = []
merges = []
cur = nodes
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for line in self.opener.read(b'series').splitlines():
if line.startswith(b'# Merges'):
Brendan Cully
Add transplant extension
r3714 cur = merges
continue
cur.append(revlog.bin(line))
return (nodes, merges)
def saveseries(self, revmap, merges):
if not revmap:
return
if not os.path.isdir(self.path):
os.mkdir(self.path)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 series = self.opener(b'series', b'w')
Matt Mackall
replace util.sort with sorted built-in...
r8209 for rev in sorted(revmap):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 series.write(nodemod.hex(revmap[rev]) + b'\n')
Brendan Cully
Add transplant extension
r3714 if merges:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 series.write(b'# Merges\n')
Brendan Cully
Add transplant extension
r3714 for m in merges:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 series.write(nodemod.hex(m) + b'\n')
Brendan Cully
Add transplant extension
r3714 series.close()
Brendan Cully
transplant: split filter args into changelog entry and patch
r3759 def parselog(self, fp):
parents = []
message = []
node = revlog.nullid
inmsg = False
Luke Plant
transplant: fix crash if filter script munges log file...
r13789 user = None
date = None
Brendan Cully
transplant: split filter args into changelog entry and patch
r3759 for line in fp.read().splitlines():
if inmsg:
message.append(line)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif line.startswith(b'# User '):
Brendan Cully
transplant: split filter args into changelog entry and patch
r3759 user = line[7:]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif line.startswith(b'# Date '):
Brendan Cully
transplant: split filter args into changelog entry and patch
r3759 date = line[7:]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif line.startswith(b'# Node ID '):
Brendan Cully
transplant: split filter args into changelog entry and patch
r3759 node = revlog.bin(line[10:])
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif line.startswith(b'# Parent '):
Brendan Cully
transplant: split filter args into changelog entry and patch
r3759 parents.append(revlog.bin(line[9:]))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif not line.startswith(b'# '):
Brendan Cully
transplant: split filter args into changelog entry and patch
r3759 inmsg = True
message.append(line)
Luke Plant
transplant: fix crash if filter script munges log file...
r13789 if None in (user, date):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(
_(b"filter corrupted changeset (no user or date)")
)
return (node, user, date, b'\n'.join(message), parents)
Thomas Arendsen Hein
Removed trailing whitespace and tabs from python files
r4516
Brendan Cully
transplant: preserve filter changes in --continue log
r3725 def log(self, user, date, message, p1, p2, merge=False):
Brendan Cully
Add transplant extension
r3714 '''journal changelog metadata for later recover'''
if not os.path.isdir(self.path):
os.mkdir(self.path)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fp = self.opener(b'journal', b'w')
fp.write(b'# User %s\n' % user)
fp.write(b'# Date %s\n' % date)
fp.write(b'# Node ID %s\n' % nodemod.hex(p2))
fp.write(b'# Parent ' + nodemod.hex(p1) + b'\n')
Brendan Cully
Add transplant extension
r3714 if merge:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fp.write(b'# Parent ' + nodemod.hex(p2) + b'\n')
fp.write(message.rstrip() + b'\n')
Brendan Cully
Add transplant extension
r3714 fp.close()
def readlog(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self.parselog(self.opener(b'journal'))
Brendan Cully
Add transplant extension
r3714
def unlog(self):
'''remove changelog journal'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 absdst = os.path.join(self.path, b'journal')
Brendan Cully
Add transplant extension
r3714 if os.path.exists(absdst):
os.unlink(absdst)
def transplantfilter(self, repo, source, root):
def matchfn(node):
if self.applied(repo, node, root):
return False
if source.changelog.parents(node)[1] != revlog.nullid:
return False
extra = source.changelog.read(node)[5]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cnode = extra.get(b'transplant_source')
Brendan Cully
Add transplant extension
r3714 if cnode and self.applied(repo, cnode, root):
return False
return True
return matchfn
Augie Fackler
formatting: blacken the codebase...
r43346
Brendan Cully
Add transplant extension
r3714 def hasnode(repo, node):
try:
Martin Geisler
code style: prefer 'is' and 'is not' tests with singletons
r13031 return repo.changelog.rev(node) is not None
Gregory Szorc
global: replace most uses of RevlogError with StorageError (API)...
r39813 except error.StorageError:
Brendan Cully
Add transplant extension
r3714 return False
Augie Fackler
formatting: blacken the codebase...
r43346
Brendan Cully
Add transplant extension
r3714 def browserevs(ui, repo, nodes, opts):
'''interactively transplant changesets'''
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
Brendan Cully
Add transplant extension
r3714 transplants = []
merges = []
Augie Fackler
formatting: blacken the codebase...
r43346 prompt = _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'apply changeset? [ynmpcq?]:'
b'$$ &yes, transplant this changeset'
b'$$ &no, skip this changeset'
b'$$ &merge at this changeset'
b'$$ show &patch'
b'$$ &commit selected changesets'
b'$$ &quit and cancel transplant'
b'$$ &? (show this help)'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Brendan Cully
Add transplant extension
r3714 for node in nodes:
Dirkjan Ochtman
cmdutil: use change contexts for cset-printer and cset-templater
r7369 displayer.show(repo[node])
Brendan Cully
Add transplant extension
r3714 action = None
while not action:
Pulkit Goyal
py3: slice over bytes to prevent getting ascii values...
r38389 choice = ui.promptchoice(prompt)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 action = b'ynmpcq?'[choice : choice + 1]
if action == b'?':
FUJIWARA Katsunori
transplant: use "ui.extractchoices()" to show the list of available responses...
r20269 for c, t in ui.extractchoices(prompt)[1]:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.write(b'%s: %s\n' % (c, t))
Brendan Cully
Add transplant extension
r3714 action = None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif action == b'p':
Brendan Cully
Add transplant extension
r3714 parent = repo.changelog.parents(node)[0]
Dirkjan Ochtman
patch: turn patch.diff() into a generator...
r7308 for chunk in patch.diff(repo, parent, node):
Martin Geisler
use ui instead of repo.ui when the former is in scope
r8615 ui.write(chunk)
Brendan Cully
Add transplant extension
r3714 action = None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if action == b'y':
Brendan Cully
Add transplant extension
r3714 transplants.append(node)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif action == b'm':
Brendan Cully
Add transplant extension
r3714 merges.append(node)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif action == b'c':
Brendan Cully
Add transplant extension
r3714 break
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif action == b'q':
Brendan Cully
Add transplant extension
r3714 transplants = ()
merges = ()
break
Robert Bachmann
Added support for templatevar "footer" to cmdutil.py
r10152 displayer.close()
Brendan Cully
Add transplant extension
r3714 return (transplants, merges)
Augie Fackler
formatting: blacken the codebase...
r43346
@command(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'transplant',
Augie Fackler
formatting: blacken the codebase...
r43346 [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (
b's',
b'source',
b'',
_(b'transplant changesets from REPO'),
_(b'REPO'),
),
Augie Fackler
formatting: blacken the codebase...
r43346 (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'b',
b'branch',
[],
_(b'use this source changeset as head'),
_(b'REV'),
),
(
b'a',
b'all',
Augie Fackler
formatting: blacken the codebase...
r43346 None,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'pull all changesets up to the --branch revisions'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'p', b'prune', [], _(b'skip over REV'), _(b'REV')),
(b'm', b'merge', [], _(b'merge at REV'), _(b'REV')),
Augie Fackler
formatting: blacken the codebase...
r43346 (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'',
b'parent',
b'',
_(b'parent to choose when transplanting merge'),
_(b'REV'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'e', b'edit', False, _(b'invoke editor on commit messages')),
(b'', b'log', None, _(b'append transplant info to log message')),
(b'', b'stop', False, _(b'stop interrupted transplant')),
(
b'c',
b'continue',
None,
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 _(b'continue last transplant session after fixing conflicts'),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ),
Augie Fackler
formatting: blacken the codebase...
r43346 (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'',
b'filter',
b'',
_(b'filter changesets through command'),
_(b'CMD'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
],
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(
b'hg transplant [-s REPO] [-b BRANCH [-a]] [-p REV] '
b'[-m REV] [REV]...'
),
Augie Fackler
formatting: blacken the codebase...
r43346 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
)
Brendan Cully
Add transplant extension
r3714 def transplant(ui, repo, *revs, **opts):
'''transplant changesets from another branch
Selected changesets will be applied on top of the current working
Martin Geisler
transplant: explain that changesets are copied, not moved
r13605 directory with the log of the original changeset. The changesets
Mads Kiilerich
transplant: improve documentation
r19028 are copied and will thus appear twice in the history with different
identities.
Consider using the graft command if everything is inside the same
repository - it will use merges and will usually give a better result.
Use the rebase extension if the changesets are unpublished and you want
to move them instead of copying them.
Martin Geisler
transplant: explain that changesets are copied, not moved
r13605
If --log is specified, log messages will have a comment appended
of the form::
Brendan Cully
Add transplant extension
r3714
Martin Geisler
transplant: better reST formatting
r9200 (transplanted from CHANGESETHASH)
Brendan Cully
Add transplant extension
r3714
You can rewrite the changelog message with the --filter option.
Martin Geisler
transplant: word-wrap help texts at 70 characters
r8000 Its argument will be invoked with the current changelog message as
$1 and the patch as $2.
Brendan Cully
Add transplant extension
r3714
Mads Kiilerich
transplant: improve documentation
r19028 --source/-s specifies another repository to use for selecting changesets,
just as if it temporarily had been pulled.
Mads Kiilerich
transplant: clarify what --branch do - it has nothing to do with branches...
r19027 If --branch/-b is specified, these revisions will be used as
Mads Kiilerich
spelling: random spell checker fixes
r19951 heads when deciding which changesets to transplant, just as if only
Mads Kiilerich
transplant: clarify what --branch do - it has nothing to do with branches...
r19027 these revisions had been pulled.
If --all/-a is specified, all the revisions up to the heads specified
with --branch will be transplanted.
Brendan Cully
Add transplant extension
r3714
Mads Kiilerich
transplant: clarify what --branch do - it has nothing to do with branches...
r19027 Example:
- transplant all changes up to REV on top of your current revision::
hg transplant --branch REV --all
Brendan Cully
Add transplant extension
r3714
Martin Geisler
transplant: word-wrap help texts at 70 characters
r8000 You can optionally mark selected transplanted changesets as merge
changesets. You will not be prompted to transplant any ancestors
of a merged transplant, and you can merge descendants of them
normally instead of transplanting them.
Brendan Cully
Add transplant extension
r3714
Steven Stallion
transplant: permit merge changesets via --parent...
r16400 Merge changesets may be transplanted directly by specifying the
Steven Stallion
transplant: remove extraneous whitespace
r16457 proper parent changeset by calling :hg:`transplant --parent`.
Steven Stallion
transplant: permit merge changesets via --parent...
r16400
Martin Geisler
Use our custom hg reStructuredText role some more...
r11193 If no merges or revisions are provided, :hg:`transplant` will
start an interactive changeset browser.
Brendan Cully
Add transplant extension
r3714
Martin Geisler
transplant: word-wrap help texts at 70 characters
r8000 If a changeset application fails, you can fix the merge by hand
Martin Geisler
Use our custom hg reStructuredText role some more...
r11193 and then resume where you left off by calling :hg:`transplant
--continue/-c`.
Brendan Cully
Add transplant extension
r3714 '''
Bryan O'Sullivan
with: use context manager for wlock in transplant
r27840 with repo.wlock():
FUJIWARA Katsunori
transplant: widen wlock scope of transplant for consitency while processing...
r27289 return _dotransplant(ui, repo, *revs, **opts)
Augie Fackler
formatting: blacken the codebase...
r43346
FUJIWARA Katsunori
transplant: widen wlock scope of transplant for consitency while processing...
r27289 def _dotransplant(ui, repo, *revs, **opts):
Peter Arrenbrecht
bundlerepo: fix and improve getremotechanges...
r14161 def incwalk(repo, csets, match=util.always):
for node in csets:
Brendan Cully
Add transplant extension
r3714 if match(node):
yield node
Mads Kiilerich
transplant: clarify what --branch do - it has nothing to do with branches...
r19027 def transplantwalk(repo, dest, heads, match=util.always):
'''Yield all nodes that are ancestors of a head but not ancestors
of dest.
If no heads are specified, the heads of repo will be used.'''
if not heads:
heads = repo.heads()
Brendan Cully
Add transplant extension
r3714 ancestors = []
Mads Kiilerich
transplant: use context ancestor instead of changelog ancestor...
r20988 ctx = repo[dest]
Mads Kiilerich
transplant: clarify what --branch do - it has nothing to do with branches...
r19027 for head in heads:
Mads Kiilerich
transplant: use context ancestor instead of changelog ancestor...
r20988 ancestors.append(ctx.ancestor(repo[head]).node())
Mads Kiilerich
transplant: clarify what --branch do - it has nothing to do with branches...
r19027 for node in repo.changelog.nodesbetween(ancestors, heads)[0]:
Brendan Cully
Add transplant extension
r3714 if match(node):
yield node
def checkopts(opts, revs):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'continue'):
Martin von Zweigbergk
transplant: use check_incompatible_arguments()...
r44355 cmdutil.check_incompatible_arguments(
Martin von Zweigbergk
cmdutil: change check_incompatible_arguments() *arg to single iterable...
r44655 opts, b'continue', [b'branch', b'all', b'merge']
Martin von Zweigbergk
transplant: use check_incompatible_arguments()...
r44355 )
Brendan Cully
Add transplant extension
r3714 return
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'stop'):
Martin von Zweigbergk
transplant: use check_incompatible_arguments()...
r44355 cmdutil.check_incompatible_arguments(
Martin von Zweigbergk
cmdutil: change check_incompatible_arguments() *arg to single iterable...
r44655 opts, b'stop', [b'branch', b'all', b'merge']
Martin von Zweigbergk
transplant: use check_incompatible_arguments()...
r44355 )
Taapas Agrawal
transplant: added support for --stop flag...
r43030 return
Augie Fackler
formatting: blacken the codebase...
r43346 if not (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 opts.get(b'source')
Augie Fackler
formatting: blacken the codebase...
r43346 or revs
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 or opts.get(b'merge')
or opts.get(b'branch')
Augie Fackler
formatting: blacken the codebase...
r43346 ):
raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'no source URL, branch revision, or revision '
b'list provided'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'all'):
if not opts.get(b'branch'):
raise error.Abort(_(b'--all requires a branch revision'))
Brendan Cully
Add transplant extension
r3714 if revs:
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'--all is incompatible with a revision list')
Augie Fackler
formatting: blacken the codebase...
r43346 )
Brendan Cully
Add transplant extension
r3714
Pulkit Goyal
py3: use pycompat.{bytes|str}kwargs in transplant.py...
r36208 opts = pycompat.byteskwargs(opts)
Brendan Cully
Add transplant extension
r3714 checkopts(opts, revs)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not opts.get(b'log'):
Matt Mackall
transplant: mark some undocumented options deprecated
r25828 # deprecated config: transplant.log
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 opts[b'log'] = ui.config(b'transplant', b'log')
if not opts.get(b'filter'):
Matt Mackall
transplant: mark some undocumented options deprecated
r25828 # deprecated config: transplant.filter
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 opts[b'filter'] = ui.config(b'transplant', b'filter')
Brendan Cully
Add transplant extension
r3714
FUJIWARA Katsunori
transplant: use "getcommiteditor()" instead of explicit editor choice...
r21411 tp = transplanter(ui, repo, opts)
Brendan Cully
Add transplant extension
r3714
Martin von Zweigbergk
cleanup: use p1() instead of parents() when we only need the first parent...
r41444 p1 = repo.dirstate.p1()
Brendan Cully
transplant: forbid transplant to nonempty repositories with no working directory....
r8176 if len(repo) > 0 and p1 == revlog.nullid:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'no revision checked out'))
if opts.get(b'continue'):
timeless
transplant: only use checkunfinished if not continue
r27677 if not tp.canresume():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'no transplant to continue'))
elif opts.get(b'stop'):
Yuya Nishihara
transplant: unnest --stop case...
r43033 if not tp.canresume():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'no interrupted transplant found'))
Yuya Nishihara
transplant: unnest --stop case...
r43033 return tp.stop(ui, repo)
timeless
transplant: only use checkunfinished if not continue
r27677 else:
cmdutil.checkunfinished(repo)
Martin von Zweigbergk
transplant: use bailifchanged() instead of reimplementing it...
r41416 cmdutil.bailifchanged(repo)
Brendan Cully
Add transplant extension
r3714
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 sourcerepo = opts.get(b'source')
Peter Arrenbrecht
bundlerepo: fix and improve getremotechanges...
r14161 if sourcerepo:
Simon Heimberg
peer: subrepo isolation, pass repo instead of repo.ui to hg.peer...
r17874 peer = hg.peer(repo, opts, ui.expandpath(sourcerepo))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 heads = pycompat.maplist(peer.lookup, opts.get(b'branch', ()))
Pierre-Yves David
transplant: only pull the transplanted revision (issue4692)...
r25679 target = set(heads)
for r in revs:
try:
target.add(peer.lookup(r))
except error.RepoError:
pass
Augie Fackler
formatting: blacken the codebase...
r43346 source, csets, cleanupfn = bundlerepo.getremotechanges(
ui, repo, peer, onlyheads=sorted(target), force=True
)
Brendan Cully
Add transplant extension
r3714 else:
source = repo
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 heads = pycompat.maplist(source.lookup, opts.get(b'branch', ()))
Peter Arrenbrecht
bundlerepo: fix and improve getremotechanges...
r14161 cleanupfn = None
Brendan Cully
Add transplant extension
r3714
try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'continue'):
Brendan Cully
transplant: fix --continue; add --continue test
r3724 tp.resume(repo, source, opts)
Brendan Cully
Add transplant extension
r3714 return
Benoit Boissinot
fix coding style (reported by pylint)
r10394 tf = tp.transplantfilter(repo, source, p1)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'prune'):
Augie Fackler
cleanup: run pyupgrade on our source tree to clean up varying things...
r44937 prune = {
Augie Fackler
formatting: blacken the codebase...
r43346 source[r].node()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for r in scmutil.revrange(source, opts.get(b'prune'))
Augie Fackler
cleanup: run pyupgrade on our source tree to clean up varying things...
r44937 }
Brendan Cully
Add transplant extension
r3714 matchfn = lambda x: tf(x) and x not in prune
else:
matchfn = tf
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 merges = pycompat.maplist(source.lookup, opts.get(b'merge', ()))
Brendan Cully
Add transplant extension
r3714 revmap = {}
if revs:
Matt Mackall
scmutil: move revsingle/pair/range from cmdutil...
r14319 for r in scmutil.revrange(source, revs):
Martin von Zweigbergk
transplant: avoid repo.lookup() for converting revnum to nodeid...
r37327 revmap[int(r)] = source[r].node()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif opts.get(b'all') or not merges:
Brendan Cully
Add transplant extension
r3714 if source != repo:
Peter Arrenbrecht
bundlerepo: fix and improve getremotechanges...
r14161 alltransplants = incwalk(source, csets, match=matchfn)
Brendan Cully
Add transplant extension
r3714 else:
Augie Fackler
formatting: blacken the codebase...
r43346 alltransplants = transplantwalk(
source, p1, heads, match=matchfn
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'all'):
Brendan Cully
Add transplant extension
r3714 revs = alltransplants
else:
revs, newmerges = browserevs(ui, source, alltransplants, opts)
merges.extend(newmerges)
for r in revs:
revmap[source.changelog.rev(r)] = r
for r in merges:
revmap[source.changelog.rev(r)] = r
tp.apply(repo, source, revmap, merges, opts)
finally:
Peter Arrenbrecht
bundlerepo: fix and improve getremotechanges...
r14161 if cleanupfn:
cleanupfn()
Brendan Cully
Add transplant extension
r3714
Augie Fackler
formatting: blacken the codebase...
r43346
Taapas Agrawal
continue: added support for transplant...
r42943 def continuecmd(ui, repo):
"""logic to resume an interrupted transplant using
'hg continue'"""
with repo.wlock():
tp = transplanter(ui, repo, {})
return tp.resume(repo, repo, {})
Augie Fackler
formatting: blacken the codebase...
r43346
FUJIWARA Katsunori
revset: replace extpredicate by revsetpredicate of registrar...
r28394 revsetpredicate = registrar.revsetpredicate()
FUJIWARA Katsunori
revset: use delayregistrar to register predicate in extension easily...
r27586
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 @revsetpredicate(b'transplanted([set])')
Juan Pablo Aroztegi
transplant: add the transplanted revset predicate...
r12581 def revsettransplanted(repo, subset, x):
FUJIWARA Katsunori
revset: use delayregistrar to register predicate in extension easily...
r27586 """Transplanted changesets in set, or all transplanted changesets.
Patrick Mezard
Fix and unify transplant and bookmarks revsets doc registration
r12822 """
Juan Pablo Aroztegi
transplant: add the transplanted revset predicate...
r12581 if x:
Mads Kiilerich
check-code: indent 4 spaces in py files
r17299 s = revset.getset(repo, subset, x)
Juan Pablo Aroztegi
transplant: add the transplanted revset predicate...
r12581 else:
Mads Kiilerich
check-code: indent 4 spaces in py files
r17299 s = subset
Augie Fackler
formatting: blacken the codebase...
r43346 return smartset.baseset(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 [r for r in s if repo[r].extra().get(b'transplant_source')]
Augie Fackler
formatting: blacken the codebase...
r43346 )
Juan Pablo Aroztegi
transplant: add the transplanted revset predicate...
r12581
FUJIWARA Katsunori
hgext: use templatekeyword to mark a function as template keyword...
r28540 templatekeyword = registrar.templatekeyword()
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 @templatekeyword(b'transplanted', requires={b'ctx'})
Yuya Nishihara
templatekw: switch non-showlist template keywords to new API
r36531 def kwtransplanted(context, mapping):
FUJIWARA Katsunori
hgext: use templatekeyword to mark a function as template keyword...
r28540 """String. The node identifier of the transplanted
Patrick Mezard
transplant: add "transplanted" keyword...
r13689 changeset if any."""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ctx = context.resource(mapping, b'ctx')
n = ctx.extra().get(b'transplant_source')
return n and nodemod.hex(n) or b''
Juan Pablo Aroztegi
transplant: add the transplanted revset predicate...
r12581
Augie Fackler
formatting: blacken the codebase...
r43346
Patrick Mezard
Fix and unify transplant and bookmarks revsets doc registration
r12822 def extsetup(ui):
Augie Fackler
formatting: blacken the codebase...
r43346 statemod.addunfinished(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'transplant',
fname=b'transplant/journal',
Augie Fackler
formatting: blacken the codebase...
r43346 clearable=True,
Taapas Agrawal
continue: added support for transplant...
r42943 continuefunc=continuecmd,
Augie Fackler
formatting: blacken the codebase...
r43346 statushint=_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'To continue: hg transplant --continue\n'
b'To stop: hg transplant --stop'
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmdhint=_(b"use 'hg transplant --continue' or 'hg transplant --stop'"),
Taapas Agrawal
state: created new class statecheck to handle unfinishedstates...
r42730 )
Juan Pablo Aroztegi
transplant: add the transplanted revset predicate...
r12581
Augie Fackler
formatting: blacken the codebase...
r43346
Patrick Mezard
hggettext: handle i18nfunctions declaration for docstrings translations
r12823 # tell hggettext to extract docstrings from these functions:
Patrick Mezard
i18n: register new template keywords for translation
r13698 i18nfunctions = [revsettransplanted, kwtransplanted]