Martin von Zweigbergk <martinvonz@google.com> [Sun, 09 Jul 2017 15:19:27 -0700] rev 33378
match: make nevermatcher an exact matcher and a prefix matcher
The m.isexact() and m.prefix() methods are used by callers to
determine whether m.files() can be used for fast paths. It seems safe
to let callers to any fast paths it can that rely on the empty
m.files().
Jun Wu <quark@fb.com> [Mon, 10 Jul 2017 10:56:40 -0700] rev 33377
revset: define successors revset
This revset returns all successors, including transit nodes and the source
nodes (to be consistent with existing revsets like "ancestors").
To filter out transit nodes, use `successors(X)-obsolete()`.
To filter out divergent case, use `successors(X)-divergent()-obsolete()`.
The revset could be useful to define rebase destination, like:
`max(successors(BASE)-divergent()-obsolete())`. The `max` is to deal with
splits.
There are other implementations where `successors` returns just one level of
successors, and `allsuccessors` returns everything. I think `successors`
returning all successors by default is more user friendly. We have seen
cases in production where people use 1-level `successors` while they really
want `allsuccessors`. So it seems better to just have one single revset
returning all successors by default to avoid user errors.
In the future we might want to add `depth` keyword argument to it and for
other revsets like `ancestors` etc. Or even build some flexible indexing
syntax [1] to satisfy people having the depth limit requirement.
[1]: https://www.mercurial-scm.org/pipermail/mercurial-devel/2017-July/101140.html
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 10 Jul 2017 21:55:43 -0700] rev 33376
sparse: shorten try..except block in updateconfig()
It now only covers refreshwdir(). This is what importfromfiles()
does. I think it is the more appropriate behavior.
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 10 Jul 2017 21:43:19 -0700] rev 33375
sparse: clean up updateconfig()
* Use context manager for wlock
* Rename oldsparsematch to oldmatcher
* Always call parseconfig() because parsing an empty string yields
the same result as the old code
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 10 Jul 2017 21:39:49 -0700] rev 33374
sparse: move config updating function into core
As part of the move, the ui argument was dropped.
Additional fixups will be made in a follow-up commit.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 08 Jul 2017 16:18:04 -0700] rev 33373
dirstate: expose a sparse matcher on dirstate (API)
The sparse extension performs a lot of monkeypatching of dirstate
to make it sparse aware. Essentially, various operations need to
take the active sparse config into account. They do this by obtaining
a matcher representing the sparse config and filtering paths through
it.
The monkeypatching is done by stuffing a reference to a repo on
dirstate and calling sparse.matcher() (which takes a repo instance)
during each function call. The reason this function takes a repo
instance is because resolving the sparse config may require resolving
file contents from filelogs, and that requires a repo. (If the
current sparse config references "profile" files, the contents of
those files from the dirstate's parent revisions is resolved.)
I seem to recall people having strong opinions that the dirstate
object not have a reference to a repo. So copying what the sparse
extension does probably won't fly in core. Plus, the dirstate
modifications shouldn't require a full repo: they only need a matcher.
So there's no good reason to stuff a reference to the repo in
dirstate.
This commit exposes a sparse matcher to dirstate via a property that
when looked up will call a function that eventually calls
sparse.matcher(). The repo instance is bound in a closure, so it
isn't exposed to dirstate.
This approach is functionally similar to what the sparse extension does
today, except it hides the repo instance from dirstate. The approach
is not optimal because we have to call a proxy function and
sparse.matcher() on every property lookup. There is room to cache
the matcher instance in dirstate. After all, the matcher only changes
if the dirstate's parents change or if the sparse config changes. It
feels like we should be able to detect both events and update the
matcher when this occurs. But for now we preserve the existing
semantics so we can move the dirstate sparseness bits into core. Once
in core, refactoring becomes a bit easier since it will be clearer how
all these components interact.
The sparse extension has been updated to use the new property.
Because all references to the repo on dirstate have been removed,
the code for setting it has been removed.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 08 Jul 2017 15:42:11 -0700] rev 33372
sparse: use self instead of repo.dirstate
"self" here is the dirstate instance. I'm pretty confident that self
and repo.dirstate will be the exact same object. So remove a dependency
on repo by just looking at self.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 08 Jul 2017 14:15:07 -0700] rev 33371
sparse: move code for importing rules from files into core
This is a pretty straightforward port. Some code cleanup was
performed. But no major changes to the logic were made.
I'm not a huge fan of this function because it does multiple
things. I'd like to get things into core first to facilitate
refactoring later.
Please also note the added inline comment about the oddities
of writeconfig() and the try..except to undo it. This is because
of the hackiness in which the sparse matcher is obtained by
various consumers, notably dirstate. We'll need a massive
refactor to address this. That refactor is effectively blocked
on having the sparse dirstate hacks live in core.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 08 Jul 2017 14:01:32 -0700] rev 33370
sparse: refactor activeprofiles into a generic function (API)
activeprofiles() is a special case of a more generic function.
Furthermore, that generic function is essentially already
implemented inline in the sparse extension.
So, refactor activeprofiles() to a generic activeconfig(). Change
the only consumer of activeprofiles() to use it. And have the
inline implementation in the sparse extension use it.
Augie Fackler <raf@durin42.com> [Fri, 07 Jul 2017 15:11:11 -0400] rev 33369
check-code: prohibit `if False` antipattern
Differential Revision: https://phab.mercurial-scm.org/D20
Augie Fackler <raf@durin42.com> [Fri, 07 Jul 2017 15:08:23 -0400] rev 33368
convert: remove `if False` block
This code has never run since its introduction on July 18th,
2007. It's time for it to go.
Differential Revision: https://phab.mercurial-scm.org/D19
Augie Fackler <raf@durin42.com> [Fri, 07 Jul 2017 15:07:36 -0400] rev 33367
filterpyflakes: move self-test into test file
This will avoid a false positive on an upcoming check-code rule.
Differential Revision: https://phab.mercurial-scm.org/D18
Matt Harbison <matt_harbison@yahoo.com> [Sun, 09 Jul 2017 16:38:04 -0400] rev 33366
test-subrepo: demonstrate a status problem when merge deletes a file
At the interactive update prompt, if (c) is chosen and then followed by `hg rm`,
both `status -R` and `status -S` show the file as 'R', and `files -R` shows no
files (OK, because explicitly removed files aren't supposed to be listed). If
`rm` follows selecting (c), then both flavors of `status` list the file as '!',
and `files -R` lists the missing file. So somehow, the (d) option has followed
a third path.
Matt Harbison <matt_harbison@yahoo.com> [Sun, 09 Jul 2017 16:13:30 -0400] rev 33365
subrepo: make the output references to subrepositories consistent
Well, mostly. The annotation on subrepo functions tacks on a parenthetical to
the abort message, which seems reasonable for a generic mechanism. But now all
messages consistently spell out 'subrepository', and double quote the name of
the repo. I noticed the inconsistency in the change for the last commit.
Matt Harbison <matt_harbison@yahoo.com> [Sun, 09 Jul 2017 02:55:46 -0400] rev 33364
subrepo: consider the parent repo dirty when a file is missing
This simply passes the 'missing' argument down from the context of the parent
repo, so the same rules apply. subrepo.bailifchanged() is hardcoded to care
about missing files, because cmdutil.bailifchanged() is too.
In the end, it looks like this addresses inconsistencies with 'archive',
'identify', blackbox logs, 'merge', and 'update --check'. I wasn't sure how to
implement this in git, so that's left for someone more familiar with it.
Matt Harbison <matt_harbison@yahoo.com> [Sun, 09 Jul 2017 02:46:03 -0400] rev 33363
archival: flag missing files as a dirty wdir() in the metadata file (BC)
Since the identify command adds a '+' for missing files, it's reasonable that
this does too. Perhaps the node field's hex value should be p1+p2 for merges?
Matt Harbison <matt_harbison@yahoo.com> [Sun, 09 Jul 2017 00:53:16 -0400] rev 33362
cmdutil: simplify the dirty check in howtocontinue()
This is equivalent to the previous code. But it seems to me that if the user is
going to be prompted that a commit is needed, missing files should be ignored,
but branch and merge changes shouldn't be.
Matt Harbison <matt_harbison@yahoo.com> [Sun, 09 Jul 2017 00:23:03 -0400] rev 33361
blackbox: simplify the dirty check
Same idea (and possibly incorrect behavior) as the previous commit.
Matt Harbison <matt_harbison@yahoo.com> [Sun, 09 Jul 2017 00:19:03 -0400] rev 33360
identify: simplify the dirty check
This is equivalent to the previous code, but it seems better to be explicit
about what aspects of dirty are being ignored. Perhaps they shouldn't be, since
the help text says 'followed by a "+" if the working directory has uncommitted
changes'. Both merges and branch changes are committable, even if the files are
unchanged.
Additionally, this will make the `identify` command notice missing subrepo
files, once subrepos are taught to look for missing files.
Matt Harbison <matt_harbison@yahoo.com> [Sun, 09 Jul 2017 00:05:31 -0400] rev 33359
tests: tweak the subrepo dirty state tests
This is a continuation of
439b4d005b4a. I overlooked that blackbox logs also
have a dirty marker. Also, the `hg update --check` test was updating to a
revision where the deleted file wasn't tracked, which is why status seemed to
show the deleted file was restored.
Martin von Zweigbergk <martinvonz@google.com> [Sun, 09 Jul 2017 23:01:11 -0700] rev 33358
match: combine regex code for path: and relpath:
The regexes for path: and relpath: patterns are the same (since the
paths have already been normalized at the point we create the
regexes).
I don't think the "if pat == '.'" will have any effect relpath:
because relpath: patterns will have the root directory already
normalized to '' by pathutil.canonpath() (unlike path:, for which the
root gets normalized to '.' by util.normpath()).
Martin von Zweigbergk <martinvonz@google.com> [Sun, 09 Jul 2017 22:53:02 -0700] rev 33357
match: remove unnecessary '^' from regexes
The regexes are passed to re.match(), which matches against the
beginning of the input, so the '^' doesn't do anything.
Note that unrooted patterns, such as globs and regexes from .hgignore
are instead achieved by adding '.*' to the expression given by the
user. (That's unless the user's expression started with '^', in which
case the '.*' is not added, perhaps to keep the regex cleaner?)
Martin von Zweigbergk <martinvonz@google.com> [Thu, 06 Jul 2017 22:20:38 -0700] rev 33356
sparse: access status fields by name instead of deconstructing it
The status tuples has had named fields for a few years now.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 08 Jul 2017 13:34:19 -0700] rev 33355
sparse: move printing of sparse config changes function into core
As part of the port, all arguments now have default values of 0.
Strings are now also given the i18n treatment.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 08 Jul 2017 13:19:38 -0700] rev 33354
sparse: move code for clearing rules to core
This is a pretty straightforward port.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 07 Jul 2017 11:51:10 -0700] rev 33353
sparse: move post commit actions into core
Instead of wrapping committablectx.markcommitted(), we inline
the call into workingctx.markcommitted().
Per smf's review, workingctx is the proper location for this
code, as committablectx is the shared base class for it and
memctx. Since this code touches the working directory, it belongs
in workingctx.
Octobus <contact@octobus.net> [Sun, 09 Jul 2017 15:11:19 +0200] rev 33352
cleanupnode: do not use generator for node mapping
The 'successors' part of the mappings used of be a tuple. This avoid issue from
code consuming the generator "by mistake". For example, an extension inspecting the
mapping content used to be able to iterate over the successors mapping without
consequence.
Since the mapping are small we do not expect any performance impact we use tuple
again for this.
Jun Wu <quark@fb.com> [Sat, 08 Jul 2017 16:50:31 -0700] rev 33351
histedit: use scmutil.cleanupnodes (BC)
This is marked as BC because the strip backup file name has changed.
Jun Wu <quark@fb.com> [Sat, 08 Jul 2017 16:50:31 -0700] rev 33350
histedit: unify strip backup files on success (BC)
Previously we wrote two different strip backup files on success. This patch
unifies them. It will make scmutil.cleanupnodes migration more smooth.
Jun Wu <quark@fb.com> [Sat, 08 Jul 2017 16:50:31 -0700] rev 33349
histedit: pass multiple nodes to strip (BC)
Previously, histedit.cleanupnode pass root nodes one by one. Since
repair.strip takes multiple nodes and can handle them just fine, pass all
strip roots at once.
This is BC because the number of strip backup files may change from N to 1.
Jun Wu <quark@fb.com> [Sat, 08 Jul 2017 16:50:31 -0700] rev 33348
histedit: remove "name" parameter from cleanupnode functions
The "name" parameter is not used any longer so let's remove it.
Jun Wu <quark@fb.com> [Sat, 08 Jul 2017 16:50:31 -0700] rev 33347
histedit: remove "should strip" debug message
The debug message was not used anywhere. Removed it to make
scmutil.cleanupnodes migration easier to reason about.
Jun Wu <quark@fb.com> [Sat, 08 Jul 2017 16:47:25 -0700] rev 33346
histedit: move topmost bookmark movement to a separate function
histedit treats topmost bookmark movement specially. The rest of the
bookmark movement could be handled by scmutil.cleanupnodes. So let's move
the special logic out to make the patch easier to review.
Jun Wu <quark@fb.com> [Sat, 08 Jul 2017 16:04:21 -0700] rev 33345
histedit: remove moving bookmarks message on verbose (BC)
This is more consistent with other commands, like "commit -v" won't show
bookmark movement messages.
It will make migrating to scmutil.cleanupnodes easier.
Matt Harbison <matt_harbison@yahoo.com> [Sat, 08 Jul 2017 18:47:50 -0400] rev 33344
test-largefiles-update: conditionalize output instead of tests
Matt Harbison <matt_harbison@yahoo.com> [Sat, 08 Jul 2017 18:46:43 -0400] rev 33343
test-status-rev: conditionalize output instead of tests
Matt Harbison <matt_harbison@yahoo.com> [Sat, 08 Jul 2017 18:46:12 -0400] rev 33342
test-mq: conditionalize output instead of tests
Matt Harbison <matt_harbison@yahoo.com> [Sat, 08 Jul 2017 18:38:44 -0400] rev 33341
test-annotate: conditionalize output instead of tests
Matt Harbison <matt_harbison@yahoo.com> [Sat, 08 Jul 2017 18:37:41 -0400] rev 33340
test-addremove: conditionalize output instead of tests
Matt Harbison <matt_harbison@yahoo.com> [Sat, 08 Jul 2017 14:21:11 -0400] rev 33339
test-tools: conditionalize output instead of tests
Matt Harbison <matt_harbison@yahoo.com> [Sat, 08 Jul 2017 14:15:01 -0400] rev 33338
test-rebase: conditionalize output instead of tests
This should help prevent breakage like was fixed in the last patch.
Matt Harbison <matt_harbison@yahoo.com> [Sat, 08 Jul 2017 14:10:10 -0400] rev 33337
tests: stabilize on Windows
I'm not sure if the difference on Windows for test-sparse.t is expected or not.
It looks like unless the leading '/' is followed by a drive letter, '/' is
resolved to 'C:/MinGW/msys/1.0'. But both cases abort with "not under root"
instead of just warning.
Jun Wu <quark@fb.com> [Sat, 24 Jun 2017 15:29:42 -0700] rev 33336
revset: make repo.anyrevs accept customized alias override (API)
Previously repo.anyrevs only expand aliases in [revsetalias] config. This
patch makes it more flexible to accept a customized dict defining aliases
without having to couple with ui.
revsetlang.expandaliases now has the signature (tree, aliases, warn=None)
which is more consistent with templater.expandaliases. revsetlang.py is now
free from "ui", which seems to be a good thing.
Matt Harbison <matt_harbison@yahoo.com> [Fri, 07 Jul 2017 01:05:20 -0400] rev 33335
tests: quote $PYTHON for Windows
When unquoted, MSYS sees the colon between the drive letter and path as a Unix
path separator and unhelpfully splits on it, feeding only the drive letter as
the command. Much chaos ensues.
I vaguely remember trying to get the test runner to use /letter/path/to/exe
syntax the last time this happened, without success. I doubt a check-code rule
would work, since sometimes it is quoted, and sometimes the quotes are escaped.
Jun Wu <quark@fb.com> [Mon, 26 Jun 2017 15:28:28 -0700] rev 33334
amend: use scmutil.cleanupnodes (BC)
This is marked as BC because the strip backup file name has changed.
Jun Wu <quark@fb.com> [Fri, 07 Jul 2017 19:03:03 -0700] rev 33333
rebase: remove "if True"
The "if True" block was to make the last patch easier to review. This patch
removes "if True" and unindents the block.
Jun Wu <quark@fb.com> [Fri, 07 Jul 2017 18:51:46 -0700] rev 33332
rebase: use scmutil.cleanupnodes (
issue5606) (BC)
This patch migrates rebase to use scmutil.cleanupnodes API. It simplifies
the code and makes rebase code reusable inside a transaction.
This is a BC because the backup file is no longer strip-backup/*-backup.hg,
but strip-backup/*-rebase.hg. The latter looks more reasonable since the
directory name is "strip-backup" so there is no need to repeat "backup".
I think the backup file name change is probably fine as a BC, since we have
changed it before (
aa4a1672583e) and didn't get complains. The end result
of this series will be a much more consistent and unified backup names:
command | old backup file suffix | new backup file suffix
-------------------------------------------------------------------
amend | amend-backup.hg | amend.hg
histedit | backup.hg (could be 2 files) | histedit.hg (single file)
rebase | backup.hg | rebase.hg
strip | backup.hg | backup.hg
(note: backup files are under .hg/strip-backup)
It also fixes
issue5606 as a side effect because the new "delayedstrip" code
path will carefully examine nodes (safestriproots) to make sure orphaned
changesets won't get stripped by accident.
Some warning messages are changed to the new "warning: orphaned descendants
detected, not stripping HASHES", which provides more information about
exactly what changesets are left behind.
Another minor behavior change is when there is an obsoleted changeset with a
successor in the destination branch, bookmarks pointing to that obsoleted
changeset will not be moved. I have commented in test-rebase-obsolete.t
explaining why that is more desirable.
Jun Wu <quark@fb.com> [Mon, 26 Jun 2017 13:13:51 -0700] rev 33331
scmutil: make cleanupnodes delete divergent bookmarks
cleanupnodes takes care of bookmark movement, and bookmark movement could
cause bookmark divergent resolution as a side effect. This patch adds such
bookmark divergent resolution logic so future rebase migration will be
easier.
The revset is carefully written to be equivalent to what rebase does today.
Although I think it might make sense to remove divergent bookmarks more
aggressively, for example:
F book@1
|
E book@2
|
| D book
| |
| C
|/
B book@3
|
A
When rebase -s C -d E, "book@1" will be removed, "book@3" will be kept,
and the end result is:
D book
|
C
|
F
|
E book@2 (?)
|
B book@3
|
A
The question is should we keep book@2? The current logic keeps it. If we
choose not to (makes some sense to me), the "deleterevs" revset could be
simplified to "newnode % oldnode".
For now, I just make it compatible with the existing behavior. If we want to
make the "deleterevs" revset simpler, we can always do it in the future.
Jun Wu <quark@fb.com> [Mon, 26 Jun 2017 15:08:37 -0700] rev 33330
scmutil: make cleanupnodes handle filtered node
In some valid usecases, the "mapping" received by scmutil.cleanupnodes have
filtered nodes. Use unfiltered repo to access them correctly.
The added test case will fail with the old cleanupnodes code.
This is important to migrate histedit to use the cleanupnodes API.
David Demelier <demelier.david@gmail.com> [Fri, 07 Jul 2017 08:33:10 +0200] rev 33329
configitems: add alias support in config
Aliases define optional alternatives to existing options. For example the old
option ui.user was deprecated and replaced by ui.username. With this mechanism,
it's even possible to create an alias to an option in a different section.
Add ui.user as alias to ui.username as an example of this concept.
The old alternates principle in ui.config is removed as it was used only for
this option.
David Demelier <demelier.david@gmail.com> [Mon, 03 Jul 2017 13:04:35 +0200] rev 33328
hgweb: use ui._unset to prevent a warning in configitems
Martin von Zweigbergk <martinvonz@google.com> [Fri, 07 Jul 2017 00:13:53 -0700] rev 33327
dispatch: fix typo suggestion for disabled extension
If the matching command lives in an in-tree extension (which is all we
scan for), and the user has disabled that extension with
"extensions.<name>=!", we were not finding it, because the path in
_disabledextensions was the empty string. If the user had set
"extensions.<name>=!<valid path>" it would work, so it seems like just
a mistake that it didn't work.
Martin von Zweigbergk <martinvonz@google.com> [Fri, 07 Jul 2017 00:12:44 -0700] rev 33326
tests: add tests for typoed commands
This includes one test showing how disabling a command with e.g.
"extensions.rebase=!" results in the command not being
suggested. We'll fix that next.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 16:10:28 -0700] rev 33325
sparse: inline signature cache clearing
It is a trivial one-liner. No need to have a separate function.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 14:53:08 -0700] rev 33324
sparse: move working directory refreshing into core
This is a pretty straightforward move of the code.
I converted the "force" argument to a keyword argument.
Like other recent changes, this code is tightly coupled with
working directory update code in merge.py. I suspect the code
will become more tightly coupled over time, possibly even moved
to merge.py. For now, let's get the code in core.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 16:29:31 -0700] rev 33323
sparse: refactor update actions filtering and call from core
merge.calculateupdates() now filters the update actions through sparse
by default.
The filtering no-ops if sparse isn't enabled or no sparse config
is defined.
The function has been refactored to behave more like a filter
instead of a wrapper of merge.calculateupdates().
We should arguably take sparse into account earlier in
merge.calculateupdates(). This patch preserves the old behavior
of applying sparse at the end of update calculation, which is the
simplest and safest approach.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 16:17:35 -0700] rev 33322
sparse: move update action filtering into core
This is a relatively straight port of the function. It is pretty large.
So refactoring will be postponed to a subsequent commit.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 14:33:18 -0700] rev 33321
sparse: move pruning of temporary includes into core
This was our last method on the custom repo type, meaning we could
remove that custom type and inline the 2 lines of code into
reposetup().
As part of the move, instead of wrapping merge.update() from
the sparse extension, we inline the function call. The ported
function now no-ops if sparse isn't enabled, making it safe to
always call.
The call site in update() may not be the most appropriate. But
it matches the previous behavior, which is the safest thing
to do. It can be improved later.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 17:41:45 -0700] rev 33320
sparse: move function for resolving sparse matcher into core
As part of the move, the function arguments changed so revs are
passed as a list instead of *args. This allows us to use keyword
arguments properly.
Since the plan is to integrate sparse into core and have it
enabled by default, we need to prepare for a sparse matcher
to always be obtained and operated on. As part of the move,
we inserted code that returns an always matcher if sparse
isn't enabled. Some callers in the sparse extension take this
into account and conditionally perform matching depending on
whether the special always matcher is seen. I /think/ this
may have sped up some operations where the extension is
installed but no sparse config is activated.
One thing I'm ensure of in this code is whether os.path.dirname()
is semantically correct. os.posixpath.dirname() (which is
exported as pathutil.dirname) might be a better choise because
all patterns should be using posix directory separators (/)
instead of Windows (\). There's an inline comment that implies
Windows was tested. So hopefully it won't be a problem. We
can improve this in a follow-up. I've added a TODO to track it.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 17:39:24 -0700] rev 33319
match: move matchers from sparse into core
The sparse extension contains some matcher types that are
generic and can exist in core.
As part of the move, the classes now inherit from basematcher.
always(), files(), and isexact() have been dropped because
they match the default implementations in basematcher.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 16:01:36 -0700] rev 33318
sparse: clean up config signature code
Before, 0 was being used as the default signature value and we cast
the int to a string. We also handled I/O exceptions manually.
The new code uses cfs.tryread() so we always feed data into the
hasher. The empty string does hash and and should be suitable
for input into a cache key.
The changes made the code simple enough that the separate checksum
function could be inlined.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 16:11:56 -0700] rev 33317
sparse: move config signature logic into core
This is a pretty straightforward port. It will be cleaned up in
a subsequent commit.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 17:31:33 -0700] rev 33316
sparse: remove custom hash matcher
With the recent change to always use repr(), this function was
functionally identical to the version in fsmonitor it was
replacing. So remove it.
Martin von Zweigbergk <martinvonz@google.com> [Thu, 06 Jul 2017 16:37:36 -0700] rev 33315
sparse: override __repr__ in matchers
sparse.py in FB's hg-experimental repo switched to using __repr__ for
non-sparse matchers soon after hg core started overriding __repr__ in
the matchers in match.py (because the core matchers also stopped
having "includepat" and other attributes that sparse used to depend
on). Let's finish that migration by implementing __repr__ in the
sparse matchers as well. That also lets us remove the special handling
of them in _hashmatcher().
Martin von Zweigbergk <martinvonz@google.com> [Thu, 06 Jul 2017 14:17:02 -0700] rev 33314
tests: fix reference to undefined variable
The delaypush() function had a reference to "repo" that was clearly
supposed to be "pushop.repo". Instead of just fixing that, let's
extract "pushop.repo.ui" to a variable, since that's the only
piece of the repo that's needed in the function.
I have not looked into why I saw a different result in the test to
start with, but that's for another patch anyway.
Martin von Zweigbergk <martinvonz@google.com> [Tue, 01 Dec 2015 09:19:54 -0800] rev 33313
shelve: don't reimplement mergestate.unresolved()
Martin von Zweigbergk <martinvonz@google.com> [Mon, 23 Nov 2015 09:37:12 -0800] rev 33312
summary: don't reimplment mergestate.unresolved()
Martin von Zweigbergk <martinvonz@google.com> [Tue, 01 Dec 2015 09:26:33 -0800] rev 33311
mergestate: implement unresolvedcount() in terms of unresolved()
This simplifies the method slightly. It does create a full list of
paths while doing so, but it's not a lot of data anyway (besides, I
would think references to strings are no larger than (references to?)
True).
Martin von Zweigbergk <martinvonz@google.com> [Tue, 01 Dec 2015 09:26:10 -0800] rev 33310
mergestate: make unresolved() use iteritems()
mergestate.unresolved() is a generator, so it seems better for it to
rely on iteritems() than items(), although it also seems unlikely for
it to make a noticeable difference.
Martin von Zweigbergk <martinvonz@google.com> [Fri, 30 Jun 2017 23:58:59 -0700] rev 33309
changegroup: don't fail on empty changegroup (API)
I don't know why applying an empty changegroup should be an error. It
seems harmless. I suspect the check was there to find code that
creates empty changegroups just because that would be wasteful. Let's
use develwarn() for that instead, so we catch any such cases that run
with our test runner, but we still allow others to generate empty
changegroups if they want to.
We have run into this check at Google once or twice and had to work
around it, but I'm changing this not so much because of that, but
because it seems like it shouldn't be an error.
I also changed the message slightly to be more modern ("changelog
group" -> "changegroup") and more generic ("received" -> "applied").
Martin von Zweigbergk <martinvonz@google.com> [Sat, 01 Jul 2017 00:00:09 -0700] rev 33308
changegroup: remove option to allow empty changegroup (API)
No caller sets the "emptyok" option, so let's remove it.
Martin von Zweigbergk <martinvonz@google.com> [Fri, 30 Jun 2017 23:58:31 -0700] rev 33307
strip: don't allow empty changegroup in bundle1
Applying an empty changegroup has been an error since the
beginning. The only exception was strip, which would allow to apply an
empty changegroup from the temporary bundle. However, the emptyok=True
option was only set for bundle1 bundles. In other words, temporary
bundle2 bundles would fail if they were empty.
Bundle2 has now been used enough that it seems safe to say that we
simply don't create bundle2 bundles with empty changegroups. That also
suggests that we never create bundle1 bundles with empty changegroups
(i.e. empty bundle1 bundles, since bundle1 is just a changegroup),
because, AFAICT, the code leading up to the application of the bundle
is the same for bundle1 and bundle2.
Therefore, let's stop passing emptyok=True, so we more clearly get the
same behavior for bundle1 and bundle2.
Martin von Zweigbergk <martinvonz@google.com> [Thu, 08 Jun 2017 22:49:21 -0700] rev 33306
match: minor cleanups to patternmatcher and includematcher
The "patterns"/"include" in "patternspat"/"includepat" is redundant,
so drop it. Also a "_" prefix since it's "private".
Inline the "pm"/"im" variables.
Boris Feld <boris.feld@octobus.net> [Thu, 06 Jul 2017 17:18:50 +0200] rev 33305
py3: fix test-diff-newlines.t to be compatible with py3
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 14:48:16 -0700] rev 33304
sparse: move some temporary includes functions into core
Functions for reading and writing the tempsparse file have been
moved. prunetemporaryincludes() will be moved separately
because it is non-trivial.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 12:24:55 -0700] rev 33303
sparse: move config file writing into core
The code was refactored during the move to be more procedural
instead of using string formatting. This has the benefit of not
writing empty sections, which changed tests.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 12:20:53 -0700] rev 33302
localrepo: add sparse caches
The sparse extension maintains caches for the sparse files
to a signature and a signature to a matcher. This allows the
sparse matchers to be resolved quickly, which is apparently
something that can occur in loops.
This patch ports the sparse caches to the localrepo class
pretty much as-is. There is potentially room to improve the
caching mechanism. But that can be done as a follow-up.
The default invalidatecaches() now clears the relevant sparse
cache. invalidatesignaturecache() has been moved to sparse.py.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 12:26:04 -0700] rev 33301
sparse: move active profiles function into core
Also includes some light formatting changes.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 12:15:14 -0700] rev 33300
sparse: move resolving of sparse patterns for rev into core
This method is reasonably well-contained and simple to move.
As part of the move, some light formatting was performed.
A "working copy" reference in an error message was changed to
"working directory."
The biggest change was to _refreshoncommit() in sparse.py. It
was previously checking for the existence of an attribute on
the repo instance. Since the moved function now returns empty
data if sparse isn't enabled, we unconditionally call the
new function. However, we do have to protect another method
call in that function. This will all be unhacked eventually.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 12:06:37 -0700] rev 33299
sparse: variable to track if sparse is enabled
Currently, the sparse extension sniffs repo instances for
attributes defined by the sparse extension to determine if
sparse is enabled. As we move code away from repo instances,
these checks will be a bit more brittle.
We introduce a module-level variable to track whether sparse is
enabled as a temporary workaround.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 12:14:12 -0700] rev 33298
sparse: move profile reading into core
One more step towards weaning off methods on repo instances and
moving code to core. While this function is only used once and
is simple, it needs to exist on its own so Facebook can monkeypatch
it to enable simplecache integration.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 12:14:03 -0700] rev 33297
sparse: move config parsing into core
This patch marks the beginning of moving code from the sparse
extension into core. The goal is to move as much of the
functionality as possible into core, where it will be an
experimental feature. The extension will likely continue to
exist to enable the feature and provide UI elements.
As part of the move, the repo method was converted to a module
function. It doesn't need to exist on repos.
An error message was also updated to reflect that an error isn't
necessarily from the .hg/sparse file. The API should be updated
later to pass in a filename so the error can be more descriptive.
Copyright of the added file was copied from the sparse extension.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 10:58:45 -0700] rev 33296
sparse: use vfs.tryread()
vfs.exists() followed by a file read is an anti-pattern because it
incurs an extra stat() to test for file presence. vfs.tryread()
returns empty string on missing file and avoids the stat().
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 01 Jul 2017 11:56:39 -0700] rev 33295
sparse: refactor sparsechecksum()
This was relying on garbage collection to close the opened
file, which is a bug. Both callers simply called into self.vfs
to resolve the path. So refactor to use the vfs layer.
While we're here, rename the method to reflect it is internal
and to break anyone relying on the old behavior.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 10:57:26 -0700] rev 33294
sparse: document config file format
This was previously undocumented. Seems useful to have.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 01 Jul 2017 10:29:27 -0700] rev 33293
sparse: rename command to debugsparse
Sparse checkout is still highly experimental and not protected
by BC guarantees yet. We also haven't had a discussion on the UX.
To discourage use, we rename the sparse command to debugsparse.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 06 Jul 2017 10:54:23 -0700] rev 33292
sparse: remove reference to simplecache
This is a 3rd party extension authored by Facebook. References in
core are not appropriate.
It will be possible to restore this code/optimization via
monkeypatching. So Facebook won't lose any functionality.
The removed code is important for performance. So add a comment
tracking it.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 01 Jul 2017 10:24:31 -0700] rev 33291
sparse: remove reference to hgwatchman
This is a legacy extension. Now that the extension is in core,
we only need to support what's in core, which is fsmonitor.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 01 Jul 2017 10:36:03 -0700] rev 33290
sparse: expand module docstring
Clarify lack of BC guarantees. And say a bit more about the extension.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 01 Jul 2017 10:43:29 -0700] rev 33289
sparse: vendor Facebook-developed extension
Facebook has developed an extension to enable "sparse" checkouts -
a working directory with a subset of files. This feature is a critical
component in enabling repositories to scale to infinite number of
files while retaining reasonable performance. It's worth noting
that sparse checkout is only one possible solution to this problem:
another is virtual filesystems that realize files on first access.
But given that virtual filesystems may not be accessible to all
users, sparse checkout is necessary as a fallback.
Per mailing list discussion at
https://www.mercurial-scm.org/pipermail/mercurial-devel/2017-March/095868.html
we want to add sparse checkout to the Mercurial distribution via
roughly the following mechanism:
1. Vendor extension as-is with minimal modifications (this patch)
2. Refactor extension so it is more clearly experimental and inline
with Mercurial practices
3. Move code from extension into core where possible
4. Drop experimental labeling and/or move feature into core
after sign-off from narrow clone feature owners
This commit essentially copies the sparse extension and tests
from revision
71e0a2aeca92a4078fe1b8c76e32c88ff1929737 of the
https://bitbucket.org/facebook/hg-experimental repository.
A list of modifications made as part of vendoring is as follows:
* "EXPERIMENTAL" added to module docstring
* Imports were changed to match Mercurial style conventions
* "testedwith" value was updated to core Mercurial special value and
comment boilerplate was inserted
* A "clone_sparse" function was renamed to "clonesparse" to appease
the style checker
* Paths to the sparse extension in tests reflect built-in location
* test-sparse-extensions.t was renamed to test-sparse-fsmonitor.t
and references to "simplecache" were removed. The test always skips
because it isn't trivial to run it given the way we currently run
fsmonitor tests
* A double empty line was removed from test-sparse-profiles.t
There are aspects of the added code that are obviously not ideal.
The goal is to make a minimal number of modifications as part of
the vendoring to make it easier to track changes from the original
implementation. Refactoring will occur in subsequent patches.
Augie Fackler <augie@google.com> [Thu, 06 Jul 2017 15:15:02 -0400] rev 33288
contrib: widen "direct use of `python`" net again
I think I've now caught all of them.
Differential Revision: https://phab.mercurial-scm.org/D15
Kevin Bullock <kbullock+mercurial@ringworld.org> [Thu, 06 Jul 2017 14:33:48 -0500] rev 33287
tests: clean up a newly-introduced instance of `python`
Differential Revision: https://phab.mercurial-scm.org/D16
Augie Fackler <augie@google.com> [Tue, 20 Jun 2017 17:31:18 -0400] rev 33286
tests: clean up even more direct `python` calls with $PYTHON
This time ones that are prefixed with =, ", ', or `. This appears to
be the last of them.
Differential Revision: https://phab.mercurial-scm.org/D14
Augie Fackler <augie@google.com> [Tue, 20 Jun 2017 17:25:57 -0400] rev 33285
contrib: widen the "don't use `python`" net a little
I'm still cleaning this up, but it's easier to do in bite-size chunks
like this than all at once. The negative lookahead avoids one false
positive category from some output related to finding Subversion
bindings.
Differential Revision: https://phab.mercurial-scm.org/D13
Denis Laxalde <denis.laxalde@logilab.fr> [Wed, 05 Jul 2017 13:54:53 +0200] rev 33284
followlines: join merge parents line ranges in blockdescendants() (
issue5595)
In blockdescendants(), we had an assertion when line range of a merge
changeset was not consistent depending on which parent was considered for
computation. For instance, this might occur when file content (in lookup
range) is significantly different between parent branches of the merge as
demonstrated in added tests (where we almost completely rewrite the "baz" file
while also introducing similarities with its content in the other branch we
later merge to).
Now, in such case, we combine line ranges from all parents by storing the
envelope of both line ranges. This is conservative (the line range is
extended, possibly unnecessarily) but at least this should avoid missing
descendants with changes in a range that would fall in that of one parent but
not in another one (the case of "baz: narrow change (2->2+)" changeset in
tests).
Phil Cohen <phillco@fb.com> [Tue, 04 Jul 2017 22:35:52 -0700] rev 33283
workingfilectx: add exists, lexists
Switch the lone call in merge.py to use it.
As with past refactors, the goal is to make wctx hot-swappable with an
in-memory context in the future. This change should be a no-op today.