mercurial@45710: 33 new changesets
33 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/bd2df58366b1 changeset: 45678:bd2df58366b1 user:Martin von Zweigbergk date:Tue Oct 06 20:37:35 2020 -0700 summary: errors: name arguments to CommandError constructor https://www.mercurial-scm.org/repo/hg/rev/65e2b64670b5 changeset: 45679:65e2b64670b5 user:Martin von Zweigbergk date:Tue Oct 06 20:45:52 2020 -0700 summary: errors: name arguments to AmbiguousCommand constructor https://www.mercurial-scm.org/repo/hg/rev/bb1a988ef4a5 changeset: 45680:bb1a988ef4a5 user:Martin von Zweigbergk date:Tue Oct 06 21:06:18 2020 -0700 summary: errors: name arguments to UnknownCommand constructor https://www.mercurial-scm.org/repo/hg/rev/a736ab681b78 changeset: 45681:a736ab681b78 user:Martin von Zweigbergk date:Thu Oct 08 15:35:44 2020 -0700 summary: errors: stop passing non-strings to Abort's constructor https://www.mercurial-scm.org/repo/hg/rev/d2e1dcd4490d changeset: 45682:d2e1dcd4490d user:Martin von Zweigbergk date:Thu Oct 08 13:37:31 2020 -0700 summary: errors: name arguments to Abort constructor https://www.mercurial-scm.org/repo/hg/rev/04aa48afab99 changeset: 45683:04aa48afab99 user:Martin von Zweigbergk date:Thu Oct 08 13:10:16 2020 -0700 summary: tests: use `git init` instead of unusual synonym `git init-db` https://www.mercurial-scm.org/repo/hg/rev/0c18493287f5 changeset: 45684:0c18493287f5 user:Martin von Zweigbergk date:Thu Oct 08 13:19:18 2020 -0700 summary: tests: set git config using `git config` for simplicity https://www.mercurial-scm.org/repo/hg/rev/57b5452a55d5 changeset: 45685:57b5452a55d5 user:Gregory Szorc date:Sun Oct 04 22:32:41 2020 -0700 summary: pyoxidizer: produce working Python 3 Windows installers (issue6366) https://www.mercurial-scm.org/repo/hg/rev/17a12f53dd72 changeset: 45686:17a12f53dd72 user:Pierre-Yves David date:Thu Oct 08 16:14:06 2020 +0200 summary: revset: add a `node` key for sorting https://www.mercurial-scm.org/repo/hg/rev/223296268c4e changeset: 45687:223296268c4e user:Martin von Zweigbergk date:Fri Oct 09 08:08:54 2020 -0700 summary: tests: fix test-url.py on py3, broken by D9179 https://www.mercurial-scm.org/repo/hg/rev/ed0ded64a8a9 changeset: 45688:ed0ded64a8a9 user:Martin von Zweigbergk date:Fri Oct 09 09:17:47 2020 -0700 summary: py3: convert an exception message to bytes https://www.mercurial-scm.org/repo/hg/rev/ef8eccefe0c3 changeset: 45689:ef8eccefe0c3 user:Gregory Szorc date:Thu Oct 08 18:02:47 2020 -0700 summary: contrib: stop installing Python 3.5 and 3.6 in Windows environment https://www.mercurial-scm.org/repo/hg/rev/7a907388a4a5 changeset: 45690:7a907388a4a5 user:Gregory Szorc date:Thu Oct 08 18:07:34 2020 -0700 summary: contrib: install Python 3.9.0 https://www.mercurial-scm.org/repo/hg/rev/eceebe3f9baf changeset: 45691:eceebe3f9baf user:Gregory Szorc date:Thu Oct 08 18:17:20 2020 -0700 summary: packaging: upgrade packages in Windows environment https://www.mercurial-scm.org/repo/hg/rev/9934920af5f7 changeset: 45692:9934920af5f7 user:Gregory Szorc date:Fri Oct 09 09:22:59 2020 -0700 summary: automation: upgrade packages in Linux environment https://www.mercurial-scm.org/repo/hg/rev/64a9423450ef changeset: 45693:64a9423450ef user:Gregory Szorc date:Fri Oct 09 09:46:03 2020 -0700 summary: automation: support running against Python 3.9 https://www.mercurial-scm.org/repo/hg/rev/d1c10d33a85c changeset: 45694:d1c10d33a85c user:Pulkit Goyal <7895pul...@gmail.com> date:Thu Oct 08 17:29:51 2020 +0530 summary: upgrade: improve documentation of matchrevlog() https://www.mercurial-scm.org/repo/hg/rev/760bb4d74aad changeset: 45695:760bb4d74aad user:Yuya Nishihara date:Wed Sep 09 15:17:26 2020 +0900 summary: grep: explicitly pass regexp to closure functions https://www.mercurial-scm.org/repo/hg/rev/de6f2afc0247 changeset: 45696:de6f2afc0247 user:Yuya Nishihara date:Wed Sep 09 15:23:49 2020 +0900 summary: grep: move match and diff logic to new module https://www.mercurial-scm.org/repo/hg/rev/494642ed3c50 changeset: 45697:494642ed3c50 user:Yuya Nishihara date:Wed Sep 09 15:56:40 2020 +0900 summary: grep: add stub class that maintains cache and states of grep operation https://www.mercurial-scm.org/repo/hg/rev/41e0cbccb260 changeset: 45698:41e0cbccb260 user:Yuya Nishihara date:Wed Sep 09 16:00:03 2020 +0900 summary: grep: move getbody() to grepsearcher class https://www.mercurial-scm.org/repo/hg/rev/888e633f0c1c changeset: 45699:888e633f0c1c user:Yuya Nishihara date:Wed Sep 09 16:04:39 2020 +
D9208: clonebundles: move a bundle of clone bundle related code to a new module
marmoute created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY In the process on general clone bundle automatically, we need to make some function available more widely. This is a good opportunity to extract a significant amount of code from `mercurial.exchange` into a new `mercurial.bundlecaches`. This make `mercurial.exchange` move under the 3K line range (hooray…). The module is called `bundlecaches` because I expect it to be eventually useful for more than just clone bundle (like pull bunbles). REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D9208 AFFECTED FILES hgext/lfs/__init__.py mercurial/bundlecaches.py mercurial/commands.py mercurial/exchange.py mercurial/wireprotov1server.py tests/flagprocessorext.py tests/test-pull-bundle.t CHANGE DETAILS diff --git a/tests/test-pull-bundle.t b/tests/test-pull-bundle.t --- a/tests/test-pull-bundle.t +++ b/tests/test-pull-bundle.t @@ -52,7 +52,7 @@ > 1.hg BUNDLESPEC=bzip2-v2 heads=ed1b79f46b9a29f5a6efa59cf12fcfca43bead5a bases=bbd179dfa0a71671c253b3ae0aa1513b60d199fa > 0.hg BUNDLESPEC=gzip-v2 heads=bbd179dfa0a71671c253b3ae0aa1513b60d199fa > EOF - $ hg --config blackbox.track=debug --debug serve -p $HGPORT2 -d --pid-file=../repo.pid + $ hg --config blackbox.track=debug --debug serve -p $HGPORT2 -d --pid-file=../repo.pid -E ../error.txt listening at http://*:$HGPORT2/ (bound to $LOCALIP:$HGPORT2) (glob) (?) $ cat ../repo.pid >> $DAEMON_PIDS $ cd .. @@ -64,6 +64,7 @@ new changesets bbd179dfa0a7 (1 drafts) updating to branch default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cat error.txt $ cd repo.pullbundle $ hg pull -r 1 pulling from http://localhost:$HGPORT2/ diff --git a/tests/flagprocessorext.py b/tests/flagprocessorext.py --- a/tests/flagprocessorext.py +++ b/tests/flagprocessorext.py @@ -6,8 +6,8 @@ import zlib from mercurial import ( +bundlecaches, changegroup, -exchange, extensions, revlog, util, @@ -134,8 +134,8 @@ revlog.REVIDX_FLAGS_ORDER.extend(flags) # Teach exchange to use changegroup 3 -for k in exchange._bundlespeccontentopts.keys(): -exchange._bundlespeccontentopts[k][b"cg.version"] = b"03" +for k in bundlecaches._bundlespeccontentopts.keys(): +bundlecaches._bundlespeccontentopts[k][b"cg.version"] = b"03" # Register flag processors for each extension flagutil.addflagprocessor( diff --git a/mercurial/wireprotov1server.py b/mercurial/wireprotov1server.py --- a/mercurial/wireprotov1server.py +++ b/mercurial/wireprotov1server.py @@ -19,6 +19,7 @@ from . import ( bundle2, +bundlecaches, changegroup as changegroupmod, discovery, encoding, @@ -387,8 +388,8 @@ manifest = repo.vfs.tryread(b'pullbundles.manifest') if not manifest: return None -res = exchange.parseclonebundlesmanifest(repo, manifest) -res = exchange.filterclonebundleentries(repo, res) +res = bundlecaches.parseclonebundlesmanifest(repo, manifest) +res = bundlecaches.filterclonebundleentries(repo, res) if not res: return None cl = repo.unfiltered().changelog diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -16,10 +16,10 @@ nullid, nullrev, ) -from .thirdparty import attr from . import ( bookmarks as bookmod, bundle2, +bundlecaches, changegroup, discovery, error, @@ -34,7 +34,6 @@ pycompat, requirements, scmutil, -sslutil, streamclone, url as urlmod, util, @@ -50,202 +49,6 @@ _NARROWACL_SECTION = b'narrowacl' -# Maps bundle version human names to changegroup versions. -_bundlespeccgversions = { -b'v1': b'01', -b'v2': b'02', -b'packed1': b's1', -b'bundle2': b'02', # legacy -} - -# Maps bundle version with content opts to choose which part to bundle -_bundlespeccontentopts = { -b'v1': { -b'changegroup': True, -b'cg.version': b'01', -b'obsolescence': False, -b'phases': False, -b'tagsfnodescache': False, -b'revbranchcache': False, -}, -b'v2': { -b'changegroup': True, -b'cg.version': b'02', -b'obsolescence': False, -b'phases': False, -b'tagsfnodescache': True, -b'revbranchcache': True, -}, -b'packed1': {b'cg.version': b's1'}, -} -_bundlespeccontentopts[b'bundle2'] = _bundlespeccontentopts[b'v2'] - -_bundlespecvariants = { -b"streamv2": { -b"changegroup": False, -b"streamv2": True, -b"tagsfnodescache": False, -b"revbranchcache": False, -} -} - -# Compression engines allowed in version 1. THIS SHOULD NEVER CHANGE. -_bundlespecv1compengines = {b'gzip', b'bzip2', b'none'} - - -@attr.s -class bundlespec(ob
D9209: clonebundle: move the manifest filename to a constant
marmoute created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY I am about to add more reference to it, so I would rather have it an explicit constant. This allow to unify various call too. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D9209 AFFECTED FILES hgext/clonebundles.py mercurial/bundlecaches.py mercurial/localrepo.py mercurial/wireprotov1server.py CHANGE DETAILS diff --git a/mercurial/wireprotov1server.py b/mercurial/wireprotov1server.py --- a/mercurial/wireprotov1server.py +++ b/mercurial/wireprotov1server.py @@ -273,7 +273,7 @@ data center given the client's IP address. """ return wireprototypes.bytesresponse( -repo.vfs.tryread(b'clonebundles.manifest') +repo.vfs.tryread(bundlecaches.CB_MANIFEST_FILE) ) diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -31,6 +31,7 @@ bookmarks, branchmap, bundle2, +bundlecaches, changegroup, color, commit, @@ -299,7 +300,7 @@ return self._caps def clonebundles(self): -return self._repo.tryread(b'clonebundles.manifest') +return self._repo.tryread(bundlecaches.CB_MANIFEST_FILE) def debugwireargs(self, one, two, three=None, four=None, five=None): """Used to test argument passing over the wire""" diff --git a/mercurial/bundlecaches.py b/mercurial/bundlecaches.py --- a/mercurial/bundlecaches.py +++ b/mercurial/bundlecaches.py @@ -16,6 +16,8 @@ urlreq = util.urlreq +CB_MANIFEST_FILE = b'clonebundles.manifest' + @attr.s class bundlespec(object): diff --git a/hgext/clonebundles.py b/hgext/clonebundles.py --- a/hgext/clonebundles.py +++ b/hgext/clonebundles.py @@ -205,6 +205,7 @@ from __future__ import absolute_import from mercurial import ( +bundlecaches, extensions, wireprotov1server, ) @@ -218,7 +219,7 @@ # Only advertise if a manifest exists. This does add some I/O to requests. # But this should be cheaper than a wasted network round trip due to # missing file. -if repo.vfs.exists(b'clonebundles.manifest'): +if repo.vfs.exists(bundlecaches.CB_MANIFEST_FILE): caps.append(b'clonebundles') return caps To: marmoute, #hg-reviewers Cc: mercurial-patches, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D9212: procutil: allow to specify arbitrary stdin bytes to runbgcommand
marmoute created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY For automatic clonebundles generation I need to pass arbitrary large amount of data to the process (eg: common nodes, target nodes). I am updating the `runbgcommand` to allow for this. Previously not stdin input was possible, now, one can provide raw bytes and they will be feed to the command through an unnamed temporary files. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D9212 AFFECTED FILES mercurial/utils/procutil.py CHANGE DETAILS diff --git a/mercurial/utils/procutil.py b/mercurial/utils/procutil.py --- a/mercurial/utils/procutil.py +++ b/mercurial/utils/procutil.py @@ -635,21 +635,35 @@ stderr=None, ensurestart=True, record_wait=None, +stdin_bytes=None, ): '''Spawn a command without waiting for it to finish.''' # we can't use close_fds *and* redirect stdin. I'm not sure that we # need to because the detached process has no console connection. -p = subprocess.Popen( -tonativestr(script), -shell=shell, -env=tonativeenv(env), -close_fds=True, -creationflags=_creationflags, -stdout=stdout, -stderr=stderr, -) -if record_wait is not None: -record_wait(p.wait) + +try: +stdin = None +if stdin_bytes is not None: +stdin = pycompat.unnamedtempfile() +stdin.write(stdin_bytes) +stdin.flush() +stdin.seek(0) + +p = subprocess.Popen( +tonativestr(script), +shell=shell, +env=tonativeenv(env), +close_fds=True, +creationflags=_creationflags, +stdin=stdin, +stdout=stdout, +stderr=stderr, +) +if record_wait is not None: +record_wait(p.wait) +finally: +if stdin is not None: +stdin.close() else: @@ -662,6 +676,7 @@ stderr=None, ensurestart=True, record_wait=None, +stdin_bytes=None, ): '''Spawn a command without waiting for it to finish. @@ -722,15 +737,21 @@ if record_wait is None: # Start a new session os.setsid() +# connect stdin to devnull to make sure the subprocess can't +# muck up that stream for mercurial. +if stdin_bytes is None: +stdin = open(os.devnull, b'r') +else: +stdin = pycompat.unnamedtempfile() +stdin.write(stdin_bytes) +stdin.flush() +stdin.seek(0) -stdin = open(os.devnull, b'r') if stdout is None: stdout = open(os.devnull, b'w') if stderr is None: stderr = open(os.devnull, b'w') -# connect stdin to devnull to make sure the subprocess can't -# muck up that stream for mercurial. p = subprocess.Popen( cmd, shell=shell, @@ -754,5 +775,6 @@ finally: # mission accomplished, this child needs to exit and not # continue the hg process here. +stdin.close() if record_wait is None: os._exit(returncode) To: marmoute, #hg-reviewers Cc: mercurial-patches, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D9211: pycompat: add an entry for unnamedtmpfile
marmoute created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY I am going to use unnamed temporary files to pass arbitrarily large input data to worker creating bundles. To do so, I need a unified API that work on py2 and py3. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D9211 AFFECTED FILES mercurial/pycompat.py CHANGE DETAILS diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py --- a/mercurial/pycompat.py +++ b/mercurial/pycompat.py @@ -506,6 +506,17 @@ return tempfile.mkstemp(suffix, prefix, dir) +# TemporaryFile does not support an "encoding=" argument on python2. +# This wrapper file are always open in byte mode. +def unnamedtempfile(mode=None, *args, **kwargs): +if mode is None: +mode = b'w+b' +else: +mode = sysstr(mode) +assert 'b' in mode +return tempfile.TemporaryFile(mode, *args, **kwargs) + + # NamedTemporaryFile does not support an "encoding=" argument on python2. # This wrapper file are always open in byte mode. def namedtempfile( To: marmoute, #hg-reviewers Cc: mercurial-patches, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D9210: pycompat: update comment about unnamedtempfile
marmoute created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY I found the comment clearer. I end up having to think about this for `TemporaryFile` and I update that one in the process. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D9210 AFFECTED FILES mercurial/pycompat.py CHANGE DETAILS diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py --- a/mercurial/pycompat.py +++ b/mercurial/pycompat.py @@ -506,7 +506,8 @@ return tempfile.mkstemp(suffix, prefix, dir) -# mode must include 'b'ytes as encoding= is not supported +# NamedTemporaryFile does not support an "encoding=" argument on python2. +# This wrapper file are always open in byte mode. def namedtempfile( mode=b'w+b', bufsize=-1, suffix=b'', prefix=b'tmp', dir=None, delete=True ): To: marmoute, #hg-reviewers Cc: mercurial-patches, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D9207: record: when backing up, avoid generating very long filenames
spectral created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY If the original file's path is longer than the individual filename maximum length (256 on Linux, I believe?), then this mechanism of "replace slashes with underscores" causes an error. Now, we'll produce just the "basename" of the file, plus some stuff to ensure it's unique. This can be potentially confusing for users if there's a file with the same name in multiple directories, but I suspect that this is better than just breaking. Example: `/a/long/path/to/somefile.txt` used to be backed up as `/.hg/record-backups/a_long_path_to_somefile.txt.abcdefgh`, it will now be backed up as `/.hg/record-backups/somefile.txt.abcdefgh` We could do the naive thing (what we were doing before) and have it to doing something with either subdirectories (`/a/long/path/to/somefile.txt.abcdefgh` or minimize #dirs with `/a_long_path/to_somefile.txt.abcdefgh`), prefix-truncated paths (such as `/__ath_to_somefile.txt.abcdefgh`, where that `__` elides enough to get us under 255 chars (counting the +9 we need to add!)), or hash-of-dirname (`//somefile.txt.abcdefgh`), but ultimately every option felt over engineered and that it would be more likely to cause problems than it would be to solve any, especially if it was conditional on directory length. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D9207 AFFECTED FILES mercurial/cmdutil.py CHANGE DETAILS diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -558,7 +558,7 @@ # backup continues for f in tobackup: fd, tmpname = pycompat.mkstemp( -prefix=f.replace(b'/', b'_') + b'.', dir=backupdir +prefix=os.path.basename(f) + b'.', dir=backupdir ) os.close(fd) ui.debug(b'backup %r as %r\n' % (f, tmpname)) To: spectral, #hg-reviewers Cc: mercurial-patches, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D9206: posix: avoid a leaked file descriptor in a unix domain socket exception case
mharbison72 created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D9206 AFFECTED FILES mercurial/posix.py CHANGE DETAILS diff --git a/mercurial/posix.py b/mercurial/posix.py --- a/mercurial/posix.py +++ b/mercurial/posix.py @@ -764,10 +764,14 @@ # platforms (see sys/un.h) dirname, basename = os.path.split(path) bakwdfd = None -if dirname: -bakwdfd = os.open(b'.', os.O_DIRECTORY) -os.chdir(dirname) -sock.bind(basename) -if bakwdfd: -os.fchdir(bakwdfd) -os.close(bakwdfd) + +try: +if dirname: +bakwdfd = os.open(b'.', os.O_DIRECTORY) +os.chdir(dirname) +sock.bind(basename) +if bakwdfd: +os.fchdir(bakwdfd) +finally: +if bakwdfd: +os.close(bakwdfd) To: mharbison72, #hg-reviewers Cc: mercurial-patches, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D9205: posix: use context managers in a couple of places
mharbison72 created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D9205 AFFECTED FILES mercurial/posix.py CHANGE DETAILS diff --git a/mercurial/posix.py b/mercurial/posix.py --- a/mercurial/posix.py +++ b/mercurial/posix.py @@ -144,26 +144,24 @@ if l: if not stat.S_ISLNK(s): # switch file to link -fp = open(f, b'rb') -data = fp.read() -fp.close() +with open(f, b'rb') as fp: +data = fp.read() unlink(f) try: os.symlink(data, f) except OSError: # failed to make a link, rewrite file -fp = open(f, b"wb") -fp.write(data) -fp.close() +with open(f, b"wb") as fp: +fp.write(data) + # no chmod needed at this point return if stat.S_ISLNK(s): # switch link to file data = os.readlink(f) unlink(f) -fp = open(f, b"wb") -fp.write(data) -fp.close() +with open(f, b"wb") as fp: +fp.write(data) s = 0o666 & ~umask # avoid restatting for chmod sx = s & 0o100 To: mharbison72, #hg-reviewers Cc: mercurial-patches, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D9204: tests: add notes about broken `hg log --follow ` with copies in extras
martinvonz created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REVISION SUMMARY I also removed some unnecessary `#if no-changeset` where the `#else` was the same :P REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D9204 AFFECTED FILES tests/test-copies-chain-merge.t CHANGE DETAILS diff --git a/tests/test-copies-chain-merge.t b/tests/test-copies-chain-merge.t --- a/tests/test-copies-chain-merge.t +++ b/tests/test-copies-chain-merge.t @@ -402,29 +402,15 @@ Log output should not include a merge commit as it did not happen -#if no-changeset - $ hg log -Gfr 'desc("mBDm-0")' d - o 8 d-2 re-add d - | - ~ -#else $ hg log -Gfr 'desc("mBDm-0")' d o 8 d-2 re-add d | ~ -#endif -#if no-changeset $ hg log -Gfr 'desc("mDBm-0")' d o 8 d-2 re-add d | ~ -#else - $ hg log -Gfr 'desc("mDBm-0")' d - o 8 d-2 re-add d - | - ~ -#endif $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBDm-0")' M b @@ -669,6 +655,7 @@ o 0 i-0 initial commit: a b h #else +BROKEN: `hg log --follow ` relies on filelog metadata to work $ hg log -Gfr 'desc("mBFm-0")' d o 22 f-2: rename i -> d | @@ -684,6 +671,7 @@ o 0 i-0 initial commit: a b h #else +BROKEN: `hg log --follow ` relies on filelog metadata to work $ hg log -Gfr 'desc("mFBm-0")' d o 22 f-2: rename i -> d | @@ -773,6 +761,7 @@ o 0 i-0 initial commit: a b h #else +BROKEN: `hg log --follow ` relies on filelog metadata to work $ hg log -Gfr 'desc("mDGm-0")' d o26 mDGm-0 simple merge - one way |\ @@ -801,6 +790,7 @@ o 0 i-0 initial commit: a b h #else +BROKEN: `hg log --follow ` relies on filelog metadata to work $ hg log -Gfr 'desc("mDGm-0")' d o26 mDGm-0 simple merge - one way |\ @@ -909,6 +899,7 @@ o 0 i-0 initial commit: a b h #else +BROKEN: `hg log --follow ` relies on filelog metadata to work $ hg log -Gfr 'desc("mFGm-0")' d o28 mFGm-0 simple merge - one way |\ @@ -938,6 +929,7 @@ o 0 i-0 initial commit: a b h #else +BROKEN: `hg log --follow ` relies on filelog metadata to work $ hg log -Gfr 'desc("mGFm-0")' d @29 mGFm-0 simple merge - the other way |\ To: martinvonz, #hg-reviewers Cc: mercurial-patches, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 7 of 7] revset: add diff(pattern) predicate for "grep --diff"
# HG changeset patch # User Yuya Nishihara # Date 1599556584 -32400 # Tue Sep 08 18:16:24 2020 +0900 # Node ID 86c34dc393abb0cd636ec03a2e81a26f4b0694d5 # Parent c71d4b4018af62936283b28ce4ed70cc9ea33840 revset: add diff(pattern) predicate for "grep --diff" I find this is useful in GUI log viewer since the tool only needs to support "log -rREV" command. This is basic implementation. Windowed search is not implemented since it wouldn't work pretty well with the smartset API. And filename matcher is not supported because the syntax isn't determined. My idea is to add handling of diff(pattern, file(..)) and diff(pattern, follow(..)), which will then be evolved to a full revset+matcher combinator support: x & diff(pattern, y & z) = y & z builds (revs(y) & revs(z), matcher(y) & matcher(z)) pair, and narrows the search space of diff() diff() returns matched (revs, matcher) pair revs and matcher will be combined respectively by &-operator, and the matcher will optionally be used to filter "hg log -p" output The predicate name "diff()" wouldn't be great, but grep() is already used. Another options I can think of are "grepdiff()" and "containsdiff()". Naming suggestions are welcome. diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -17,6 +17,7 @@ from . import ( diffutil, encoding, error, +grep as grepmod, hbisect, match as matchmod, node, @@ -993,6 +994,45 @@ def destination(repo, subset, x): ) +@predicate(b'diff(pattern)', weight=110) +def diff(repo, subset, x): +"""Search revision differences for when the pattern was added or removed. + +The pattern may be a substring literal or a regular expression. See +:hg:`help revisions.patterns`. +""" +args = getargsdict(x, b'diff', b'pattern') +if b'pattern' not in args: +# i18n: "diff" is a keyword +raise error.ParseError(_(b'diff takes at least 1 argument')) + +pattern = getstring(args[b'pattern'], _(b'diff requires a string pattern')) +regexp = stringutil.substringregexp(pattern, re.M) + +# TODO: add support for file pattern and --follow. For example, +# diff(pattern[, set]) where set may be file(pattern) or follow(pattern), +# and we'll eventually add a support for narrowing files by revset? +fmatch = matchmod.always() + +def makefilematcher(ctx): +return fmatch + +# TODO: search in a windowed way +searcher = grepmod.grepsearcher(repo.ui, repo, regexp, diff=True) + +def testdiff(rev): +# consume the generator to discard revfiles/matches cache +found = False +for fn, ctx, pstates, states in searcher.searchfiles( +baseset([rev]), makefilematcher +): +if next(grepmod.difflinestates(pstates, states), None): +found = True +return found + +return subset.filter(testdiff, condrepr=(b'', pattern)) + + @predicate(b'contentdivergent()', safe=True) def contentdivergent(repo, subset, x): """ diff --git a/tests/test-grep.t b/tests/test-grep.t --- a/tests/test-grep.t +++ b/tests/test-grep.t @@ -21,6 +21,18 @@ pattern error grep: invalid match pattern: nothing to repeat* (glob) [1] +invalid revset syntax + + $ hg log -r 'diff()' + hg: parse error: diff takes at least 1 argument + [255] + $ hg log -r 'diff(:)' + hg: parse error: diff requires a string pattern + [255] + $ hg log -r 'diff("re:**test**")' + hg: parse error: invalid regular expression: nothing to repeat* (glob) + [255] + simple $ hg grep -r tip:0 '.*' @@ -553,6 +565,18 @@ Test wdir color:2:-:orange color:1:+:orange +revset predicate for "grep --diff" + + $ hg log -qr 'diff("re:^bl...$")' + 0:203191eb5e21 + $ hg log -qr 'diff("orange")' + 1:7c585a21e0d1 + 2:11bd8bc8d653 + 3:e0116d3829f8 + $ hg log -qr '2:0 & diff("orange")' + 2:11bd8bc8d653 + 1:7c585a21e0d1 + test substring match: '^' should only match at the beginning $ hg grep -r tip:0 '^.' --config extensions.color= --color debug ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 6 of 7] stringutil: add function to compile stringmatcher pattern into regexp
# HG changeset patch # User Yuya Nishihara # Date 1601898039 -32400 # Mon Oct 05 20:40:39 2020 +0900 # Node ID c71d4b4018af62936283b28ce4ed70cc9ea33840 # Parent 18bb913c45acf3f8d1fcbc90e22853f8e5f8e767 stringutil: add function to compile stringmatcher pattern into regexp Prepares for adding a revset predicate for "grep --diff". The grep logic needs a regexp object instead of a match function. diff --git a/mercurial/utils/stringutil.py b/mercurial/utils/stringutil.py --- a/mercurial/utils/stringutil.py +++ b/mercurial/utils/stringutil.py @@ -376,6 +376,58 @@ def stringmatcher(pattern, casesensitive raise error.ProgrammingError(b'unhandled pattern kind: %s' % kind) +def substringregexp(pattern, flags=0): +"""Build a regexp object from a string pattern possibly starting with +'re:' or 'literal:' prefix. + +helper for tests: +>>> def test(pattern, *tests): +... regexp = substringregexp(pattern) +... return [bool(regexp.search(t)) for t in tests] +>>> def itest(pattern, *tests): +... regexp = substringregexp(pattern, remod.I) +... return [bool(regexp.search(t)) for t in tests] + +substring matching (no prefix): +>>> test(b'bcde', b'abc', b'def', b'abcdefg') +[False, False, True] + +substring pattern should be escaped: +>>> substringregexp(b'.bc').pattern +'.bc' +>>> test(b'.bc', b'abc', b'def', b'abcdefg') +[False, False, False] + +regex matching ('re:' prefix) +>>> test(b're:a.+b', b'nomatch', b'fooadef', b'fooadefbar') +[False, False, True] + +force substring matches ('literal:' prefix) +>>> test(b'literal:re:foobar', b'foobar', b're:foobar') +[False, True] + +case insensitive literal matches +>>> itest(b'BCDE', b'abc', b'def', b'abcdefg') +[False, False, True] + +case insensitive regex matches +>>> itest(b're:A.+b', b'nomatch', b'fooadef', b'fooadefBar') +[False, False, True] +""" +kind, pattern = _splitpattern(pattern) +if kind == b're': +try: +return remod.compile(pattern, flags) +except remod.error as e: +raise error.ParseError( +_(b'invalid regular expression: %s') % forcebytestr(e) +) +elif kind == b'literal': +return remod.compile(remod.escape(pattern), flags) + +raise error.ProgrammingError(b'unhandled pattern kind: %s' % kind) + + def shortuser(user): """Return a short representation of a user name or email address.""" f = user.find(b'@') ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 5 of 7] py3: fix stringmatcher() to byte-stringify exception message
# HG changeset patch # User Yuya Nishihara # Date 1602681048 -32400 # Wed Oct 14 22:10:48 2020 +0900 # Node ID 18bb913c45acf3f8d1fcbc90e22853f8e5f8e767 # Parent b6c30689b9fe9e5f53bceb7913c71ae98109c804 py3: fix stringmatcher() to byte-stringify exception message Spotted while writing regexp variant of stringmatcher(). diff --git a/mercurial/utils/stringutil.py b/mercurial/utils/stringutil.py --- a/mercurial/utils/stringutil.py +++ b/mercurial/utils/stringutil.py @@ -361,7 +361,9 @@ def stringmatcher(pattern, casesensitive flags = remod.I regex = remod.compile(pattern, flags) except remod.error as e: -raise error.ParseError(_(b'invalid regular expression: %s') % e) +raise error.ParseError( +_(b'invalid regular expression: %s') % forcebytestr(e) +) return kind, pattern, regex.search elif kind == b'literal': if casesensitive: diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -1448,6 +1448,9 @@ test author (string '(')) hg: parse error: invalid match pattern: (unbalanced parenthesis|missing \),.*) (re) [255] + $ log 'desc("re:(")' + hg: parse error: invalid regular expression: (unbalanced parenthesis|missing \),.*) (re) + [255] $ try 'grep("\bissue\d+")' (func (symbol 'grep') ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 4 of 7] stringutil: extract helper function that splits stringmatcher() pattern
# HG changeset patch # User Yuya Nishihara # Date 1601898814 -32400 # Mon Oct 05 20:53:34 2020 +0900 # Node ID b6c30689b9fe9e5f53bceb7913c71ae98109c804 # Parent 5b3013b8e40a903e7d31196c1e00877120339242 stringutil: extract helper function that splits stringmatcher() pattern diff --git a/mercurial/utils/stringutil.py b/mercurial/utils/stringutil.py --- a/mercurial/utils/stringutil.py +++ b/mercurial/utils/stringutil.py @@ -307,6 +307,14 @@ def binary(s): return bool(s and b'\0' in s) +def _splitpattern(pattern): +if pattern.startswith(b're:'): +return b're', pattern[3:] +elif pattern.startswith(b'literal:'): +return b'literal', pattern[8:] +return b'literal', pattern + + def stringmatcher(pattern, casesensitive=True): """ accepts a string, possibly starting with 're:' or 'literal:' prefix. @@ -345,8 +353,8 @@ def stringmatcher(pattern, casesensitive >>> itest(b'ABCDEFG', b'abc', b'def', b'abcdefg') ('literal', 'ABCDEFG', [False, False, True]) """ -if pattern.startswith(b're:'): -pattern = pattern[3:] +kind, pattern = _splitpattern(pattern) +if kind == b're': try: flags = 0 if not casesensitive: @@ -354,16 +362,16 @@ def stringmatcher(pattern, casesensitive regex = remod.compile(pattern, flags) except remod.error as e: raise error.ParseError(_(b'invalid regular expression: %s') % e) -return b're', pattern, regex.search -elif pattern.startswith(b'literal:'): -pattern = pattern[8:] +return kind, pattern, regex.search +elif kind == b'literal': +if casesensitive: +match = pattern.__eq__ +else: +ipat = encoding.lower(pattern) +match = lambda s: ipat == encoding.lower(s) +return kind, pattern, match -match = pattern.__eq__ - -if not casesensitive: -ipat = encoding.lower(pattern) -match = lambda s: ipat == encoding.lower(s) -return b'literal', pattern, match +raise error.ProgrammingError(b'unhandled pattern kind: %s' % kind) def shortuser(user): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 7] grep: extract main search loop as searcher method
# HG changeset patch # User Yuya Nishihara # Date 1599639458 -32400 # Wed Sep 09 17:17:38 2020 +0900 # Node ID 5b3013b8e40a903e7d31196c1e00877120339242 # Parent 09a598f9d9790918f47f66b6ce5e51f198510289 grep: extract main search loop as searcher method Still displayer part is in commands.grep(), the core grep logic is now reusable. I'll revisit the displayer stuff later since it will be another long series. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -3403,8 +3403,6 @@ def grep(ui, repo, pattern, *pats, **opt ) getfile = searcher._getfile -matches = searcher._matches -copies = searcher._copies uipathfn = scmutil.getuipathfn(repo) @@ -3514,8 +3512,6 @@ def grep(ui, repo, pattern, *pats, **opt fm.data(matched=False) fm.end() -skip = searcher._skip -revfiles = searcher._revfiles found = False wopts = logcmdutil.walkopts( @@ -3532,29 +3528,11 @@ def grep(ui, repo, pattern, *pats, **opt ui.pager(b'grep') fm = ui.formatter(b'grep', opts) -for ctx in scmutil.walkchangerevs( -repo, revs, makefilematcher, searcher._prep -): -rev = ctx.rev() -parent = ctx.p1().rev() -for fn in sorted(revfiles.get(rev, [])): -states = matches[rev][fn] -copy = copies.get(rev, {}).get(fn) -if fn in skip: -if copy: -skip.add(copy) -continue -pstates = matches.get(parent, {}).get(copy or fn, []) -if pstates or states: -r = display(fm, fn, ctx, pstates, states) -found = found or r -if r and not diff and not all_files: -searcher.skipfile(fn, rev) -del revfiles[rev] -# We will keep the matches dict for the duration of the window -# clear the matches dict once the window is over -if not revfiles: -matches.clear() +for fn, ctx, pstates, states in searcher.searchfiles(revs, makefilematcher): +r = display(fm, fn, ctx, pstates, states) +found = found or r +if r and not diff and not all_files: +searcher.skipfile(fn, ctx.rev()) fm.end() return not found diff --git a/mercurial/grep.py b/mercurial/grep.py --- a/mercurial/grep.py +++ b/mercurial/grep.py @@ -115,6 +115,34 @@ class grepsearcher(object): if copy: self._skip.add(copy) +def searchfiles(self, revs, makefilematcher): +"""Walk files and revisions to yield (fn, ctx, pstates, states) +matches + +states is a list of linestate objects. pstates may be empty unless +diff is True. +""" +for ctx in scmutil.walkchangerevs( +self._repo, revs, makefilematcher, self._prep +): +rev = ctx.rev() +parent = ctx.p1().rev() +for fn in sorted(self._revfiles.get(rev, [])): +states = self._matches[rev][fn] +copy = self._copies.get(rev, {}).get(fn) +if fn in self._skip: +if copy: +self._skip.add(copy) +continue +pstates = self._matches.get(parent, {}).get(copy or fn, []) +if pstates or states: +yield fn, ctx, pstates, states +del self._revfiles[rev] +# We will keep the matches dict for the duration of the window +# clear the matches dict once the window is over +if not self._revfiles: +self._matches.clear() + def _grepbody(self, fn, rev, body): self._matches[rev].setdefault(fn, []) m = self._matches[rev][fn] ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 7] scmutil: move walkchangerevs() from cmdutil
# HG changeset patch # User Yuya Nishihara # Date 1601785077 -32400 # Sun Oct 04 13:17:57 2020 +0900 # Node ID 09a598f9d9790918f47f66b6ce5e51f198510289 # Parent d36d703c291e45670245384440993ff70ad17da4 scmutil: move walkchangerevs() from cmdutil It's no longer a command-level function, but a pure helper to walk revisions in a windowed way. This change will help eliminate reverse dependency of revset.py -> grep.py -> cmdutil.py in future patches. diff --git a/hgext/churn.py b/hgext/churn.py --- a/hgext/churn.py +++ b/hgext/churn.py @@ -23,6 +23,7 @@ from mercurial import ( patch, pycompat, registrar, +scmutil, ) cmdtable = {} @@ -98,7 +99,7 @@ def countrate(ui, repo, amap, *pats, **o exclude_pats=opts[b'exclude'], ) revs, makefilematcher = logcmdutil.makewalker(repo, wopts) -for ctx in cmdutil.walkchangerevs(repo, revs, makefilematcher, prep): +for ctx in scmutil.walkchangerevs(repo, revs, makefilematcher, prep): continue progress.complete() diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -2240,55 +2240,6 @@ def finddate(ui, repo, date): return b'%d' % rev -def increasingwindows(windowsize=8, sizelimit=512): -while True: -yield windowsize -if windowsize < sizelimit: -windowsize *= 2 - - -def walkchangerevs(repo, revs, makefilematcher, prepare): -'''Iterate over files and the revs in a "windowed" way. - -Callers most commonly need to iterate backwards over the history -in which they are interested. Doing so has awful (quadratic-looking) -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. - -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.''' - -if not revs: -return [] -change = repo.__getitem__ - -def iterate(): -it = iter(revs) -stopiteration = False -for windowsize in increasingwindows(): -nrevs = [] -for i in pycompat.xrange(windowsize): -rev = next(it, None) -if rev is None: -stopiteration = True -break -nrevs.append(rev) -for rev in sorted(nrevs): -ctx = change(rev) -prepare(ctx, makefilematcher(ctx)) -for rev in nrevs: -yield change(rev) - -if stopiteration: -break - -return iterate() - - def add(ui, repo, match, prefix, uipathfn, explicitonly, **opts): bad = [] diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -3532,7 +3532,7 @@ def grep(ui, repo, pattern, *pats, **opt ui.pager(b'grep') fm = ui.formatter(b'grep', opts) -for ctx in cmdutil.walkchangerevs( +for ctx in scmutil.walkchangerevs( repo, revs, makefilematcher, searcher._prep ): rev = ctx.rev() diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -760,6 +760,55 @@ def revrange(repo, specs, localalias=Non return repo.anyrevs(allspecs, user=True, localalias=localalias) +def increasingwindows(windowsize=8, sizelimit=512): +while True: +yield windowsize +if windowsize < sizelimit: +windowsize *= 2 + + +def walkchangerevs(repo, revs, makefilematcher, prepare): +'''Iterate over files and the revs in a "windowed" way. + +Callers most commonly need to iterate backwards over the history +in which they are interested. Doing so has awful (quadratic-looking) +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. + +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.''' + +if not revs: +return [] +change = repo.__getitem__ + +def iterate(): +it = iter(revs) +stopiteration = False +for windowsize in increasingwindows(): +nrevs = [] +for i in pycompat.xrange(windowsize): +rev = next(it, None) +if rev is None: +stopiteration = True +break +nrevs.append(rev) +for rev in sorted(nrevs): +ctx = change(rev) +prepare(ctx, makefilem
[PATCH 1 of 7] grep: extract public function to register file to be skipped
# HG changeset patch # User Yuya Nishihara # Date 1599638684 -32400 # Wed Sep 09 17:04:44 2020 +0900 # Node ID d36d703c291e45670245384440993ff70ad17da4 # Parent 0428978bca22dc1173577ca6247d588182805b78 grep: extract public function to register file to be skipped The main grep loop will be extracted to a searcher method, but this skipping condition depends on the result of display() function. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -3549,9 +3549,7 @@ def grep(ui, repo, pattern, *pats, **opt r = display(fm, fn, ctx, pstates, states) found = found or r if r and not diff and not all_files: -skip.add(fn) -if copy: -skip.add(copy) +searcher.skipfile(fn, rev) del revfiles[rev] # We will keep the matches dict for the duration of the window # clear the matches dict once the window is over diff --git a/mercurial/grep.py b/mercurial/grep.py --- a/mercurial/grep.py +++ b/mercurial/grep.py @@ -107,6 +107,14 @@ class grepsearcher(object): self._skip = set() self._revfiles = {} +def skipfile(self, fn, rev): +"""Exclude the given file (and the copy at the specified revision) +from future search""" +copy = self._copies.get(rev, {}).get(fn) +self._skip.add(fn) +if copy: +self._skip.add(copy) + def _grepbody(self, fn, rev, body): self._matches[rev].setdefault(fn, []) m = self._matches[rev][fn] ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH V2] mergestate: add `allextras()` to get all extras
On Wed, 14 Oct 2020 13:47:17 +0530, Pulkit Goyal wrote: > # HG changeset patch > # User Pulkit Goyal <7895pul...@gmail.com> > # Date 1602313984 -19800 > # Sat Oct 10 12:43:04 2020 +0530 > # Node ID 4884022d4ad9b918f863946f6557fac47c664af7 > # Parent 04de8a1ec08f380fda794dda3b3f2ed1ccfd442b > # EXP-Topic merge-newnode-final > mergestate: add `allextras()` to get all extras Queued, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH V2] mergestate: document `o` merge record state in _mergestate_base docs
On Wed, 14 Oct 2020 13:40:43 +0530, Pulkit Goyal wrote: > # HG changeset patch > # User Pulkit Goyal <7895pul...@gmail.com> > # Date 1601991694 -19800 > # Tue Oct 06 19:11:34 2020 +0530 > # Node ID c3ffbf50856b954e3a8be968b9a93000b03b1843 > # Parent 04de8a1ec08f380fda794dda3b3f2ed1ccfd442b > mergestate: document `o` merge record state in _mergestate_base docs Queued, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH V2] mergestate: make filename argument optional in _mergestate_base.extras()
On Wed, Oct 14, 2020 at 1:46 PM Pulkit Goyal <7895pul...@gmail.com> wrote: > > # HG changeset patch > # User Pulkit Goyal <7895pul...@gmail.com> > # Date 1602313984 -19800 > # Sat Oct 10 12:43:04 2020 +0530 > # Node ID 16290c7c8eea7f859aade5c8c2f9af357da97164 > # Parent 04de8a1ec08f380fda794dda3b3f2ed1ccfd442b > # EXP-Topic merge-newnode-final > mergestate: make filename argument optional in _mergestate_base.extras() > > Earlier `extras()` can only be used for getting extra for a file. However at > couple of places in code, we wanted to iterate over all the extras stored with > the mergestate and they were accessing the private `_stateextras`. > > Now, if filename is not passed, we return all the extras. > > Differential Revision: https://phab.mercurial-scm.org/D9190 Kindly ignore this. Forgot to update commit message before sending. Sent another one with updated commit message. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH V2] mergestate: add `allextras()` to get all extras
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1602313984 -19800 # Sat Oct 10 12:43:04 2020 +0530 # Node ID 4884022d4ad9b918f863946f6557fac47c664af7 # Parent 04de8a1ec08f380fda794dda3b3f2ed1ccfd442b # EXP-Topic merge-newnode-final mergestate: add `allextras()` to get all extras `extras()` can only be used for getting extra for a file. However at couple of places in code, we wanted to iterate over all the extras stored with the mergestate and they were accessing the private `_stateextras`. We add a new function for this. Differential Revision: https://phab.mercurial-scm.org/D9190 diff --git a/mercurial/commit.py b/mercurial/commit.py --- a/mercurial/commit.py +++ b/mercurial/commit.py @@ -155,7 +155,7 @@ def _get_salvaged(repo, ms, ctx): copy_sd = repo.filecopiesmode == b'changeset-sidedata' if copy_sd and len(ctx.parents()) > 1: if ms.active(): -for fname in sorted(ms._stateextras.keys()): +for fname in sorted(ms.allextras().keys()): might_removed = ms.extras(fname).get(b'merge-removal-candidate') if might_removed == b'yes': if fname in ctx: diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -2107,7 +2107,7 @@ def debugmergestate(ui, repo, *args, **o fm_files.end() fm_extras = fm.nested(b'extras') -for f, d in sorted(pycompat.iteritems(ms._stateextras)): +for f, d in sorted(pycompat.iteritems(ms.allextras())): if f in ms: # If file is in mergestate, we have already processed it's extras continue diff --git a/mercurial/mergestate.py b/mercurial/mergestate.py --- a/mercurial/mergestate.py +++ b/mercurial/mergestate.py @@ -305,7 +305,12 @@ class _mergestate_base(object): ): yield f +def allextras(self): +""" return all extras information stored with the mergestate """ +return self._stateextras + def extras(self, filename): +""" return extras stored with the mergestate for the given filename """ return self._stateextras[filename] def _resolve(self, preresolve, dfile, wctx): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH V2] mergestate: make filename argument optional in _mergestate_base.extras()
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1602313984 -19800 # Sat Oct 10 12:43:04 2020 +0530 # Node ID 16290c7c8eea7f859aade5c8c2f9af357da97164 # Parent 04de8a1ec08f380fda794dda3b3f2ed1ccfd442b # EXP-Topic merge-newnode-final mergestate: make filename argument optional in _mergestate_base.extras() Earlier `extras()` can only be used for getting extra for a file. However at couple of places in code, we wanted to iterate over all the extras stored with the mergestate and they were accessing the private `_stateextras`. Now, if filename is not passed, we return all the extras. Differential Revision: https://phab.mercurial-scm.org/D9190 diff --git a/mercurial/commit.py b/mercurial/commit.py --- a/mercurial/commit.py +++ b/mercurial/commit.py @@ -155,7 +155,7 @@ def _get_salvaged(repo, ms, ctx): copy_sd = repo.filecopiesmode == b'changeset-sidedata' if copy_sd and len(ctx.parents()) > 1: if ms.active(): -for fname in sorted(ms._stateextras.keys()): +for fname in sorted(ms.allextras().keys()): might_removed = ms.extras(fname).get(b'merge-removal-candidate') if might_removed == b'yes': if fname in ctx: diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -2107,7 +2107,7 @@ def debugmergestate(ui, repo, *args, **o fm_files.end() fm_extras = fm.nested(b'extras') -for f, d in sorted(pycompat.iteritems(ms._stateextras)): +for f, d in sorted(pycompat.iteritems(ms.allextras())): if f in ms: # If file is in mergestate, we have already processed it's extras continue diff --git a/mercurial/mergestate.py b/mercurial/mergestate.py --- a/mercurial/mergestate.py +++ b/mercurial/mergestate.py @@ -305,7 +305,12 @@ class _mergestate_base(object): ): yield f +def allextras(self): +""" return all extras information stored with the mergestate """ +return self._stateextras + def extras(self, filename): +""" return extras stored with the mergestate for the given filename """ return self._stateextras[filename] def _resolve(self, preresolve, dfile, wctx): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH V2] mergestate: document `o` merge record state in _mergestate_base docs
# HG changeset patch # User Pulkit Goyal <7895pul...@gmail.com> # Date 1601991694 -19800 # Tue Oct 06 19:11:34 2020 +0530 # Node ID c3ffbf50856b954e3a8be968b9a93000b03b1843 # Parent 04de8a1ec08f380fda794dda3b3f2ed1ccfd442b mergestate: document `o` merge record state in _mergestate_base docs _mergestate_base documentation serves as a nice documentation for mergestate. This also documents known merge records and known merge record states. I missed adding `o` state to it when I introduced it. Let's add it now. Differential Revision: https://phab.mercurial-scm.org/D9156 diff --git a/mercurial/mergestate.py b/mercurial/mergestate.py --- a/mercurial/mergestate.py +++ b/mercurial/mergestate.py @@ -160,6 +160,7 @@ class _mergestate_base(object): r: resolved conflict pu: unresolved path conflict (file conflicts with directory) pr: resolved path conflict +o: file was merged in favor of other parent of merge (DEPRECATED) The resolve command transitions between 'u' and 'r' for conflicts and 'pu' and 'pr' for path conflicts. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel