##// END OF EJS Templates
interfaces: make the `peer` mixin not a Protocol to fix Python 3.10 failures...
interfaces: make the `peer` mixin not a Protocol to fix Python 3.10 failures I can't find any documentation on this, but it appears that Protocol class attributes don't get inherited in subclasses that explicitly subclass a Protocol until Python 3.11, which caused a ton of failures in CI on macOS and Windows (which both test using Python 3.9). The problem started with 1df97507c6b8, and typically manifested as most tests failing to access `ui` on various `peer` classes. Here's a short proof of concept: from __future__ import annotations from typing import ( Protocol, ) class peer(Protocol): limitedarguments: bool = False def __init__(self, arg1, arg2, remotehidden: bool = False) -> None: self.arg1 = arg1 self.arg2 = arg2 class subclass(peer): def __init__(self, arg1, arg2): super(subclass, self).__init__(arg1, arg2, False) sub = subclass(1, 2) print("sub.arg1 is %r" % sub.arg1) When run with Python 3.8.10, 3.9.13, and 3.10.11, the result is: $ py -3.8 prot-test.py Traceback (most recent call last): File "prot-test.py", line 20, in <module> print("sub.arg1 is %r" % sub.arg1) AttributeError: 'subclass' object has no attribute 'arg1' On Python 3.11.9, 3.12.7, and 3.13.0, the result is: $ py -3.11 ../prot-test.py sub.arg1 is 1 Explicitly adding annotations to `peer` like `limitedarguments` didn't help.

File last commit:

