##// END OF EJS Templates
nodemap: track the maximum revision tracked in the nodemap...
nodemap: track the maximum revision tracked in the nodemap We need a simple way to detect when the on disk data contains less revision than the index we read from disk. The docket file is meant for this, we just had to start tracking that data. We should also try to detect strip operation, but we will deal with this in later changesets. Right now we are focusing on defining the API for index supporting persistent nodemap. Differential Revision: https://phab.mercurial-scm.org/D7888

File last commit:

r44787:a0ec05d9 default
r44807:e41a164d default
Show More
cmdutil.py
4072 lines | 132.8 KiB | text/x-python | PythonLexer
Vadim Gelfer
fix comment.
r2957 # cmdutil.py - help for command processing in mercurial
Vadim Gelfer
refactor text diff/patch code....
r2874 #
Thomas Arendsen Hein
Updated copyright notices and add "and others" to "hg version"
r4635 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
Vadim Gelfer
refactor text diff/patch code....
r2874 #
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.
Vadim Gelfer
refactor text diff/patch code....
r2874
Gregory Szorc
cmdutil: use absolute_import...
r28322 from __future__ import absolute_import
Matt Harbison
record: prevent commits that don't pick up dirty subrepo changes (issue6102)...
r42143 import copy as copymod
Gregory Szorc
cmdutil: use absolute_import...
r28322 import errno
import os
import re
from .i18n import _
from .node import (
hex,
nullid,
nullrev,
short,
)
Gregory Szorc
py3: manually import pycompat.setattr where it is needed...
r43357 from .pycompat import (
Gregory Szorc
py3: manually import getattr where it is needed...
r43359 getattr,
Gregory Szorc
py3: manually import pycompat.setattr where it is needed...
r43357 open,
setattr,
)
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293 from .thirdparty import attr
Gregory Szorc
cmdutil: use absolute_import...
r28322
from . import (
bookmarks,
changelog,
copies,
crecord as crecordmod,
Martin von Zweigbergk
commit: don't let failed commit with --addremove update dirstate (issue5645)...
r33619 dirstateguard,
Gregory Szorc
cmdutil: use absolute_import...
r28322 encoding,
error,
formatter,
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 logcmdutil,
Gregory Szorc
cmdutil: use absolute_import...
r28322 match as matchmod,
Yuya Nishihara
merge: cut import cycle at merge -> extensions...
r36027 merge as mergemod,
Yuya Nishihara
amend: abort if unresolved merge conflicts found (issue5805)...
r36927 mergeutil,
Gregory Szorc
cmdutil: use absolute_import...
r28322 obsolete,
patch,
pathutil,
Martin von Zweigbergk
scmutil: make cleanupnodes optionally also fix the phase...
r38442 phases,
Pulkit Goyal
py3: use pycompat.getcwd() instead of os.getcwd()...
r30519 pycompat,
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768 repair,
Gregory Szorc
cmdutil: use absolute_import...
r28322 revlog,
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763 rewriteutil,
Gregory Szorc
cmdutil: use absolute_import...
r28322 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,
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 subrepoutil,
Gregory Szorc
cmdutil: use absolute_import...
r28322 templatekw,
templater,
util,
Pierre-Yves David
vfs: use 'vfs' module directly in 'mercurial.cmdutil'...
r31237 vfs as vfsmod,
Gregory Szorc
cmdutil: use absolute_import...
r28322 )
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102
from .utils import (
dateutil,
stringutil,
)
Yuya Nishihara
typing: consolidate "if not globals():" trick...
r44212 if pycompat.TYPE_CHECKING:
Augie Fackler
cmdutil: add a pytype annotation to help out some callsites...
r44099 from typing import (
Any,
Dict,
)
for t in (Any, Dict):
assert t
timeless
pycompat: switch to util.stringio for py3 compat
r28861 stringio = util.stringio
Vadim Gelfer
refactor text diff/patch code....
r2874
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 # templates of common command options
dryrunopts = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'n', b'dry-run', None, _(b'do not perform actions, just print output')),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ]
Sushil khanchi
rebase: add --confirm option...
r38689 confirmopts = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'', b'confirm', None, _(b'ask before applying actions')),
Sushil khanchi
rebase: add --confirm option...
r38689 ]
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 remoteopts = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'e', b'ssh', b'', _(b'specify ssh command to use'), _(b'CMD')),
Augie Fackler
formatting: blacken the codebase...
r43346 (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'',
b'remotecmd',
b'',
_(b'specify hg command to run on the remote side'),
_(b'CMD'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'',
b'insecure',
Augie Fackler
formatting: blacken the codebase...
r43346 None,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'do not verify server certificate (ignoring web.cacerts config)'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ]
walkopts = [
Augie Fackler
formatting: blacken the codebase...
r43346 (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'I',
b'include',
Augie Fackler
formatting: blacken the codebase...
r43346 [],
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'include names matching the given patterns'),
_(b'PATTERN'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'X',
b'exclude',
Augie Fackler
formatting: blacken the codebase...
r43346 [],
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'exclude names matching the given patterns'),
_(b'PATTERN'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ]
commitopts = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'm', b'message', b'', _(b'use text as commit message'), _(b'TEXT')),
(b'l', b'logfile', b'', _(b'read commit message from file'), _(b'FILE')),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ]
commitopts2 = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (
b'd',
b'date',
b'',
_(b'record the specified date as commit date'),
_(b'DATE'),
),
(
b'u',
b'user',
b'',
_(b'record the specified user as committer'),
_(b'USER'),
),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ]
Matt Harbison
uncommit: add options to update to the current user or current date...
r43173 commitopts3 = [
Augie Fackler
formatting: blacken the codebase...
r43346 (b'D', b'currentdate', None, _(b'record the current date as commit date')),
(b'U', b'currentuser', None, _(b'record the current user as committer')),
Matt Harbison
uncommit: add options to update to the current user or current date...
r43173 ]
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 formatteropts = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'T', b'template', b'', _(b'display with template'), _(b'TEMPLATE')),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ]
templateopts = [
Augie Fackler
formatting: blacken the codebase...
r43346 (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'',
b'style',
b'',
_(b'display using template map file (DEPRECATED)'),
_(b'STYLE'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'T', b'template', b'', _(b'display with template'), _(b'TEMPLATE')),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ]
logopts = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'p', b'patch', None, _(b'show patch')),
(b'g', b'git', None, _(b'use git extended diff format')),
(b'l', b'limit', b'', _(b'limit number of changes displayed'), _(b'NUM')),
(b'M', b'no-merges', None, _(b'do not show merges')),
(b'', b'stat', None, _(b'output diffstat-style summary of changes')),
(b'G', b'graph', None, _(b"show the revision DAG")),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ] + templateopts
diffopts = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'a', b'text', None, _(b'treat all files as text')),
Augie Fackler
cleanup: re-run black on the codebase...
r44787 (
b'g',
b'git',
None,
_(b'use git extended diff format (DEFAULT: diff.git)'),
),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'', b'binary', None, _(b'generate binary diffs in git mode (default)')),
(b'', b'nodates', None, _(b'omit dates from diff headers')),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ]
diffwsopts = [
Augie Fackler
formatting: blacken the codebase...
r43346 (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'w',
b'ignore-all-space',
Augie Fackler
formatting: blacken the codebase...
r43346 None,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'ignore white space when comparing lines'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'b',
b'ignore-space-change',
Augie Fackler
formatting: blacken the codebase...
r43346 None,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'ignore changes in the amount of white space'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'B',
b'ignore-blank-lines',
Augie Fackler
formatting: blacken the codebase...
r43346 None,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'ignore changes whose lines are all blank'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'Z',
b'ignore-space-at-eol',
Augie Fackler
formatting: blacken the codebase...
r43346 None,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'ignore changes in whitespace at EOL'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ]
Augie Fackler
formatting: blacken the codebase...
r43346 diffopts2 = (
[
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'', b'noprefix', None, _(b'omit a/ and b/ prefixes from filenames')),
Augie Fackler
formatting: blacken the codebase...
r43346 (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'p',
b'show-function',
Augie Fackler
formatting: blacken the codebase...
r43346 None,
Augie Fackler
cleanup: re-run black on the codebase...
r44787 _(
b'show which function each change is in (DEFAULT: diff.showfunc)'
),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'', b'reverse', None, _(b'produce a diff that undoes the changes')),
Augie Fackler
formatting: blacken the codebase...
r43346 ]
+ diffwsopts
+ [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (
b'U',
b'unified',
b'',
_(b'number of lines of context to show'),
_(b'NUM'),
),
(b'', b'stat', None, _(b'output diffstat-style summary of changes')),
(
b'',
b'root',
b'',
_(b'produce diffs relative to subdirectory'),
_(b'DIR'),
),
Augie Fackler
formatting: blacken the codebase...
r43346 ]
)
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375
mergetoolopts = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b't', b'tool', b'', _(b'specify merge tool'), _(b'TOOL')),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ]
similarityopts = [
Augie Fackler
formatting: blacken the codebase...
r43346 (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b's',
b'similarity',
b'',
_(b'guess renamed files by similarity (0<=s<=100)'),
_(b'SIMILARITY'),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 subrepoopts = [(b'S', b'subrepos', None, _(b'recurse into subrepositories'))]
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375
debugrevlogopts = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'c', b'changelog', False, _(b'open changelog')),
(b'm', b'manifest', False, _(b'open manifest')),
(b'', b'dir', b'', _(b'open directory manifest')),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ]
Sean Farley
cmdutil: add special string that ignores rest of text...
r30703 # special string such that everything below this line will be ingored in the
# editor text
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _linebelow = b"^HG: ------------------------ >8 ------------------------$"
Sean Farley
cmdutil: add special string that ignores rest of text...
r30703
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
clone: extract helper for checking mutually exclusive args...
r44344 def check_at_most_one_arg(opts, *args):
Martin von Zweigbergk
rebase: use cmdutil.check_at_most_one_arg() for action...
r44351 """abort if more than one of the arguments are in opts
Returns the unique argument or None if none of them were specified.
"""
Martin von Zweigbergk
cmdutil: return underscore-separate name from check_at_most_one_arg()...
r44394
def to_display(name):
Martin von Zweigbergk
cmdutil: allow native string as input to check_at_most_one_arg()...
r44395 return pycompat.sysbytes(name).replace(b'_', b'-')
Martin von Zweigbergk
cmdutil: return underscore-separate name from check_at_most_one_arg()...
r44394
Martin von Zweigbergk
clone: extract helper for checking mutually exclusive args...
r44344 previous = None
for x in args:
if opts.get(x):
if previous:
raise error.Abort(
Martin von Zweigbergk
cmdutil: return underscore-separate name from check_at_most_one_arg()...
r44394 _(b'cannot specify both --%s and --%s')
% (to_display(previous), to_display(x))
Martin von Zweigbergk
clone: extract helper for checking mutually exclusive args...
r44344 )
previous = x
Martin von Zweigbergk
rebase: use cmdutil.check_at_most_one_arg() for action...
r44351 return previous
Martin von Zweigbergk
clone: extract helper for checking mutually exclusive args...
r44344
Martin von Zweigbergk
cmdutil: change check_incompatible_arguments() *arg to single iterable...
r44655 def check_incompatible_arguments(opts, first, others):
Martin von Zweigbergk
releasenotes: extract helper for checking for incompatible arguments...
r44350 """abort if the first argument is given along with any of the others
Unlike check_at_most_one_arg(), `others` are not mutually exclusive
Martin von Zweigbergk
cmdutil: change check_incompatible_arguments() *arg to single iterable...
r44655 among themselves, and they're passed as a single collection.
Martin von Zweigbergk
releasenotes: extract helper for checking for incompatible arguments...
r44350 """
for other in others:
check_at_most_one_arg(opts, first, other)
Matt Harbison
uncommit: add options to update to the current user or current date...
r43173 def resolvecommitoptions(ui, opts):
"""modify commit options dict to handle related options
Matt Harbison
amend: add option to update to the current user...
r43202
The return value indicates that ``rewrite.update-timestamp`` is the reason
the ``date`` option is set.
Matt Harbison
uncommit: add options to update to the current user or current date...
r43173 """
Martin von Zweigbergk
commit: use cmdutil.check_at_most_one_arg()...
r44345 check_at_most_one_arg(opts, b'date', b'currentdate')
check_at_most_one_arg(opts, b'user', b'currentuser')
Matt Harbison
uncommit: make -D/--date and -U/--user mutually exclusive...
r43191
Matt Harbison
amend: add option to update to the current user...
r43202 datemaydiffer = False # date-only change should be ignored?
Matt Harbison
uncommit: make -D/--date and -U/--user mutually exclusive...
r43191 if opts.get(b'currentdate'):
Matt Harbison
uncommit: add options to update to the current user or current date...
r43173 opts[b'date'] = b'%d %d' % dateutil.makedate()
Augie Fackler
formatting: blacken the codebase...
r43346 elif (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 not opts.get(b'date')
and ui.configbool(b'rewrite', b'update-timestamp')
and opts.get(b'currentdate') is None
Augie Fackler
formatting: blacken the codebase...
r43346 ):
Matt Harbison
amend: add option to update to the current user...
r43202 opts[b'date'] = b'%d %d' % dateutil.makedate()
datemaydiffer = True
Matt Harbison
uncommit: make -D/--date and -U/--user mutually exclusive...
r43191 if opts.get(b'currentuser'):
Matt Harbison
uncommit: add options to update to the current user or current date...
r43173 opts[b'user'] = ui.username()
Matt Harbison
amend: add option to update to the current user...
r43202 return datemaydiffer
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
amend: prevent '\n' in the note string...
r43203 def checknotesize(ui, opts):
""" make sure note is of valid format """
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 note = opts.get(b'note')
Matt Harbison
amend: prevent '\n' in the note string...
r43203 if not note:
return
if len(note) > 255:
raise error.Abort(_(b"cannot store a note of more than 255 bytes"))
if b'\n' in note:
raise error.Abort(_(b"note cannot contain a newline"))
Augie Fackler
formatting: blacken the codebase...
r43346
Laurent Charignon
record: extract ishunk to a function...
r25256 def ishunk(x):
hunkclasses = (crecordmod.uihunk, patch.recordhunk)
return isinstance(x, hunkclasses)
Augie Fackler
formatting: blacken the codebase...
r43346
Laurent Charignon
record: extract code to compute newly added and modified files...
r25257 def newandmodified(chunks, originalchunks):
newlyaddedandmodifiedfiles = set()
Kyle Lippincott
split: handle partial commit of renames when doing split or record (issue5723)...
r43122 alsorestore = set()
Laurent Charignon
record: extract code to compute newly added and modified files...
r25257 for chunk in chunks:
Augie Fackler
formatting: blacken the codebase...
r43346 if (
ishunk(chunk)
and chunk.header.isnewfile()
and chunk not in originalchunks
):
Laurent Charignon
record: extract code to compute newly added and modified files...
r25257 newlyaddedandmodifiedfiles.add(chunk.header.filename())
Augie Fackler
formatting: blacken the codebase...
r43346 alsorestore.update(
set(chunk.header.files()) - {chunk.header.filename()}
)
Kyle Lippincott
split: handle partial commit of renames when doing split or record (issue5723)...
r43122 return newlyaddedandmodifiedfiles, alsorestore
Laurent Charignon
record: extract code to compute newly added and modified files...
r25257
Augie Fackler
formatting: blacken the codebase...
r43346
Brendan Cully
mq: add -Q option to all commands not in norepo
r10401 def parsealiases(cmd):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return cmd.split(b"|")
Brendan Cully
mq: add -Q option to all commands not in norepo
r10401
Augie Fackler
formatting: blacken the codebase...
r43346
Laurent Charignon
record: consolidate ui.write wrapping in a function
r24356 def setupwrapcolorwrite(ui):
# wrap ui.write so diff output can be labeled/colorized
def wrapwrite(orig, *args, **kw):
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 label = kw.pop('label', b'')
Laurent Charignon
record: consolidate ui.write wrapping in a function
r24356 for chunk, l in patch.difflabel(lambda: args):
orig(chunk, label=label + l)
oldwrite = ui.write
Augie Fackler
formatting: blacken the codebase...
r43346
Laurent Charignon
record: consolidate ui.write wrapping in a function
r24356 def wrap(*args, **kwargs):
return wrapwrite(oldwrite, *args, **kwargs)
Augie Fackler
formatting: blacken the codebase...
r43346
Laurent Charignon
record: consolidate ui.write wrapping in a function
r24356 setattr(ui, 'write', wrap)
return oldwrite
Augie Fackler
formatting: blacken the codebase...
r43346
def filterchunks(ui, originalhunks, usecurses, testfile, match, operation=None):
Kyle Lippincott
crecord: fallback to text mode if diffs are too big for curses mode...
r38058 try:
if usecurses:
if testfile:
recordfn = crecordmod.testdecorator(
Augie Fackler
formatting: blacken the codebase...
r43346 testfile, crecordmod.testchunkselector
)
Kyle Lippincott
crecord: fallback to text mode if diffs are too big for curses mode...
r38058 else:
recordfn = crecordmod.chunkselector
Augie Fackler
formatting: blacken the codebase...
r43346 return crecordmod.filterpatch(
ui, originalhunks, recordfn, operation
)
Kyle Lippincott
crecord: fallback to text mode if diffs are too big for curses mode...
r38058 except crecordmod.fallbackerror as e:
Kyle Lippincott
py3: fix curses chunkselector fallback (when diffs are too large) on py3...
r44557 ui.warn(b'%s\n' % e)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.warn(_(b'falling back to text mode\n'))
Kyle Lippincott
crecord: fallback to text mode if diffs are too big for curses mode...
r38058
Denis Laxalde
interactive: do not prompt about files given in command line...
r42238 return patch.filterpatch(ui, originalhunks, match, operation)
Augie Fackler
formatting: blacken the codebase...
r43346
Denis Laxalde
interactive: do not prompt about files given in command line...
r42238 def recordfilter(ui, originalhunks, match, operation=None):
Laurent Charignon
record: add an operation arguments to customize recording ui...
r25310 """ Prompts the user to filter the originalhunks and return a list of
selected hunks.
Denis Laxalde
patch: define full messages for interactive record/revert...
r29326 *operation* is used for to build ui messages to indicate the user what
kind of filtering they are doing: reverting, committing, shelving, etc.
(see patch.filterpatch).
Laurent Charignon
record: add an operation arguments to customize recording ui...
r25310 """
Sean Farley
cmdutil: use crecordmod.checkcurses...
r27531 usecurses = crecordmod.checkcurses(ui)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 testfile = ui.config(b'experimental', b'crecordtest')
Laurent Charignon
record: move ui.write wrapping where it should be...
r24358 oldwrite = setupwrapcolorwrite(ui)
try:
Augie Fackler
formatting: blacken the codebase...
r43346 newchunks, newopts = filterchunks(
ui, originalhunks, usecurses, testfile, match, operation
)
Laurent Charignon
record: move ui.write wrapping where it should be...
r24358 finally:
ui.write = oldwrite
Laurent Charignon
commit: add a way to return more information from the chunkselector...
r27155 return newchunks, newopts
Laurent Charignon
record: refactor the filtering code
r24357
Augie Fackler
formatting: blacken the codebase...
r43346
def dorecord(
ui, repo, commitfunc, cmdsuggest, backupall, filterfn, *pats, **opts
):
Pulkit Goyal
py3: convert opts to bytes in cmdutil.dorecord()...
r32144 opts = pycompat.byteskwargs(opts)
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 if not ui.interactive():
FUJIWARA Katsunori
cmdutil: allow callers of cmdutil.dorecord to omit suggestion...
r25795 if cmdsuggest:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg = _(b'running non-interactively, use %s instead') % cmdsuggest
FUJIWARA Katsunori
cmdutil: allow callers of cmdutil.dorecord to omit suggestion...
r25795 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg = _(b'running non-interactively')
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(msg)
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272
# make sure username is set before going interactive
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not opts.get(b'user'):
Augie Fackler
formatting: blacken the codebase...
r43346 ui.username() # raise exception, username not provided
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272
def recordfunc(ui, repo, message, match, opts):
"""This is generic record driver.
Its job is to interactively filter local changes, and
accordingly prepare working directory into a state in which the
job can be delegated to a non-interactive commit command such as
'commit' or 'qrefresh'.
After the actual job is done by non-interactive command, the
working directory is restored to its original state.
In the end we'll record interesting changes, and everything else
will be left in place, so the user can continue working.
"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not opts.get(b'interactive-unshelve'):
Navaneeth Suresh
unshelve: add interactive mode...
r42835 checkunfinished(repo, commit=True)
timeless
crecord: check for untracked arguments...
r28815 wctx = repo[None]
merge = len(wctx.parents()) > 1
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 if merge:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'cannot partially commit a merge '
b'(use "hg commit" instead)'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272
Matt Harbison
commit: allow --interactive to work again when naming a directory (issue6131)
r42444 def fail(f, msg):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(b'%s: %s' % (f, msg))
force = opts.get(b'force')
Matt Harbison
commit: allow --interactive to work again when naming a directory (issue6131)
r42444 if not force:
Matt Harbison
record: avoid modifying the matcher passed as a method parameter...
r42456 match = matchmod.badmatch(match, fail)
Matt Harbison
commit: allow --interactive to work again when naming a directory (issue6131)
r42444
Matt Harbison
record: prevent commits that don't pick up dirty subrepo changes (issue6102)...
r42143 status = repo.status(match=match)
overrides = {(b'ui', b'commitsubrepos'): True}
with repo.ui.configoverride(overrides, b'record'):
# subrepoutil.precommit() modifies the status
Augie Fackler
formatting: blacken the codebase...
r43346 tmpstatus = scmutil.status(
Augie Fackler
cmdutil: use field names instead of field numbers on scmutil.status...
r44043 copymod.copy(status.modified),
copymod.copy(status.added),
copymod.copy(status.removed),
copymod.copy(status.deleted),
copymod.copy(status.unknown),
copymod.copy(status.ignored),
copymod.copy(status.clean), # pytype: disable=wrong-arg-count
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
record: prevent commits that don't pick up dirty subrepo changes (issue6102)...
r42143
# Force allows -X subrepo to skip the subrepo.
subs, commitsubs, newstate = subrepoutil.precommit(
Augie Fackler
formatting: blacken the codebase...
r43346 repo.ui, wctx, tmpstatus, match, force=True
)
Matt Harbison
record: prevent commits that don't pick up dirty subrepo changes (issue6102)...
r42143 for s in subs:
if s in commitsubs:
dirtyreason = wctx.sub(s).dirtyreason(True)
raise error.Abort(dirtyreason)
timeless
crecord: check for untracked arguments...
r28815 if not force:
Martin von Zweigbergk
commit: drop unused "vdirs" argument from repo.checkcommitpatterns()...
r44111 repo.checkcommitpatterns(wctx, match, status, fail)
Augie Fackler
formatting: blacken the codebase...
r43346 diffopts = patch.difffeatureopts(
ui,
opts=opts,
whitespace=True,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 section=b'commands',
configprefix=b'commit.interactive.',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 diffopts.nodates = True
diffopts.git = True
timeless
record: turn on showfunc...
r27411 diffopts.showfunc = True
timeless
cleanup: remove superfluous space after space after equals (python)
r27637 originaldiff = patch.diff(repo, changes=status, opts=diffopts)
Laurent Charignon
record: change interface of the filtering function...
r24341 originalchunks = patch.parsepatch(originaldiff)
Denis Laxalde
interactive: do not prompt about files given in command line...
r42238 match = scmutil.match(repo[None], pats)
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272
Jordi Gutiérrez Hermoso
crecord: rewrite a comment about filtering patches...
r28570 # 1. filter patch, since we are intending to apply subset of it
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 try:
Denis Laxalde
interactive: do not prompt about files given in command line...
r42238 chunks, newopts = filterfn(ui, originalchunks, match)
Yuya Nishihara
error: move patch.PatchError so it can easily implement __bytes__ (API)
r34252 except error.PatchError as err:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'error parsing patch: %s') % err)
Laurent Charignon
commit: add a way to return more information from the chunkselector...
r27155 opts.update(newopts)
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272
Laurent Charignon
record: edit patch of newly added files (issue4304)...
r24845 # We need to keep a backup of files that have been newly added and
# modified during the recording process because there is a previous
Kyle Lippincott
split: handle partial commit of renames when doing split or record (issue5723)...
r43122 # version without the edit in the workdir. We also will need to restore
# files that were the sources of renames so that the patch application
# works.
Augie Fackler
formatting: blacken the codebase...
r43346 newlyaddedandmodifiedfiles, alsorestore = newandmodified(
chunks, originalchunks
)
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 contenders = set()
for h in chunks:
try:
contenders.update(set(h.files()))
except AttributeError:
pass
changed = status.modified + status.added + status.removed
newfiles = [f for f in changed if f in contenders]
if not newfiles:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'no changes to record\n'))
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 return 0
modified = set(status.modified)
# 2. backup changed files, so we can restore them in the end
if backupall:
tobackup = changed
else:
Augie Fackler
formatting: blacken the codebase...
r43346 tobackup = [
f
for f in newfiles
if f in modified or f in newlyaddedandmodifiedfiles
]
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 backups = {}
if tobackup:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 backupdir = repo.vfs.join(b'record-backups')
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 try:
os.mkdir(backupdir)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except OSError as err:
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 if err.errno != errno.EEXIST:
raise
try:
# backup continues
for f in tobackup:
Augie Fackler
formatting: blacken the codebase...
r43346 fd, tmpname = pycompat.mkstemp(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prefix=f.replace(b'/', b'_') + b'.', dir=backupdir
Augie Fackler
formatting: blacken the codebase...
r43346 )
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 os.close(fd)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.debug(b'backup %r as %r\n' % (f, tmpname))
Siddharth Agarwal
record: don't dereference symlinks while copying over stat data...
r27370 util.copyfile(repo.wjoin(f), tmpname, copystat=True)
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 backups[f] = tmpname
timeless
pycompat: switch to util.stringio for py3 compat
r28861 fp = stringio()
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 for c in chunks:
fname = c.filename()
Laurent Charignon
record: fix record with change on moved file crashes (issue4619)...
r24837 if fname in backups:
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 c.write(fp)
dopatch = fp.tell()
fp.seek(0)
Jordi Gutiérrez Hermoso
crecord: re-enable reviewing a patch before comitting it...
r28638 # 2.5 optionally review / modify patch in text editor
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'review', False):
Augie Fackler
formatting: blacken the codebase...
r43346 patchtext = (
crecordmod.diffhelptext
+ crecordmod.patchhelptext
+ fp.read()
)
reviewedpatch = ui.edit(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 patchtext, b"", action=b"diff", repopath=repo.path
Augie Fackler
formatting: blacken the codebase...
r43346 )
Jordi Gutiérrez Hermoso
crecord: re-enable reviewing a patch before comitting it...
r28638 fp.truncate(0)
fp.write(reviewedpatch)
fp.seek(0)
Laurent Charignon
record: fix adding new file with record from within a subdir (issue4626)...
r24866 [os.unlink(repo.wjoin(c)) for c in newlyaddedandmodifiedfiles]
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 # 3a. apply filtered patch to clean repo (clean)
if backups:
Kyle Lippincott
split: handle partial commit of renames when doing split or record (issue5723)...
r43122 m = scmutil.matchfiles(repo, set(backups.keys()) | alsorestore)
Martin von Zweigbergk
merge: introduce a revert_to() for that use-case...
r44744 mergemod.revert_to(repo[b'.'], matcher=m)
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272
# 3b. (apply)
if dopatch:
try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.debug(b'applying patch\n')
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 ui.debug(fp.getvalue())
patch.internalpatch(ui, repo, fp, 1, eolmode=None)
Yuya Nishihara
error: move patch.PatchError so it can easily implement __bytes__ (API)
r34252 except error.PatchError as err:
Pulkit Goyal
py3: use pycompat.bytestr instead of str...
r36736 raise error.Abort(pycompat.bytestr(err))
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 del fp
# 4. We prepared working directory according to filtered
# patch. Now is the time to delegate the job to
# commit/qrefresh or the like!
# Make all of the pathnames absolute.
newfiles = [repo.wjoin(nf) for nf in newfiles]
Pulkit Goyal
py3: handle keyword arguments correctly in cmdutil.py...
r35351 return commitfunc(ui, repo, *newfiles, **pycompat.strkwargs(opts))
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 finally:
# 5. finally restore backed-up files
try:
FUJIWARA Katsunori
cmdutil: apply dirstate.normallookup on (maybe partially) committed files...
r25759 dirstate = repo.dirstate
Gregory Szorc
py3: finish porting iteritems() to pycompat and remove source transformer...
r43376 for realname, tmpname in pycompat.iteritems(backups):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.debug(b'restoring %r to %r\n' % (tmpname, realname))
if dirstate[realname] == b'n':
FUJIWARA Katsunori
cmdutil: apply dirstate.normallookup on (maybe partially) committed files...
r25759 # without normallookup, restoring timestamp
# may cause partially committed files
# to be treated as unmodified
dirstate.normallookup(realname)
Siddharth Agarwal
record: don't dereference symlinks while copying over stat data...
r27370 # copystat=True here and above are a hack to trick any
# editors that have f open that we haven't modified them.
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 #
Siddharth Agarwal
record: don't dereference symlinks while copying over stat data...
r27370 # Also note that this racy as an editor could notice the
# file's mtime before we've finished writing it.
util.copyfile(tmpname, repo.wjoin(realname), copystat=True)
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272 os.unlink(tmpname)
if tobackup:
os.rmdir(backupdir)
except OSError:
pass
FUJIWARA Katsunori
cmdutil: put recordfunc invocation into wlock scope for consistency...
r25758 def recordinwlock(ui, repo, message, match, opts):
Bryan O'Sullivan
with: use context manager for wlock in recordinwlock
r27801 with repo.wlock():
FUJIWARA Katsunori
cmdutil: put recordfunc invocation into wlock scope for consistency...
r25758 return recordfunc(ui, repo, message, match, opts)
return commit(ui, repo, recordinwlock, pats, opts)
Laurent Charignon
record: move dorecord from record to cmdutil...
r24272
Augie Fackler
formatting: blacken the codebase...
r43346
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683 class dirnode(object):
Pulkit Goyal
status: add a flag to terse the output (issue4119)...
r33548 """
Denis Laxalde
tersestatus: rework dirnode and tersedir docstrings...
r34699 Represent a directory in user working copy with information required for
the purpose of tersing its status.
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683
Matt Harbison
cmdutil: use internal separators when building the terse list...
r38221 path is the path to the directory, without a trailing '/'
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683
statuses is a set of statuses of all files in this directory (this includes
all the files in all the subdirectories too)
files is a list of files which are direct child of this directory
subdirs is a dictionary of sub-directory name as the key and it's own
dirnode object as the value
"""
def __init__(self, dirpath):
self.path = dirpath
Martin von Zweigbergk
cleanup: use set literals where possible...
r42224 self.statuses = set()
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683 self.files = []
self.subdirs = {}
def _addfileindir(self, filename, status):
Denis Laxalde
tersestatus: rework dirnode and tersedir docstrings...
r34699 """Add a file in this directory as a direct child."""
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683 self.files.append((filename, status))
def addfile(self, filename, status):
Pulkit Goyal
status: add a flag to terse the output (issue4119)...
r33548 """
Denis Laxalde
tersestatus: rework dirnode and tersedir docstrings...
r34699 Add a file to this directory or to its direct parent directory.
If the file is not direct child of this directory, we traverse to the
directory of which this file is a direct child of and add the file
there.
Pulkit Goyal
status: add a flag to terse the output (issue4119)...
r33548 """
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683
# the filename contains a path separator, it means it's not the direct
# child of this directory
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'/' in filename:
subdir, filep = filename.split(b'/', 1)
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683
# does the dirnode object for subdir exists
if subdir not in self.subdirs:
Matt Harbison
cmdutil: use internal separators when building the terse list...
r38221 subdirpath = pathutil.join(self.path, subdir)
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683 self.subdirs[subdir] = dirnode(subdirpath)
# try adding the file in subdir
self.subdirs[subdir].addfile(filep, status)
else:
self._addfileindir(filename, status)
if status not in self.statuses:
self.statuses.add(status)
Denis Laxalde
tersestatus: avoid modifying tersedict...
r34685 def iterfilepaths(self):
Denis Laxalde
tersestatus: rework dirnode and tersedir docstrings...
r34699 """Yield (status, path) for files directly under this directory."""
Denis Laxalde
tersestatus: make methods part of the dirnode class...
r34684 for f, st in self.files:
Matt Harbison
cmdutil: use internal separators when building the terse list...
r38221 yield st, pathutil.join(self.path, f)
Denis Laxalde
tersestatus: avoid modifying tersedict...
r34685
def tersewalk(self, terseargs):
Denis Laxalde
tersestatus: make methods part of the dirnode class...
r34684 """
Denis Laxalde
tersestatus: rework dirnode and tersedir docstrings...
r34699 Yield (status, path) obtained by processing the status of this
dirnode.
Denis Laxalde
tersestatus: make methods part of the dirnode class...
r34684
terseargs is the string of arguments passed by the user with `--terse`
flag.
Following are the cases which can happen:
1) All the files in the directory (including all the files in its
subdirectories) share the same status and the user has asked us to terse
Matt Harbison
cmdutil: use internal separators when building the terse list...
r38221 that status. -> yield (status, dirpath). dirpath will end in '/'.
Denis Laxalde
tersestatus: make methods part of the dirnode class...
r34684
Denis Laxalde
tersestatus: rework dirnode and tersedir docstrings...
r34699 2) Otherwise, we do following:
Denis Laxalde
tersestatus: make methods part of the dirnode class...
r34684
Denis Laxalde
tersestatus: avoid modifying tersedict...
r34685 a) Yield (status, filepath) for all the files which are in this
directory (only the ones in this directory, not the subdirs)
Denis Laxalde
tersestatus: make methods part of the dirnode class...
r34684
b) Recurse the function on all the subdirectories of this
directory
"""
if len(self.statuses) == 1:
onlyst = self.statuses.pop()
# Making sure we terse only when the status abbreviation is
# passed as terse argument
if onlyst in terseargs:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 yield onlyst, self.path + b'/'
Denis Laxalde
tersestatus: make methods part of the dirnode class...
r34684 return
# add the files to status list
Denis Laxalde
tersestatus: avoid modifying tersedict...
r34685 for st, fpath in self.iterfilepaths():
yield st, fpath
Denis Laxalde
tersestatus: make methods part of the dirnode class...
r34684
Augie Fackler
formatting: blacken the codebase...
r43346 # recurse on the subdirs
Denis Laxalde
tersestatus: make methods part of the dirnode class...
r34684 for dirobj in self.subdirs.values():
Denis Laxalde
tersestatus: avoid modifying tersedict...
r34685 for st, fpath in dirobj.tersewalk(terseargs):
yield st, fpath
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683
Augie Fackler
formatting: blacken the codebase...
r43346
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683 def tersedir(statuslist, terseargs):
"""
Denis Laxalde
tersestatus: rework dirnode and tersedir docstrings...
r34699 Terse the status if all the files in a directory shares the same status.
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683
statuslist is scmutil.status() object which contains a list of files for
each status.
terseargs is string which is passed by the user as the argument to `--terse`
flag.
The function makes a tree of objects of dirnode class, and at each node it
stores the information required to know whether we can terse a certain
directory or not.
"""
# the order matters here as that is used to produce final list
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 allst = (b'm', b'a', b'r', b'd', b'u', b'i', b'c')
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683
# checking the argument validity
Augie Fackler
cmdutil: fix status tersing on Python 3...
r34894 for s in pycompat.bytestr(terseargs):
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683 if s not in allst:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"'%s' not recognized") % s)
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683
# creating a dirnode object for the root of the repo
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 rootobj = dirnode(b'')
Augie Fackler
formatting: blacken the codebase...
r43346 pstatus = (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'modified',
b'added',
b'deleted',
b'clean',
b'unknown',
b'ignored',
b'removed',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683
tersedict = {}
for attrname in pstatus:
Augie Fackler
cmdutil: fix status tersing on Python 3...
r34894 statuschar = attrname[0:1]
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683 for f in getattr(statuslist, attrname):
Augie Fackler
cmdutil: fix status tersing on Python 3...
r34894 rootobj.addfile(f, statuschar)
tersedict[statuschar] = []
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683
# we won't be tersing the root dir, so add files in it
Denis Laxalde
tersestatus: avoid modifying tersedict...
r34685 for st, fpath in rootobj.iterfilepaths():
tersedict[st].append(fpath)
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683
# process each sub-directory and build tersedict
for subdir in rootobj.subdirs.values():
Denis Laxalde
tersestatus: avoid modifying tersedict...
r34685 for st, f in subdir.tersewalk(terseargs):
tersedict[st].append(f)
Pulkit Goyal
tersestatus: re-implement the functionality to terse the status...
r34683
tersedlist = []
for st in allst:
tersedict[st].sort()
tersedlist.append(tersedict[st])
Augie Fackler
cmdutil: convert terse status result back to an scmutil.status...
r44044 return scmutil.status(*tersedlist)
Pulkit Goyal
status: add a flag to terse the output (issue4119)...
r33548
Augie Fackler
formatting: blacken the codebase...
r43346
Pulkit Goyal
morestatus: move fb extension to core by plugging to `hg status --verbose`...
r33766 def _commentlines(raw):
'''Surround lineswith a comment char and a new line'''
lines = raw.splitlines()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 commentedlines = [b'# %s' % line for line in lines]
return b'\n'.join(commentedlines) + b'\n'
Pulkit Goyal
morestatus: move fb extension to core by plugging to `hg status --verbose`...
r33766
Augie Fackler
formatting: blacken the codebase...
r43346
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293 @attr.s(frozen=True)
class morestatus(object):
reporoot = attr.ib()
unfinishedop = attr.ib()
unfinishedmsg = attr.ib()
Rodrigo Damazio Bovendorp
status: extract active-merge state for reuse...
r44390 activemerge = attr.ib()
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293 unresolvedpaths = attr.ib()
Rodrigo Damazio Bovendorp
status: make unresolved files always be in the morestatus structured output...
r44392 _formattedpaths = attr.ib(init=False, default=set())
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293 _label = b'status.morestatus'
Rodrigo Damazio Bovendorp
status: add template/json data about whether a file has unresolved conflicts...
r44294 def formatfile(self, path, fm):
Rodrigo Damazio Bovendorp
status: make unresolved files always be in the morestatus structured output...
r44392 self._formattedpaths.add(path)
Rodrigo Damazio Bovendorp
status: extract active-merge state for reuse...
r44390 if self.activemerge and path in self.unresolvedpaths:
Rodrigo Damazio Bovendorp
status: add template/json data about whether a file has unresolved conflicts...
r44294 fm.data(unresolved=True)
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293 def formatfooter(self, fm):
Rodrigo Damazio Bovendorp
status: make morestatus call out unresolved conflicts after update...
r44391 if self.unfinishedop or self.unfinishedmsg:
fm.startitem()
fm.data(itemtype=b'morestatus')
if self.unfinishedop:
fm.data(unfinished=self.unfinishedop)
statemsg = (
_(b'The repository is in an unfinished *%s* state.')
% self.unfinishedop
)
fm.plain(b'%s\n' % _commentlines(statemsg), label=self._label)
if self.unfinishedmsg:
fm.data(unfinishedmsg=self.unfinishedmsg)
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293
Rodrigo Damazio Bovendorp
status: make unresolved files always be in the morestatus structured output...
r44392 # May also start new data items.
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293 self._formatconflicts(fm)
Rodrigo Damazio Bovendorp
status: make morestatus call out unresolved conflicts after update...
r44391
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293 if self.unfinishedmsg:
Martin von Zweigbergk
formatting: fix some recent formatting regressions...
r44307 fm.plain(
b'%s\n' % _commentlines(self.unfinishedmsg), label=self._label
)
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293
def _formatconflicts(self, fm):
Rodrigo Damazio Bovendorp
status: extract active-merge state for reuse...
r44390 if not self.activemerge:
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293 return
if self.unresolvedpaths:
mergeliststr = b'\n'.join(
[
Martin von Zweigbergk
formatting: fix some recent formatting regressions...
r44307 b' %s'
% util.pathto(self.reporoot, encoding.getcwd(), path)
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293 for path in self.unresolvedpaths
]
)
msg = (
_(
'''Unresolved merge conflicts:
Pulkit Goyal
morestatus: move fb extension to core by plugging to `hg status --verbose`...
r33766
%s
Augie Fackler
formatting: blacken the codebase...
r43346 To mark files as resolved: hg resolve --mark FILE'''
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293 )
% mergeliststr
Augie Fackler
formatting: blacken the codebase...
r43346 )
Rodrigo Damazio Bovendorp
status: make unresolved files always be in the morestatus structured output...
r44392
# If any paths with unresolved conflicts were not previously
# formatted, output them now.
for f in self.unresolvedpaths:
if f in self._formattedpaths:
# Already output.
continue
fm.startitem()
# We can't claim to know the status of the file - it may just
# have been in one of the states that were not requested for
# display, so it could be anything.
fm.data(itemtype=b'file', path=f, unresolved=True)
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293 else:
msg = _(b'No unresolved merge conflicts.')
fm.plain(b'%s\n' % _commentlines(msg), label=self._label)
def readmorestatus(repo):
"""Returns a morestatus object if the repo has unfinished state."""
Taapas Agrawal
state: moved cmdutil.STATES and utilities to state.py...
r42731 statetuple = statemod.getrepostate(repo)
Rodrigo Damazio Bovendorp
status: extract active-merge state for reuse...
r44390 mergestate = mergemod.mergestate.read(repo)
activemerge = mergestate.active()
Rodrigo Damazio Bovendorp
status: make morestatus call out unresolved conflicts after update...
r44391 if not statetuple and not activemerge:
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293 return None
Rodrigo Damazio Bovendorp
status: make morestatus call out unresolved conflicts after update...
r44391 unfinishedop = unfinishedmsg = unresolved = None
if statetuple:
unfinishedop, unfinishedmsg = statetuple
Rodrigo Damazio Bovendorp
status: extract active-merge state for reuse...
r44390 if activemerge:
Rodrigo Damazio Bovendorp
status: split morestatus data loading from display...
r44293 unresolved = sorted(mergestate.unresolved())
Martin von Zweigbergk
formatting: fix some recent formatting regressions...
r44307 return morestatus(
Rodrigo Damazio Bovendorp
status: extract active-merge state for reuse...
r44390 repo.root, unfinishedop, unfinishedmsg, activemerge, unresolved
Martin von Zweigbergk
formatting: fix some recent formatting regressions...
r44307 )
Pulkit Goyal
morestatus: move fb extension to core by plugging to `hg status --verbose`...
r33766
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
findcmd: have dispatch look up strict flag
r7213 def findpossible(cmd, table, strict=False):
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549 """
Return cmd -> (aliases, command table entry)
for each matching command.
Return debug commands (or their aliases) only if no normal command matches.
"""
choice = {}
debugchoice = {}
Matt Mackall
alias: shortcut command matching show shadowing works properly (issue3104)...
r15600
if cmd in table:
Rodrigo Damazio
help: adding a proper declaration for shortlist/basic commands (API)...
r40331 # short-circuit exact matches, "log" alias beats "log|history"
Matt Mackall
alias: shortcut command matching show shadowing works properly (issue3104)...
r15600 keys = [cmd]
else:
keys = table.keys()
Augie Fackler
dispatch: offer suggestions of similar-named commands...
r24222 allcmds = []
Matt Mackall
alias: shortcut command matching show shadowing works properly (issue3104)...
r15600 for e in keys:
Brendan Cully
mq: add -Q option to all commands not in norepo
r10401 aliases = parsealiases(e)
Augie Fackler
dispatch: offer suggestions of similar-named commands...
r24222 allcmds.extend(aliases)
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549 found = None
if cmd in aliases:
found = cmd
Matt Mackall
findcmd: have dispatch look up strict flag
r7213 elif not strict:
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549 for a in aliases:
if a.startswith(cmd):
found = a
break
if found is not None:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if aliases[0].startswith(b"debug") or found.startswith(b"debug"):
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 debugchoice[found] = (aliases, table[e])
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549 else:
Matt Mackall
dispatch: move command dispatching into its own module...
r5178 choice[found] = (aliases, table[e])
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549
if not choice and debugchoice:
choice = debugchoice
Augie Fackler
dispatch: offer suggestions of similar-named commands...
r24222 return choice, allcmds
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
findcmd: have dispatch look up strict flag
r7213 def findcmd(cmd, table, strict=True):
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549 """Return (aliases, command table entry) for command string."""
Augie Fackler
dispatch: offer suggestions of similar-named commands...
r24222 choice, allcmds = findpossible(cmd, table, strict)
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549
Christian Ebert
Prefer i in d over d.has_key(i)
r5915 if cmd in choice:
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549 return choice[cmd]
if len(choice) > 1:
Augie Fackler
cmdutil: use sorted(dict) instead of x = dict.keys(); x.sort()...
r32528 clist = sorted(choice)
Matt Mackall
error: move UnknownCommand and AmbiguousCommand
r7643 raise error.AmbiguousCommand(cmd, clist)
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549
if choice:
Pulkit Goyal
py3: explicitly convert dict.values() to a list on py3...
r32862 return list(choice.values())[0]
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549
Augie Fackler
dispatch: offer suggestions of similar-named commands...
r24222 raise error.UnknownCommand(cmd, allcmds)
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549
Augie Fackler
formatting: blacken the codebase...
r43346
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763 def changebranch(ui, repo, revs, label):
""" Change the branch name of given revs to label """
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 with repo.wlock(), repo.lock(), repo.transaction(b'branches'):
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763 # abort in case of uncommitted merge or dirty wdir
bailifchanged(repo)
revs = scmutil.revrange(repo, revs)
if not revs:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(b"empty revision set")
roots = repo.revs(b'roots(%ld)', revs)
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763 if len(roots) > 1:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(
_(b"cannot change branch of non-linear revisions")
)
rewriteutil.precheck(repo, revs, b'change branch of')
Pulkit Goyal
branch: allow changing branch name to existing name if possible...
r35764
root = repo[roots.first()]
av6
branch: allow changing branch of merge commits with --rev...
r40702 rpb = {parent.branch() for parent in root.parents()}
if label not in rpb and label in repo.branchmap():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"a branch of the same name already exists"))
if repo.revs(b'obsolete() and %ld', revs):
raise error.Abort(
_(b"cannot change branch of a obsolete changeset")
)
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763
# make sure only topological heads
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if repo.revs(b'heads(%ld) - head()', revs):
raise error.Abort(_(b"cannot change branch in middle of a stack"))
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763
replacements = {}
# avoid import cycle mercurial.cmdutil -> mercurial.context ->
# mercurial.subrepo -> mercurial.cmdutil
from . import context
Augie Fackler
formatting: blacken the codebase...
r43346
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763 for rev in revs:
ctx = repo[rev]
oldbranch = ctx.branch()
# check if ctx has same branch
if oldbranch == label:
continue
def filectxfn(repo, newctx, path):
try:
return ctx[path]
except error.ManifestLookupError:
return None
Augie Fackler
formatting: blacken the codebase...
r43346 ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"changing branch of '%s' from '%s' to '%s'\n"
Augie Fackler
formatting: blacken the codebase...
r43346 % (hex(ctx.node()), oldbranch, label)
)
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763 extra = ctx.extra()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extra[b'branch_change'] = hex(ctx.node())
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763 # While changing branch of set of linear commits, make sure that
# we base our commits on new parent rather than old parent which
# was obsoleted while changing the branch
p1 = ctx.p1().node()
p2 = ctx.p2().node()
if p1 in replacements:
p1 = replacements[p1][0]
if p2 in replacements:
p2 = replacements[p2][0]
Augie Fackler
formatting: blacken the codebase...
r43346 mc = context.memctx(
repo,
(p1, p2),
ctx.description(),
ctx.files(),
filectxfn,
user=ctx.user(),
date=ctx.date(),
extra=extra,
branch=label,
)
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763
Martin von Zweigbergk
scmutil: make cleanupnodes optionally also fix the phase...
r38442 newnode = repo.commitctx(mc)
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763 replacements[ctx.node()] = (newnode,)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.debug(b'new node id is %s\n' % hex(newnode))
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763
# create obsmarkers and move bookmarks
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 scmutil.cleanupnodes(
repo, replacements, b'branch-change', fixphase=True
)
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763
# move the working copy too
wctx = repo[None]
# in-progress merge is a bit too complex for now.
if len(wctx.parents()) == 1:
newid = replacements.get(wctx.p1().node())
if newid is not None:
# avoid import cycle mercurial.cmdutil -> mercurial.hg ->
# mercurial.cmdutil
from . import hg
Augie Fackler
formatting: blacken the codebase...
r43346
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763 hg.update(repo, newid[0], quietempty=True)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b"changed branch on %d changesets\n") % len(replacements))
Pulkit Goyal
branch: add a --rev flag to change branch name of given revisions...
r35763
Augie Fackler
formatting: blacken the codebase...
r43346
Brendan Cully
mq: make init -Q do what qinit -c did
r10402 def findrepo(p):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 while not os.path.isdir(os.path.join(p, b".hg")):
Brendan Cully
mq: make init -Q do what qinit -c did
r10402 oldp, p = p, os.path.dirname(p)
if p == oldp:
return None
return p
Augie Fackler
formatting: blacken the codebase...
r43346
Valters Vingolds
rebase: provide detailed hint to abort message if working dir is not clean...
r30755 def bailifchanged(repo, merge=True, hint=None):
""" enforce the precondition that working directory must be clean.
'merge' can be set to false if a pending uncommitted merge should be
ignored (such as when 'update --check' runs).
'hint' is the usual hint given to Abort exception.
"""
FUJIWARA Katsunori
cmdutil: allow bailifchanged to ignore merging in progress...
r24472 if merge and repo.dirstate.p2() != nullid:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'outstanding uncommitted merge'), hint=hint)
Augie Fackler
cmdutil: use field names instead of field numbers on scmutil.status...
r44043 st = repo.status()
if st.modified or st.added or st.removed or st.deleted:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'uncommitted changes'), hint=hint)
Eric Roshan Eisner
cmdutil.bailifchanged: abort for dirty subrepos
r15231 ctx = repo[None]
Mads Kiilerich
subrepos: process subrepos in sorted order...
r18364 for s in sorted(ctx.substate):
Valters Vingolds
rebase: provide detailed hint to abort message if working dir is not clean...
r30755 ctx.sub(s).bailifchanged(hint=hint)
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549
Augie Fackler
formatting: blacken the codebase...
r43346
Idan Kamara
cmdutil, logmessage: use ui.fin when reading from '-'
r14635 def logmessage(ui, opts):
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549 """ get the log message according to -m and -l option """
Martin von Zweigbergk
amend: use cmdutil.check_at_most_one_arg()...
r44346
check_at_most_one_arg(opts, b'message', b'logfile')
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 message = opts.get(b'message')
logfile = opts.get(b'logfile')
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549
if not message and logfile:
try:
Yuya Nishihara
cmdutil: use isstdiofilename() where appropriate
r32618 if isstdiofilename(logfile):
Idan Kamara
cmdutil, logmessage: use ui.fin when reading from '-'
r14635 message = ui.fin.read()
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 message = b'\n'.join(util.readfile(logfile).splitlines())
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except IOError as inst:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"can't read commit message '%s': %s")
Augie Fackler
formatting: blacken the codebase...
r43346 % (logfile, encoding.strtolocal(inst.strerror))
)
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549 return message
Augie Fackler
formatting: blacken the codebase...
r43346
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r24180 def mergeeditform(ctxorbool, baseformname):
"""return appropriate editform name (referencing a committemplate)
'ctxorbool' is either a ctx to be committed, or a bool indicating whether
FUJIWARA Katsunori
commit: change "editform" to distinguish merge commits from others...
r22248 merging is committed.
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r24180 This returns baseformname with '.merge' appended if it is a merge,
otherwise '.normal' is appended.
FUJIWARA Katsunori
commit: change "editform" to distinguish merge commits from others...
r22248 """
if isinstance(ctxorbool, bool):
if ctxorbool:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return baseformname + b".merge"
Martin von Zweigbergk
cleanup: some Yoda conditions, this patch removes...
r40065 elif len(ctxorbool.parents()) > 1:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return baseformname + b".merge"
return baseformname + b".normal"
FUJIWARA Katsunori
commit: change "editform" to distinguish merge commits from others...
r22248
Augie Fackler
formatting: blacken the codebase...
r43346
def getcommiteditor(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 edit=False, finishdesc=None, extramsg=None, editform=b'', **opts
Augie Fackler
formatting: blacken the codebase...
r43346 ):
FUJIWARA Katsunori
cmdutil: enhance "getcommiteditor()" for specific usages in MQ...
r21419 """get appropriate commit message editor according to '--edit' option
'finishdesc' is a function to be called with edited commit message
(= 'description' of the new changeset) just after editing, but
before checking empty-ness. It should return actual text to be
stored into history. This allows to change description before
storing.
'extramsg' is a extra message to be shown in the editor instead of
'Leave message empty to abort commit' line. 'HG: ' prefix and EOL
is automatically added.
FUJIWARA Katsunori
cmdutil: introduce 'editform' to distinguish the purpose of commit text editing...
r21999 'editform' is a dot-separated list of names, to distinguish
the purpose of commit text editing.
FUJIWARA Katsunori
cmdutil: enhance "getcommiteditor()" for specific usages in MQ...
r21419 'getcommiteditor' returns 'commitforceeditor' regardless of
'edit', if one of 'finishdesc' or 'extramsg' is specified, because
they are specific for usage in MQ.
"""
if edit or finishdesc or extramsg:
Augie Fackler
formatting: blacken the codebase...
r43346 return lambda r, c, s: commitforceeditor(
r, c, s, finishdesc=finishdesc, extramsg=extramsg, editform=editform
)
FUJIWARA Katsunori
cmdutil: introduce 'editform' to distinguish the purpose of commit text editing...
r21999 elif editform:
return lambda r, c, s: commiteditor(r, c, s, editform=editform)
FUJIWARA Katsunori
cmdutil: introduce "getcommiteditor()" to simplify code paths to choose editor...
r21405 else:
return commiteditor
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
fix: use templater to substitute values in command string...
r37792 def _escapecommandtemplate(tmpl):
parts = []
for typ, start, end in templater.scantemplate(tmpl, raw=True):
if typ == b'string':
parts.append(stringutil.escapestr(tmpl[start:end]))
else:
parts.append(tmpl[start:end])
return b''.join(parts)
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
fix: use templater to substitute values in command string...
r37792 def rendercommandtemplate(ui, tmpl, props):
r"""Expand a literal template 'tmpl' in a way suitable for command line
'\' in outermost string is not taken as an escape character because it
is a directory separator on Windows.
>>> from . import ui as uimod
>>> ui = uimod.ui()
>>> rendercommandtemplate(ui, b'c:\\{path}', {b'path': b'foo'})
'c:\\foo'
>>> rendercommandtemplate(ui, b'{"c:\\{path}"}', {'path': b'foo'})
'c:{path}'
"""
if not tmpl:
return tmpl
t = formatter.maketemplater(ui, _escapecommandtemplate(tmpl))
return t.renderdefault(props)
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 def rendertemplate(ctx, tmpl, props=None):
"""Expand a literal template 'tmpl' byte-string against one changeset
Each props item must be a stringify-able value or a callable returning
such value, i.e. no bare list nor dict should be passed.
"""
repo = ctx.repo()
tres = formatter.templateresources(repo.ui, repo)
Augie Fackler
formatting: blacken the codebase...
r43346 t = formatter.maketemplater(
repo.ui, tmpl, defaults=templatekw.keywords, resources=tres
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 mapping = {b'ctx': ctx}
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 if props:
mapping.update(props)
Yuya Nishihara
templater: rename .render(mapping) to .renderdefault(mapping) (API)...
r37003 return t.renderdefault(mapping)
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 def _buildfntemplate(pat, total=None, seqno=None, revwidth=None, pathname=None):
r"""Convert old-style filename format string to template string
>>> _buildfntemplate(b'foo-%b-%n.patch', seqno=0)
'foo-{reporoot|basename}-{seqno}.patch'
>>> _buildfntemplate(b'%R{tags % "{tag}"}%H')
'{rev}{tags % "{tag}"}{node}'
'\' in outermost strings has to be escaped because it is a directory
separator on Windows:
>>> _buildfntemplate(b'c:\\tmp\\%R\\%n.patch', seqno=0)
'c:\\\\tmp\\\\{rev}\\\\{seqno}.patch'
>>> _buildfntemplate(b'\\\\foo\\bar.patch')
'\\\\\\\\foo\\\\bar.patch'
>>> _buildfntemplate(b'\\{tags % "{tag}"}')
'\\\\{tags % "{tag}"}'
but inner strings follow the template rules (i.e. '\' is taken as an
escape character):
>>> _buildfntemplate(br'{"c:\tmp"}', seqno=0)
'{"c:\\tmp"}'
"""
Vadim Gelfer
refactor text diff/patch code....
r2874 expander = {
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 b'H': b'{node}',
b'R': b'{rev}',
b'h': b'{node|short}',
b'm': br'{sub(r"[^\w]", "_", desc|firstline)}',
b'r': b'{if(revwidth, pad(rev, revwidth, "0", left=True), rev)}',
b'%': b'%',
b'b': b'{reporoot|basename}',
}
Yuya Nishihara
cmdutil: narrow scope of KeyError in makefilename()...
r36257 if total is not None:
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 expander[b'N'] = b'{total}'
Yuya Nishihara
cmdutil: narrow scope of KeyError in makefilename()...
r36257 if seqno is not None:
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 expander[b'n'] = b'{seqno}'
Yuya Nishihara
cmdutil: narrow scope of KeyError in makefilename()...
r36257 if total is not None and seqno is not None:
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 expander[b'n'] = b'{pad(seqno, total|stringify|count, "0", left=True)}'
Yuya Nishihara
cmdutil: narrow scope of KeyError in makefilename()...
r36257 if pathname is not None:
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 expander[b's'] = b'{pathname|basename}'
expander[b'd'] = b'{if(pathname|dirname, pathname|dirname, ".")}'
expander[b'p'] = b'{pathname}'
Yuya Nishihara
cmdutil: narrow scope of KeyError in makefilename()...
r36257
newname = []
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 for typ, start, end in templater.scantemplate(pat, raw=True):
if typ != b'string':
newname.append(pat[start:end])
continue
i = start
while i < end:
n = pat.find(b'%', i, end)
if n < 0:
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 newname.append(stringutil.escapestr(pat[i:end]))
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 break
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 newname.append(stringutil.escapestr(pat[i:n]))
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 if n + 2 > end:
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"incomplete format spec in output filename")
Augie Fackler
formatting: blacken the codebase...
r43346 )
c = pat[n + 1 : n + 2]
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 i = n + 2
Yuya Nishihara
cmdutil: narrow scope of KeyError in makefilename()...
r36257 try:
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 newname.append(expander[c])
Yuya Nishihara
cmdutil: narrow scope of KeyError in makefilename()...
r36257 except KeyError:
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"invalid format spec '%%%s' in output filename") % c
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b''.join(newname)
Vadim Gelfer
refactor text diff/patch code....
r2874
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cmdutil: expand filename format string by templater (BC)...
r36528 def makefilename(ctx, pat, **props):
if not pat:
return pat
tmpl = _buildfntemplate(pat, **props)
# BUG: alias expansion shouldn't be made against template fragments
# rewritten from %-format strings, but we have no easy way to partially
# disable the expansion.
return rendertemplate(ctx, tmpl, pycompat.byteskwargs(props))
Vadim Gelfer
refactor text diff/patch code....
r2874
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cmdutil: extract function checking if pattern should be taken as stdin/out...
r32539 def isstdiofilename(pat):
"""True if the given pat looks like a filename denoting stdin/stdout"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return not pat or pat == b'-'
Yuya Nishihara
cmdutil: extract function checking if pattern should be taken as stdin/out...
r32539
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cmdutil: reimplement file wrapper that disables close()...
r27418 class _unclosablefile(object):
def __init__(self, fp):
self._fp = fp
def close(self):
pass
def __iter__(self):
return iter(self._fp)
def __getattr__(self, attr):
return getattr(self._fp, attr)
Mads Kiilerich
largefiles: use context for file closing...
r30142 def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, exc_tb):
pass
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 def makefileobj(ctx, pat, mode=b'wb', **props):
writable = mode not in (b'r', b'rb')
Ronny Pfannschmidt
export: fixed silent output file overwriting...
r7319
Yuya Nishihara
cmdutil: extract function checking if pattern should be taken as stdin/out...
r32539 if isstdiofilename(pat):
Yuya Nishihara
cmdutil: pass ctx to makefileobj() in place of repo/node pair (API)
r36223 repo = ctx.repo()
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if writable:
fp = repo.ui.fout
else:
fp = repo.ui.fin
Yuya Nishihara
cmdutil: do not duplicate stdout by makefileobj()...
r27419 return _unclosablefile(fp)
Yuya Nishihara
cmdutil: reorder optional arguments passed to makefileobj()...
r36526 fn = makefilename(ctx, pat, **props)
Augie Fackler
export: clobber files with -o (bc) (issue3652)...
r18613 return open(fn, mode)
Vadim Gelfer
move walk and matchpats from commands to cmdutil.
r2882
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
cmdutil: return a revlog from openrevlog() and split function...
r39314 def openstorage(repo, cmd, file_, opts, returnrevlog=False):
Sune Foldager
debugindex etc.: add --changelog and --manifest options...
r14323 """opens the changelog, manifest, a filelog or a given revlog"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cl = opts[b'changelog']
mf = opts[b'manifest']
dir = opts[b'dir']
Sune Foldager
debugindex etc.: add --changelog and --manifest options...
r14323 msg = None
if cl and mf:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg = _(b'cannot specify --changelog and --manifest at the same time')
Martin von Zweigbergk
treemanifest: add --dir option to debug{revlog,data,index}...
r25119 elif cl and dir:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg = _(b'cannot specify --changelog and --dir at the same time')
Martin von Zweigbergk
debug: make debug{revlog,index,data} --dir not just a flag...
r29427 elif cl or mf or dir:
Sune Foldager
debugindex etc.: add --changelog and --manifest options...
r14323 if file_:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg = _(b'cannot specify filename with --changelog or --manifest')
Sune Foldager
debugindex etc.: add --changelog and --manifest options...
r14323 elif not repo:
Augie Fackler
formatting: blacken the codebase...
r43346 msg = _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'cannot specify --changelog or --manifest or --dir '
b'without a repository'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Sune Foldager
debugindex etc.: add --changelog and --manifest options...
r14323 if msg:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(msg)
Sune Foldager
debugindex etc.: add --changelog and --manifest options...
r14323
r = None
if repo:
if cl:
Matt Mackall
debugrevlog: use unfiltered view for changelog
r21033 r = repo.unfiltered().changelog
Martin von Zweigbergk
treemanifest: add --dir option to debug{revlog,data,index}...
r25119 elif dir:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'treemanifest' not in repo.requirements:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"--dir can only be used on repos with "
b"treemanifest enabled"
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not dir.endswith(b'/'):
dir = dir + b'/'
Gregory Szorc
manifest: add getstorage() to manifestlog and use it globally...
r39280 dirlog = repo.manifestlog.getstorage(dir)
Martin von Zweigbergk
treemanifest: add --dir option to debug{revlog,data,index}...
r25119 if len(dirlog):
r = dirlog
Sune Foldager
debugindex etc.: add --changelog and --manifest options...
r14323 elif mf:
Gregory Szorc
manifest: add getstorage() to manifestlog and use it globally...
r39280 r = repo.manifestlog.getstorage(b'')
Sune Foldager
debugindex etc.: add --changelog and --manifest options...
r14323 elif file_:
filelog = repo.file(file_)
if len(filelog):
r = filelog
Gregory Szorc
cmdutil: return a revlog from openrevlog() and split function...
r39314
# Not all storage may be revlogs. If requested, try to return an actual
# revlog instance.
if returnrevlog:
if isinstance(r, revlog.revlog):
pass
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif util.safehasattr(r, b'_revlog'):
Augie Fackler
cmdutil: suppress bogus pytype errors...
r43792 r = r._revlog # pytype: disable=attribute-error
Gregory Szorc
cmdutil: return a revlog from openrevlog() and split function...
r39314 elif r is not None:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'%r does not appear to be a revlog') % r)
Gregory Szorc
cmdutil: return a revlog from openrevlog() and split function...
r39314
Sune Foldager
debugindex etc.: add --changelog and --manifest options...
r14323 if not r:
Gregory Szorc
cmdutil: return a revlog from openrevlog() and split function...
r39314 if not returnrevlog:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'cannot give path to non-revlog'))
Gregory Szorc
cmdutil: return a revlog from openrevlog() and split function...
r39314
Sune Foldager
debugindex etc.: add --changelog and --manifest options...
r14323 if not file_:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.CommandError(cmd, _(b'invalid arguments'))
Sune Foldager
debugindex etc.: add --changelog and --manifest options...
r14323 if not os.path.isfile(file_):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"revlog '%s' not found") % file_)
Augie Fackler
formatting: blacken the codebase...
r43346 r = revlog.revlog(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 vfsmod.vfs(encoding.getcwd(), audit=False), file_[:-2] + b".i"
Augie Fackler
formatting: blacken the codebase...
r43346 )
Sune Foldager
debugindex etc.: add --changelog and --manifest options...
r14323 return r
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
cmdutil: return a revlog from openrevlog() and split function...
r39314 def openrevlog(repo, cmd, file_, opts):
"""Obtain a revlog backing storage of an item.
This is similar to ``openstorage()`` except it always returns a revlog.
In most cases, a caller cares about the main storage object - not the
revlog backing it. Therefore, this function should only be used by code
that needs to examine low-level revlog implementation details. e.g. debug
commands.
"""
return openstorage(repo, cmd, file_, opts, returnrevlog=True)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
copy: handle rename internally...
r5610 def copy(ui, repo, pats, opts, rename=False):
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 # called with the repo lock held
#
# hgsep => pathname that uses "/" to separate directories
# ossep => pathname that uses os.sep to separate directories
cwd = repo.getcwd()
targets = {}
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 after = opts.get(b"after")
dryrun = opts.get(b"dry_run")
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 wctx = repo[None]
Matt Mackall
move commands.docopy to cmdutil.copy
r5589
Martin von Zweigbergk
copy: respect ui.relative-paths in copy/rename...
r41806 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
copy: refactor okaytocopy into walkpat...
r5605 def walkpat(pat):
srcs = []
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if after:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 badstates = b'?'
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 badstates = b'?r'
Martin von Zweigbergk
cleanup: reuse existing wctx variables instead of calling repo[None]...
r32382 m = scmutil.match(wctx, [pat], opts, globbed=True)
for abs in wctx.walk(m):
Matt Mackall
copy: refactor okaytocopy into walkpat...
r5605 state = repo.dirstate[abs]
Martin von Zweigbergk
copy: respect ui.relative-paths in copy/rename...
r41806 rel = uipathfn(abs)
Matt Mackall
walk: remove rel and exact returns
r6584 exact = m.exact(abs)
Peter Arrenbrecht
rename: make --after work if source is already in R state...
r11223 if state in badstates:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if exact and state == b'?':
ui.warn(_(b'%s: not copying - file is not managed\n') % rel)
if exact and state == b'r':
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'%s: not copying - file has been marked for'
b' remove\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% rel
)
Matt Mackall
copy: refactor okaytocopy into walkpat...
r5605 continue
# abs: hgsep
# rel: ossep
srcs.append((abs, rel, exact))
return srcs
Matt Mackall
move commands.docopy to cmdutil.copy
r5589
# abssrc: hgsep
# relsrc: ossep
# otarget: ossep
Matt Mackall
copy: refactor okaytocopy into walkpat...
r5605 def copyfile(abssrc, relsrc, otarget, exact):
Augie Fackler
pathutil: tease out a new library to break an import cycle from canonpath use
r20033 abstarget = pathutil.canonpath(repo.root, cwd, otarget)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'/' in abstarget:
Patrick Mezard
dirstate: preserve path components case on renames (issue3402)...
r16542 # We cannot normalize abstarget itself, this would prevent
# case only renames, like a => A.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 abspath, absname = abstarget.rsplit(b'/', 1)
abstarget = repo.dirstate.normalize(abspath) + b'/' + absname
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 reltarget = repo.pathto(abstarget, cwd)
Matt Mackall
copy: minor cleanups...
r5607 target = repo.wjoin(abstarget)
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 src = repo.wjoin(abssrc)
Matt Mackall
copy: simplify inner copy...
r5608 state = repo.dirstate[abstarget]
Matt Mackall
copy: minor cleanups...
r5607
Adrian Buehlmann
add: introduce a warning message for non-portable filenames (issue2756) (BC)...
r13962 scmutil.checkportable(ui, abstarget)
Adrian Buehlmann
copy: do not copy file if name is disallowed anyway
r13945
Matt Mackall
copy: minor cleanups...
r5607 # check for collisions
prevsrc = targets.get(abstarget)
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 if prevsrc is not None:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s: not overwriting - %s collides with %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (
reltarget,
repo.pathto(abssrc, cwd),
repo.pathto(prevsrc, cwd),
)
)
return True # report a failure
Matt Mackall
copy: minor cleanups...
r5607
# check for overwrites
Patrick Mezard
rename: do not overwrite existing broken symlinks
r12342 exists = os.path.lexists(target)
Matt Mackall
rename: handle case-changing (issue1717)
r16283 samefile = False
if exists and abssrc != abstarget:
Augie Fackler
formatting: blacken the codebase...
r43346 if repo.dirstate.normalize(abssrc) == repo.dirstate.normalize(
abstarget
):
Matt Mackall
rename: handle case-changing (issue1717)
r16283 if not rename:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.warn(_(b"%s: can't copy - same file\n") % reltarget)
Augie Fackler
formatting: blacken the codebase...
r43346 return True # report a failure
Matt Mackall
rename: handle case-changing (issue1717)
r16283 exists = False
samefile = True
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not after and exists or after and state in b'mn':
if not opts[b'force']:
if state in b'mn':
msg = _(b'%s: not overwriting - file already committed\n')
Augie Fackler
copy: distinguish "file exists" cases and add a hint (BC)...
r30151 if after:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 flags = b'--after --force'
Augie Fackler
copy: distinguish "file exists" cases and add a hint (BC)...
r30151 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 flags = b'--force'
Augie Fackler
copy: distinguish "file exists" cases and add a hint (BC)...
r30151 if rename:
Augie Fackler
formatting: blacken the codebase...
r43346 hint = (
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"('hg rename %s' to replace the file by "
b'recording a rename)\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% flags
)
Augie Fackler
copy: distinguish "file exists" cases and add a hint (BC)...
r30151 else:
Augie Fackler
formatting: blacken the codebase...
r43346 hint = (
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"('hg copy %s' to replace the file by "
b'recording a copy)\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% flags
)
Augie Fackler
copy: distinguish "file exists" cases and add a hint (BC)...
r30151 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg = _(b'%s: not overwriting - file exists\n')
Augie Fackler
copy: distinguish "file exists" cases and add a hint (BC)...
r30151 if rename:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 hint = _(
b"('hg rename --after' to record the rename)\n"
)
Augie Fackler
copy: distinguish "file exists" cases and add a hint (BC)...
r30151 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 hint = _(b"('hg copy --after' to record the copy)\n")
Augie Fackler
copy: distinguish "file exists" cases and add a hint (BC)...
r30151 ui.warn(msg % reltarget)
ui.warn(hint)
Augie Fackler
formatting: blacken the codebase...
r43346 return True # report a failure
Matt Mackall
copy: minor cleanups...
r5607
if after:
Matt Mackall
copy: simplify inner copy...
r5608 if not exists:
Steve Losh
cmdutil: Warn when trying to copy/rename --after to a nonexistant file....
r11152 if rename:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s: not recording move - %s does not exist\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (relsrc, reltarget)
)
Steve Losh
cmdutil: Warn when trying to copy/rename --after to a nonexistant file....
r11152 else:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s: not recording copy - %s does not exist\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (relsrc, reltarget)
)
return True # report a failure
Matt Mackall
copy: simplify inner copy...
r5608 elif not dryrun:
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 try:
Matt Mackall
copy: simplify inner copy...
r5608 if exists:
os.unlink(target)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 targetdir = os.path.dirname(target) or b'.'
Matt Mackall
copy: simplify inner copy...
r5608 if not os.path.isdir(targetdir):
os.makedirs(targetdir)
Matt Mackall
rename: handle case-changing (issue1717)
r16283 if samefile:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tmp = target + b"~hgrename"
Matt Mackall
rename: handle case-changing (issue1717)
r16283 os.rename(src, tmp)
os.rename(tmp, target)
else:
Kyle Lippincott
copyfile: preserve stat info (mtime, etc.) when doing copies/renames...
r37106 # Preserve stat info on renames, not on copies; this matches
# Linux CLI behavior.
util.copyfile(src, target, copystat=rename)
Adrian Buehlmann
workingctx: eliminate remove function...
r14518 srcexists = True
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except IOError as inst:
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 if inst.errno == errno.ENOENT:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.warn(_(b'%s: deleted in working directory\n') % relsrc)
Adrian Buehlmann
workingctx: eliminate remove function...
r14518 srcexists = False
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 else:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s: cannot copy - %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (relsrc, encoding.strtolocal(inst.strerror))
)
return True # report a failure
Matt Mackall
copy: minor cleanups...
r5607
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 if ui.verbose or not exact:
Martin Geisler
cmdutil: fix untranslatable string in copy
r7894 if rename:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'moving %s to %s\n') % (relsrc, reltarget))
Martin Geisler
cmdutil: fix untranslatable string in copy
r7894 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'copying %s to %s\n') % (relsrc, reltarget))
Matt Mackall
copy: simplify inner copy...
r5608
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 targets[abstarget] = abssrc
Matt Mackall
copy: minor cleanups...
r5607
# fix up dirstate
Augie Fackler
formatting: blacken the codebase...
r43346 scmutil.dirstatecopy(
ui, repo, wctx, abssrc, abstarget, dryrun=dryrun, cwd=cwd
)
Matt Mackall
copy: handle rename internally...
r5610 if rename and not dryrun:
Matt Mackall
rename: handle case-changing (issue1717)
r16283 if not after and srcexists and not samefile:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 rmdir = repo.ui.configbool(b'experimental', b'removeemptydirs')
Kyle Lippincott
unlinkpath: make empty directory removal optional (issue5901) (issue5826)...
r38512 repo.wvfs.unlinkpath(abssrc, rmdir=rmdir)
Adrian Buehlmann
workingctx: eliminate remove function...
r14518 wctx.forget([abssrc])
Matt Mackall
move commands.docopy to cmdutil.copy
r5589
# pat: ossep
# dest ossep
# srcs: list of (hgsep, hgsep, ossep, bool)
# return: function that takes hgsep and returns ossep
def targetpathfn(pat, dest, srcs):
if os.path.isdir(pat):
Augie Fackler
pathutil: tease out a new library to break an import cycle from canonpath use
r20033 abspfx = pathutil.canonpath(repo.root, cwd, pat)
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 abspfx = util.localpath(abspfx)
if destdirexists:
striplen = len(os.path.split(abspfx)[0])
else:
striplen = len(abspfx)
if striplen:
Pulkit Goyal
py3: replace os.sep with pycompat.ossep (part 3 of 4)
r30615 striplen += len(pycompat.ossep)
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
elif destdirexists:
Augie Fackler
formatting: blacken the codebase...
r43346 res = lambda p: os.path.join(
dest, os.path.basename(util.localpath(p))
)
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 else:
res = lambda p: dest
return res
# pat: ossep
# dest ossep
# srcs: list of (hgsep, hgsep, ossep, bool)
# return: function that takes hgsep and returns ossep
def targetpathafterfn(pat, dest, srcs):
Martin Geisler
Consistently import foo as foomod when foo to avoid shadowing...
r12085 if matchmod.patkind(pat):
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 # a mercurial pattern
Augie Fackler
formatting: blacken the codebase...
r43346 res = lambda p: os.path.join(
dest, os.path.basename(util.localpath(p))
)
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 else:
Augie Fackler
pathutil: tease out a new library to break an import cycle from canonpath use
r20033 abspfx = pathutil.canonpath(repo.root, cwd, pat)
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 if len(abspfx) < len(srcs[0][0]):
# A directory. Either the target path contains the last
# component of the source path or it does not.
def evalpath(striplen):
score = 0
for s in srcs:
t = os.path.join(dest, util.localpath(s[0])[striplen:])
Patrick Mezard
Restore lexists() changes lost in e0ee3e822a9a merge
r12357 if os.path.lexists(t):
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 score += 1
return score
abspfx = util.localpath(abspfx)
striplen = len(abspfx)
if striplen:
Pulkit Goyal
py3: replace os.sep with pycompat.ossep (part 3 of 4)
r30615 striplen += len(pycompat.ossep)
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
score = evalpath(striplen)
striplen1 = len(os.path.split(abspfx)[0])
if striplen1:
Pulkit Goyal
py3: replace os.sep with pycompat.ossep (part 3 of 4)
r30615 striplen1 += len(pycompat.ossep)
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 if evalpath(striplen1) > score:
striplen = striplen1
Augie Fackler
formatting: blacken the codebase...
r43346 res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 else:
# a file
if destdirexists:
Augie Fackler
formatting: blacken the codebase...
r43346 res = lambda p: os.path.join(
dest, os.path.basename(util.localpath(p))
)
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 else:
res = lambda p: dest
return res
Matt Mackall
scmutil: drop some aliases in cmdutil
r14321 pats = scmutil.expandpats(pats)
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 if not pats:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'no source or destination specified'))
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 if len(pats) == 1:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'no destination specified'))
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 dest = pats.pop()
Alexis S. L. Carvalho
Fix issue995 (copy --after and symlinks pointing to a directory)...
r6258 destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 if not destdirexists:
Martin Geisler
Consistently import foo as foomod when foo to avoid shadowing...
r12085 if len(pats) > 1 or matchmod.patkind(pats[0]):
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'with multiple sources, destination must be an '
b'existing directory'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Shun-ichi GOTO
Add endswithsep() and use it instead of using os.sep and os.altsep directly....
r5843 if util.endswithsep(dest):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'destination %s is not a directory') % dest)
Matt Mackall
copy: minor cleanups...
r5607
tfn = targetpathfn
if after:
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 tfn = targetpathafterfn
copylist = []
for pat in pats:
Matt Mackall
copy: refactor okaytocopy into walkpat...
r5605 srcs = walkpat(pat)
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 if not srcs:
continue
copylist.append((tfn(pat, dest, srcs), srcs))
if not copylist:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'no files to copy'))
Matt Mackall
move commands.docopy to cmdutil.copy
r5589
Matt Mackall
copy: propagate errors properly
r5606 errors = 0
Matt Mackall
move commands.docopy to cmdutil.copy
r5589 for targetpath, srcs in copylist:
Matt Mackall
copy: refactor okaytocopy into walkpat...
r5605 for abssrc, relsrc, exact in srcs:
Matt Mackall
copy: propagate errors properly
r5606 if copyfile(abssrc, relsrc, targetpath(abssrc), exact):
errors += 1
Matt Mackall
move commands.docopy to cmdutil.copy
r5589
Matt Mackall
commands: initial audit of exit codes...
r11177 return errors != 0
Matt Mackall
move commands.docopy to cmdutil.copy
r5589
Augie Fackler
formatting: blacken the codebase...
r43346
Pierre-Yves David
import: allow processing of extra part header during import...
r26561 ## facility to let extension process additional data into an import patch
# list of identifier to be executed in order
extrapreimport = [] # run before commit
Augie Fackler
formatting: blacken the codebase...
r43346 extrapostimport = [] # run after commit
Pierre-Yves David
import: allow processing of extra part header during import...
r26561 # mapping from identifier to actual import function
#
# 'preimport' are run before the commit is made and are provided the following
# arguments:
# - repo: the localrepository instance,
# - patchdata: data extracted from patch header (cf m.patch.patchheadermap),
Mads Kiilerich
spelling: trivial spell checking
r26781 # - extra: the future extra dictionary of the changeset, please mutate it,
Pierre-Yves David
import: allow processing of extra part header during import...
r26561 # - opts: the import options.
# XXX ideally, we would just pass an ctx ready to be computed, that would allow
# mutation of in memory commit and more. Feel free to rework the code to get
# there.
extrapreimportmap = {}
Pierre-Yves David
import: allow processing of extra part header after import...
r26562 # 'postimport' are run after the commit is made and are provided the following
# argument:
# - ctx: the changectx created by import.
extrapostimportmap = {}
Pierre-Yves David
import: allow processing of extra part header during import...
r26561
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
cmdutil: pass in parsed patch to tryimportone() (API)...
r37638 def tryimportone(ui, repo, patchdata, parents, opts, msgs, updatefunc):
Pierre-Yves David
import: move tryone closure in cmdutil...
r20500 """Utility function used by commands.import to import a single patch
This function is explicitly defined here to help the evolve extension to
wrap this part of the import logic.
The API is currently a bit ugly because it a simple code translation from
the import command. Feel free to make it better.
Gregory Szorc
cmdutil: pass in parsed patch to tryimportone() (API)...
r37638 :patchdata: a dictionary containing parsed patch data (such as from
``patch.extract()``)
Pierre-Yves David
import: move tryone closure in cmdutil...
r20500 :parents: nodes that will be parent of the created commit
:opts: the full dict of option passed to the import command
:msgs: list to save commit message to.
(used in case we need to save it when failing)
:updatefunc: a function that update a repo to a given node
updatefunc(<repo>, <node>)
"""
Gregory Szorc
cmdutil: break import cycle...
r25930 # avoid cycle context -> subrepo -> cmdutil
Gregory Szorc
cmdutil: use absolute_import...
r28322 from . import context
Gregory Szorc
cmdutil: pass in parsed patch to tryimportone() (API)...
r37638
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tmpname = patchdata.get(b'filename')
message = patchdata.get(b'message')
user = opts.get(b'user') or patchdata.get(b'user')
date = opts.get(b'date') or patchdata.get(b'date')
branch = patchdata.get(b'branch')
nodeid = patchdata.get(b'nodeid')
p1 = patchdata.get(b'p1')
p2 = patchdata.get(b'p2')
nocommit = opts.get(b'no_commit')
importbranch = opts.get(b'import_branch')
update = not opts.get(b'bypass')
strip = opts[b"strip"]
prefix = opts[b"prefix"]
sim = float(opts.get(b'similarity') or 0)
Gregory Szorc
patch: make extract() a context manager (API)...
r37639
Pierre-Yves David
import: move tryone closure in cmdutil...
r20500 if not tmpname:
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 return None, None, False
Pierre-Yves David
import: move tryone closure in cmdutil...
r20500
Pierre-Yves David
import: add --partial flag to create a changeset despite failed hunks...
r21553 rejects = False
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 cmdline_message = logmessage(ui, opts)
if cmdline_message:
# pickup the cmdline msg
message = cmdline_message
elif message:
# pickup the patch msg
message = message.strip()
else:
# launch the editor
message = None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.debug(b'message:\n%s\n' % (message or b''))
Gregory Szorc
patch: make extract() a context manager (API)...
r37639
if len(parents) == 1:
parents.append(repo[nullid])
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'exact'):
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 if not nodeid or not p1:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'not a Mercurial patch'))
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 p1 = repo[p1]
p2 = repo[p2 or nullid]
elif p2:
try:
Pierre-Yves David
import: move tryone closure in cmdutil...
r20500 p1 = repo[p1]
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 p2 = repo[p2]
# Without any options, consider p2 only if the
# patch is being applied on top of the recorded
# first parent.
if p1 != parents[0]:
p1 = parents[0]
p2 = repo[nullid]
except error.RepoError:
p1, p2 = parents
if p2.node() == nullid:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"warning: import the patch as a normal revision\n"
b"(use --exact to import the patch as a merge)\n"
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 else:
p1, p2 = parents
n = None
if update:
if p1 != parents[0]:
updatefunc(repo, p1.node())
if p2 != parents[1]:
repo.setparents(p1.node(), p2.node())
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'exact') or importbranch:
repo.dirstate.setbranch(branch or b'default')
partial = opts.get(b'partial', False)
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 files = set()
try:
Augie Fackler
formatting: blacken the codebase...
r43346 patch.patch(
ui,
repo,
tmpname,
strip=strip,
prefix=prefix,
files=files,
eolmode=None,
similarity=sim / 100.0,
)
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 except error.PatchError as e:
if not partial:
raise error.Abort(pycompat.bytestr(e))
if partial:
rejects = True
files = list(files)
if nocommit:
if message:
msgs.append(message)
Pierre-Yves David
import: move tryone closure in cmdutil...
r20500 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'exact') or p2:
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 # If you got here, you either use --force and know what
# you are doing or used --exact or a merge patch while
# being updated to its first parent.
m = None
else:
m = scmutil.matchfiles(repo, files or [])
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 editform = mergeeditform(repo[None], b'import.normal')
if opts.get(b'exact'):
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 editor = None
else:
Augie Fackler
formatting: blacken the codebase...
r43346 editor = getcommiteditor(
editform=editform, **pycompat.strkwargs(opts)
)
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 extra = {}
for idfunc in extrapreimport:
extrapreimportmap[idfunc](repo, patchdata, extra, opts)
overrides = {}
if partial:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 overrides[(b'ui', b'allowemptycommit')] = True
Denis Laxalde
import: add a --secret option...
r44118 if opts.get(b'secret'):
overrides[(b'phases', b'new-commit')] = b'secret'
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 with repo.ui.configoverride(overrides, b'import'):
Augie Fackler
formatting: blacken the codebase...
r43346 n = repo.commit(
message, user, date, match=m, editor=editor, extra=extra
)
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 for idfunc in extrapostimport:
extrapostimportmap[idfunc](repo[n])
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'exact') or importbranch:
branch = branch or b'default'
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 else:
branch = p1.branch()
store = patch.filestore()
try:
Pierre-Yves David
import: move tryone closure in cmdutil...
r20500 files = set()
Pierre-Yves David
import: add --partial flag to create a changeset despite failed hunks...
r21553 try:
Augie Fackler
formatting: blacken the codebase...
r43346 patch.patchrepo(
ui,
repo,
p1,
store,
tmpname,
strip,
prefix,
files,
eolmode=None,
)
Yuya Nishihara
error: move patch.PatchError so it can easily implement __bytes__ (API)
r34252 except error.PatchError as e:
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 raise error.Abort(stringutil.forcebytestr(e))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'exact'):
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 editor = None
Pierre-Yves David
import: move tryone closure in cmdutil...
r20500 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 editor = getcommiteditor(editform=b'import.bypass')
Augie Fackler
formatting: blacken the codebase...
r43346 memctx = context.memctx(
repo,
(p1.node(), p2.node()),
message,
files=files,
filectxfn=store,
user=user,
date=date,
branch=branch,
editor=editor,
)
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 n = memctx.commit()
finally:
store.close()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'exact') and nocommit:
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 # --exact with --no-commit is still useful in that it does merge
# and branch bits
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.warn(_(b"warning: can't check exact import with --no-commit\n"))
elif opts.get(b'exact') and (not n or hex(n) != nodeid):
raise error.Abort(_(b'patch is damaged or loses information'))
msg = _(b'applied to working directory')
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 if n:
# i18n: refers to a short changeset id
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg = _(b'created %s') % short(n)
Gregory Szorc
patch: make extract() a context manager (API)...
r37639 return msg, n, rejects
Pierre-Yves David
import: move tryone closure in cmdutil...
r20500
Augie Fackler
formatting: blacken the codebase...
r43346
Pierre-Yves David
export: introduce a generic way to add patch header on export...
r26545 # facility to let extensions include additional data in an exported patch
# list of identifiers to be executed in order
extraexport = []
# mapping from identifier to actual export function
# function as to return a string to be added to the header or None
# it is given two arguments (sequencenumber, changectx)
extraexportmap = {}
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
export: port _exportsingle() to formatter...
r37620 def _exportsingle(repo, ctx, fm, match, switch_parent, seqno, diffopts):
Yuya Nishihara
export: map wctx.node() to 'ff...' node id (issue5438)
r32660 node = scmutil.binnode(ctx)
Augie Fackler
cmdutil: extract closure that performs the actual export formatting...
r32433 parents = [p.node() for p in ctx.parents() if p]
branch = ctx.branch()
if switch_parent:
parents.reverse()
if parents:
prev = parents[0]
else:
prev = nullid
Yuya Nishihara
export: port _exportsingle() to formatter...
r37620 fm.context(ctx=ctx)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fm.plain(b'# HG changeset patch\n')
fm.write(b'user', b'# User %s\n', ctx.user())
fm.plain(b'# Date %d %d\n' % ctx.date())
fm.write(b'date', b'# %s\n', fm.formatdate(ctx.date()))
Augie Fackler
formatting: blacken the codebase...
r43346 fm.condwrite(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 branch and branch != b'default', b'branch', b'# Branch %s\n', branch
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fm.write(b'node', b'# Node ID %s\n', hex(node))
fm.plain(b'# Parent %s\n' % hex(prev))
Augie Fackler
cmdutil: extract closure that performs the actual export formatting...
r32433 if len(parents) > 1:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fm.plain(b'# Parent %s\n' % hex(parents[1]))
fm.data(parents=fm.formatlist(pycompat.maplist(hex, parents), name=b'node'))
Yuya Nishihara
export: port _exportsingle() to formatter...
r37620
# TODO: redesign extraexportmap function to support formatter
Augie Fackler
cmdutil: extract closure that performs the actual export formatting...
r32433 for headerid in extraexport:
header = extraexportmap[headerid](seqno, ctx)
if header is not None:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fm.plain(b'# %s\n' % header)
fm.write(b'desc', b'%s\n', ctx.description().rstrip())
fm.plain(b'\n')
Yuya Nishihara
export: port _exportsingle() to formatter...
r37620
if fm.isplain():
chunkiter = patch.diffui(repo, prev, node, match, opts=diffopts)
for chunk, label in chunkiter:
fm.plain(chunk, label=label)
else:
chunkiter = patch.diff(repo, prev, node, match, opts=diffopts)
# TODO: make it structured?
fm.data(diff=b''.join(chunkiter))
Augie Fackler
cmdutil: extract closure that performs the actual export formatting...
r32433
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
export: enable formatter support (API)...
r37622 def _exportfile(repo, revs, fm, dest, switch_parent, diffopts, match):
Yuya Nishihara
export: split cmdutil.export() to single-file and maybe-multiple-files cases...
r37618 """Export changesets to stdout or a single file"""
for seqno, rev in enumerate(revs, 1):
ctx = repo[rev]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not dest.startswith(b'<'):
repo.ui.note(b"%s\n" % dest)
Yuya Nishihara
export: port _exportsingle() to formatter...
r37620 fm.startitem()
_exportsingle(repo, ctx, fm, match, switch_parent, seqno, diffopts)
Yuya Nishihara
export: enable formatter support (API)...
r37622
Augie Fackler
formatting: blacken the codebase...
r43346
def _exportfntemplate(
repo, revs, basefm, fntemplate, switch_parent, diffopts, match
):
Yuya Nishihara
export: split cmdutil.export() to single-file and maybe-multiple-files cases...
r37618 """Export changesets to possibly multiple files"""
total = len(revs)
revwidth = max(len(str(rev)) for rev in revs)
Yuya Nishihara
export: serialize revisions to be exported per destination file...
r37619 filemap = util.sortdict() # filename: [(seqno, rev), ...]
Yuya Nishihara
export: split cmdutil.export() to single-file and maybe-multiple-files cases...
r37618
for seqno, rev in enumerate(revs, 1):
ctx = repo[rev]
Augie Fackler
formatting: blacken the codebase...
r43346 dest = makefilename(
ctx, fntemplate, total=total, seqno=seqno, revwidth=revwidth
)
Yuya Nishihara
export: serialize revisions to be exported per destination file...
r37619 filemap.setdefault(dest, []).append((seqno, rev))
for dest in filemap:
Yuya Nishihara
export: enable formatter support (API)...
r37622 with formatter.maybereopen(basefm, dest) as fm:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.note(b"%s\n" % dest)
Yuya Nishihara
export: serialize revisions to be exported per destination file...
r37619 for seqno, rev in filemap[dest]:
Yuya Nishihara
export: port _exportsingle() to formatter...
r37620 fm.startitem()
Yuya Nishihara
export: serialize revisions to be exported per destination file...
r37619 ctx = repo[rev]
Augie Fackler
formatting: blacken the codebase...
r43346 _exportsingle(
repo, ctx, fm, match, switch_parent, seqno, diffopts
)
Yuya Nishihara
export: split cmdutil.export() to single-file and maybe-multiple-files cases...
r37618
Martin von Zweigbergk
export: don't prefetch *all* files in manifest...
r42673 def _prefetchchangedfiles(repo, revs, match):
allfiles = set()
for rev in revs:
for file in repo[rev].files():
if not match or match(file):
allfiles.add(file)
scmutil.prefetchfiles(repo, revs, scmutil.matchfiles(repo, allfiles))
Augie Fackler
formatting: blacken the codebase...
r43346
def export(
repo,
revs,
basefm,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fntemplate=b'hg-%h.patch',
Augie Fackler
formatting: blacken the codebase...
r43346 switch_parent=False,
opts=None,
match=None,
):
Augie Fackler
cmdutil: comprehensively document the interface of export...
r32430 '''export changesets as hg patches
Args:
repo: The repository from which we're exporting revisions.
revs: A list of revisions to export as revision numbers.
Yuya Nishihara
export: enable formatter support (API)...
r37622 basefm: A formatter to which patches should be written.
Augie Fackler
cmdutil: rename template param to export to fntemplate...
r32431 fntemplate: An optional string to use for generating patch file names.
Augie Fackler
cmdutil: comprehensively document the interface of export...
r32430 switch_parent: If True, show diffs against second parent when not nullid.
Default is false, which always shows diff against p1.
opts: diff options to use for generating the patch.
match: If specified, only export changes to files matching this matcher.
Returns:
Nothing.
Side Effect:
"HG Changeset Patch" data is emitted to one of the following
destinations:
Augie Fackler
cmdutil: rename template param to export to fntemplate...
r32431 fntemplate specified: Each rev is written to a unique file named using
Augie Fackler
cmdutil: comprehensively document the interface of export...
r32430 the given template.
Yuya Nishihara
export: enable formatter support (API)...
r37622 Otherwise: All revs will be written to basefm.
Augie Fackler
cmdutil: comprehensively document the interface of export...
r32430 '''
Martin von Zweigbergk
export: don't prefetch *all* files in manifest...
r42673 _prefetchchangedfiles(repo, revs, match)
Matt Harbison
export: invoke the file prefetch hook...
r37781
Yuya Nishihara
export: extract function to write patch to file object (API)...
r37621 if not fntemplate:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _exportfile(
repo, revs, basefm, b'<unnamed>', switch_parent, opts, match
)
Yuya Nishihara
export: split cmdutil.export() to single-file and maybe-multiple-files cases...
r37618 else:
Augie Fackler
formatting: blacken the codebase...
r43346 _exportfntemplate(
repo, revs, basefm, fntemplate, switch_parent, opts, match
)
Benoit Boissinot
patch/diff: move patch.export() to cmdutil.export()...
r10611
Yuya Nishihara
export: extract function to write patch to file object (API)...
r37621 def exportfile(repo, revs, fp, switch_parent=False, opts=None, match=None):
"""Export changesets to the given file stream"""
Martin von Zweigbergk
export: don't prefetch *all* files in manifest...
r42673 _prefetchchangedfiles(repo, revs, match)
Matt Harbison
export: invoke the file prefetch hook...
r37781
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 dest = getattr(fp, 'name', b'<unnamed>')
with formatter.formatter(repo.ui, fp, b'export', {}) as fm:
Yuya Nishihara
export: enable formatter support (API)...
r37622 _exportfile(repo, revs, fm, dest, switch_parent, opts, match)
Yuya Nishihara
export: extract function to write patch to file object (API)...
r37621
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
debugobsolete: add formatter support (issue5134)...
r29795 def showmarker(fm, marker, index=None):
Pierre-Yves David
debugobsolete: extract marker display in a dedicated function...
r20470 """utility function to display obsolescence marker in a readable way
To be used by debug function."""
Kostia Balytskyi
debugobsolete: add an option to show marker index...
r28613 if index is not None:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fm.write(b'index', b'%i ', index)
fm.write(b'prednode', b'%s ', hex(marker.prednode()))
Yuya Nishihara
debugobsolete: add formatter support (issue5134)...
r29795 succs = marker.succnodes()
Augie Fackler
formatting: blacken the codebase...
r43346 fm.condwrite(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 succs,
b'succnodes',
b'%s ',
fm.formatlist(map(hex, succs), name=b'node'),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fm.write(b'flag', b'%X ', marker.flags())
Pierre-Yves David
debugobsolete: display parents information from markers...
r22260 parents = marker.parentnodes()
if parents is not None:
Augie Fackler
formatting: blacken the codebase...
r43346 fm.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'parentnodes',
b'{%s} ',
fm.formatlist(map(hex, parents), name=b'node', sep=b', '),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fm.write(b'date', b'(%s) ', fm.formatdate(marker.date()))
Yuya Nishihara
debugobsolete: add formatter support (issue5134)...
r29795 meta = marker.metadata().copy()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 meta.pop(b'date', None)
Yuya Nishihara
pycompat: move rapply() from util...
r38594 smeta = pycompat.rapply(pycompat.maybebytestr, meta)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fm.write(
b'metadata', b'{%s}', fm.formatdict(smeta, fmt=b'%r: %r', sep=b', ')
)
fm.plain(b'\n')
Pierre-Yves David
debugobsolete: extract marker display in a dedicated function...
r20470
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
Add --date support to update and revert...
r3814 def finddate(ui, repo, date):
"""Find the tipmost changeset that matches the given date spec"""
Dirkjan Ochtman
merge changes from mpm
r9667
Boris Feld
util: extract all date-related utils in utils/dateutil module...
r36625 df = dateutil.matchdate(date)
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 m = scmutil.matchall(repo)
Matt Mackall
Add --date support to update and revert...
r3814 results = {}
Matt Mackall
walkchangerevs: move 'add' to callback...
r9662
def prep(ctx, fns):
d = ctx.date()
if df(d[0]):
Dirkjan Ochtman
cmdutil: fix bug in finddate() implementation
r9668 results[ctx.rev()] = d
Matt Mackall
walkchangerevs: move 'add' to callback...
r9662
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for ctx in walkchangerevs(repo, m, {b'rev': None}, prep):
Matt Mackall
walkchangerevs: move 'add' to callback...
r9662 rev = ctx.rev()
if rev in results:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
Martin von Zweigbergk
py3: use '%d' for formatting a revnum in `hg co --date` code...
r44097 _(b"found revision %d from %s\n")
Augie Fackler
formatting: blacken the codebase...
r43346 % (rev, dateutil.datestr(results[rev]))
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b'%d' % rev
raise error.Abort(_(b"revision matching date not found"))
Matt Mackall
Add --date support to update and revert...
r3814
Augie Fackler
formatting: blacken the codebase...
r43346
Lucas Moscovicz
cmdutil: implemented new lazy increasingwindows...
r20553 def increasingwindows(windowsize=8, sizelimit=512):
while True:
yield windowsize
if windowsize < sizelimit:
windowsize *= 2
Patrick Mezard
cmdutil: extract increasing_windows() from walkchangerevs()...
r16776
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
log: duplicate _logrevs() dedicated for walkchangerevs()...
r35700 def _walkrevs(repo, opts):
# Default --rev value depends on --follow but --follow behavior
# depends on revisions resolved from --rev...
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 follow = opts.get(b'follow') or opts.get(b'follow_first')
if opts.get(b'rev'):
revs = scmutil.revrange(repo, opts[b'rev'])
Yuya Nishihara
log: duplicate _logrevs() dedicated for walkchangerevs()...
r35700 elif follow and repo.dirstate.p1() == nullid:
revs = smartset.baseset()
elif follow:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 revs = repo.revs(b'reverse(:.)')
Yuya Nishihara
log: duplicate _logrevs() dedicated for walkchangerevs()...
r35700 else:
revs = smartset.spanset(repo)
revs.reverse()
return revs
Augie Fackler
formatting: blacken the codebase...
r43346
Durham Goode
log: move log file walk to its own function...
r19290 class FileWalkError(Exception):
pass
Augie Fackler
formatting: blacken the codebase...
r43346
Durham Goode
log: move log file walk to its own function...
r19290 def walkfilerevs(repo, match, follow, revs, fncache):
'''Walks the file history for the matched files.
Returns the changeset revs that are involved in the file history.
Throws FileWalkError if the file history can't be walked using
filelogs alone.
'''
wanted = set()
copies = []
minrev, maxrev = min(revs), max(revs)
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
walkfilerevs: rename filerevgen() to filerevs() since it's not a generator...
r42004 def filerevs(filelog, last):
Durham Goode
log: move log file walk to its own function...
r19290 """
Only files, no patterns. Check the history of each file.
Examines filelog entries within minrev, maxrev linkrev range
Returns an iterator yielding (linkrev, parentlinkrevs, copied)
tuples in backwards order
"""
cl_count = len(repo)
revs = []
Gregory Szorc
global: use pycompat.xrange()...
r38806 for j in pycompat.xrange(0, last + 1):
Durham Goode
log: move log file walk to its own function...
r19290 linkrev = filelog.linkrev(j)
if linkrev < minrev:
continue
# only yield rev for which we have the changelog, it can
# happen while doing "hg log" during a pull or commit
if linkrev >= cl_count:
break
parentlinkrevs = []
for p in filelog.parentrevs(j):
if p != nullrev:
parentlinkrevs.append(filelog.linkrev(p))
n = filelog.node(j)
Augie Fackler
formatting: blacken the codebase...
r43346 revs.append(
(linkrev, parentlinkrevs, follow and filelog.renamed(n))
)
Durham Goode
log: move log file walk to its own function...
r19290
return reversed(revs)
Augie Fackler
formatting: blacken the codebase...
r43346
Durham Goode
log: move log file walk to its own function...
r19290 def iterfiles():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 pctx = repo[b'.']
Durham Goode
log: move log file walk to its own function...
r19290 for filename in match.files():
if follow:
if filename not in pctx:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(
b'cannot follow file not in parent '
b'revision: "%s"'
)
Augie Fackler
formatting: blacken the codebase...
r43346 % filename
)
Durham Goode
log: move log file walk to its own function...
r19290 yield filename, pctx[filename].filenode()
else:
yield filename, None
for filename_node in copies:
yield filename_node
for file_, node in iterfiles():
filelog = repo.file(file_)
if not len(filelog):
if node is None:
# A zero count may be a directory or deleted file, so
# try to find matching entries on the slow path.
if follow:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'cannot follow nonexistent file: "%s"') % file_
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise FileWalkError(b"Cannot walk via filelog")
Durham Goode
log: move log file walk to its own function...
r19290 else:
continue
if node is None:
last = len(filelog) - 1
else:
last = filelog.rev(node)
# keep track of all ancestors of the file
Martin von Zweigbergk
cleanup: use set literals...
r32291 ancestors = {filelog.linkrev(last)}
Durham Goode
log: move log file walk to its own function...
r19290
# iterate from latest to oldest revision
Martin von Zweigbergk
walkfilerevs: rename filerevgen() to filerevs() since it's not a generator...
r42004 for rev, flparentlinkrevs, copied in filerevs(filelog, last):
Durham Goode
log: move log file walk to its own function...
r19290 if not follow:
if rev > maxrev:
continue
else:
# Note that last might not be the first interesting
# rev to us:
# if the file has been changed after maxrev, we'll
# have linkrev(last) > maxrev, and we still need
# to explore the file graph
if rev not in ancestors:
continue
# XXX insert 1327 fix here
if flparentlinkrevs:
ancestors.update(flparentlinkrevs)
fncache.setdefault(rev, []).append(file_)
wanted.add(rev)
if copied:
copies.append(copied)
return wanted
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
walkchangerevs: make followfilter a top-level class...
r24391 class _followfilter(object):
def __init__(self, repo, onlyfirst=False):
self.repo = repo
self.startrev = nullrev
self.roots = set()
self.onlyfirst = onlyfirst
def match(self, rev):
def realparents(rev):
if self.onlyfirst:
return self.repo.changelog.parentrevs(rev)[0:1]
else:
Augie Fackler
formatting: blacken the codebase...
r43346 return filter(
lambda x: x != nullrev, self.repo.changelog.parentrevs(rev)
)
Martin von Zweigbergk
walkchangerevs: make followfilter a top-level class...
r24391
if self.startrev == nullrev:
self.startrev = rev
return True
if rev > self.startrev:
# forward: all descendants
if not self.roots:
self.roots.add(self.startrev)
for parent in realparents(rev):
if parent in self.roots:
self.roots.add(rev)
return True
else:
# backwards: all parents
if not self.roots:
self.roots.update(realparents(self.startrev))
if rev in self.roots:
self.roots.remove(rev)
self.roots.update(realparents(rev))
return True
return False
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
walkchangerevs: drop ui arg
r9665 def walkchangerevs(repo, match, opts, prepare):
timeless
help: miscellaneous language fixes
r7807 '''Iterate over files and the revs in which they changed.
Matt Mackall
move walkchangerevs to cmdutils
r3650
Callers most commonly need to iterate backwards over the history
timeless
help: miscellaneous language fixes
r7807 in which they are interested. Doing so has awful (quadratic-looking)
Matt Mackall
move walkchangerevs to cmdutils
r3650 performance, so we use iterators in a "windowed" way.
We walk a window of revisions in the desired order. Within the
window, we first walk forwards to gather data, then in the desired
order (usually backwards) to display it.
Matt Mackall
walkchangerevs: move 'add' to callback...
r9662 This function returns an iterator yielding contexts. Before
yielding each context, the iterator will first call the prepare
function on each context in the window in forward order.'''
Matt Mackall
move walkchangerevs to cmdutils
r3650
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 allfiles = opts.get(b'all_files')
follow = opts.get(b'follow') or opts.get(b'follow_first')
Yuya Nishihara
log: duplicate _logrevs() dedicated for walkchangerevs()...
r35700 revs = _walkrevs(repo, opts)
Matt Mackall
walkchangerevs: allow empty query sets
r11281 if not revs:
return []
Martin Geisler
replace set-like dictionaries with real sets...
r8152 wanted = set()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 slowpath = match.anypats() or (not match.always() and opts.get(b'removed'))
Matt Mackall
move walkchangerevs to cmdutils
r3650 fncache = {}
Martin von Zweigbergk
log: remove dependence on repo.changectx()...
r37319 change = repo.__getitem__
Matt Mackall
move walkchangerevs to cmdutils
r3650
Nicolas Dumazet
log: document the different phases in walkchangerevs
r11632 # First step is to fill wanted, the set of revisions that we want to yield.
# When it does not induce extra cost, we also fill fncache for revisions in
# wanted: a cache of filenames that were changed (ctx.files()) and that
# match the file filtering conditions.
Sangeet Kumar Mishra
grep: search all commits in allfiles mode...
r38996 if match.always() or allfiles:
Matt Mackall
move walkchangerevs to cmdutils
r3650 # No files, no patterns. Display all revs.
Lucas Moscovicz
cmdutil: implemented new lazy increasingwindows...
r20553 wanted = revs
Martin von Zweigbergk
walkchangerevs: simplify with an 'elif'...
r25271 elif not slowpath:
Nicolas Dumazet
log: document the different phases in walkchangerevs
r11632 # We only have to read through the filelog to find wanted revisions
Durham Goode
log: move log file walk to its own function...
r19290 try:
wanted = walkfilerevs(repo, match, follow, revs, fncache)
except FileWalkError:
slowpath = True
Nicolas Dumazet
log: remove increasing windows usage in fastpath...
r11608
Durham Goode
log: move log file walk to its own function...
r19290 # We decided to fall back to the slowpath because at least one
# of the paths was not a file. Check to see if at least one of them
# existed in history, otherwise simply return
smuralid
log: speed up hg log for untracked files (issue1340)...
r17746 for path in match.files():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if path == b'.' or path in repo.store:
smuralid
log: speed up hg log for untracked files (issue1340)...
r17746 break
Mads Kiilerich
log: make log work even if first parameter doesn't exist...
r18340 else:
return []
smuralid
log: speed up hg log for untracked files (issue1340)...
r17746
Matt Mackall
move walkchangerevs to cmdutils
r3650 if slowpath:
Nicolas Dumazet
log: document the different phases in walkchangerevs
r11632 # We have to read the changelog to match filenames against
# changed files
Matt Mackall
move walkchangerevs to cmdutils
r3650 if follow:
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'can only follow copies/renames for explicit filenames')
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Mackall
move walkchangerevs to cmdutils
r3650
# The slow path checks files modified in every changeset.
Durham Goode
log: make file log slow path usable on large repos...
r19730 # This is really slow on large repos, so compute the set lazily.
class lazywantedset(object):
def __init__(self):
self.set = set()
self.revs = set(revs)
# No need to worry about locality here because it will be accessed
# in the same order as the increasing window below.
def __contains__(self, value):
if value in self.set:
return True
elif not value in self.revs:
return False
else:
self.revs.discard(value)
ctx = change(value)
Jordi Gutiérrez Hermoso
walkchangerevs: obey allfiles parameter when taking the slow path...
r41832 if allfiles:
matches = list(ctx.manifest().walk(match))
else:
matches = [f for f in ctx.files() if match(f)]
Durham Goode
log: make file log slow path usable on large repos...
r19730 if matches:
fncache[value] = matches
self.set.add(value)
return True
return False
def discard(self, value):
self.revs.discard(value)
self.set.discard(value)
wanted = lazywantedset()
Matt Mackall
move walkchangerevs to cmdutils
r3650
# it might be worthwhile to do this in the iterator if the rev range
# is descending and the prune args are all within that range
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for rev in opts.get(b'prune', ()):
Matt Mackall
cmdutil: use context instead of lookup
r16380 rev = repo[rev].rev()
Martin von Zweigbergk
walkchangerevs: make followfilter a top-level class...
r24391 ff = _followfilter(repo)
Matt Mackall
move walkchangerevs to cmdutils
r3650 stop = min(revs[0], revs[-1])
Gregory Szorc
global: use pycompat.xrange()...
r38806 for x in pycompat.xrange(rev, stop - 1, -1):
Martin Geisler
replace set-like dictionaries with real sets...
r8152 if ff.match(x):
Lucas Moscovicz
cmdutil: implemented new lazy increasingwindows...
r20553 wanted = wanted - [x]
Bryan O'Sullivan
cmdutil: use a small initial window with --limit...
r18710
Nicolas Dumazet
log: document the different phases in walkchangerevs
r11632 # Now that wanted is correctly initialized, we can iterate over the
# revision range, yielding only revisions in wanted.
Matt Mackall
move walkchangerevs to cmdutils
r3650 def iterate():
Martin von Zweigbergk
walkchangerevs: avoid match.files() in conditions...
r25272 if follow and match.always():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ff = _followfilter(repo, onlyfirst=opts.get(b'follow_first'))
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
move walkchangerevs to cmdutils
r3650 def want(rev):
Martin Geisler
cmdutil: return boolean result directly in want function
r8119 return ff.match(rev) and rev in wanted
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
move walkchangerevs to cmdutils
r3650 else:
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
move walkchangerevs to cmdutils
r3650 def want(rev):
return rev in wanted
Lucas Moscovicz
cmdutil: implemented new lazy increasingwindows...
r20553 it = iter(revs)
stopiteration = False
for windowsize in increasingwindows():
nrevs = []
Gregory Szorc
global: use pycompat.xrange()...
r38806 for i in pycompat.xrange(windowsize):
Pierre-Yves David
walkchangerevs: replace try/except with 'next'...
r25147 rev = next(it, None)
if rev is None:
Lucas Moscovicz
cmdutil: implemented new lazy increasingwindows...
r20553 stopiteration = True
break
Pierre-Yves David
walkchangerevs: replace try/except with 'next'...
r25147 elif want(rev):
nrevs.append(rev)
Matt Mackall
replace util.sort with sorted built-in...
r8209 for rev in sorted(nrevs):
Matt Mackall
move walkchangerevs to cmdutils
r3650 fns = fncache.get(rev)
Matt Mackall
walkchangerevs: yield contexts
r9654 ctx = change(rev)
Matt Mackall
move walkchangerevs to cmdutils
r3650 if not fns:
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
move walkchangerevs to cmdutils
r3650 def fns_generator():
Sangeet Kumar Mishra
grep: adds allfiles mode...
r38361 if allfiles:
Martin von Zweigbergk
grep: speed up `hg grep --all-files some/path` by using ctx.matches(match)...
r44501
def bad(f, msg):
pass
for f in ctx.matches(matchmod.badmatch(match, bad)):
yield f
Sangeet Kumar Mishra
grep: adds allfiles mode...
r38361 else:
Martin von Zweigbergk
grep: speed up `hg grep --all-files some/path` by using ctx.matches(match)...
r44501 for f in ctx.files():
if match(f):
yield f
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
move walkchangerevs to cmdutils
r3650 fns = fns_generator()
Matt Mackall
walkchangerevs: move 'add' to callback...
r9662 prepare(ctx, fns)
Matt Mackall
move walkchangerevs to cmdutils
r3650 for rev in nrevs:
Matt Mackall
walkchangerevs: move 'add' to callback...
r9662 yield change(rev)
Lucas Moscovicz
cmdutil: implemented new lazy increasingwindows...
r20553
if stopiteration:
break
Matt Mackall
walkchangerevs: pull out matchfn...
r9652 return iterate()
Bryan O'Sullivan
commands: move commit to cmdutil as wrapper for commit-like functions
r5034
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
add: pass around uipathfn and use instead of m.rel() (API)...
r41799 def add(ui, repo, match, prefix, uipathfn, explicitonly, **opts):
Martin Geisler
add: move main part to cmdutil to make it easier to reuse
r12269 bad = []
Matt Harbison
add: replace match.bad() monkey patching with match.badmatch()...
r25436
badfn = lambda x, y: bad.append(x) or match.bad(x, y)
Martin Geisler
add: move main part to cmdutil to make it easier to reuse
r12269 names = []
Martin Geisler
add: recurse into subrepositories with --subrepos/-S flag
r12270 wctx = repo[None]
Adrian Buehlmann
scmutil: introduce casecollisionauditor...
r14138 cca = None
abort, warn = scmutil.checkportabilityalert(ui)
if abort or warn:
Joshua Redstone
scmutil: 25% speedup in casecollisionauditor...
r17201 cca = scmutil.casecollisionauditor(ui, abort, repo.dirstate)
Matt Harbison
add: replace match.bad() monkey patching with match.badmatch()...
r25436
Martin von Zweigbergk
narrow: move remaining narrow-limited dirstate walks to core...
r40123 match = repo.narrowmatch(match, includeexact=True)
Durham Goode
add: pass full=False to dirstate walk...
r26206 badmatch = matchmod.badmatch(match, badfn)
dirstate = repo.dirstate
# We don't want to just call wctx.walk here, since it would return a lot of
# clean files, which we aren't interested in and takes time.
Augie Fackler
formatting: blacken the codebase...
r43346 for f in sorted(
dirstate.walk(
badmatch,
subrepos=sorted(wctx.substate),
unknown=True,
ignored=False,
full=False,
)
):
Martin Geisler
add: move main part to cmdutil to make it easier to reuse
r12269 exact = match.exact(f)
John Coomes
add: use lexists so that broken symbolic links are added...
r23462 if exact or not explicitonly and f not in wctx and repo.wvfs.lexists(f):
Adrian Buehlmann
scmutil: introduce casecollisionauditor...
r14138 if cca:
cca(f)
Martin Geisler
add: move main part to cmdutil to make it easier to reuse
r12269 names.append(f)
if ui.verbose or not exact:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'adding %s\n') % uipathfn(f), label=b'ui.addremove.added'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martin Geisler
add: recurse into subrepositories with --subrepos/-S flag
r12270
Mads Kiilerich
subrepos: process subrepos in sorted order...
r18364 for subpath in sorted(wctx.substate):
David M. Carr
add: support adding explicit files in subrepos...
r15410 sub = wctx.sub(subpath)
try:
Martin von Zweigbergk
match: rename "narrowmatcher" to "subdirmatcher" (API)...
r28017 submatch = matchmod.subdirmatcher(subpath, match)
Martin von Zweigbergk
subrepo: adjust subrepo prefix before calling subrepo.add() (API)...
r41777 subprefix = repo.wvfs.reljoin(prefix, subpath)
Martin von Zweigbergk
add: pass around uipathfn and use instead of m.rel() (API)...
r41799 subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if opts.get('subrepos'):
Augie Fackler
formatting: blacken the codebase...
r43346 bad.extend(
sub.add(ui, submatch, subprefix, subuipathfn, False, **opts)
)
David M. Carr
add: support adding explicit files in subrepos...
r15410 else:
Augie Fackler
formatting: blacken the codebase...
r43346 bad.extend(
sub.add(ui, submatch, subprefix, subuipathfn, True, **opts)
)
David M. Carr
add: support adding explicit files in subrepos...
r15410 except error.LookupError:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"skipping missing subrepository: %s\n") % uipathfn(subpath)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martin Geisler
add: recurse into subrepositories with --subrepos/-S flag
r12270
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if not opts.get('dry_run'):
Martin Geisler
add: recurse into subrepositories with --subrepos/-S flag
r12270 rejected = wctx.add(names, prefix)
Martin Geisler
add: move main part to cmdutil to make it easier to reuse
r12269 bad.extend(f for f in rejected if f in match.files())
return bad
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
serve: add support for Mercurial subrepositories...
r32005 def addwebdirpath(repo, serverpath, webconf):
webconf[serverpath] = repo.root
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.debug(b'adding %s = %s\n' % (serverpath, repo.root))
for r in repo.revs(b'filelog("path:.hgsub")'):
Matt Harbison
serve: add support for Mercurial subrepositories...
r32005 ctx = repo[r]
for subpath in ctx.substate:
ctx.sub(subpath).addwebdirpath(serverpath, webconf)
Augie Fackler
formatting: blacken the codebase...
r43346
def forget(
ui, repo, match, prefix, uipathfn, explicitonly, dryrun, interactive
):
Sushil khanchi
forget: rename --confirm to --interactive...
r37796 if dryrun and interactive:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"cannot specify both --dry-run and --interactive"))
David M. Carr
forget: fix subrepo recursion for explicit path handling...
r15912 bad = []
Matt Harbison
forget: replace match.bad() monkey patching with match.badmatch()...
r25437 badfn = lambda x, y: bad.append(x) or match.bad(x, y)
David M. Carr
forget: fix subrepo recursion for explicit path handling...
r15912 wctx = repo[None]
forgot = []
Matt Harbison
forget: replace match.bad() monkey patching with match.badmatch()...
r25437
s = repo.status(match=matchmod.badmatch(match, badfn), clean=True)
Martin von Zweigbergk
forget: access status fields by name, not index
r32174 forget = sorted(s.modified + s.added + s.deleted + s.clean)
David M. Carr
forget: fix subrepo recursion for explicit path handling...
r15912 if explicitonly:
forget = [f for f in forget if match.exact(f)]
Mads Kiilerich
subrepos: process subrepos in sorted order...
r18364 for subpath in sorted(wctx.substate):
David M. Carr
forget: fix subrepo recursion for explicit path handling...
r15912 sub = wctx.sub(subpath)
Martin von Zweigbergk
subrepo: adjust subrepo prefix before calling subrepo.forget() (API)...
r41776 submatch = matchmod.subdirmatcher(subpath, match)
subprefix = repo.wvfs.reljoin(prefix, subpath)
Martin von Zweigbergk
forget: pass around uipathfn and use instead of m.rel() (API)...
r41802 subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
David M. Carr
forget: fix subrepo recursion for explicit path handling...
r15912 try:
Augie Fackler
formatting: blacken the codebase...
r43346 subbad, subforgot = sub.forget(
submatch,
subprefix,
subuipathfn,
dryrun=dryrun,
interactive=interactive,
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 bad.extend([subpath + b'/' + f for f in subbad])
forgot.extend([subpath + b'/' + f for f in subforgot])
David M. Carr
forget: fix subrepo recursion for explicit path handling...
r15912 except error.LookupError:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"skipping missing subrepository: %s\n") % uipathfn(subpath)
Augie Fackler
formatting: blacken the codebase...
r43346 )
David M. Carr
forget: fix subrepo recursion for explicit path handling...
r15912
FUJIWARA Katsunori
forget: show warning messages for forgetting in subrepo correctly...
r16070 if not explicitonly:
for f in match.files():
Matt Harbison
forget: use vfs instead of os.path + match.rel() for filesystem checks
r23673 if f not in repo.dirstate and not repo.wvfs.isdir(f):
David M. Carr
forget: fix subrepo recursion for explicit path handling...
r15912 if f not in forgot:
Matt Harbison
forget: use vfs instead of os.path + match.rel() for filesystem checks
r23673 if repo.wvfs.exists(f):
Matt Harbison
forget: cleanup the output for an inexact case match on icasefs...
r24548 # Don't complain if the exact case match wasn't given.
# But don't do this until after checking 'forgot', so
# that subrepo files aren't normalized, and this op is
# purely from data cached by the status walk above.
if repo.dirstate.normalize(f) in repo.dirstate:
continue
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(
b'not removing %s: '
b'file is already untracked\n'
)
Augie Fackler
formatting: blacken the codebase...
r43346 % uipathfn(f)
)
David M. Carr
forget: fix subrepo recursion for explicit path handling...
r15912 bad.append(f)
Sushil khanchi
forget: rename --confirm to --interactive...
r37796 if interactive:
Augie Fackler
formatting: blacken the codebase...
r43346 responses = _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'[Ynsa?]'
b'$$ &Yes, forget this file'
b'$$ &No, skip this file'
b'$$ &Skip remaining files'
b'$$ Include &all remaining files'
b'$$ &? (display help)'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Sushil khanchi
forget: add --confirm option...
r37774 for filename in forget[:]:
Augie Fackler
formatting: blacken the codebase...
r43346 r = ui.promptchoice(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'forget %s %s') % (uipathfn(filename), responses)
Augie Fackler
formatting: blacken the codebase...
r43346 )
if r == 4: # ?
Sushil khanchi
forget: add --confirm option...
r37774 while r == 4:
for c, t in ui.extractchoices(responses)[1]:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.write(b'%s - %s\n' % (c, encoding.lower(t)))
Augie Fackler
formatting: blacken the codebase...
r43346 r = ui.promptchoice(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'forget %s %s') % (uipathfn(filename), responses)
Augie Fackler
formatting: blacken the codebase...
r43346 )
if r == 0: # yes
Sushil khanchi
forget: add --confirm option...
r37774 continue
Augie Fackler
formatting: blacken the codebase...
r43346 elif r == 1: # no
Sushil khanchi
forget: add --confirm option...
r37774 forget.remove(filename)
Augie Fackler
formatting: blacken the codebase...
r43346 elif r == 2: # Skip
Sushil khanchi
forget: add --confirm option...
r37774 fnindex = forget.index(filename)
del forget[fnindex:]
break
Augie Fackler
formatting: blacken the codebase...
r43346 elif r == 3: # All
Sushil khanchi
forget: add --confirm option...
r37774 break
David M. Carr
forget: fix subrepo recursion for explicit path handling...
r15912 for f in forget:
Sushil khanchi
forget: rename --confirm to --interactive...
r37796 if ui.verbose or not match.exact(f) or interactive:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'removing %s\n') % uipathfn(f), label=b'ui.addremove.removed'
Augie Fackler
formatting: blacken the codebase...
r43346 )
David M. Carr
forget: fix subrepo recursion for explicit path handling...
r15912
Sushil khanchi
forget: add --dry-run mode
r36957 if not dryrun:
rejected = wctx.forget(forget, prefix)
bad.extend(f for f in rejected if f in match.files())
forgot.extend(f for f in forget if f not in rejected)
David M. Carr
forget: fix subrepo recursion for explicit path handling...
r15912 return bad, forgot
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
subrepo: use root-repo-relative path from `hg files` with ui.relative-paths=no...
r41914 def files(ui, ctx, m, uipathfn, fm, fmt, subrepos):
Matt Harbison
files: split reusable implementation into cmdutil for subrepo support
r24275 ret = 1
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 needsfctx = ui.verbose or {b'size', b'flags'} & fm.datahint()
Matt Harbison
files: split reusable implementation into cmdutil for subrepo support
r24275 for f in ctx.matches(m):
fm.startitem()
Yuya Nishihara
files: add support for log-like template keywords and functions...
r38560 fm.context(ctx=ctx)
Yuya Nishihara
files: automatically populate fields referenced from template
r38559 if needsfctx:
Matt Harbison
files: split reusable implementation into cmdutil for subrepo support
r24275 fc = ctx[f]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fm.write(b'size flags', b'% 10d % 1s ', fc.size(), fc.flags())
Yuya Nishihara
formatter: rename {abspath}/{file} to {path}, and drop relative {path} (BC)...
r39405 fm.data(path=f)
Martin von Zweigbergk
files: respect ui.relative-paths...
r41717 fm.plain(fmt % uipathfn(f))
Matt Harbison
files: split reusable implementation into cmdutil for subrepo support
r24275 ret = 0
Matt Harbison
files: recurse into subrepos automatically with an explicit path
r25228 for subpath in sorted(ctx.substate):
Hannes Oldenburg
subrepo: cleanup of subrepo filematcher logic...
r29802 submatch = matchmod.subdirmatcher(subpath, m)
Martin von Zweigbergk
subrepo: use root-repo-relative path from `hg files` with ui.relative-paths=no...
r41914 subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
Augie Fackler
formatting: blacken the codebase...
r43346 if subrepos or m.exact(subpath) or any(submatch.files()):
Matt Harbison
subrepo: add basic support to hgsubrepo for the files command...
r24413 sub = ctx.sub(subpath)
try:
Matt Harbison
files: don't recurse into subrepos without a path or -S (issue5127)...
r28387 recurse = m.exact(subpath) or subrepos
Augie Fackler
formatting: blacken the codebase...
r43346 if (
sub.printfiles(ui, submatch, subuipathfn, fm, fmt, recurse)
== 0
):
Matt Harbison
subrepo: add basic support to hgsubrepo for the files command...
r24413 ret = 0
except error.LookupError:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"skipping missing subrepository: %s\n")
Augie Fackler
formatting: blacken the codebase...
r43346 % uipathfn(subpath)
)
Matt Harbison
subrepo: add basic support to hgsubrepo for the files command...
r24413
Matt Harbison
files: split reusable implementation into cmdutil for subrepo support
r24275 return ret
Augie Fackler
formatting: blacken the codebase...
r43346
def remove(
ui, repo, m, prefix, uipathfn, after, force, subrepos, dryrun, warnings=None
):
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289 ret = 0
s = repo.status(match=m, clean=True)
Augie Fackler
cmdutil: use field names instead of field numbers on scmutil.status...
r44043 modified, added, deleted, clean = s.modified, s.added, s.deleted, s.clean
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289
Matt Harbison
remove: recurse into subrepositories with --subrepos/-S flag...
r23325 wctx = repo[None]
timeless
remove: queue warnings until after status messages (issue5140) (API)...
r28607 if warnings is None:
warnings = []
warn = True
else:
warn = False
timeless
remove: add progress support
r28608 subs = sorted(wctx.substate)
Augie Fackler
formatting: blacken the codebase...
r43346 progress = ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'searching'), total=len(subs), unit=_(b'subrepos')
Augie Fackler
formatting: blacken the codebase...
r43346 )
timeless
remove: add progress support
r28608 for subpath in subs:
Hannes Oldenburg
subrepo: cleanup of subrepo filematcher logic...
r29802 submatch = matchmod.subdirmatcher(subpath, m)
Martin von Zweigbergk
subrepo: adjust subrepo prefix before calling subrepo.removefiles() (API)...
r41775 subprefix = repo.wvfs.reljoin(prefix, subpath)
Martin von Zweigbergk
remove: pass around uipathfn and use instead of m.rel() (API)...
r41800 subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
Hannes Oldenburg
subrepo: cleanup of subrepo filematcher logic...
r29802 if subrepos or m.exact(subpath) or any(submatch.files()):
Martin von Zweigbergk
remove: use progress helper...
r38366 progress.increment()
Matt Harbison
remove: recurse into subrepositories with --subrepos/-S flag...
r23325 sub = wctx.sub(subpath)
try:
Augie Fackler
formatting: blacken the codebase...
r43346 if sub.removefiles(
submatch,
subprefix,
subuipathfn,
after,
force,
subrepos,
dryrun,
warnings,
):
Matt Harbison
remove: recurse into subrepositories with --subrepos/-S flag...
r23325 ret = 1
except error.LookupError:
Augie Fackler
formatting: blacken the codebase...
r43346 warnings.append(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"skipping missing subrepository: %s\n")
Augie Fackler
formatting: blacken the codebase...
r43346 % uipathfn(subpath)
)
Martin von Zweigbergk
progress: hide update(None) in a new complete() method...
r38392 progress.complete()
Matt Harbison
remove: recurse into subrepositories with --subrepos/-S flag...
r23325
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289 # warn about failure to delete explicit files/dirs
utils: move the `dirs` definition in pathutil (API)...
r43923 deleteddirs = pathutil.dirs(deleted)
timeless
remove: add progress support
r28608 files = m.files()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 progress = ui.makeprogress(
_(b'deleting'), total=len(files), unit=_(b'files')
)
timeless
remove: add progress support
r28608 for f in files:
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
remove: recurse into subrepositories with --subrepos/-S flag...
r23325 def insubrepo():
for subpath in wctx.substate:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if f.startswith(subpath + b'/'):
Matt Harbison
remove: recurse into subrepositories with --subrepos/-S flag...
r23325 return True
return False
Martin von Zweigbergk
remove: use progress helper...
r38366 progress.increment()
Martin von Zweigbergk
remove: use ctx.hasdir(f) instead of 'f in ctx.dirs()'...
r24955 isdir = f in deleteddirs or wctx.hasdir(f)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if f in repo.dirstate or isdir or f == b'.' or insubrepo() or f in subs:
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289 continue
Matt Harbison
remove: recurse into subrepositories with --subrepos/-S flag...
r23325
Matt Harbison
remove: use vfs instead of os.path + match.rel() for filesystem checks
r23674 if repo.wvfs.exists(f):
if repo.wvfs.isdir(f):
Augie Fackler
formatting: blacken the codebase...
r43346 warnings.append(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'not removing %s: no tracked files\n') % uipathfn(f)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289 else:
Augie Fackler
formatting: blacken the codebase...
r43346 warnings.append(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'not removing %s: file is untracked\n') % uipathfn(f)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289 # missing files will generate a warning elsewhere
ret = 1
Martin von Zweigbergk
progress: hide update(None) in a new complete() method...
r38392 progress.complete()
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289
if force:
list = modified + deleted + clean + added
elif after:
list = deleted
timeless
remove: add progress support
r28608 remaining = modified + added + clean
Augie Fackler
formatting: blacken the codebase...
r43346 progress = ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'skipping'), total=len(remaining), unit=_(b'files')
Augie Fackler
formatting: blacken the codebase...
r43346 )
timeless
remove: add progress support
r28608 for f in remaining:
Martin von Zweigbergk
remove: use progress helper...
r38366 progress.increment()
pavanpc@fb.com
remove: print message for each file in verbose mode only while using `-A` (BC)...
r35120 if ui.verbose or (f in files):
Augie Fackler
formatting: blacken the codebase...
r43346 warnings.append(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'not removing %s: file still exists\n') % uipathfn(f)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289 ret = 1
Martin von Zweigbergk
progress: hide update(None) in a new complete() method...
r38392 progress.complete()
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289 else:
list = deleted + clean
Augie Fackler
formatting: blacken the codebase...
r43346 progress = ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'skipping'), total=(len(modified) + len(added)), unit=_(b'files')
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289 for f in modified:
Martin von Zweigbergk
remove: use progress helper...
r38366 progress.increment()
Augie Fackler
formatting: blacken the codebase...
r43346 warnings.append(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'not removing %s: file is modified (use -f'
b' to force removal)\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% uipathfn(f)
)
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289 ret = 1
for f in added:
Martin von Zweigbergk
remove: use progress helper...
r38366 progress.increment()
Augie Fackler
formatting: blacken the codebase...
r43346 warnings.append(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"not removing %s: file has been marked for add"
b" (use 'hg forget' to undo add)\n"
Augie Fackler
formatting: blacken the codebase...
r43346 )
% uipathfn(f)
)
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289 ret = 1
Martin von Zweigbergk
progress: hide update(None) in a new complete() method...
r38392 progress.complete()
timeless
remove: add progress support
r28608
list = sorted(list)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 progress = ui.makeprogress(
_(b'deleting'), total=len(list), unit=_(b'files')
)
timeless
remove: add progress support
r28608 for f in list:
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289 if ui.verbose or not m.exact(f):
Martin von Zweigbergk
remove: use progress helper...
r38366 progress.increment()
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'removing %s\n') % uipathfn(f), label=b'ui.addremove.removed'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martin von Zweigbergk
progress: hide update(None) in a new complete() method...
r38392 progress.complete()
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289
Sushil khanchi
remove: add dry-run functionality
r37168 if not dryrun:
with repo.wlock():
if not after:
for f in list:
if f in added:
Augie Fackler
formatting: blacken the codebase...
r43346 continue # we never unlink added files on remove
rmdir = repo.ui.configbool(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'experimental', b'removeemptydirs'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Kyle Lippincott
unlinkpath: make empty directory removal optional (issue5901) (issue5826)...
r38512 repo.wvfs.unlinkpath(f, ignoremissing=True, rmdir=rmdir)
Sushil khanchi
remove: add dry-run functionality
r37168 repo[None].forget(list)
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289
timeless
remove: queue warnings until after status messages (issue5140) (API)...
r28607 if warn:
for warning in warnings:
ui.warn(warning)
Matt Harbison
remove: move most of the implementation into cmdutils.remove()...
r23289 return ret
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
cat: don't prefetch files unless the output requires it...
r42678 def _catfmtneedsdata(fm):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return not fm.datahint() or b'data' in fm.datahint()
Matt Harbison
cat: don't prefetch files unless the output requires it...
r42678
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
cat: factor out a function that populates the formatter...
r35680 def _updatecatformatter(fm, ctx, matcher, path, decode):
"""Hook for adding data to the formatter used by ``hg cat``.
Extensions (e.g., lfs) can wrap this to inject keywords/data, but must call
this method first."""
Matt Harbison
cat: don't prefetch files unless the output requires it...
r42678
# data() can be expensive to fetch (e.g. lfs), so don't fetch it if it
# wasn't requested.
data = b''
if _catfmtneedsdata(fm):
data = ctx[path].data()
if decode:
data = ctx.repo().wwritedata(path, data)
Matt Harbison
cat: factor out a function that populates the formatter...
r35680 fm.startitem()
Yuya Nishihara
cat: add support for log-like template keywords and functions
r38557 fm.context(ctx=ctx)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fm.write(b'data', b'%s', data)
Yuya Nishihara
formatter: rename {abspath}/{file} to {path}, and drop relative {path} (BC)...
r39405 fm.data(path=path)
Matt Harbison
cat: factor out a function that populates the formatter...
r35680
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cat: add formatter support...
r32578 def cat(ui, repo, ctx, matcher, basefm, fntemplate, prefix, **opts):
Matt Harbison
cat: move most of the implementation into cmdutils.cat()...
r21040 err = 1
Pulkit Goyal
py3: handle keyword arguments correctly in cmdutil.py...
r35351 opts = pycompat.byteskwargs(opts)
Matt Harbison
cat: move most of the implementation into cmdutils.cat()...
r21040
def write(path):
Yuya Nishihara
cat: add formatter support...
r32578 filename = None
Yuya Nishihara
cat: stop using makefileobj()...
r32576 if fntemplate:
Augie Fackler
formatting: blacken the codebase...
r43346 filename = makefilename(
ctx, fntemplate, pathname=os.path.join(prefix, path)
)
Ryan McElroy
cmdutil: create dirs for templated cat file output...
r35010 # attempt to create the directory if it does not already exist
try:
os.makedirs(os.path.dirname(filename))
except OSError:
pass
Yuya Nishihara
formatter: carry opts to file-based formatters by basefm...
r37615 with formatter.maybereopen(basefm, filename) as fm:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _updatecatformatter(fm, ctx, matcher, path, opts.get(b'decode'))
Matt Harbison
cat: move most of the implementation into cmdutils.cat()...
r21040
# Automation often uses hg cat on single files, so special case it
# for performance to avoid the cost of parsing the manifest.
if len(matcher.files()) == 1 and not matcher.anypats():
file = matcher.files()[0]
Durham Goode
manifest: remove manifest.find...
r30340 mfl = repo.manifestlog
Yuya Nishihara
cat: use ctx.manifestnode() in place of ctx._changeset[0]
r24718 mfnode = ctx.manifestnode()
Durham Goode
manifest: remove manifest.find...
r30340 try:
if mfnode and mfl[mfnode].find(file)[0]:
Matt Harbison
cat: don't prefetch files unless the output requires it...
r42678 if _catfmtneedsdata(basefm):
scmutil.prefetchfiles(repo, [ctx.rev()], matcher)
Durham Goode
manifest: remove manifest.find...
r30340 write(file)
return 0
except KeyError:
pass
Matt Harbison
cat: move most of the implementation into cmdutils.cat()...
r21040
Matt Harbison
cat: don't prefetch files unless the output requires it...
r42678 if _catfmtneedsdata(basefm):
scmutil.prefetchfiles(repo, [ctx.rev()], matcher)
Matt Harbison
scmutil: teach the file prefetch hook to handle multiple commits...
r37780
for abs in ctx.walk(matcher):
Matt Harbison
cat: move most of the implementation into cmdutils.cat()...
r21040 write(abs)
err = 0
Matt Harbison
cat: support cat with explicit paths in subrepos...
r21041
Martin von Zweigbergk
cat: respect ui.relative-paths for "skipping missing subrepository"...
r41812 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
Matt Harbison
cat: support cat with explicit paths in subrepos...
r21041 for subpath in sorted(ctx.substate):
sub = ctx.sub(subpath)
try:
Martin von Zweigbergk
match: rename "narrowmatcher" to "subdirmatcher" (API)...
r28017 submatch = matchmod.subdirmatcher(subpath, matcher)
Martin von Zweigbergk
subrepo: (mostly) use relative path in "skipping missing subrepository"...
r41798 subprefix = os.path.join(prefix, subpath)
Augie Fackler
formatting: blacken the codebase...
r43346 if not sub.cat(
submatch,
basefm,
fntemplate,
subprefix,
**pycompat.strkwargs(opts)
):
Matt Harbison
cat: support cat with explicit paths in subrepos...
r21041 err = 0
except error.RepoLookupError:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"skipping missing subrepository: %s\n") % uipathfn(subpath)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
cat: support cat with explicit paths in subrepos...
r21041
Matt Harbison
cat: move most of the implementation into cmdutils.cat()...
r21040 return err
Augie Fackler
formatting: blacken the codebase...
r43346
Bryan O'Sullivan
commands: move commit to cmdutil as wrapper for commit-like functions
r5034 def commit(ui, repo, commitfunc, pats, opts):
'''commit the specified files or all outstanding changes'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 date = opts.get(b'date')
Thomas Arendsen Hein
Fix bad behaviour when specifying an invalid date (issue700)...
r6139 if date:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 opts[b'date'] = dateutil.parsedate(date)
Idan Kamara
cmdutil, logmessage: use ui.fin when reading from '-'
r14635 message = logmessage(ui, opts)
Matt Harbison
scmutil: pass a matcher to scmutil.addremove() instead of a list of patterns...
r23533 matcher = scmutil.match(repo[None], pats, opts)
Bryan O'Sullivan
commands: move commit to cmdutil as wrapper for commit-like functions
r5034
Martin von Zweigbergk
commit: don't let failed commit with --addremove update dirstate (issue5645)...
r33619 dsguard = None
Kirill Smelkov
cmdutil.commit: extract 'addremove' from opts carefully...
r5829 # extract addremove carefully -- this function can be called from a command
# that doesn't support addremove
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'addremove'):
dsguard = dirstateguard.dirstateguard(repo, b'commit')
Martin von Zweigbergk
commit: use context manager with dirstateguard...
r33823 with dsguard or util.nullcontextmanager():
Martin von Zweigbergk
commit: move dirstateguard creation out of try-block...
r33822 if dsguard:
Martin von Zweigbergk
addremove: pass around uipathfn and use instead of m.uipath() (API)...
r41801 relative = scmutil.anypats(pats, opts)
Martin von Zweigbergk
addremove: respect ui.relative-paths...
r41834 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if scmutil.addremove(repo, matcher, b"", uipathfn, opts) != 0:
Martin von Zweigbergk
commit: don't let failed commit with --addremove update dirstate (issue5645)...
r33619 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"failed to mark all new/missing files as added/removed")
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martin von Zweigbergk
commit: don't let failed commit with --addremove update dirstate (issue5645)...
r33619
Martin von Zweigbergk
commit: use context manager with dirstateguard...
r33823 return commitfunc(ui, repo, message, matcher, opts)
Matt Mackall
commit: move commit editor to cmdutil, pass as function
r8407
Augie Fackler
formatting: blacken the codebase...
r43346
Hannes Oldenburg
cmdutil: extract samefile function from amend()
r29819 def samefile(f, ctx1, ctx2):
if f in ctx1.manifest():
a = ctx1.filectx(f)
if f in ctx2.manifest():
b = ctx2.filectx(f)
Augie Fackler
formatting: blacken the codebase...
r43346 return not a.cmp(b) and a.flags() == b.flags()
Hannes Oldenburg
cmdutil: extract samefile function from amend()
r29819 else:
return False
else:
return f not in ctx2.manifest()
Augie Fackler
formatting: blacken the codebase...
r43346
Saurabh Singh
cmdutil: remove redundant commitfunc parameter in amend (API)...
r34088 def amend(ui, repo, old, extra, pats, opts):
Gregory Szorc
cmdutil: break import cycle...
r25930 # avoid cycle context -> subrepo -> cmdutil
Gregory Szorc
cmdutil: use absolute_import...
r28322 from . import context
Gregory Szorc
cmdutil: break import cycle...
r25930
Matt Harbison
amend: abort early if no username is configured with evolve enabled (issue4211)...
r23101 # amend will reuse the existing user if not specified, but the obsolete
# marker creation requires that the current user's name is specified.
Durham Goode
obsolete: remove last instance of _enabled...
r24379 if obsolete.isenabled(repo, obsolete.createmarkersopt):
Augie Fackler
formatting: blacken the codebase...
r43346 ui.username() # raise exception if username not set
Matt Harbison
amend: abort early if no username is configured with evolve enabled (issue4211)...
r23101
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.note(_(b'amending changeset %s\n') % old)
Idan Kamara
commit: add option to amend the working dir parent...
r16458 base = old.p1()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 with repo.wlock(), repo.lock(), repo.transaction(b'amend'):
Jun Wu
codemod: simplify nested withs...
r33438 # Participating changesets:
#
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 # wctx o - workingctx that contains changes from working copy
# | to go into amending commit
Jun Wu
codemod: simplify nested withs...
r33438 # |
# old o - changeset to amend
# |
Saurabh Singh
amend: rectify comment...
r34058 # base o - first parent of the changeset to amend
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 wctx = repo[None]
Jun Wu
codemod: simplify nested withs...
r33438
Martin von Zweigbergk
amend: make a copy of "extra" to avoid mutating an input...
r35197 # Copy to avoid mutating input
extra = extra.copy()
Jun Wu
codemod: simplify nested withs...
r33438 # Update extra dict from amended commit (e.g. to preserve graft
# source)
extra.update(old.extra())
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 # Also update it from the from the wctx
extra.update(wctx.extra())
Matt Harbison
amend: add option to update to the current user...
r43202 # date-only change should be ignored?
datemaydiffer = resolvecommitoptions(ui, opts)
date = old.date()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'date'):
date = dateutil.parsedate(opts.get(b'date'))
user = opts.get(b'user') or old.user()
Boris Feld
cmdutil: fix amend when passing a date...
r34123
Jun Wu
codemod: simplify nested withs...
r33438 if len(old.parents()) > 1:
# ctx.files() isn't reliable for merges, so fall back to the
# slower repo.status() method
Augie Fackler
cmdutil: use field names instead of field numbers on scmutil.status...
r44043 st = base.status(old)
files = set(st.modified) | set(st.added) | set(st.removed)
Jun Wu
codemod: simplify nested withs...
r33438 else:
files = set(old.files())
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 # add/remove the files to the working copy if the "addremove" option
# was specified.
matcher = scmutil.match(wctx, pats, opts)
Martin von Zweigbergk
addremove: pass around uipathfn and use instead of m.uipath() (API)...
r41801 relative = scmutil.anypats(pats, opts)
Martin von Zweigbergk
addremove: respect ui.relative-paths...
r41834 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'addremove') and scmutil.addremove(
repo, matcher, b"", uipathfn, opts
Augie Fackler
formatting: blacken the codebase...
r43346 ):
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"failed to mark all new/missing files as added/removed")
Augie Fackler
formatting: blacken the codebase...
r43346 )
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087
Yuya Nishihara
amend: update .hgsubstate before committing a memctx (issue5677)...
r35019 # Check subrepos. This depends on in-place wctx._status update in
# subrepo.precommit(). To minimize the risk of this hack, we do
# nothing if .hgsub does not exist.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'.hgsub' in wctx or b'.hgsub' in old:
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 subs, commitsubs, newsubstate = subrepoutil.precommit(
Augie Fackler
formatting: blacken the codebase...
r43346 ui, wctx, wctx._status, matcher
)
Yuya Nishihara
amend: update .hgsubstate before committing a memctx (issue5677)...
r35019 # amend should abort if commitsubrepos is enabled
assert not commitsubs
if subs:
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 subrepoutil.writestate(repo, newsubstate)
Yuya Nishihara
amend: update .hgsubstate before committing a memctx (issue5677)...
r35019
Yuya Nishihara
amend: abort if unresolved merge conflicts found (issue5805)...
r36927 ms = mergemod.mergestate.read(repo)
mergeutil.checkunresolved(ms)
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 filestoamend = set(f for f in wctx.files() if matcher(f))
Augie Fackler
formatting: blacken the codebase...
r43346 changes = len(filestoamend) > 0
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 if changes:
Jun Wu
codemod: simplify nested withs...
r33438 # Recompute copies (avoid recording a -> b -> a)
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 copied = copies.pathcopies(base, wctx, matcher)
Jun Wu
codemod: simplify nested withs...
r33438 if old.p2:
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 copied.update(copies.pathcopies(old.p2(), wctx, matcher))
Jun Wu
codemod: simplify nested withs...
r33438
# Prune files which were reverted by the updates: if old
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 # introduced file X and the file was renamed in the working
# copy, then those two files are the same and
Jun Wu
codemod: simplify nested withs...
r33438 # we can discard X from our list of files. Likewise if X
Yuya Nishihara
amend: do not drop missing files (issue5732)...
r35016 # was removed, it's no longer relevant. If X is missing (aka
# deleted), old X must be preserved.
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 files.update(filestoamend)
Augie Fackler
formatting: blacken the codebase...
r43346 files = [
f
for f in files
if (f not in filestoamend or not samefile(f, wctx, base))
]
Jun Wu
codemod: simplify nested withs...
r33438
def filectxfn(repo, ctx_, path):
try:
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 # If the file being considered is not amongst the files
# to be amended, we should return the file context from the
# old changeset. This avoids issues when only some files in
# the working copy are being amended but there are also
# changes to other files from the old changeset.
if path not in filestoamend:
return old.filectx(path)
Yuya Nishihara
amend: do not take untracked files as modified or clean (issue5732)...
r35015 # Return None for removed files.
if path in wctx.removed():
return None
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 fctx = wctx[path]
Jun Wu
codemod: simplify nested withs...
r33438 flags = fctx.flags()
Augie Fackler
formatting: blacken the codebase...
r43346 mctx = context.memfilectx(
repo,
ctx_,
fctx.path(),
fctx.data(),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 islink=b'l' in flags,
isexec=b'x' in flags,
Augie Fackler
formatting: blacken the codebase...
r43346 copysource=copied.get(path),
)
Jun Wu
codemod: simplify nested withs...
r33438 return mctx
except KeyError:
return None
Augie Fackler
formatting: blacken the codebase...
r43346
Jun Wu
codemod: simplify nested withs...
r33438 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.note(_(b'copying changeset %s to %s\n') % (old, base))
Jun Wu
codemod: simplify nested withs...
r33438
# Use version of files as in the old cset
def filectxfn(repo, ctx_, path):
try:
return old.filectx(path)
except KeyError:
return None
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 # See if we got a message from -m or -l, if not, open the editor with
# the message of the changeset to amend.
message = logmessage(ui, opts)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 editform = mergeeditform(old, b'commit.amend')
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087
Jun Wu
codemod: simplify nested withs...
r33438 if not message:
message = old.description()
Kyle Lippincott
commit: respect --no-edit in combination with --amend...
r42591 # Default if message isn't provided and --edit is not passed is to
# invoke editor, but allow --no-edit. If somehow we don't have any
# description, let's always start the editor.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 doedit = not message or opts.get(b'edit') in [True, None]
Kyle Lippincott
commit: respect --no-edit in combination with --amend...
r42591 else:
# Default if message is provided is to not invoke editor, but allow
# --edit.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 doedit = opts.get(b'edit') is True
Kyle Lippincott
commit: respect --no-edit in combination with --amend...
r42591 editor = getcommiteditor(edit=doedit, editform=editform)
Jun Wu
codemod: simplify nested withs...
r33438
pureextra = extra.copy()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extra[b'amend_source'] = old.hex()
Jun Wu
codemod: simplify nested withs...
r33438
Augie Fackler
formatting: blacken the codebase...
r43346 new = context.memctx(
repo,
parents=[base.node(), old.p2().node()],
text=message,
files=files,
filectxfn=filectxfn,
user=user,
date=date,
extra=extra,
editor=editor,
)
Jun Wu
codemod: simplify nested withs...
r33438
newdesc = changelog.stripdesc(new.description())
Augie Fackler
formatting: blacken the codebase...
r43346 if (
(not changes)
Jun Wu
codemod: simplify nested withs...
r33438 and newdesc == old.description()
and user == old.user()
Yuya Nishihara
amend: add boolean to ignore date-only change...
r41159 and (date == old.date() or datemaydiffer)
Augie Fackler
formatting: blacken the codebase...
r43346 and pureextra == old.extra()
):
Jun Wu
codemod: simplify nested withs...
r33438 # nothing changed. continuing here would create a new node
# anyway because of the amend_source noise.
Pierre-Yves David
amend: wrap all commit operations in a single transaction...
r17472 #
Jun Wu
codemod: simplify nested withs...
r33438 # This not what we expect from amend.
Yuya Nishihara
amend: add boolean to ignore date-only change...
r41159 return old.node()
Jun Wu
codemod: simplify nested withs...
r33438
Martin von Zweigbergk
scmutil: make cleanupnodes optionally also fix the phase...
r38442 commitphase = None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'secret'):
Martin von Zweigbergk
scmutil: make cleanupnodes optionally also fix the phase...
r38442 commitphase = phases.secret
newid = repo.commitctx(new)
Saurabh Singh
amend: removing redundant if condition...
r34057
# Reroute the working copy parent to the new changeset
repo.setparents(newid, nullid)
mapping = {old.node(): (newid,)}
Pulkit Goyal
cmdutil: pass metadata from amend() to cleanupnodes...
r34795 obsmetadata = None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'note'):
obsmetadata = {b'note': encoding.fromlocal(opts[b'note'])}
backup = ui.configbool(b'rewrite', b'backup-bundle')
Augie Fackler
formatting: blacken the codebase...
r43346 scmutil.cleanupnodes(
repo,
mapping,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'amend',
Augie Fackler
formatting: blacken the codebase...
r43346 metadata=obsmetadata,
fixphase=True,
targetphase=commitphase,
backup=backup,
)
Saurabh Singh
amend: removing redundant if condition...
r34057
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 # Fixing the dirstate because localrepo.commitctx does not update
# it. This is rather convenient because we did not need to update
# the dirstate for all the files in the new commit which commitctx
# could have done if it updated the dirstate. Now, we can
# selectively update the dirstate only for the amended files.
dirstate = repo.dirstate
Kyle Lippincott
amend: check for file modifications when updating dirstate (issue6233)...
r44238 # Update the state of the files which were added and modified in the
# amend to "normal" in the dirstate. We need to use "normallookup" since
# the files may have changed since the command started; using "normal"
# would mark them as clean but with uncommitted contents.
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087 normalfiles = set(wctx.modified() + wctx.added()) & filestoamend
for f in normalfiles:
Kyle Lippincott
amend: check for file modifications when updating dirstate (issue6233)...
r44238 dirstate.normallookup(f)
Saurabh Singh
cmdutil: remove the redundant commit during amend...
r34087
# Update the state of files which were removed in the amend
# to "removed" in the dirstate.
removedfiles = set(wctx.removed()) & filestoamend
for f in removedfiles:
dirstate.drop(f)
Idan Kamara
commit: add option to amend the working dir parent...
r16458 return newid
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 def commiteditor(repo, ctx, subs, editform=b''):
Matt Mackall
commit: move commit editor to cmdutil, pass as function
r8407 if ctx.description():
return ctx.description()
Augie Fackler
formatting: blacken the codebase...
r43346 return commitforceeditor(
repo, ctx, subs, editform=editform, unchangedmessagedetection=True
)
def commitforceeditor(
repo,
ctx,
subs,
finishdesc=None,
extramsg=None,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 editform=b'',
Augie Fackler
formatting: blacken the codebase...
r43346 unchangedmessagedetection=False,
):
Matt Mackall
commiteditor: refactor default extramsg
r21923 if not extramsg:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extramsg = _(b"Leave message empty to abort commit.")
forms = [e for e in editform.split(b'.') if e]
forms.insert(0, b'changeset')
Tony Tung
commit: abort when a committemplate is not changed...
r26742 templatetext = None
FUJIWARA Katsunori
cmdutil: look commit template definition up by specified 'editform'...
r22012 while forms:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ref = b'.'.join(forms)
if repo.ui.config(b'committemplate', ref):
Tony Tung
commit: abort when a committemplate is not changed...
r26742 templatetext = committext = buildcommittemplate(
Augie Fackler
formatting: blacken the codebase...
r43346 repo, ctx, subs, extramsg, ref
)
FUJIWARA Katsunori
cmdutil: look commit template definition up by specified 'editform'...
r22012 break
forms.pop()
FUJIWARA Katsunori
cmdutil: make commit message shown in text editor customizable by template...
r21924 else:
committext = buildcommittext(repo, ctx, subs, extramsg)
FUJIWARA Katsunori
cmdutil: separate building commit text from 'commitforceeditor'...
r21869
# run editor in the repository root
Matt Harbison
py3: rename pycompat.getcwd() to encoding.getcwd() (API)...
r39843 olddir = encoding.getcwd()
FUJIWARA Katsunori
cmdutil: separate building commit text from 'commitforceeditor'...
r21869 os.chdir(repo.root)
FUJIWARA Katsunori
cmdutil: make in-memory changes visible to external editor (issue4378)...
r26750
# make in-memory changes visible to external process
tr = repo.currenttransaction()
repo.dirstate.write(tr)
pending = tr and tr.writepending() and repo.root
Augie Fackler
formatting: blacken the codebase...
r43346 editortext = repo.ui.edit(
committext,
ctx.user(),
ctx.extra(),
editform=editform,
pending=pending,
repopath=repo.path,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 action=b'commit',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
commit: fix unmodified message detection for the "--- >8 ----" magic...
r30724 text = editortext
Sean Farley
cmdutil: add special string that ignores rest of text...
r30703
# strip away anything below this special string (used for editors that want
# to display the diff)
Yuya Nishihara
commit: fix unmodified message detection for the "--- >8 ----" magic...
r30724 stripbelow = re.search(_linebelow, text, flags=re.MULTILINE)
Sean Farley
cmdutil: add special string that ignores rest of text...
r30703 if stripbelow:
Augie Fackler
formatting: blacken the codebase...
r43346 text = text[: stripbelow.start()]
Yuya Nishihara
commit: fix unmodified message detection for the "--- >8 ----" magic...
r30724
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 text = re.sub(b"(?m)^HG:.*(\n|$)", b"", text)
FUJIWARA Katsunori
cmdutil: separate building commit text from 'commitforceeditor'...
r21869 os.chdir(olddir)
if finishdesc:
text = finishdesc(text)
if not text.strip():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"empty commit message"))
Tony Tung
commit: abort when a committemplate is not changed...
r26742 if unchangedmessagedetection and editortext == templatetext:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"commit message unchanged"))
FUJIWARA Katsunori
cmdutil: separate building commit text from 'commitforceeditor'...
r21869
return text
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
commit: select template by spec.ref name...
r32878 def buildcommittemplate(repo, ctx, subs, extramsg, ref):
FUJIWARA Katsunori
cmdutil: make commit message shown in text editor customizable by template...
r21924 ui = repo.ui
Yuya Nishihara
commit: select template by spec.ref name...
r32878 spec = formatter.templatespec(ref, None, None)
Yuya Nishihara
logcmdutil: drop default arguments from changesetdisplayer/templater() calls
r35972 t = logcmdutil.changesettemplater(ui, repo, spec)
Augie Fackler
formatting: blacken the codebase...
r43346 t.t.cache.update(
(k, templater.unquotestring(v))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for k, v in repo.ui.configitems(b'committemplate')
Augie Fackler
formatting: blacken the codebase...
r43346 )
FUJIWARA Katsunori
cmdutil: use '[committemplate]' section like as map file for style definition...
r22013
FUJIWARA Katsunori
cmdutil: make commit message shown in text editor customizable by template...
r21924 if not extramsg:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extramsg = b'' # ensure that extramsg is string
FUJIWARA Katsunori
cmdutil: make commit message shown in text editor customizable by template...
r21924
ui.pushbuffer()
t.show(ctx, extramsg=extramsg)
return ui.popbuffer()
Augie Fackler
formatting: blacken the codebase...
r43346
timeless@mozdev.org
cmdutil: handle multiline translations of HG: messages safely...
r26426 def hgprefix(msg):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b"\n".join([b"HG: %s" % a for a in msg.split(b"\n") if a])
timeless@mozdev.org
cmdutil: handle multiline translations of HG: messages safely...
r26426
Augie Fackler
formatting: blacken the codebase...
r43346
FUJIWARA Katsunori
cmdutil: separate building commit text from 'commitforceeditor'...
r21869 def buildcommittext(repo, ctx, subs, extramsg):
Matt Mackall
commit: move commit editor to cmdutil, pass as function
r8407 edittext = []
Matt Mackall
commit: editor reads file lists from provided context
r8707 modified, added, removed = ctx.modified(), ctx.added(), ctx.removed()
Matt Mackall
commit: move commit editor to cmdutil, pass as function
r8407 if ctx.description():
edittext.append(ctx.description())
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 edittext.append(b"")
edittext.append(b"") # Empty line between message and comments.
Augie Fackler
formatting: blacken the codebase...
r43346 edittext.append(
hgprefix(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"Enter commit message."
b" Lines beginning with 'HG:' are removed."
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
)
timeless@mozdev.org
cmdutil: handle multiline translations of HG: messages safely...
r26426 edittext.append(hgprefix(extramsg))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 edittext.append(b"HG: --")
edittext.append(hgprefix(_(b"user: %s") % ctx.user()))
Matt Mackall
commit: move commit editor to cmdutil, pass as function
r8407 if ctx.p2():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 edittext.append(hgprefix(_(b"branch merge")))
Matt Mackall
commit: move commit editor to cmdutil, pass as function
r8407 if ctx.branch():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 edittext.append(hgprefix(_(b"branch '%s'") % ctx.branch()))
Ryan McElroy
bookmarks: simplify iscurrent to isactivewdirparent (API)...
r24986 if bookmarks.isactivewdirparent(repo):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 edittext.append(hgprefix(_(b"bookmark '%s'") % repo._activebookmark))
edittext.extend([hgprefix(_(b"subrepo %s") % s) for s in subs])
edittext.extend([hgprefix(_(b"added %s") % f) for f in added])
edittext.extend([hgprefix(_(b"changed %s") % f) for f in modified])
edittext.extend([hgprefix(_(b"removed %s") % f) for f in removed])
Matt Mackall
commit: editor reads file lists from provided context
r8707 if not added and not modified and not removed:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 edittext.append(hgprefix(_(b"no files changed")))
edittext.append(b"")
return b"\n".join(edittext)
Adrian Buehlmann
commands: use a decorator to build table incrementally...
r14297
Augie Fackler
formatting: blacken the codebase...
r43346
Pierre-Yves David
addremove: remove a mutable default argument...
r26324 def commitstatus(repo, node, branch, bheads=None, opts=None):
if opts is None:
opts = {}
Kevin Bullock
commit: factor out status printing into a helper function...
r18688 ctx = repo[node]
parents = ctx.parents()
Augie Fackler
formatting: blacken the codebase...
r43346 if (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 not opts.get(b'amend')
Augie Fackler
formatting: blacken the codebase...
r43346 and bheads
and node not in bheads
and not [
x for x in parents if x.node() in bheads and x.branch() == branch
]
):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.status(_(b'created new head\n'))
Kevin Bullock
commit: factor out status printing into a helper function...
r18688 # The message is not printed for initial roots. For the other
# changesets, it is printed in the following situations:
#
# Par column: for the 2 parents with ...
# N: null or no parent
# B: parent is on another named branch
# C: parent is a regular non head changeset
# H: parent was a branch head of the current branch
# Msg column: whether we print "created new head" message
# In the following, it is assumed that there already exists some
# initial branch heads of the current branch, otherwise nothing is
# printed anyway.
#
# Par Msg Comment
# N N y additional topo root
#
# B N y additional branch root
# C N y additional topo head
# H N n usual case
#
# B B y weird additional branch root
# C B y branch merge
# H B n merge with named branch
#
# C C y additional head from merge
# C H n merge with a head
#
# H H n head merge: head count decreases
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not opts.get(b'close_branch'):
Kevin Bullock
commit: factor out status printing into a helper function...
r18688 for r in parents:
if r.closesbranch() and r.branch() == branch:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.status(
_(b'reopening closed branch head %d\n') % r.rev()
)
Kevin Bullock
commit: factor out status printing into a helper function...
r18688
if repo.ui.debugflag:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.write(
_(b'committed changeset %d:%s\n') % (ctx.rev(), ctx.hex())
)
Kevin Bullock
commit: factor out status printing into a helper function...
r18688 elif repo.ui.verbose:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.write(_(b'committed changeset %d:%s\n') % (ctx.rev(), ctx))
Kevin Bullock
commit: factor out status printing into a helper function...
r18688
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
commit: factor the post commit status check into a cmdutil method...
r27943 def postcommitstatus(repo, pats, opts):
return repo.status(match=scmutil.match(repo[None], pats, opts))
Augie Fackler
formatting: blacken the codebase...
r43346
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304 def revert(ui, repo, ctx, parents, *pats, **opts):
Pulkit Goyal
py3: fix handling of keyword arguments in revert...
r35148 opts = pycompat.byteskwargs(opts)
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304 parent, p2 = parents
node = ctx.node()
mf = ctx.manifest()
Pierre-Yves David
revert: use p2 as parent when reverting against it...
r21579 if node == p2:
parent = p2
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304
# need all matching names in dirstate and manifest of target rev,
# so have to walk both. do not print errors if files exist in one
Yuya Nishihara
revert: comment that filesets are always evaluated against workingctx
r24451 # but not other. in both cases, filesets should be evaluated against
# workingctx to get consistent result (issue4497). this means 'set:**'
# cannot be used to select missing files from target rev.
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304
Pierre-Yves David
revert: add some inline comments...
r21575 # `names` is a mapping for all elements in working copy and target revision
# The mapping is in the form:
Sushil khanchi
cmdutil: fix typo in revert()...
r39323 # <abs path in repo> -> (<path from CWD>, <exactly specified by matcher?>)
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304 names = {}
Martin von Zweigbergk
revert: respect ui.relative-paths...
r41754 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304
Bryan O'Sullivan
with: use context manager for wlock in revert
r27803 with repo.wlock():
Pierre-Yves David
revert: add some inline comments...
r21575 ## filling of the `names` mapping
# walk dirstate to fill `names`
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 interactive = opts.get(b'interactive', False)
Martin von Zweigbergk
revert: define 'wctx' a little earlier and use it more
r24449 wctx = repo[None]
m = scmutil.match(wctx, pats, opts)
Matt Mackall
revert: move calculation of targetsubs earlier
r24479
# we'll need this later
targetsubs = sorted(s for s in wctx.substate if m(s))
Martin von Zweigbergk
revert: take fast path also when not reverting to '.'...
r24450 if not m.always():
Augie Fackler
cmdutil: use repo[None].walk instead of repo.walk
r32362 matcher = matchmod.badmatch(m, lambda x, y: False)
Martin von Zweigbergk
cleanup: reuse existing wctx variables instead of calling repo[None]...
r32382 for abs in wctx.walk(matcher):
Martin von Zweigbergk
revert: respect ui.relative-paths...
r41754 names[abs] = m.exact(abs)
Durham Goode
revert: special case 'hg revert --all'...
r22573
# walk target manifest to fill `names`
def badfn(path, msg):
if path in names:
return
if path in ctx.substate:
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304 return
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 path_ = path + b'/'
Durham Goode
revert: special case 'hg revert --all'...
r22573 for f in names:
if f.startswith(path_):
return
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.warn(b"%s: %s\n" % (uipathfn(path), msg))
Durham Goode
revert: special case 'hg revert --all'...
r22573
Matt Harbison
revert: replace match.bad() monkey patching with match.badmatch()...
r25439 for abs in ctx.walk(matchmod.badmatch(m, badfn)):
Durham Goode
revert: special case 'hg revert --all'...
r22573 if abs not in names:
Martin von Zweigbergk
revert: respect ui.relative-paths...
r41754 names[abs] = m.exact(abs)
Durham Goode
revert: special case 'hg revert --all'...
r22573
# Find status of all file in `names`.
m = scmutil.matchfiles(repo, names)
Augie Fackler
formatting: blacken the codebase...
r43346 changes = repo.status(
node1=node, match=m, unknown=True, ignored=True, clean=True
)
Durham Goode
revert: special case 'hg revert --all'...
r22573 else:
Martin von Zweigbergk
revert: take fast path also when not reverting to '.'...
r24450 changes = repo.status(node1=node, match=m)
Durham Goode
revert: special case 'hg revert --all'...
r22573 for kind in changes:
for abs in kind:
Martin von Zweigbergk
revert: respect ui.relative-paths...
r41754 names[abs] = m.exact(abs)
Durham Goode
revert: special case 'hg revert --all'...
r22573
m = scmutil.matchfiles(repo, names)
Martin von Zweigbergk
revert: access status fields by name rather than index...
r23374 modified = set(changes.modified)
Augie Fackler
formatting: blacken the codebase...
r43346 added = set(changes.added)
removed = set(changes.removed)
Martin von Zweigbergk
revert: access status fields by name rather than index...
r23374 _deleted = set(changes.deleted)
Augie Fackler
formatting: blacken the codebase...
r43346 unknown = set(changes.unknown)
Martin von Zweigbergk
revert: access status fields by name rather than index...
r23374 unknown.update(changes.ignored)
Augie Fackler
formatting: blacken the codebase...
r43346 clean = set(changes.clean)
Pierre-Yves David
revert: track added files with local modifications...
r22610 modadded = set()
Pierre-Yves David
revert: triage "deleted" files into more appropriate categories...
r22185
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r24180 # We need to account for the state of the file in the dirstate,
# even when we revert against something else than parent. This will
Pierre-Yves David
revert: call status against revert target too...
r22155 # slightly alter the behavior of revert (doing back up or not, delete
Mads Kiilerich
spelling: fixes from proofreading of spell checker issues
r23139 # or just forget etc).
Pierre-Yves David
revert: call status against revert target too...
r22155 if parent == node:
dsmodified = modified
dsadded = added
dsremoved = removed
Pierre-Yves David
revert: look for copy information for all local modifications...
r23403 # store all local modifications, useful later for rename detection
localchanges = dsmodified | dsadded
Pierre-Yves David
revert: call status against revert target too...
r22155 modified, added, removed = set(), set(), set()
else:
changes = repo.status(node1=parent, match=m)
Martin von Zweigbergk
revert: access status fields by name rather than index...
r23374 dsmodified = set(changes.modified)
Augie Fackler
formatting: blacken the codebase...
r43346 dsadded = set(changes.added)
dsremoved = set(changes.removed)
Pierre-Yves David
revert: look for copy information for all local modifications...
r23403 # store all local modifications, useful later for rename detection
localchanges = dsmodified | dsadded
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304
Pierre-Yves David
revert: use "remove" information from both statuses...
r22188 # only take into account for removes between wc and target
clean |= dsremoved - removed
dsremoved &= removed
# distinct between dirstate remove and other
removed -= dsremoved
Pierre-Yves David
revert: track added files with local modifications...
r22610 modadded = added & dsmodified
added -= modadded
Pierre-Yves David
revert: use modified information from both statuses...
r22190 # tell newly modified apart.
dsmodified &= modified
Augie Fackler
formatting: blacken the codebase...
r43346 dsmodified |= modified & dsadded # dirstate added may need backup
Pierre-Yves David
revert: use modified information from both statuses...
r22190 modified -= dsmodified
Pierre-Yves David
revert: split between newly added file and file added in other changeset...
r22488 # We need to wait for some post-processing to update this set
# before making the distinction. The dirstate will be used for
# that purpose.
Pierre-Yves David
revert: simplify handling of `added` files...
r22208 dsadded = added
Pierre-Yves David
revert: detect files added during a merge...
r22209 # in case of merge, files that are actually added can be reported as
# modified, we need to post process the result
if p2 != nullid:
Durham Goode
revert: remove set(mf) because it's O(manifest)...
r31134 mergeadd = set(dsmodified)
for path in dsmodified:
if path in mf:
mergeadd.remove(path)
Pierre-Yves David
revert: detect files added during a merge...
r22209 dsadded |= mergeadd
dsmodified -= mergeadd
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304
Pierre-Yves David
revert: add some inline comments...
r21575 # if f is a rename, update `names` to also revert the source
Pierre-Yves David
revert: look for copy information for all local modifications...
r23403 for f in localchanges:
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304 src = repo.dirstate.copied(f)
Pierre-Yves David
revert: add an XXX about rename tracking...
r22213 # XXX should we check for rename down to target node?
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if src and src not in names and repo.dirstate[src] == b'r':
Pierre-Yves David
revert: prefix variable names for dirstate status with "ds"...
r22154 dsremoved.add(src)
Martin von Zweigbergk
revert: respect ui.relative-paths...
r41754 names[src] = True
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304
Martin von Zweigbergk
revert: move code dealing with deletions closer together
r31157 # determine the exact nature of the deleted changesets
deladded = set(_deleted)
for path in _deleted:
if path in mf:
deladded.remove(path)
deleted = _deleted - deladded
Pierre-Yves David
revert: split between newly added file and file added in other changeset...
r22488 # distinguish between file to forget and the other
added = set()
for abs in dsadded:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if repo.dirstate[abs] != b'a':
Pierre-Yves David
revert: split between newly added file and file added in other changeset...
r22488 added.add(abs)
dsadded -= added
Pierre-Yves David
revert: explicitly track added but deleted file...
r22490 for abs in deladded:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if repo.dirstate[abs] == b'a':
Pierre-Yves David
revert: explicitly track added but deleted file...
r22490 dsadded.add(abs)
deladded -= dsadded
Pierre-Yves David
revert: detect unknown files in the same path as files marked as removed...
r22396 # For files marked as removed, we check if an unknown file is present at
# the same path. If a such file exists it may need to be backed up.
# Making the distinction at this stage helps have simpler backup
# logic.
removunk = set()
for abs in removed:
target = repo.wjoin(abs)
if os.path.lexists(target):
removunk.add(abs)
removed -= removunk
dsremovunk = set()
for abs in dsremoved:
target = repo.wjoin(abs)
if os.path.lexists(target):
dsremovunk.add(abs)
dsremoved -= dsremovunk
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304
Pierre-Yves David
revert: add some inline comments...
r21575 # action to be actually performed by revert
# (<list of file>, message>) tuple
Augie Fackler
formatting: blacken the codebase...
r43346 actions = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'revert': ([], _(b'reverting %s\n')),
b'add': ([], _(b'adding %s\n')),
b'remove': ([], _(b'removing %s\n')),
b'drop': ([], _(b'removing %s\n')),
b'forget': ([], _(b'forgetting %s\n')),
b'undelete': ([], _(b'undeleting %s\n')),
b'noop': (None, _(b'no changes needed to %s\n')),
b'unknown': (None, _(b'file not managed: %s\n')),
Augie Fackler
formatting: blacken the codebase...
r43346 }
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304
Pierre-Yves David
revert: small refactoring in the way backup value are handled...
r22608 # "constant" that convey the backup strategy.
# All set to `discard` if `no-backup` is set do avoid checking
# no_backup lower in the code.
Pierre-Yves David
revert: distinguish between "check" and "backup" strategy...
r22609 # These values are ordered for comparison purposes
Augie Fackler
formatting: blacken the codebase...
r43346 backupinteractive = 3 # do backup if interactively modified
Pierre-Yves David
revert: small refactoring in the way backup value are handled...
r22608 backup = 2 # unconditionally do backup
Augie Fackler
formatting: blacken the codebase...
r43346 check = 1 # check if the existing file differs from target
discard = 0 # never do backup
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'no_backup'):
skarlage
revert: don't backup if no files reverted in interactive mode (issue4793)...
r29498 backupinteractive = backup = check = discard
if interactive:
dsmodifiedbackup = backupinteractive
else:
dsmodifiedbackup = backup
tobackup = set()
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 backupanddel = actions[b'remove']
if not opts.get(b'no_backup'):
backupanddel = actions[b'drop']
Pierre-Yves David
revert: properly back up added files with local modification...
r22611
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304 disptable = (
# dispatch table:
# file state
Pierre-Yves David
revert: move manifest membership condition outside of the loop...
r22153 # action
# make backup
Pierre-Yves David
revert: add documentation in the dispatch table...
r22371 ## Sets that results that will change file on disk
# Modified compared to target, no local change
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (modified, actions[b'revert'], discard),
Pierre-Yves David
revert: distinguish between deleted file and locally modified...
r22397 # Modified compared to target, but local file is deleted
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (deleted, actions[b'revert'], discard),
Pierre-Yves David
revert: add documentation in the dispatch table...
r22371 # Modified compared to target, local change
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (dsmodified, actions[b'revert'], dsmodifiedbackup),
Pierre-Yves David
revert: add documentation in the dispatch table...
r22371 # Added since target
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (added, actions[b'remove'], discard),
Pierre-Yves David
revert: split between newly added file and file added in other changeset...
r22488 # Added in working directory
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (dsadded, actions[b'forget'], discard),
Pierre-Yves David
revert: track added files with local modifications...
r22610 # Added since target, have local modification
Augie Fackler
formatting: blacken the codebase...
r43346 (modadded, backupanddel, backup),
Pierre-Yves David
revert: explicitly track added but deleted file...
r22490 # Added since target but file is missing in working directory
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (deladded, actions[b'drop'], discard),
Pierre-Yves David
revert: add documentation in the dispatch table...
r22371 # Removed since target, before working copy parent
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (removed, actions[b'add'], discard),
Pierre-Yves David
revert: detect unknown files in the same path as files marked as removed...
r22396 # Same as `removed` but an unknown file exists at the same path
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (removunk, actions[b'add'], check),
Pierre-Yves David
revert: add documentation in the dispatch table...
r22371 # Removed since targe, marked as such in working copy parent
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (dsremoved, actions[b'undelete'], discard),
Pierre-Yves David
revert: detect unknown files in the same path as files marked as removed...
r22396 # Same as `dsremoved` but an unknown file exists at the same path
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (dsremovunk, actions[b'undelete'], check),
Pierre-Yves David
revert: add documentation in the dispatch table...
r22371 ## the following sets does not result in any file changes
# File with no modification
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (clean, actions[b'noop'], discard),
Pierre-Yves David
revert: add documentation in the dispatch table...
r22371 # Existing file, not tracked anywhere
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (unknown, actions[b'unknown'], discard),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304
Martin von Zweigbergk
revert: respect ui.relative-paths...
r41754 for abs, exact in sorted(names.items()):
Pierre-Yves David
revert: add some inline comments...
r21575 # target file to be touch on disk (relative to cwd)
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304 target = repo.wjoin(abs)
Pierre-Yves David
revert: add some inline comments...
r21575 # search the entry in the dispatch table.
Pierre-Yves David
revert: inline a now useless closure...
r22212 # if the file is in any of these sets, it was touched in the working
Pierre-Yves David
revert: add some inline comments...
r21575 # directory parent and we are sure it needs to be reverted.
Pierre-Yves David
revert: explode the action tuple in the for loop...
r22232 for table, (xlist, msg), dobackup in disptable:
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304 if abs not in table:
continue
Pierre-Yves David
revert: simplify loop conditional...
r22233 if xlist is not None:
xlist.append(abs)
skarlage
revert: don't backup if no files reverted in interactive mode (issue4793)...
r29498 if dobackup:
# If in interactive mode, don't automatically create
# .orig files (issue4793)
if dobackup == backupinteractive:
tobackup.add(abs)
Augie Fackler
formatting: blacken the codebase...
r43346 elif backup <= dobackup or wctx[abs].cmp(ctx[abs]):
Martin von Zweigbergk
revert: respect ui.relative-paths...
r41754 absbakname = scmutil.backuppath(ui, repo, abs)
Augie Fackler
formatting: blacken the codebase...
r43346 bakname = os.path.relpath(
absbakname, start=repo.root
)
ui.note(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'saving current version of %s as %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (uipathfn(abs), uipathfn(bakname))
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not opts.get(b'dry_run'):
Laurent Charignon
revert: fix --interactive on local modification (issue4576)...
r24475 if interactive:
Martin von Zweigbergk
revert: respect ui.relative-paths...
r41754 util.copyfile(target, absbakname)
Laurent Charignon
revert: fix --interactive on local modification (issue4576)...
r24475 else:
Martin von Zweigbergk
revert: respect ui.relative-paths...
r41754 util.rename(target, absbakname)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'dry_run'):
Sushil khanchi
revert: fix the inconsistency of status msgs in --interactive mode...
r39442 if ui.verbose or not exact:
Martin von Zweigbergk
revert: respect ui.relative-paths...
r41754 ui.status(msg % uipathfn(abs))
Pierre-Yves David
revert: simplify loop conditional...
r22233 elif exact:
Martin von Zweigbergk
revert: respect ui.relative-paths...
r41754 ui.warn(msg % uipathfn(abs))
Angel Ezquerra
revert: move bulk of revert command from commands to cmdutil...
r16304 break
Pierre-Yves David
revert: add some inline comments...
r21575
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not opts.get(b'dry_run'):
needdata = (b'revert', b'add', b'undelete')
Matt Harbison
cmdutil: convert _revertprefetch() to a generic stored file hook (API)...
r35941 oplist = [actions[name][0] for name in needdata]
Matt Harbison
scmutil: teach the file prefetch hook to handle multiple commits...
r37780 prefetch = scmutil.prefetchfiles
matchfiles = scmutil.matchfiles
Augie Fackler
formatting: blacken the codebase...
r43346 prefetch(
repo,
[ctx.rev()],
matchfiles(repo, [f for sublist in oplist for f in sublist]),
)
Denis Laxalde
interactive: do not prompt about files given in command line...
r42238 match = scmutil.match(repo[None], pats)
Augie Fackler
formatting: blacken the codebase...
r43346 _performrevert(
repo,
parents,
ctx,
names,
uipathfn,
actions,
match,
interactive,
tobackup,
)
Bryan O'Sullivan
revert: ensure that copies and renames are honored (issue3920)...
r19129
Matt Harbison
revert: display full subrepo output with --dry-run...
r24134 if targetsubs:
# Revert the subrepos on the revert list
for sub in targetsubs:
Matt Harbison
revert: handle subrepos missing in the given --rev...
r24463 try:
Augie Fackler
formatting: blacken the codebase...
r43346 wctx.sub(sub).revert(
ctx.substate[sub], *pats, **pycompat.strkwargs(opts)
)
Matt Harbison
revert: handle subrepos missing in the given --rev...
r24463 except KeyError:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"subrepository '%s' does not exist in %s!"
Augie Fackler
formatting: blacken the codebase...
r43346 % (sub, short(ctx.node()))
)
def _performrevert(
repo,
parents,
ctx,
names,
uipathfn,
actions,
match,
interactive=False,
tobackup=None,
):
Pierre-Yves David
revert: group action into a single dictionary...
r21576 """function that actually perform all the actions computed for revert
Pierre-Yves David
revert: extract actual revert in its own function...
r20571
This is an independent function to let extension to plug in and react to
the imminent revert.
Mads Kiilerich
spelling: fixes from spell checker
r21024 Make sure you have the working directory locked when calling this function.
Pierre-Yves David
revert: extract actual revert in its own function...
r20571 """
parent, p2 = parents
node = ctx.node()
liscju
revert: makes interactive mode ask to forget added files (issue4936)...
r27985 excluded_files = []
Pierre-Yves David
revert: extract actual revert in its own function...
r20571 def checkout(f):
fc = ctx[f]
FUJIWARA Katsunori
cmdutil: remove useless dirstate.normallookup() invocation in revert()...
r25755 repo.wwrite(f, fc.data(), fc.flags())
Pierre-Yves David
revert: extract actual revert in its own function...
r20571
Denis Laxalde
revert: prompt before removing files in interactive mode...
r30532 def doremove(f):
try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 rmdir = repo.ui.configbool(b'experimental', b'removeemptydirs')
Kyle Lippincott
unlinkpath: make empty directory removal optional (issue5901) (issue5826)...
r38512 repo.wvfs.unlinkpath(f, rmdir=rmdir)
Denis Laxalde
revert: prompt before removing files in interactive mode...
r30532 except OSError:
pass
repo.dirstate.remove(f)
Sushil khanchi
revert: fix the inconsistency of status msgs in --interactive mode...
r39442 def prntstatusmsg(action, f):
Martin von Zweigbergk
revert: respect ui.relative-paths...
r41754 exact = names[f]
Sushil khanchi
revert: fix the inconsistency of status msgs in --interactive mode...
r39442 if repo.ui.verbose or not exact:
Martin von Zweigbergk
revert: respect ui.relative-paths...
r41754 repo.ui.status(actions[action][1] % uipathfn(f))
Sushil khanchi
revert: fix the inconsistency of status msgs in --interactive mode...
r39442
Yuya Nishihara
pathauditor: disable cache of audited paths by default (issue5628)...
r33722 audit_path = pathutil.pathauditor(repo.root, cached=True)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for f in actions[b'forget'][0]:
liscju
revert: makes interactive mode ask to forget added files (issue4936)...
r27985 if interactive:
Denis Laxalde
style: avoid an unnecessary line split
r30530 choice = repo.ui.promptchoice(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"forget added file %s (Yn)?$$ &Yes $$ &No") % uipathfn(f)
Augie Fackler
formatting: blacken the codebase...
r43346 )
liscju
revert: makes interactive mode ask to forget added files (issue4936)...
r27985 if choice == 0:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prntstatusmsg(b'forget', f)
liscju
revert: makes interactive mode ask to forget added files (issue4936)...
r27985 repo.dirstate.drop(f)
else:
Denis Laxalde
revert: use an exact matcher in interactive diff selection (issue5789)...
r36212 excluded_files.append(f)
liscju
revert: makes interactive mode ask to forget added files (issue4936)...
r27985 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prntstatusmsg(b'forget', f)
liscju
revert: makes interactive mode ask to forget added files (issue4936)...
r27985 repo.dirstate.drop(f)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for f in actions[b'remove'][0]:
Pierre-Yves David
revert: extract actual revert in its own function...
r20571 audit_path(f)
Denis Laxalde
revert: prompt before removing files in interactive mode...
r30532 if interactive:
choice = repo.ui.promptchoice(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"remove added file %s (Yn)?$$ &Yes $$ &No") % uipathfn(f)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Denis Laxalde
revert: prompt before removing files in interactive mode...
r30532 if choice == 0:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prntstatusmsg(b'remove', f)
Denis Laxalde
revert: prompt before removing files in interactive mode...
r30532 doremove(f)
else:
Denis Laxalde
revert: use an exact matcher in interactive diff selection (issue5789)...
r36212 excluded_files.append(f)
Denis Laxalde
revert: prompt before removing files in interactive mode...
r30532 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prntstatusmsg(b'remove', f)
Denis Laxalde
revert: prompt before removing files in interactive mode...
r30532 doremove(f)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for f in actions[b'drop'][0]:
Pierre-Yves David
revert: add a `drop` action...
r22491 audit_path(f)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prntstatusmsg(b'drop', f)
Pierre-Yves David
revert: extract actual revert in its own function...
r20571 repo.dirstate.remove(f)
normal = None
if node == parent:
# We're reverting to our parent. If possible, we'd like status
# to report the file as clean. We have to use normallookup for
# merges to avoid losing information about merged/dirty files.
if p2 != nullid:
normal = repo.dirstate.normallookup
else:
normal = repo.dirstate.normal
Laurent Charignon
revert: add flag to make revert interactive
r24359
Laurent Charignon
revert: fix edition of newly added file during --interactive...
r25259 newlyaddedandmodifiedfiles = set()
Laurent Charignon
revert: add flag to make revert interactive
r24359 if interactive:
# Prompt the user for changes to revert
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 torevert = [f for f in actions[b'revert'][0] if f not in excluded_files]
Denis Laxalde
revert: use an exact matcher in interactive diff selection (issue5789)...
r36212 m = scmutil.matchfiles(repo, torevert)
Augie Fackler
formatting: blacken the codebase...
r43346 diffopts = patch.difffeatureopts(
repo.ui,
whitespace=True,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 section=b'commands',
configprefix=b'revert.interactive.',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Laurent Charignon
revert: make revert --interactive use git style diff...
r25258 diffopts.nodates = True
diffopts.git = True
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 operation = b'apply'
Martin von Zweigbergk
revert: option to choose what to keep, not what to discard...
r42154 if node == parent:
Augie Fackler
formatting: blacken the codebase...
r43346 if repo.ui.configbool(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'experimental', b'revert.interactive.select-to-keep'
Augie Fackler
formatting: blacken the codebase...
r43346 ):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 operation = b'keep'
Martin von Zweigbergk
revert: option to choose what to keep, not what to discard...
r42154 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 operation = b'discard'
if operation == b'apply':
Martin von Zweigbergk
revert: option to choose what to keep, not what to discard...
r42154 diff = patch.diff(repo, None, ctx.node(), m, opts=diffopts)
else:
Laurent Charignon
revert: add an experimental config to use inverted selection...
r25424 diff = patch.diff(repo, ctx.node(), None, m, opts=diffopts)
Laurent Charignon
revert: add flag to make revert interactive
r24359 originalchunks = patch.parsepatch(diff)
Laurent Charignon
revert: add an experimental config to use inverted selection...
r25424
Laurent Charignon
revert: add flag to make revert interactive
r24359 try:
Laurent Charignon
revert: add an experimental config to use inverted selection...
r25424
Augie Fackler
formatting: blacken the codebase...
r43346 chunks, opts = recordfilter(
repo.ui, originalchunks, match, operation=operation
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if operation == b'discard':
Laurent Charignon
revert: add an experimental config to use inverted selection...
r25424 chunks = patch.reversehunks(chunks)
Yuya Nishihara
error: move patch.PatchError so it can easily implement __bytes__ (API)
r34252 except error.PatchError as err:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'error parsing patch: %s') % err)
Laurent Charignon
revert: add flag to make revert interactive
r24359
Kyle Lippincott
split: handle partial commit of renames when doing split or record (issue5723)...
r43122 # FIXME: when doing an interactive revert of a copy, there's no way of
# performing a partial revert of the added file, the only option is
# "remove added file <name> (Yn)?", so we don't need to worry about the
# alsorestore value. Ideally we'd be able to partially revert
# copied/renamed files.
newlyaddedandmodifiedfiles, unusedalsorestore = newandmodified(
Augie Fackler
formatting: blacken the codebase...
r43346 chunks, originalchunks
)
skarlage
revert: don't backup if no files reverted in interactive mode (issue4793)...
r29498 if tobackup is None:
tobackup = set()
Laurent Charignon
revert: add flag to make revert interactive
r24359 # Apply changes
timeless
pycompat: switch to util.stringio for py3 compat
r28861 fp = stringio()
Yuya Nishihara
revert: stabilize status message of chunks selected interactively...
r39451 # chunks are serialized per file, but files aren't sorted
for f in sorted(set(c.header.filename() for c in chunks if ishunk(c))):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prntstatusmsg(b'revert', f)
Martin von Zweigbergk
revert: option to choose what to keep, not what to discard...
r42154 files = set()
Laurent Charignon
revert: add flag to make revert interactive
r24359 for c in chunks:
Sushil khanchi
revert: fix the inconsistency of status msgs in --interactive mode...
r39442 if ishunk(c):
skarlage
revert: don't backup if no files reverted in interactive mode (issue4793)...
r29498 abs = c.header.filename()
Sushil khanchi
revert: fix the inconsistency of status msgs in --interactive mode...
r39442 # Create a backup file only if this hunk should be backed up
if c.header.filename() in tobackup:
target = repo.wjoin(abs)
Martin von Zweigbergk
revert: migrate to scmutil.backuppath()...
r41737 bakname = scmutil.backuppath(repo.ui, repo, abs)
Sushil khanchi
revert: fix the inconsistency of status msgs in --interactive mode...
r39442 util.copyfile(target, bakname)
tobackup.remove(abs)
Martin von Zweigbergk
revert: option to choose what to keep, not what to discard...
r42154 if abs not in files:
files.add(abs)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if operation == b'keep':
Martin von Zweigbergk
revert: option to choose what to keep, not what to discard...
r42154 checkout(abs)
Laurent Charignon
revert: add flag to make revert interactive
r24359 c.write(fp)
dopatch = fp.tell()
fp.seek(0)
if dopatch:
try:
patch.internalpatch(repo.ui, repo, fp, 1, eolmode=None)
Yuya Nishihara
error: move patch.PatchError so it can easily implement __bytes__ (API)
r34252 except error.PatchError as err:
Pulkit Goyal
py3: use pycompat.bytestr instead of str...
r36736 raise error.Abort(pycompat.bytestr(err))
Laurent Charignon
revert: add flag to make revert interactive
r24359 del fp
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for f in actions[b'revert'][0]:
prntstatusmsg(b'revert', f)
FUJIWARA Katsunori
cmdutil: remove useless dirstate.normallookup() invocation in revert()...
r25755 checkout(f)
Laurent Charignon
revert: add flag to make revert interactive
r24359 if normal:
normal(f)
Pierre-Yves David
revert: extract actual revert in its own function...
r20571
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for f in actions[b'add'][0]:
Laurent Charignon
revert: fix edition of newly added file during --interactive...
r25259 # Don't checkout modified files, they are already created by the diff
if f not in newlyaddedandmodifiedfiles:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prntstatusmsg(b'add', f)
Laurent Charignon
revert: fix edition of newly added file during --interactive...
r25259 checkout(f)
repo.dirstate.add(f)
Pierre-Yves David
revert: extract actual revert in its own function...
r20571
normal = repo.dirstate.normallookup
if node == parent and p2 == nullid:
normal = repo.dirstate.normal
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for f in actions[b'undelete'][0]:
Taapas Agrawal
revert: add prompt before undeleting a file in -i (issue6008)...
r41663 if interactive:
choice = repo.ui.promptchoice(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"add back removed file %s (Yn)?$$ &Yes $$ &No") % f
Augie Fackler
formatting: blacken the codebase...
r43346 )
Taapas Agrawal
revert: add prompt before undeleting a file in -i (issue6008)...
r41663 if choice == 0:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prntstatusmsg(b'undelete', f)
Taapas Agrawal
revert: add prompt before undeleting a file in -i (issue6008)...
r41663 checkout(f)
normal(f)
else:
excluded_files.append(f)
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prntstatusmsg(b'undelete', f)
Taapas Agrawal
revert: add prompt before undeleting a file in -i (issue6008)...
r41663 checkout(f)
normal(f)
Pierre-Yves David
revert: extract actual revert in its own function...
r20571
copied = copies.pathcopies(repo[parent], ctx)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for f in (
actions[b'add'][0] + actions[b'undelete'][0] + actions[b'revert'][0]
):
Pierre-Yves David
revert: extract actual revert in its own function...
r20571 if f in copied:
repo.dirstate.copy(copied[f], f)
Augie Fackler
formatting: blacken the codebase...
r43346
FUJIWARA Katsunori
outgoing: introduce "outgoinghooks" to avoid redundant outgoing check...
r21051 # a list of (ui, repo, otherpeer, opts, missing) functions called by
# commands.outgoing. "missing" is "missing" of the result of
# "findcommonoutgoing()"
outgoinghooks = util.hooks()
Bryan O'Sullivan
summary: augment output with info from extensions
r19211 # a list of (ui, repo) functions called by commands.summary
summaryhooks = util.hooks()
Matt Mackall
cmdutil: core functionality to block during multistep commands (issue3955)...
r19474
FUJIWARA Katsunori
summary: introduce "summaryremotehooks" to avoid redundant incoming/outgoing check...
r21047 # a list of (ui, repo, opts, changes) functions called by commands.summary.
#
# functions should return tuple of booleans below, if 'changes' is None:
# (whether-incomings-are-needed, whether-outgoings-are-needed)
#
# otherwise, 'changes' is a tuple of tuples below:
# - (sourceurl, sourcebranch, sourcepeer, incoming)
# - (desturl, destbranch, destpeer, outgoing)
summaryremotehooks = util.hooks()
Taapas Agrawal
state: created new class statecheck to handle unfinishedstates...
r42730
Taapas Agrawal
statecheck: added support for STATES...
r42732 def checkunfinished(repo, commit=False, skipmerge=False):
Matt Mackall
cmdutil: core functionality to block during multistep commands (issue3955)...
r19474 '''Look for an unfinished multistep operation, like graft, and abort
if found. It's probably good to check this right before
bailifchanged().
'''
Matt Harbison
rebase: prioritize indicating an interrupted rebase over update (issue5838)...
r38220 # Check for non-clearable states first, so things like rebase will take
# precedence over update.
Taapas Agrawal
state: created new class statecheck to handle unfinishedstates...
r42730 for state in statemod._unfinishedstates:
Augie Fackler
formatting: blacken the codebase...
r43346 if (
state._clearable
or (commit and state._allowcommit)
or state._reportonly
):
Matt Harbison
rebase: prioritize indicating an interrupted rebase over update (issue5838)...
r38220 continue
Taapas Agrawal
state: created new class statecheck to handle unfinishedstates...
r42730 if state.isunfinished(repo):
raise error.Abort(state.msg(), hint=state.hint())
for s in statemod._unfinishedstates:
Augie Fackler
formatting: blacken the codebase...
r43346 if (
not s._clearable
or (commit and s._allowcommit)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 or (s._opname == b'merge' and skipmerge)
Augie Fackler
formatting: blacken the codebase...
r43346 or s._reportonly
):
Matt Mackall
checkunfinished: accommodate histedit quirk...
r19496 continue
Taapas Agrawal
state: created new class statecheck to handle unfinishedstates...
r42730 if s.isunfinished(repo):
raise error.Abort(s.msg(), hint=s.hint())
Matt Mackall
cmdutil: core functionality to block during multistep commands (issue3955)...
r19474
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
cmdutil: core functionality to block during multistep commands (issue3955)...
r19474 def clearunfinished(repo):
'''Check for unfinished operations (as above), and clear the ones
that are clearable.
'''
Taapas Agrawal
state: created new class statecheck to handle unfinishedstates...
r42730 for state in statemod._unfinishedstates:
Taapas Agrawal
statecheck: added support for STATES...
r42732 if state._reportonly:
continue
Taapas Agrawal
state: created new class statecheck to handle unfinishedstates...
r42730 if not state._clearable and state.isunfinished(repo):
raise error.Abort(state.msg(), hint=state.hint())
for s in statemod._unfinishedstates:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if s._opname == b'merge' or state._reportonly:
Taapas Agrawal
statecheck: added support for STATES...
r42732 continue
Taapas Agrawal
state: created new class statecheck to handle unfinishedstates...
r42730 if s._clearable and s.isunfinished(repo):
util.unlink(repo.vfs.join(s._fname))
FUJIWARA Katsunori
cmdutil: add class to restore dirstate during unexpected failure...
r24991
Augie Fackler
formatting: blacken the codebase...
r43346
Taapas Agrawal
merge: disallow merge abort in case of an unfinished operation (issue6160)...
r42780 def getunfinishedstate(repo):
''' Checks for unfinished operations and returns statecheck object
for it'''
for state in statemod._unfinishedstates:
if state.isunfinished(repo):
return state
return None
Augie Fackler
formatting: blacken the codebase...
r43346
timeless
cmdutil: provide a way to report how to continue...
r28120 def howtocontinue(repo):
'''Check for an unfinished operation and return the command to finish
it.
Taapas Agrawal
statecheck: updated docstrings related to afterresolvedstates...
r42777 statemod._unfinishedstates list is checked for an unfinished operation
and the corresponding message to finish it is generated if a method to
continue is supported by the operation.
timeless
cmdutil: provide a way to report how to continue...
r28120
Returns a (msg, warning) tuple. 'msg' is a string and 'warning' is
a boolean.
'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 contmsg = _(b"continue: %s")
Taapas Agrawal
statecheck: added support for cmdutil.afterresolvedstates...
r42733 for state in statemod._unfinishedstates:
if not state._continueflag:
continue
if state.isunfinished(repo):
return contmsg % state.continuemsg(), True
Matt Harbison
cmdutil: simplify the dirty check in howtocontinue()...
r33362 if repo[None].dirty(missing=True, merge=False, branch=False):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return contmsg % _(b"hg commit"), False
timeless
cmdutil: provide a way to report how to continue...
r28120 return None, None
Augie Fackler
formatting: blacken the codebase...
r43346
timeless
cmdutil: provide a way to report how to continue...
r28120 def checkafterresolved(repo):
'''Inform the user about the next action after completing hg resolve
Taapas Agrawal
statecheck: updated docstrings related to afterresolvedstates...
r42777 If there's a an unfinished operation that supports continue flag,
howtocontinue will yield repo.ui.warn as the reporter.
timeless
cmdutil: provide a way to report how to continue...
r28120
Otherwise, it will yield repo.ui.note.
'''
msg, warning = howtocontinue(repo)
if msg is not None:
if warning:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.warn(b"%s\n" % msg)
timeless
cmdutil: provide a way to report how to continue...
r28120 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.note(b"%s\n" % msg)
timeless
cmdutil: provide a way to report how to continue...
r28120
Augie Fackler
formatting: blacken the codebase...
r43346
timeless
cmdutil: provide a way to report how to continue...
r28120 def wrongtooltocontinue(repo, task):
'''Raise an abort suggesting how to properly continue if there is an
active task.
Uses howtocontinue() to find the active task.
If there's no task (repo.ui.note for 'hg commit'), it does not offer
a hint.
'''
after = howtocontinue(repo)
hint = None
if after[1]:
hint = after[0]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'no %s in progress') % task, hint=hint)
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768
Augie Fackler
formatting: blacken the codebase...
r43346
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768 def abortgraft(ui, repo, graftstate):
"""abort the interrupted graft and rollbacks to the state before interrupted
graft"""
if not graftstate.exists():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"no interrupted graft to abort"))
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768 statedata = readgraftstate(repo, graftstate)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 newnodes = statedata.get(b'newnodes')
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768 if newnodes is None:
# and old graft state which does not have all the data required to abort
# the graft
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"cannot abort using an old graftstate"))
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768
# changeset from which graft operation was started
if len(newnodes) > 0:
startctx = repo[newnodes[0]].p1()
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 startctx = repo[b'.']
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768 # whether to strip or not
cleanup = False
from . import hg
Augie Fackler
formatting: blacken the codebase...
r43346
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768 if newnodes:
newnodes = [repo[r].rev() for r in newnodes]
cleanup = True
# checking that none of the newnodes turned public or is public
immutable = [c for c in newnodes if not repo[c].mutable()]
if immutable:
Augie Fackler
formatting: blacken the codebase...
r43346 repo.ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"cannot clean up public changesets %s\n")
% b', '.join(bytes(repo[r]) for r in immutable),
hint=_(b"see 'hg help phases' for details"),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768 cleanup = False
# checking that no new nodes are created on top of grafted revs
desc = set(repo.changelog.descendants(newnodes))
if desc - set(newnodes):
Augie Fackler
formatting: blacken the codebase...
r43346 repo.ui.warn(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"new changesets detected on destination "
b"branch, can't strip\n"
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768 cleanup = False
if cleanup:
with repo.wlock(), repo.lock():
hg.updaterepo(repo, startctx.node(), overwrite=True)
# stripping the new nodes created
Augie Fackler
formatting: blacken the codebase...
r43346 strippoints = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 c.node() for c in repo.set(b"roots(%ld)", newnodes)
Augie Fackler
formatting: blacken the codebase...
r43346 ]
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768 repair.strip(repo.ui, repo, strippoints, backup=False)
if not cleanup:
# we don't update to the startnode if we can't strip
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 startctx = repo[b'.']
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768 hg.updaterepo(repo, startctx.node(), overwrite=True)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b"graft aborted\n"))
ui.status(_(b"working directory is now at %s\n") % startctx.hex()[:12])
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768 graftstate.delete()
return 0
Augie Fackler
formatting: blacken the codebase...
r43346
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768 def readgraftstate(repo, graftstate):
Augie Fackler
cmdutil: add a pytype annotation to help out some callsites...
r44099 # type: (Any, statemod.cmdstate) -> Dict[bytes, Any]
Taapas Agrawal
graft: moved abortgraft and readgraft to cmdutil...
r42768 """read the graft state file and return a dict of the data stored in it"""
try:
return graftstate.read()
except error.CorruptedState:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 nodes = repo.vfs.read(b'graftstate').splitlines()
return {b'nodes': nodes}
Taapas Agrawal
abort: added support for graft...
r42785
Augie Fackler
formatting: blacken the codebase...
r43346
Taapas Agrawal
abort: added support for graft...
r42785 def hgabortgraft(ui, repo):
""" abort logic for aborting graft using 'hg abort'"""
with repo.wlock():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 graftstate = statemod.cmdstate(repo, b'graftstate')
Taapas Agrawal
abort: added support for graft...
r42785 return abortgraft(ui, repo, graftstate)