Siddharth Agarwal <sid0@fb.com> [Tue, 31 Mar 2015 10:25:29 -0700] rev 24574
parsers: factor out most of asciilower into an internal function
We're going to reuse this in upcoming patches.
The change to Py_ssize_t is necessary because parsers.c doesn't define
PY_SSIZE_T_CLEAN. That macro changes the behavior of PyArg_ParseTuple but not
PyBytes_GET_SIZE.
Martin von Zweigbergk <martinvonz@google.com> [Tue, 31 Mar 2015 14:01:33 -0700] rev 24573
manifestv2: add support for writing new manifest format
If .hg/requires has 'manifestv2', the manifest will be written using
the new format.
Martin von Zweigbergk <martinvonz@google.com> [Fri, 27 Mar 2015 22:26:41 -0700] rev 24572
manifestv2: add support for reading new manifest format
The new manifest format is designed to be smaller, in particular to
produce smaller deltas. It stores hashes in binary and puts the hash
on a new line (for smaller deltas). It also uses stem compression to
save space for long paths. The format has room for metadata, but
that's there only for future-proofing. The parser thus accepts any
metadata and throws it away. For more information, see
http://mercurial.selenic.com/wiki/ManifestV2Plan.
The current manifest format doesn't allow an empty filename, so we use
an empty filename on the first line to tell a manifest of the new
format from the old. Since we still never write manifests in the new
format, the added code is unused, but it is tested by
test-manifest.py.
Martin von Zweigbergk <martinvonz@google.com> [Tue, 31 Mar 2015 22:45:45 -0700] rev 24571
manifestv2: set requires at repo creation time
While it should be safe to switch to the new manifest format on an
existing repo, let's keep it simple for now and make the configuration
have any effect only at repo creation time. If the configuration is
enabled then (at repo creation), we add an entry to requires and read
that instead of the configuration from then on.
Martin von Zweigbergk <martinvonz@google.com> [Tue, 31 Mar 2015 15:06:55 -0700] rev 24570
test-manifest: extract constants for binary hashes
The binary hashes are used quite frequently, so let's extract
constants for them so we don't have to repeat binascii.unhexlify() so
often.
Martin von Zweigbergk <martinvonz@google.com> [Tue, 31 Mar 2015 14:46:05 -0700] rev 24569
test-manifest: create constant for empty manifest
For symmetry with manifest v2, once we add that, let's extract a
constant for the empty v1 manifest.
Yuya Nishihara <yuya@tcha.org> [Mon, 30 Mar 2015 23:25:55 +0900] rev 24568
patchbomb: factor out scmutil.revrange() calls
This allows us to access the calculated revs in patchbomb() function.
Yuya Nishihara <yuya@tcha.org> [Tue, 31 Mar 2015 00:52:17 +0900] rev 24567
patchbomb: return outgoing revs as a smartset
This helps to factor out scmutil.revrange() calls from _getpatches() and
_getoutgoing(). In future patches, a smartset will be passed to _getpatches().
Yuya Nishihara <yuya@tcha.org> [Mon, 30 Mar 2015 23:54:29 +0900] rev 24566
templatefilters: add "upper" and "lower" for case conversion
Typically it will be used in patchbomb's flag template, which will be
implemented by future patches.
Durham Goode <durham@fb.com> [Wed, 01 Apr 2015 12:50:10 -0700] rev 24565
repoview: improve compute staticblockers perf
Previously we would compute the repoview's static blockers by finding all the
children of hidden commits that were not hidden. This was O(number of commits
since first hidden change) since 'children' requires walking every commit from
tip until the first hidden change.
The new algorithm walks all heads down until it sees a public commit. This makes
the computation O(number of draft) commits, which is much faster in large
repositories with a large number of commits and a low number of drafts.
On a large repo with 1000+ obsolete markers and the earliest draft commit around
tip~200000, this improves computehidden perf by 200x (2s to 0.01s).
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 31 Mar 2015 22:29:12 -0700] rev 24564
hgweb: add phase to {changeset} template
It's pretty surprising phase wasn't part of this template call already.
We now expose {phase} to the {changeset} template and we expose this
data to JSON.
This brings JSON output in line with the output from `hg log -Tjson`.
The lone exception is hweb doesn't print the numeric rev. As has been
stated previously, I don't believe hgweb should be exposing these
unstable identifiers. (We can add them later if we really want them.)
There is still work to bring hgweb in parity with --verbose and
--debug output from the CLI.
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 31 Mar 2015 22:35:12 -0700] rev 24563
json: implement {changeset} template
Output only contains basic changeset information for the moment. The
format is compatible with `hg log -Tjson`.
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 31 Mar 2015 21:49:10 -0700] rev 24562
test-hgweb-json: fix URL for file revision tests
Likely a copy and paste fail.
Siddharth Agarwal <sid0@fb.com> [Tue, 31 Mar 2015 19:34:37 -0700] rev 24561
dirstate._normalize: don't construct dirfoldmap if not necessary
Constructing the dirfoldmap is expensive, so if there's a hit in the
filefoldmap, don't construct the directory foldmap.
This helps with cases like 'hg add foo' where foo is already tracked: for a
large repository, the operation goes from 1.5 seconds to 1.2 (which is still
way too much, but that's a matter for another day.)
Siddharth Agarwal <sid0@fb.com> [Tue, 31 Mar 2015 19:29:39 -0700] rev 24560
dirstate.walk: don't keep track of normalized files in parallel
Rev
2bb13f2b778c changed the semantics of the work list to store (normalized,
non-normalized) pairs. All the tuple creation and destruction hurts perf: on a
large repo on OS X, 'hg status' went from 3.62 seconds to 3.78.
It also is unnecessary in most cases:
- it is clearly unnecessary on case-sensitive filesystems.
- it is also unnecessary when filenames have been read off of disk rather than
being supplied by the user.
The only case where the non-normalized case is required at all is when the file
is unknown.
To eliminate most of the perf cost, keep trace of whether the directory needs
to be normalized at all with a boolean called 'alreadynormed'. Pay the cost of
directory normalization only when necessary.
For the above large repo, 'hg status' goes to 3.63 seconds.
Siddharth Agarwal <sid0@fb.com> [Tue, 31 Mar 2015 19:18:27 -0700] rev 24559
dirstate.walk: factor out directory traversal
This function will be used in upcoming patches.
Matt Mackall <mpm@selenic.com> [Wed, 01 Apr 2015 13:27:56 -0500] rev 24558
Added signature for changeset
2e2e9a0750f9
Matt Mackall <mpm@selenic.com> [Wed, 01 Apr 2015 13:27:42 -0500] rev 24557
Added tag 3.3.3 for changeset
2e2e9a0750f9
Wagner Bruna <wbruna@softwareexpress.com.br> [Tue, 31 Mar 2015 20:20:17 -0300] rev 24556
i18n-pt_BR: synchronized with
d09262d6ec23
Matt Mackall <mpm@selenic.com> [Tue, 31 Mar 2015 18:09:21 -0500] rev 24555
tests: fix py2.4 glob for devel warnings
Matt Mackall <mpm@selenic.com> [Tue, 31 Mar 2015 17:49:46 -0500] rev 24554
merge with stable
Siddharth Agarwal <sid0@fb.com> [Tue, 31 Mar 2015 15:41:02 -0700] rev 24553
dirstate: fix order of initializing nf vs f
Result of a bad merge.
Drew Gottlieb <drgott@google.com> [Mon, 30 Mar 2015 18:10:59 -0700] rev 24552
treemanifest: make treemanifest.matches() faster
By converting treemanifest.matches() into a recursively additivie operation,
it becomes O(n).
The old matches function made a copy of the entire manifest and deleted
files that didn't match. With tree manifests, this was an O(n log n) operation
because del() was O(log n).
This change speeds up the command
"hg status --rev .^ 'relglob:*.js'
on the Mozilla repo, now taking 2.53s, down from 3.51s.
Drew Gottlieb <drgott@google.com> [Mon, 30 Mar 2015 17:21:49 -0700] rev 24551
treemanifest: add treemanifest._isempty()
During operations that involve building up a new manifest tree, it will be
useful to be able to quickly check if a submanifest is empty, and if so, to
avoid including it in the final tree. Doing this check lets us avoid creating
treemanifest structures that contain any empty submanifests.
Drew Gottlieb <drgott@google.com> [Fri, 27 Mar 2015 13:16:13 -0700] rev 24550
treemanifest: remove treemanifest._intersectfiles()
In preparation for the optimization in the following commit, this commit
removes treemanifest.matches()'s call to _intersectfiles(), and removes
_intersectfiles() itself since it's unused at this point.
Drew Gottlieb <drgott@google.com> [Mon, 30 Mar 2015 11:58:39 -0700] rev 24549
manifest: add some tests for manifest.matches()
There were no tests for the various code paths in manifestdict.matches(), so I
added some. This also adds a more complex testing manifest so that any bugs
relating to traversal of directories are more likely to be caught.
Matt Harbison <matt_harbison@yahoo.com> [Tue, 31 Mar 2015 17:42:46 -0400] rev 24548
forget: cleanup the output for an inexact case match on icasefs
Previously, specifying a file name but not matching the dirstate case yielded
the following, even though the file was actually removed:
$ hg forget capsdir1/capsdir/abc.txt
not removing capsdir\a.txt: file is already untracked
removing CapsDir\A.txt
[1]
This change doesn't appear to cause any extra filesystem accesses, even if a
nonexistant file is specified.
If a directory is specified without a case match, it is (and was previously)
still silently ignored.
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 30 Mar 2015 21:37:24 -0700] rev 24547
json: implement {branches} template
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 31 Mar 2015 14:54:56 -0700] rev 24546
json: implement {bookmarks} template
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 31 Mar 2015 14:52:21 -0700] rev 24545
json: implement {tags} template
Tags is pretty easy to implement. Let's start there.
The output is slightly different from `hg tags -Tjson`. For reference,
the CLI has the following output:
[
{
"node": "
e2049974f9a23176c2addb61d8f5b86e0d620490",
"rev": 29880,
"tag": "tip",
"type": ""
},
...
]
Our output has the format:
{
"node": "
0aeb19ea57a6d223bacddda3871cb78f24b06510",
"tags": [
{
"node": "
e2049974f9a23176c2addb61d8f5b86e0d620490",
"tag": "tag1",
"date": [
1427775457.0, 25200]
},
...
]
}
"rev" is omitted because it isn't a reliable identifier. We shouldn't
be exposing them in web APIs and giving the impression it remotely
resembles a stable identifier. Perhaps we could one day hide this behind
a config option (it might be useful to expose when running servers
locally).
The "type" of the tag isn't defined because this information isn't yet
exposed to the hgweb templater (it could be in a follow-up) and because
it is questionable whether different types should be exposed at all.
(Should the web interface really be exposing "local" tags?)
We use an object for the outer type instead of Array for a few reasons.
First, it is extensible. If we ever need to throw more global properties
into the output, we can do that without breaking backwards compatibility
(property additions should be backwards compatible). Second, uniformity
in web APIs is nice. Having everything return objects seems much saner than
a mix of array and object. Third, there are security issues with arrays
in older browsers. The JSON web services world almost never uses arrays
as the main type for this reason.
Another possibly controversial part about this patch is how dates are
defined. While JSON has a Date type, it is based on the JavaScript Date
type, which is widely considered a pile of garbage. It is a non-starter
for this reason.
Many of Mercurial's built-in date filters drop seconds resolution. So
that's a non-starter as well, since we want the API to be lossless where
possible. r
fc3339date, rfc822date, isodatesec, and date are all lossless.
However, they each require the client to perform string parsing on top of
JSON decoding. While date parsing libraries are pretty ubiquitous, some
languages don't have them out of the box. However, pretty much every
programming language can deal with UNIX timestamps (which are just
integers or floats). So, we choose to use Mercurial's internal date
representation, which in JSON is modeled as float seconds since UNIX
epoch and an integer timezone offset from UTC (keep in mind
JavaScript/JSON models all "Numbers" as double prevision floating point
numbers, so there isn't a difference between ints and floats in JSON).