r52756:f4733654 default
r53403:199b0e62 default
Show More
shelve.py
1286 lines | 41.6 KiB | text/x-python | PythonLexer
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 # shelve.py - save/restore working directory state
#
# Copyright 2013 Facebook, Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
"""save and restore changes to the working directory
The "hg shelve" command saves changes made to the working directory
and reverts those changes, resetting the working directory to a clean
state.
Later on, the "hg unshelve" command restores the changes saved by "hg
shelve". Changes can be restored even after updating to a different
parent, in which case Mercurial's merge machinery will resolve any
conflicts if necessary.
You can have more than one shelved change outstanding at a time; each
shelved change has a distinct name. For details, see the help for "hg
shelve".
"""
Matt Harbison
typing: add `from __future__ import annotations` to most files...
r52756 from __future__ import annotations
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 import collections
Jason R. Coombs
phase-shelve: read patch details from a (possibly internal) node in the repo
r50321 import io
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 import itertools
import stat
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 from typing import (
Any,
Dict,
Iterable,
Iterator,
List,
Sequence,
Tuple,
)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 from .i18n import _
Joerg Sonnenberger
node: import symbols explicitly...
r46729 from .node import (
bin,
hex,
nullrev,
)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 from . import (
bookmarks,
bundle2,
changegroup,
cmdutil,
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 context as contextmod,
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 discovery,
error,
exchange,
hg,
lock as lockmod,
mdiff,
merge,
Augie Fackler
mergestate: split out merge state handling code from main merge module...
r45383 mergestate as mergestatemod,
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 patch,
phases,
pycompat,
repair,
scmutil,
templatefilters,
util,
vfs as vfsmod,
)
from .utils import (
dateutil,
stringutil,
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 backupdir = b'shelve-backup'
shelvedir = b'shelved'
shelvefileextensions = [b'hg', b'patch', b'shelve']
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
# we never need the user, so we use a
# generic user for all shelve operations
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 shelveuser = b'shelve@localhost'
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
py3: use class X: instead of class X(object):...
r49801 class ShelfDir:
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def __init__(self, repo, for_backups: bool = False) -> None:
Martin von Zweigbergk
shelve: also create class representing whole directory of shelves...
r47014 if for_backups:
self.vfs = vfsmod.vfs(repo.vfs.join(backupdir))
else:
self.vfs = vfsmod.vfs(repo.vfs.join(shelvedir))
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def get(self, name: bytes) -> "Shelf":
Martin von Zweigbergk
shelve: also create class representing whole directory of shelves...
r47014 return Shelf(self.vfs, name)
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def listshelves(self) -> List[Tuple[float, bytes]]:
Martin von Zweigbergk
shelve: move listshelves() to new ShelfDir class, so caller need not pass vfs...
r47015 """return all shelves in repo as list of (time, name)"""
try:
names = self.vfs.listdir()
Manuel Jacob
py3: catch FileNotFoundError instead of checking errno == ENOENT
r50201 except FileNotFoundError:
Martin von Zweigbergk
shelve: move listshelves() to new ShelfDir class, so caller need not pass vfs...
r47015 return []
info = []
seen = set()
for filename in names:
name = filename.rsplit(b'.', 1)[0]
if name in seen:
continue
seen.add(name)
shelf = self.get(name)
if not shelf.exists():
continue
mtime = shelf.mtime()
info.append((mtime, name))
return sorted(info, reverse=True)
Martin von Zweigbergk
shelve: also create class representing whole directory of shelves...
r47014
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _use_internal_phase(repo) -> bool:
Jason R. Coombs
phase-shelve: Implement a 'shelve.store' experimental config...
r50325 return (
phases.supportinternal(repo)
Jason R. Coombs
phase-shelve: correct unicode string to honor 'shelve.store=internal'...
r50352 and repo.ui.config(b'shelve', b'store') == b'internal'
Jason R. Coombs
phase-shelve: Implement a 'shelve.store' experimental config...
r50325 )
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _target_phase(repo) -> int:
Jason R. Coombs
phase-shelve: Implement a 'shelve.store' experimental config...
r50325 return phases.internal if _use_internal_phase(repo) else phases.secret
Jason R. Coombs
phase-shelve: Extract function for _target_phase
r50324
Gregory Szorc
py3: use class X: instead of class X(object):...
r49801 class Shelf:
Martin von Zweigbergk
shelve: introduce class representing a shelf...
r46991 """Represents a shelf, including possibly multiple files storing it.
Old shelves will have a .patch and a .hg file. Newer shelves will
also have a .shelve file. This class abstracts away some of the
differences and lets you work with the shelf as a whole.
"""
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def __init__(self, vfs: vfsmod.vfs, name: bytes) -> None:
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 self.vfs = vfs
Martin von Zweigbergk
shelve: introduce class representing a shelf...
r46991 self.name = name
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def exists(self) -> bool:
Jason R. Coombs
phase-shelve: honor and prefer obs shelves for existence and modified time
r50322 return self._exists(b'.shelve') or self._exists(b'.patch', b'.hg')
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _exists(self, *exts: bytes) -> bool:
Jason R. Coombs
phase-shelve: honor and prefer obs shelves for existence and modified time
r50322 return all(self.vfs.exists(self.name + ext) for ext in exts)
Martin von Zweigbergk
shelve: introduce class representing a shelf...
r46991
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def mtime(self) -> float:
Jason R. Coombs
phase-shelve: honor and prefer obs shelves for existence and modified time
r50322 try:
return self._stat(b'.shelve')[stat.ST_MTIME]
except FileNotFoundError:
return self._stat(b'.patch')[stat.ST_MTIME]
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _stat(self, ext: bytes):
Jason R. Coombs
phase-shelve: honor and prefer obs shelves for existence and modified time
r50322 return self.vfs.stat(self.name + ext)
Martin von Zweigbergk
shelve: move method for getting stat (mtime) to new shelf class...
r46998
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def writeinfo(self, info) -> None:
Martin von Zweigbergk
shelve: move method for writing .shelve to new shelf class...
r46992 scmutil.simplekeyvaluefile(self.vfs, self.name + b'.shelve').write(info)
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def hasinfo(self) -> bool:
Martin von Zweigbergk
shelve: teach new shelf class to check if .shelve file exists...
r47004 return self.vfs.exists(self.name + b'.shelve')
Martin von Zweigbergk
shelve: move method for reading .shelve file to new shelf class...
r46993 def readinfo(self):
return scmutil.simplekeyvaluefile(
self.vfs, self.name + b'.shelve'
).read()
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def writebundle(self, repo, bases, node) -> None:
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 cgversion = changegroup.safeversion(repo)
Martin von Zweigbergk
shelve: move method for writing bundle to new shelf class...
r46994 if cgversion == b'01':
btype = b'HG10BZ'
compression = None
else:
btype = b'HG20'
compression = b'BZ'
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 repo = repo.unfiltered()
Martin von Zweigbergk
shelve: move method for writing bundle to new shelf class...
r46994
outgoing = discovery.outgoing(
repo, missingroots=bases, ancestorsof=[node]
)
cg = changegroup.makechangegroup(repo, outgoing, cgversion, b'shelve')
bundle_filename = self.vfs.join(self.name + b'.hg')
bundle2.writebundle(
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 repo.ui,
Martin von Zweigbergk
shelve: move method for writing bundle to new shelf class...
r46994 cg,
bundle_filename,
btype,
self.vfs,
compression=compression,
)
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def applybundle(self, repo, tr) -> contextmod.changectx:
Martin von Zweigbergk
shelve: move method for reading .hg to new shelf class...
r46995 filename = self.name + b'.hg'
fp = self.vfs(filename)
try:
Jason R. Coombs
phase-shelve: Extract function for _target_phase
r50324 targetphase = _target_phase(repo)
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 gen = exchange.readbundle(repo.ui, fp, filename, self.vfs)
pretip = repo[b'tip']
Martin von Zweigbergk
shelve: move method for reading .hg to new shelf class...
r46995 bundle2.applybundle(
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 repo,
Martin von Zweigbergk
shelve: move method for reading .hg to new shelf class...
r46995 gen,
tr,
source=b'unshelve',
url=b'bundle:' + self.vfs.join(filename),
targetphase=targetphase,
)
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 shelvectx = repo[b'tip']
Martin von Zweigbergk
shelve: move method for reading .hg to new shelf class...
r46995 if pretip == shelvectx:
shelverev = tr.changes[b'revduplicates'][-1]
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 shelvectx = repo[shelverev]
Martin von Zweigbergk
shelve: move method for reading .hg to new shelf class...
r46995 return shelvectx
finally:
fp.close()
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def open_patch(self, mode: bytes = b'rb'):
Martin von Zweigbergk
shelve: move function for opening .patch file to new shelf class...
r46996 return self.vfs(self.name + b'.patch', mode)
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def patch_from_node(self, repo, node) -> io.BytesIO:
Jason R. Coombs
phase-shelve: read patch details from a (possibly internal) node in the repo
r50321 repo = repo.unfiltered()
match = _optimized_match(repo, node)
fp = io.BytesIO()
cmdutil.exportfile(
repo,
[node],
fp,
opts=mdiff.diffopts(git=True),
match=match,
)
fp.seek(0)
return fp
def load_patch(self, repo):
try:
# prefer node-based shelf
return self.patch_from_node(repo, self.readinfo()[b'node'])
except (FileNotFoundError, error.RepoLookupError):
return self.open_patch()
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _backupfilename(self, backupvfs: vfsmod.vfs, filename: bytes) -> bytes:
def gennames(base: bytes):
Martin von Zweigbergk
shelve: move method for creating backup to new shelf class...
r47003 yield base
base, ext = base.rsplit(b'.', 1)
for i in itertools.count(1):
yield b'%s-%d.%s' % (base, i, ext)
for n in gennames(filename):
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 if not backupvfs.exists(n):
return backupvfs.join(n)
Martin von Zweigbergk
shelve: move method for creating backup to new shelf class...
r47003
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 # Help pytype- gennames() yields infinitely
raise error.ProgrammingError("unreachable")
def movetobackup(self, backupvfs: vfsmod.vfs) -> None:
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 if not backupvfs.isdir():
backupvfs.makedir()
Martin von Zweigbergk
shelve: move method for creating backup to new shelf class...
r47003 for suffix in shelvefileextensions:
filename = self.name + b'.' + suffix
if self.vfs.exists(filename):
util.rename(
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 self.vfs.join(filename),
self._backupfilename(backupvfs, filename),
Martin von Zweigbergk
shelve: move method for creating backup to new shelf class...
r47003 )
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def delete(self) -> None:
Martin von Zweigbergk
shelve: add a method for deleting shelf to new shelf class...
r47013 for ext in shelvefileextensions:
self.vfs.tryunlink(self.name + b'.' + ext)
Jason R. Coombs
shelve: add Shelf.changed_files for resolving changed files in a plugin
r50481 def changed_files(self, ui, repo):
try:
ctx = repo.unfiltered()[self.readinfo()[b'node']]
return ctx.files()
except (FileNotFoundError, error.RepoLookupError):
filename = self.vfs.join(self.name + b'.patch')
return patch.changedfiles(ui, repo, filename)
Martin von Zweigbergk
shelve: introduce class representing a shelf...
r46991
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _optimized_match(repo, node: bytes):
Jason R. Coombs
phase-shelve: Extract function for _optimized_match for re-use
r50320 """
Create a matcher so that prefetch doesn't attempt to fetch
the entire repository pointlessly, and as an optimisation
for movedirstate, if needed.
"""
return scmutil.matchfiles(repo, repo[node].files())
Gregory Szorc
py3: use class X: instead of class X(object):...
r49801 class shelvedstate:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """Handle persistence during unshelving operations.
Handles saving and restoring a shelved state. Ensures that different
versions of a shelved state are possible and handles them appropriately.
"""
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 # Class-wide constants
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 _version = 2
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _filename = b'shelvedstate'
_keep = b'keep'
_nokeep = b'nokeep'
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 # colon is essential to differentiate from a real bookmark name
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _noactivebook = b':no-active-bookmark'
_interactive = b'interactive'
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 # Per instance attrs
name: bytes
wctx: contextmod.workingctx
pendingctx: contextmod.changectx
parents: List[bytes]
nodestoremove: List[bytes]
branchtorestore: bytes
keep: bool
activebookmark: bytes
interactive: bool
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 @classmethod
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _verifyandtransform(cls, d: Dict[bytes, Any]) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """Some basic shelvestate syntactic verification and transformation"""
try:
Joerg Sonnenberger
node: import symbols explicitly...
r46729 d[b'originalwctx'] = bin(d[b'originalwctx'])
d[b'pendingctx'] = bin(d[b'pendingctx'])
Jason R. Coombs
shelve: handle empty parents and nodestoremove in shelvedstate (issue6748)
r50455 d[b'parents'] = [bin(h) for h in d[b'parents'].split(b' ') if h]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 d[b'nodestoremove'] = [
Jason R. Coombs
shelve: handle empty parents and nodestoremove in shelvedstate (issue6748)
r50455 bin(h) for h in d[b'nodestoremove'].split(b' ') if h
Augie Fackler
formatting: blacken the codebase...
r43346 ]
Manuel Jacob
node: stop converting binascii.Error to TypeError in bin()...
r50143 except (ValueError, KeyError) as err:
Matt Harbison
shelve: fix conversion of exceptions to strings flagged by pytype...
r47386 raise error.CorruptedState(stringutil.forcebytestr(err))
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
@classmethod
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _getversion(cls, repo) -> int:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """Read version information from shelvestate file"""
fp = repo.vfs(cls._filename)
try:
version = int(fp.readline().strip())
except ValueError as err:
Matt Harbison
shelve: fix conversion of exceptions to strings flagged by pytype...
r47386 raise error.CorruptedState(stringutil.forcebytestr(err))
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 finally:
fp.close()
return version
@classmethod
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _readold(cls, repo) -> Dict[bytes, Any]:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """Read the old position-based version of a shelvestate file"""
# Order is important, because old shelvestate file uses it
# to detemine values of fields (i.g. name is on the second line,
# originalwctx is on the third and so forth). Please do not change.
Augie Fackler
formatting: blacken the codebase...
r43346 keys = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'version',
b'name',
b'originalwctx',
b'pendingctx',
b'parents',
b'nodestoremove',
b'branchtorestore',
b'keep',
b'activebook',
Augie Fackler
formatting: blacken the codebase...
r43346 ]
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 # this is executed only seldomly, so it is not a big deal
# that we open this file twice
fp = repo.vfs(cls._filename)
d = {}
try:
for key in keys:
d[key] = fp.readline().strip()
finally:
fp.close()
return d
@classmethod
def load(cls, repo):
version = cls._getversion(repo)
if version < cls._version:
d = cls._readold(repo)
elif version == cls._version:
Augie Fackler
formatting: blacken the codebase...
r43346 d = scmutil.simplekeyvaluefile(repo.vfs, cls._filename).read(
firstlinenonkeyval=True
)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 else:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'this version of shelve is incompatible '
b'with the version used in this repo'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
cls._verifyandtransform(d)
try:
obj = cls()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 obj.name = d[b'name']
obj.wctx = repo[d[b'originalwctx']]
obj.pendingctx = repo[d[b'pendingctx']]
obj.parents = d[b'parents']
obj.nodestoremove = d[b'nodestoremove']
obj.branchtorestore = d.get(b'branchtorestore', b'')
obj.keep = d.get(b'keep') == cls._keep
obj.activebookmark = b''
if d.get(b'activebook', b'') != cls._noactivebook:
obj.activebookmark = d.get(b'activebook', b'')
obj.interactive = d.get(b'interactive') == cls._interactive
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 except (error.RepoLookupError, KeyError) as err:
Matt Harbison
shelve: consistently convert exception to bytes via `stringutil.forcebytestr`...
r52710 raise error.CorruptedState(stringutil.forcebytestr(err))
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
return obj
@classmethod
Augie Fackler
formatting: blacken the codebase...
r43346 def save(
cls,
repo,
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 name: bytes,
originalwctx: contextmod.workingctx,
pendingctx: contextmod.changectx,
nodestoremove: List[bytes],
branchtorestore: bytes,
keep: bool = False,
activebook: bytes = b'',
interactive: bool = False,
) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 info = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"name": name,
Joerg Sonnenberger
node: import symbols explicitly...
r46729 b"originalwctx": hex(originalwctx.node()),
b"pendingctx": hex(pendingctx.node()),
b"parents": b' '.join([hex(p) for p in repo.dirstate.parents()]),
b"nodestoremove": b' '.join([hex(n) for n in nodestoremove]),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"branchtorestore": branchtorestore,
b"keep": cls._keep if keep else cls._nokeep,
b"activebook": activebook or cls._noactivebook,
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 }
Navaneeth Suresh
unshelve: store information about interactive mode in shelvedstate...
r42889 if interactive:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 info[b'interactive'] = cls._interactive
Augie Fackler
formatting: blacken the codebase...
r43346 scmutil.simplekeyvaluefile(repo.vfs, cls._filename).write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 info, firstline=(b"%d" % cls._version)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
@classmethod
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def clear(cls, repo) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 repo.vfs.unlinkpath(cls._filename, ignoremissing=True)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def cleanupoldbackups(repo) -> None:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 maxbackups = repo.ui.configint(b'shelve', b'maxbackups')
Martin von Zweigbergk
shelve: move listshelves() to new ShelfDir class, so caller need not pass vfs...
r47015 backup_dir = ShelfDir(repo, for_backups=True)
hgfiles = backup_dir.listshelves()
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if maxbackups > 0 and maxbackups < len(hgfiles):
Martin von Zweigbergk
shelve: use listshelves() in cleanupoldbackups()...
r47011 bordermtime = hgfiles[maxbackups - 1][0]
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 else:
bordermtime = None
Martin von Zweigbergk
shelve: use listshelves() in cleanupoldbackups()...
r47011 for mtime, name in hgfiles[maxbackups:]:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if mtime == bordermtime:
# keep it, because timestamp can't decide exact order of backups
continue
Martin von Zweigbergk
shelve: move listshelves() to new ShelfDir class, so caller need not pass vfs...
r47015 backup_dir.get(name).delete()
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _backupactivebookmark(repo) -> bytes:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 activebookmark = repo._activebookmark
if activebookmark:
bookmarks.deactivate(repo)
return activebookmark
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _restoreactivebookmark(repo, mark) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if mark:
bookmarks.activate(repo, mark)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _aborttransaction(repo, tr) -> None:
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """Abort current transaction for shelve/unshelve, but keep dirstate"""
dirstate: simplify the shelve hack to not go through the disk...
r50974 # disable the transaction invalidation of the dirstate, to preserve the
# current change in memory.
ds = repo.dirstate
# The assert below check that nobody else did such wrapping.
#
# These is not such other wrapping currently, but if someone try to
# implement one in the future, this will explicitly break here instead of
# misbehaving in subtle ways.
transaction: use the standard transaction mechanism to backup branch...
r51090 current_branch = ds.branch()
dirstate: simplify the shelve hack to not go through the disk...
r50974 assert 'invalidate' not in vars(ds)
try:
# note : we could simply disable the transaction abort callback, but
# other code also tries to rollback and invalidate this.
ds.invalidate = lambda: None
tr.abort()
finally:
del ds.invalidate
# manually write the change in memory since we can no longer rely on the
# transaction to do so.
assert repo.currenttransaction() is None
repo.dirstate.write(None)
branch: pass current transaction when writing branch in shelve
r51159 ds.setbranch(current_branch, None)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def getshelvename(repo, parent, opts) -> bytes:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """Decide on the name this shelve is going to have"""
Augie Fackler
formatting: blacken the codebase...
r43346
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 def gennames():
yield label
for i in itertools.count(1):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 yield b'%s-%02d' % (label, i)
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 name = opts.get(b'name')
label = repo._activebookmark or parent.branch() or b'default'
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 # slashes aren't allowed in filenames, therefore we rename it
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 label = label.replace(b'/', b'_')
label = label.replace(b'\\', b'_')
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 # filenames must not start with '.' as it should not be hidden
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if label.startswith(b'.'):
label = label.replace(b'.', b'_', 1)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
if name:
Martin von Zweigbergk
shelve: also create class representing whole directory of shelves...
r47014 if ShelfDir(repo).get(name).exists():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 e = _(b"a shelved change named '%s' already exists") % name
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 raise error.Abort(e)
# ensure we are not creating a subdirectory or a hidden file
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'/' in name or b'\\' in name:
raise error.Abort(
_(b'shelved change names can not contain slashes')
)
if name.startswith(b'.'):
raise error.Abort(_(b"shelved change names can not start with '.'"))
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
else:
Martin von Zweigbergk
shelve: also create class representing whole directory of shelves...
r47014 shelf_dir = ShelfDir(repo)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 for n in gennames():
Martin von Zweigbergk
shelve: also create class representing whole directory of shelves...
r47014 if not shelf_dir.get(n).exists():
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 name = n
break
return name
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def mutableancestors(ctx) -> Iterator[bytes]:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """return all mutable ancestors for ctx (included)
Much faster than the revset ancestors(ctx) & draft()"""
Joerg Sonnenberger
node: import symbols explicitly...
r46729 seen = {nullrev}
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 visit = collections.deque()
visit.append(ctx)
while visit:
ctx = visit.popleft()
yield ctx.node()
for parent in ctx.parents():
rev = parent.rev()
if rev not in seen:
seen.add(rev)
if parent.mutable():
visit.append(parent)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def getcommitfunc(extra, interactive: bool, editor: bool = False):
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 def commitfunc(ui, repo, message, match, opts):
safehasattr: drop usage in favor of hasattr...
r51821 hasmq = hasattr(repo, 'mq')
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if hasmq:
saved, repo.mq.checkapplied = repo.mq.checkapplied, False
Jason R. Coombs
phase-shelve: Extract function for _target_phase
r50324 targetphase = _target_phase(repo)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 overrides = {(b'phases', b'new-commit'): targetphase}
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 try:
editor_ = False
if editor:
Augie Fackler
formatting: blacken the codebase...
r43346 editor_ = cmdutil.getcommiteditor(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 editform=b'shelve.shelve', **pycompat.strkwargs(opts)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 with repo.ui.configoverride(overrides):
Augie Fackler
formatting: blacken the codebase...
r43346 return repo.commit(
message,
shelveuser,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 opts.get(b'date'),
Augie Fackler
formatting: blacken the codebase...
r43346 match,
editor=editor_,
extra=extra,
)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 finally:
if hasmq:
repo.mq.checkapplied = saved
def interactivecommitfunc(ui, repo, *pats, **opts):
opts = pycompat.byteskwargs(opts)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 match = scmutil.match(repo[b'.'], pats, {})
message = opts[b'message']
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 return commitfunc(ui, repo, message, match, opts)
return interactivecommitfunc if interactive else commitfunc
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _nothingtoshelvemessaging(ui, repo, pats, opts) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
if stat.deleted:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 _(b"nothing changed (%d missing files, see 'hg status')\n")
Augie Fackler
formatting: blacken the codebase...
r43346 % len(stat.deleted)
)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b"nothing changed\n"))
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _shelvecreatedcommit(repo, node: bytes, name: bytes, match) -> None:
Joerg Sonnenberger
node: import symbols explicitly...
r46729 info = {b'node': hex(node)}
Martin von Zweigbergk
shelve: also create class representing whole directory of shelves...
r47014 shelf = ShelfDir(repo).get(name)
Martin von Zweigbergk
shelve: extract some repeated creation of shelf instances to variables...
r47005 shelf.writeinfo(info)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 bases = list(mutableancestors(repo[node]))
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 shelf.writebundle(repo, bases, node)
Martin von Zweigbergk
shelve: extract some repeated creation of shelf instances to variables...
r47005 with shelf.open_patch(b'wb') as fp:
Augie Fackler
formatting: blacken the codebase...
r43346 cmdutil.exportfile(
repo, [node], fp, opts=mdiff.diffopts(git=True), match=match
)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _includeunknownfiles(repo, pats, opts, extra) -> None:
Augie Fackler
formatting: blacken the codebase...
r43346 s = repo.status(match=scmutil.match(repo[None], pats, opts), unknown=True)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if s.unknown:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extra[b'shelve_unknown'] = b'\0'.join(s.unknown)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 repo[None].add(s.unknown)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _finishshelve(repo, tr) -> None:
Jason R. Coombs
phase-shelve: Implement a 'shelve.store' experimental config...
r50325 if _use_internal_phase(repo):
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 tr.close()
else:
_aborttransaction(repo, tr)
Augie Fackler
formatting: blacken the codebase...
r43346
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 def createcmd(ui, repo, pats, opts):
"""subcommand that creates a new shelve"""
with repo.wlock():
cmdutil.checkunfinished(repo)
return _docreatecmd(ui, repo, pats, opts)
Augie Fackler
formatting: blacken the codebase...
r43346
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 def _docreatecmd(ui, repo, pats, opts):
wctx = repo[None]
parents = wctx.parents()
parent = parents[0]
origbranch = wctx.branch()
Joerg Sonnenberger
refactor: prefer checks against nullrev over nullid...
r47601 if parent.rev() != nullrev:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 desc = b"changes to: %s" % parent.description().split(b'\n', 1)[0]
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 desc = b'(changes in empty repository)'
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not opts.get(b'message'):
opts[b'message'] = desc
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
lock = tr = activebookmark = None
try:
lock = repo.lock()
# use an uncommitted transaction to generate the bundle to avoid
# pull races. ensure we don't print the abort message to stderr.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tr = repo.transaction(b'shelve', report=lambda x: None)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 interactive = opts.get(b'interactive', False)
includeunknown = opts.get(b'unknown', False) and not opts.get(
b'addremove', False
Augie Fackler
formatting: blacken the codebase...
r43346 )
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
name = getshelvename(repo, parent, opts)
activebookmark = _backupactivebookmark(repo)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extra = {b'internal': b'shelve'}
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if includeunknown:
dirstate: use `dirstate.change_files` to scope the change in `shelve`...
r50949 with repo.dirstate.changing_files(repo):
_includeunknownfiles(repo, pats, opts, extra)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
if _iswctxonnewbranch(repo) and not _isbareshelve(pats, opts):
# In non-bare shelve we don't store newly created branch
# at bundled commit
branch: pass current transaction when writing branch in shelve
r51159 repo.dirstate.setbranch(
repo[b'.'].branch(), repo.currenttransaction()
)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
commitfunc = getcommitfunc(extra, interactive, editor=True)
if not interactive:
node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
else:
Augie Fackler
formatting: blacken the codebase...
r43346 node = cmdutil.dorecord(
ui,
repo,
commitfunc,
None,
False,
cmdutil.recordfilter,
*pats,
Matt Harbison
format: add many "missing" comma...
r52755 **pycompat.strkwargs(opts),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if not node:
_nothingtoshelvemessaging(ui, repo, pats, opts)
return 1
Jason R. Coombs
phase-shelve: Extract function for _optimized_match for re-use
r50320 match = _optimized_match(repo, node)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 _shelvecreatedcommit(repo, node, name, match)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'shelved as %s\n') % name)
if opts[b'keep']:
dirstate: rename parentchange to changing_parents...
r50855 with repo.dirstate.changing_parents(repo):
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 scmutil.movedirstate(repo, parent, match)
else:
hg.update(repo, parent.node())
Martin von Zweigbergk
shelve: clear merge state after partial shelve...
r46464 ms = mergestatemod.mergestate.read(repo)
if not ms.unresolvedcount():
ms.reset()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if origbranch != repo[b'.'].branch() and not _isbareshelve(pats, opts):
branch: pass current transaction when writing branch in shelve
r51159 repo.dirstate.setbranch(origbranch, repo.currenttransaction())
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
_finishshelve(repo, tr)
finally:
_restoreactivebookmark(repo, activebookmark)
lockmod.release(tr, lock)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _isbareshelve(pats, opts) -> bool:
Augie Fackler
formatting: blacken the codebase...
r43346 return (
not pats
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 and not opts.get(b'interactive', False)
and not opts.get(b'include', False)
and not opts.get(b'exclude', False)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _iswctxonnewbranch(repo) -> bool:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return repo[None].branch() != repo[b'.'].branch()
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def cleanupcmd(ui, repo) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """subcommand that deletes all shelves"""
with repo.wlock():
Martin von Zweigbergk
shelve: move listshelves() to new ShelfDir class, so caller need not pass vfs...
r47015 shelf_dir = ShelfDir(repo)
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 backupvfs = vfsmod.vfs(repo.vfs.join(backupdir))
Martin von Zweigbergk
shelve: move listshelves() to new ShelfDir class, so caller need not pass vfs...
r47015 for _mtime, name in shelf_dir.listshelves():
shelf_dir.get(name).movetobackup(backupvfs)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 cleanupoldbackups(repo)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def deletecmd(ui, repo, pats) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """subcommand that deletes a specific shelve"""
if not pats:
Martin von Zweigbergk
shelve: raise more specific errors...
r46990 raise error.InputError(_(b'no shelved changes specified!'))
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 with repo.wlock():
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 backupvfs = vfsmod.vfs(repo.vfs.join(backupdir))
Matt Harbison
shelve: fix a missing variable in the exception handler for delete...
r44123 for name in pats:
Martin von Zweigbergk
shelve: also create class representing whole directory of shelves...
r47014 shelf = ShelfDir(repo).get(name)
Martin von Zweigbergk
shelve: extract some repeated creation of shelf instances to variables...
r47005 if not shelf.exists():
Martin von Zweigbergk
shelve: raise more specific errors...
r46990 raise error.InputError(
_(b"shelved change '%s' not found") % name
)
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 shelf.movetobackup(backupvfs)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 cleanupoldbackups(repo)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def listcmd(ui, repo, pats: Iterable[bytes], opts) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """subcommand that displays the list of shelves"""
pats = set(pats)
width = 80
if not ui.plain():
width = ui.termwidth()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 namelabel = b'shelve.newest'
ui.pager(b'shelve')
Martin von Zweigbergk
shelve: also create class representing whole directory of shelves...
r47014 shelf_dir = ShelfDir(repo)
Martin von Zweigbergk
shelve: move listshelves() to new ShelfDir class, so caller need not pass vfs...
r47015 for mtime, name in shelf_dir.listshelves():
Martin von Zweigbergk
shelve: make listshelves() return shelf names instead of filenames...
r46999 if pats and name not in pats:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 continue
Martin von Zweigbergk
shelve: make listshelves() return shelf names instead of filenames...
r46999 ui.write(name, label=namelabel)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 namelabel = b'shelve.name'
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if ui.quiet:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.write(b'\n')
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 continue
Martin von Zweigbergk
shelve: make listshelves() return shelf names instead of filenames...
r46999 ui.write(b' ' * (16 - len(name)))
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 used = 16
date = dateutil.makedate(mtime)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 age = b'(%s)' % templatefilters.age(date, abbrev=True)
ui.write(age, label=b'shelve.age')
ui.write(b' ' * (12 - len(age)))
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 used += 12
Jason R. Coombs
phase-shelve: read patch details from a (possibly internal) node in the repo
r50321 with shelf_dir.get(name).load_patch(repo) as fp:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 while True:
line = fp.readline()
if not line:
break
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not line.startswith(b'#'):
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 desc = line.rstrip()
if ui.formatted():
desc = stringutil.ellipsis(desc, width - used)
ui.write(desc)
break
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.write(b'\n')
if not (opts[b'patch'] or opts[b'stat']):
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 continue
difflines = fp.readlines()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts[b'patch']:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 for chunk, label in patch.difflabel(iter, difflines):
ui.write(chunk, label=label)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts[b'stat']:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 for chunk, label in patch.diffstatui(difflines, width=width):
ui.write(chunk, label=label)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def patchcmds(ui, repo, pats: Sequence[bytes], opts) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """subcommand that displays shelves"""
Martin von Zweigbergk
shelve: move listshelves() to new ShelfDir class, so caller need not pass vfs...
r47015 shelf_dir = ShelfDir(repo)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if len(pats) == 0:
Martin von Zweigbergk
shelve: move listshelves() to new ShelfDir class, so caller need not pass vfs...
r47015 shelves = shelf_dir.listshelves()
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if not shelves:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"there are no shelves to show"))
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 mtime, name = shelves[0]
Martin von Zweigbergk
shelve: make listshelves() return shelf names instead of filenames...
r46999 pats = [name]
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
for shelfname in pats:
Martin von Zweigbergk
shelve: also create class representing whole directory of shelves...
r47014 if not shelf_dir.get(shelfname).exists():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"cannot find shelf %s") % shelfname)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
listcmd(ui, repo, pats, opts)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def checkparents(repo, state: shelvedstate) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """check parent while resuming an unshelve"""
if state.parents != repo.dirstate.parents():
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 _(b'working directory parents do not match unshelve state')
Augie Fackler
formatting: blacken the codebase...
r43346 )
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _loadshelvedstate(ui, repo, opts) -> shelvedstate:
Taapas Agrawal
abort: added support for unshelve...
r42802 try:
state = shelvedstate.load(repo)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'keep') is None:
opts[b'keep'] = state.keep
Matt Harbison
shelve: raise an error when loading a corrupt state file in an impossible case...
r52706 return state
Manuel Jacob
py3: catch FileNotFoundError instead of checking errno == ENOENT
r50201 except FileNotFoundError:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmdutil.wrongtooltocontinue(repo, _(b'unshelve'))
Taapas Agrawal
abort: added support for unshelve...
r42802 except error.CorruptedState as err:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.debug(pycompat.bytestr(err) + b'\n')
if opts.get(b'continue'):
msg = _(b'corrupted shelved state file')
Augie Fackler
formatting: blacken the codebase...
r43346 hint = _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'please run hg unshelve --abort to abort unshelve '
b'operation'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Taapas Agrawal
abort: added support for unshelve...
r42802 raise error.Abort(msg, hint=hint)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif opts.get(b'abort'):
Taapas Agrawal
abort: added support for unshelve...
r42802 shelvedstate.clear(repo)
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'could not read shelved state file, your '
b'working copy may be in an unexpected state\n'
b'please update to some commit\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Matt Harbison
shelve: raise an error when loading a corrupt state file in an impossible case...
r52706 else:
raise error.ProgrammingError(
"a corrupted shelvedstate exists without --abort or --continue"
)
Taapas Agrawal
abort: added support for unshelve...
r42802
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def unshelveabort(ui, repo, state: shelvedstate) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """subcommand that abort an in-progress unshelve"""
with repo.lock():
try:
checkparents(repo, state)
Martin von Zweigbergk
merge: introduce a clean_update() for that use-case...
r44743 merge.clean_update(state.pendingctx)
Augie Fackler
formatting: blacken the codebase...
r43346 if state.activebookmark and state.activebookmark in repo._bookmarks:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 bookmarks.activate(repo, state.activebookmark)
mergefiles(ui, repo, state.wctx, state.pendingctx)
Jason R. Coombs
phase-shelve: Implement a 'shelve.store' experimental config...
r50325 if not _use_internal_phase(repo):
Augie Fackler
formatting: blacken the codebase...
r43346 repair.strip(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui, repo, state.nodestoremove, backup=False, topic=b'shelve'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 finally:
shelvedstate.clear(repo)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.warn(_(b"unshelve of '%s' aborted\n") % state.name)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def hgabortunshelve(ui, repo) -> None:
Taapas Agrawal
abort: added support for unshelve...
r42802 """logic to abort unshelve using 'hg abort"""
with repo.wlock():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 state = _loadshelvedstate(ui, repo, {b'abort': True})
Taapas Agrawal
abort: added support for unshelve...
r42802 return unshelveabort(ui, repo, state)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def mergefiles(ui, repo, wctx, shelvectx) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """updates to wctx and merges the changes from shelvectx into the
dirstate."""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 with ui.configoverride({(b'ui', b'quiet'): True}):
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 hg.update(repo, wctx.node())
Martin von Zweigbergk
revert: remove dangerous `parents` argument from `cmdutil.revert()`...
r45935 cmdutil.revert(ui, repo, shelvectx)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def restorebranch(ui, repo, branchtorestore: bytes) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if branchtorestore and branchtorestore != repo.dirstate.branch():
branch: pass current transaction when writing branch in shelve
r51159 repo.dirstate.setbranch(branchtorestore, repo.currenttransaction())
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'marked working directory as branch %s\n') % branchtorestore
Augie Fackler
formatting: blacken the codebase...
r43346 )
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def unshelvecleanup(ui, repo, name: bytes, opts) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """remove related files after an unshelve"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not opts.get(b'keep'):
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 backupvfs = vfsmod.vfs(repo.vfs.join(backupdir))
Martin von Zweigbergk
shelve: also create class representing whole directory of shelves...
r47014 ShelfDir(repo).get(name).movetobackup(backupvfs)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 cleanupoldbackups(repo)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def unshelvecontinue(ui, repo, state: shelvedstate, opts) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """subcommand to continue an in-progress unshelve"""
# We're finishing off a merge. First parent is our original
# parent, second is the temporary "fake" commit we're unshelving.
Navaneeth Suresh
unshelve: store information about interactive mode in shelvedstate...
r42889 interactive = state.interactive
basename = state.name
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 with repo.lock():
checkparents(repo, state)
Augie Fackler
mergestate: split out merge state handling code from main merge module...
r45383 ms = mergestatemod.mergestate.read(repo)
Augie Fackler
cleanup: use mergestate.unresolvedcount() instead of bool(list(unresolved()))...
r47070 if ms.unresolvedcount():
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"unresolved conflicts, can't continue"),
hint=_(b"see 'hg resolve', then 'hg unshelve --continue'"),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
shelvectx = repo[state.parents[1]]
pendingctx = state.pendingctx
dirstate: rename parentchange to changing_parents...
r50855 with repo.dirstate.changing_parents(repo):
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 repo.setparents(state.pendingctx.node(), repo.nullid)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 repo.dirstate.write(repo.currenttransaction())
Jason R. Coombs
phase-shelve: Extract function for _target_phase
r50324 targetphase = _target_phase(repo)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 overrides = {(b'phases', b'new-commit'): targetphase}
with repo.ui.configoverride(overrides, b'unshelve'):
dirstate: rename parentchange to changing_parents...
r50855 with repo.dirstate.changing_parents(repo):
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 repo.setparents(state.parents[0], repo.nullid)
shelve: adjust what happens in some `changing_parents` context...
r50947 newnode, ispartialunshelve = _createunshelvectx(
ui, repo, shelvectx, basename, interactive, opts
)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
if newnode is None:
shelvectx = state.pendingctx
Augie Fackler
formatting: blacken the codebase...
r43346 msg = _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'note: unshelved changes already existed '
b'in the working copy\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 ui.status(msg)
else:
# only strip the shelvectx if we produced one
state.nodestoremove.append(newnode)
shelvectx = repo[newnode]
Martin von Zweigbergk
merge: replace calls to hg.updaterepo() by merge.update()...
r46151 merge.update(pendingctx)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 mergefiles(ui, repo, state.wctx, shelvectx)
restorebranch(ui, repo, state.branchtorestore)
Jason R. Coombs
phase-shelve: Implement a 'shelve.store' experimental config...
r50325 if not _use_internal_phase(repo):
Augie Fackler
formatting: blacken the codebase...
r43346 repair.strip(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui, repo, state.nodestoremove, backup=False, topic=b'shelve'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Navaneeth Suresh
unshelve: delete shelvedstate after a successful unshelve --continue...
r42931 shelvedstate.clear(repo)
Navaneeth Suresh
unshelve: add interactive mode...
r42835 if not ispartialunshelve:
unshelvecleanup(ui, repo, state.name, opts)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 _restoreactivebookmark(repo, state.activebookmark)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b"unshelve of '%s' complete\n") % state.name)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def hgcontinueunshelve(ui, repo) -> None:
Taapas Agrawal
continue: added support for unshelve...
r42833 """logic to resume unshelve using 'hg continue'"""
with repo.wlock():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 state = _loadshelvedstate(ui, repo, {b'continue': True})
return unshelvecontinue(ui, repo, state, {b'keep': state.keep})
Augie Fackler
formatting: blacken the codebase...
r43346
Taapas Agrawal
continue: added support for unshelve...
r42833
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 def _commitworkingcopychanges(ui, repo, opts, tmpwctx):
"""Temporarily commit working copy changes before moving unshelve commit"""
# Store pending changes in a commit and remember added in case a shelve
# contains unknown files that are part of the pending change
s = repo.status()
addedbefore = frozenset(s.added)
if not (s.modified or s.added or s.removed):
return tmpwctx, addedbefore
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"temporarily committing pending changes "
b"(restore with 'hg unshelve --abort')\n"
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extra = {b'internal': b'shelve'}
Augie Fackler
formatting: blacken the codebase...
r43346 commitfunc = getcommitfunc(extra=extra, interactive=False, editor=False)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 tempopts = {}
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tempopts[b'message'] = b"pending changes temporary commit"
tempopts[b'date'] = opts.get(b'date')
with ui.configoverride({(b'ui', b'quiet'): True}):
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 node = cmdutil.commit(ui, repo, commitfunc, [], tempopts)
tmpwctx = repo[node]
return tmpwctx, addedbefore
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _unshelverestorecommit(ui, repo, tr, basename: bytes):
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """Recreate commit in the repository during the unshelve"""
repo = repo.unfiltered()
node = None
Martin von Zweigbergk
shelve: also create class representing whole directory of shelves...
r47014 shelf = ShelfDir(repo).get(basename)
Martin von Zweigbergk
shelve: extract some repeated creation of shelf instances to variables...
r47005 if shelf.hasinfo():
node = shelf.readinfo()[b'node']
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if node is None or node not in repo:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 with ui.configoverride({(b'ui', b'quiet'): True}):
Martin von Zweigbergk
shelve: replace repo instance in Shelf class by vfs instance...
r47009 shelvectx = shelf.applybundle(repo, tr)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 # We might not strip the unbundled changeset, so we should keep track of
# the unshelve node in case we need to reuse it (eg: unshelve --keep)
if node is None:
Joerg Sonnenberger
node: import symbols explicitly...
r46729 info = {b'node': hex(shelvectx.node())}
Martin von Zweigbergk
shelve: extract some repeated creation of shelf instances to variables...
r47005 shelf.writeinfo(info)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 else:
shelvectx = repo[node]
return repo, shelvectx
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _createunshelvectx(
ui, repo, shelvectx, basename: bytes, interactive: bool, opts
) -> Tuple[bytes, bool]:
Navaneeth Suresh
unshelve: unify logic around creating an unshelve changeset...
r42886 """Handles the creation of unshelve commit and updates the shelve if it
was partially unshelved.
If interactive is:
* False: Commits all the changes in the working directory.
* True: Prompts the user to select changes to unshelve and commit them.
Update the shelve with remaining changes.
Returns the node of the new commit formed and a bool indicating whether
the shelve was partially unshelved.Creates a commit ctx to unshelve
interactively or non-interactively.
The user might want to unshelve certain changes only from the stored
shelve in interactive. So, we would create two commits. One with requested
changes to unshelve at that time and the latter is shelved for future.
Here, we return both the newnode which is created interactively and a
bool to know whether the shelve is partly done or completely done.
Navaneeth Suresh
unshelve: add interactive mode...
r42835 """
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 opts[b'message'] = shelvectx.description()
opts[b'interactive-unshelve'] = True
Navaneeth Suresh
unshelve: add interactive mode...
r42835 pats = []
Navaneeth Suresh
unshelve: unify logic around creating an unshelve changeset...
r42886 if not interactive:
Augie Fackler
formatting: blacken the codebase...
r43346 newnode = repo.commit(
text=shelvectx.description(),
extra=shelvectx.extra(),
user=shelvectx.user(),
date=shelvectx.date(),
)
Navaneeth Suresh
unshelve: unify logic around creating an unshelve changeset...
r42886 return newnode, False
Augie Fackler
formatting: blacken the codebase...
r43346 commitfunc = getcommitfunc(shelvectx.extra(), interactive=True, editor=True)
newnode = cmdutil.dorecord(
ui,
repo,
commitfunc,
None,
False,
cmdutil.recordfilter,
*pats,
Matt Harbison
format: add many "missing" comma...
r52755 **pycompat.strkwargs(opts),
Augie Fackler
formatting: blacken the codebase...
r43346 )
snode = repo.commit(
text=shelvectx.description(),
extra=shelvectx.extra(),
user=shelvectx.user(),
)
Navaneeth Suresh
unshelve: add interactive mode...
r42835 if snode:
Jason R. Coombs
phase-shelve: Extract function for _optimized_match for re-use
r50320 m = _optimized_match(repo, snode)
Navaneeth Suresh
unshelve: add interactive mode...
r42835 _shelvecreatedcommit(repo, snode, basename, m)
return newnode, bool(snode)
Augie Fackler
formatting: blacken the codebase...
r43346
def _rebaserestoredcommit(
ui,
repo,
opts,
tr,
oldtiprev,
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 basename: bytes,
Augie Fackler
formatting: blacken the codebase...
r43346 pctx,
tmpwctx,
shelvectx,
branchtorestore,
activebookmark,
):
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """Rebase restored commit from its original location to a destination"""
# If the shelve is not immediately on top of the commit
# we'll be merging with, rebase it to be on top.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 interactive = opts.get(b'interactive')
Navaneeth Suresh
unshelve: add interactive mode...
r42835 if tmpwctx.node() == shelvectx.p1().node() and not interactive:
# We won't skip on interactive mode because, the user might want to
# unshelve certain changes only.
return shelvectx, False
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
overrides = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'ui', b'forcemerge'): opts.get(b'tool', b''),
(b'phases', b'new-commit'): phases.secret,
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 }
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 with repo.ui.configoverride(overrides, b'unshelve'):
ui.status(_(b'rebasing shelved changes\n'))
Augie Fackler
formatting: blacken the codebase...
r43346 stats = merge.graft(
repo,
shelvectx,
Martin von Zweigbergk
shelve: attempt to make merge labels more helpful...
r49438 labels=[
b'working-copy',
b'shelved change',
b'parent of shelved change',
],
Augie Fackler
formatting: blacken the codebase...
r43346 keepconflictparent=True,
)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if stats.unresolvedcount:
tr.close()
Augie Fackler
formatting: blacken the codebase...
r43346 nodestoremove = [
Manuel Jacob
py3: replace `pycompat.xrange` by `range`
r50179 repo.changelog.node(rev) for rev in range(oldtiprev, len(repo))
Augie Fackler
formatting: blacken the codebase...
r43346 ]
shelvedstate.save(
repo,
basename,
pctx,
tmpwctx,
nodestoremove,
branchtorestore,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 opts.get(b'keep'),
Augie Fackler
formatting: blacken the codebase...
r43346 activebookmark,
interactive,
)
Daniel Ploch
error: normalize "unresolved conflicts" error messages with a custom class...
r45711 raise error.ConflictResolutionRequired(b'unshelve')
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
dirstate: rename parentchange to changing_parents...
r50855 with repo.dirstate.changing_parents(repo):
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 repo.setparents(tmpwctx.node(), repo.nullid)
shelve: adjust what happens in some `changing_parents` context...
r50947 newnode, ispartialunshelve = _createunshelvectx(
ui, repo, shelvectx, basename, interactive, opts
)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
if newnode is None:
shelvectx = tmpwctx
Augie Fackler
formatting: blacken the codebase...
r43346 msg = _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'note: unshelved changes already existed '
b'in the working copy\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 ui.status(msg)
else:
shelvectx = repo[newnode]
Martin von Zweigbergk
merge: replace calls to hg.updaterepo() by merge.update()...
r46151 merge.update(tmpwctx)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Navaneeth Suresh
unshelve: add interactive mode...
r42835 return shelvectx, ispartialunshelve
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _forgetunknownfiles(repo, shelvectx, addedbefore) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 # Forget any files that were unknown before the shelve, unknown before
# unshelve started, but are now added.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 shelveunknown = shelvectx.extra().get(b'shelve_unknown')
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if not shelveunknown:
return
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 shelveunknown = frozenset(shelveunknown.split(b'\0'))
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 addedafter = frozenset(repo.status().added)
toforget = (addedafter & shelveunknown) - addedbefore
repo[None].forget(toforget)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _finishunshelve(repo, oldtiprev, tr, activebookmark) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 _restoreactivebookmark(repo, activebookmark)
shelve: drop some weird manually stripping before transaction abort...
r51993 # We used to manually strip the commit to update inmemory structure and
# prevent some issue around hooks. This no longer seems to be the case, so
# we simply abort the transaction.
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 _aborttransaction(repo, tr)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _checkunshelveuntrackedproblems(ui, repo, shelvectx) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 """Check potential problems which may result from working
copy having untracked changes."""
wcdeleted = set(repo.status().deleted)
shelvetouched = set(shelvectx.files())
intersection = wcdeleted.intersection(shelvetouched)
if intersection:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 m = _(b"shelved change touches missing files")
hint = _(b"run hg status to see which files are missing")
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 raise error.Abort(m, hint=hint)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def unshelvecmd(ui, repo, *shelved, **opts) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 opts = pycompat.byteskwargs(opts)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 abortf = opts.get(b'abort')
continuef = opts.get(b'continue')
interactive = opts.get(b'interactive')
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if not abortf and not continuef:
cmdutil.checkunfinished(repo)
shelved = list(shelved)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b"name"):
shelved.append(opts[b"name"])
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if interactive and opts.get(b'keep'):
Martin von Zweigbergk
shelve: raise more specific errors...
r46990 raise error.InputError(
_(b'--keep on --interactive is not yet supported')
)
Navaneeth Suresh
unshelve: store information about interactive mode in shelvedstate...
r42889 if abortf or continuef:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if abortf and continuef:
Martin von Zweigbergk
shelve: raise more specific errors...
r46990 raise error.InputError(_(b'cannot use both abort and continue'))
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if shelved:
Martin von Zweigbergk
shelve: raise more specific errors...
r46990 raise error.InputError(
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'cannot combine abort/continue with '
b'naming a shelved change'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if abortf and opts.get(b'tool', False):
ui.warn(_(b'tool option will be ignored\n'))
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Taapas Agrawal
abort: added support for unshelve...
r42802 state = _loadshelvedstate(ui, repo, opts)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if abortf:
Taapas Agrawal
abort: added support for unshelve...
r42802 return unshelveabort(ui, repo, state)
Navaneeth Suresh
unshelve: add abort on using continue and interactive together...
r42893 elif continuef and interactive:
Martin von Zweigbergk
shelve: raise more specific errors...
r46990 raise error.InputError(
_(b'cannot use both continue and interactive')
)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 elif continuef:
return unshelvecontinue(ui, repo, state, opts)
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 else:
# Unreachable code, but help type checkers not think that
# 'basename' may be used before initialization when checking
# ShelfDir below.
raise error.ProgrammingError("neither abort nor continue specified")
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 elif len(shelved) > 1:
Martin von Zweigbergk
shelve: raise more specific errors...
r46990 raise error.InputError(_(b'can only unshelve one change at a time'))
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 elif not shelved:
Martin von Zweigbergk
shelve: move listshelves() to new ShelfDir class, so caller need not pass vfs...
r47015 shelved = ShelfDir(repo).listshelves()
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if not shelved:
Martin von Zweigbergk
shelve: raise more specific errors...
r46990 raise error.StateError(_(b'no shelved changes to apply!'))
Martin von Zweigbergk
shelve: make listshelves() return shelf names instead of filenames...
r46999 basename = shelved[0][1]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b"unshelving change '%s'\n") % basename)
Navaneeth Suresh
unshelve: store information about interactive mode in shelvedstate...
r42889 else:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 basename = shelved[0]
Martin von Zweigbergk
shelve: also create class representing whole directory of shelves...
r47014 if not ShelfDir(repo).get(basename).exists():
Martin von Zweigbergk
shelve: raise more specific errors...
r46990 raise error.InputError(_(b"shelved change '%s' not found") % basename)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744
Martin von Zweigbergk
shelve: split up dounshelve() in unshelvecmd() and _dounshelve()...
r45086 return _dounshelve(ui, repo, basename, opts)
Matt Harbison
typing: add type hints to `mercurial.shelve`...
r52709 def _dounshelve(ui, repo, basename: bytes, opts) -> None:
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 repo = repo.unfiltered()
lock = tr = None
try:
lock = repo.lock()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tr = repo.transaction(b'unshelve', report=lambda x: None)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 oldtiprev = len(repo)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 pctx = repo[b'.']
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 # The goal is to have a commit structure like so:
# ...-> pctx -> tmpwctx -> shelvectx
# where tmpwctx is an optional commit with the user's pending changes
# and shelvectx is the unshelved changes. Then we merge it all down
# to the original pctx.
activebookmark = _backupactivebookmark(repo)
Jason R. Coombs
shelve: re-wrap now that the line fits
r50417 tmpwctx, addedbefore = _commitworkingcopychanges(ui, repo, opts, pctx)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 repo, shelvectx = _unshelverestorecommit(ui, repo, tr, basename)
_checkunshelveuntrackedproblems(ui, repo, shelvectx)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 branchtorestore = b''
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 if shelvectx.branch() != shelvectx.p1().branch():
branchtorestore = shelvectx.branch()
Augie Fackler
formatting: blacken the codebase...
r43346 shelvectx, ispartialunshelve = _rebaserestoredcommit(
ui,
repo,
opts,
tr,
oldtiprev,
basename,
pctx,
tmpwctx,
shelvectx,
branchtorestore,
activebookmark,
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
with ui.configoverride(overrides, b'unshelve'):
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 mergefiles(ui, repo, pctx, shelvectx)
restorebranch(ui, repo, branchtorestore)
Navaneeth Suresh
unshelve: clear shelvedstate and _finishunshelve() on partial unshelve...
r42932 shelvedstate.clear(repo)
_finishunshelve(repo, oldtiprev, tr, activebookmark)
dirstate: use `dirstate.change_files` to scope the change in `unshelve`...
r50948 with repo.dirstate.changing_files(repo):
_forgetunknownfiles(repo, shelvectx, addedbefore)
Navaneeth Suresh
unshelve: add interactive mode...
r42835 if not ispartialunshelve:
unshelvecleanup(ui, repo, basename, opts)
Navaneeth Suresh
shelve: move shelve extension to core...
r42744 finally:
if tr:
tr.release()
lockmod.release(lock)