D4039: shortest: cache disambiguation revset
martinvonz added a comment. I've added support for passing in a cache, so this is ready for review again, thanks. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4039 To: martinvonz, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4040: shortest: make isrev() a top-level function
martinvonz updated this revision to Diff 9888. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4040?vs=9756=9888 REVISION DETAIL https://phab.mercurial-scm.org/D4040 AFFECTED FILES mercurial/scmutil.py CHANGE DETAILS diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -462,6 +462,19 @@ repo.changelog.rev(node) # make sure node isn't filtered return node +def mayberevnum(repo, prefix): +"""Checks if the given prefix may be mistaken for a revision number""" +try: +i = int(prefix) +# if we are a pure int, then starting with zero will not be +# confused as a rev; or, obviously, if the int is larger +# than the value of the tip rev +if prefix[0:1] == b'0' or i > len(repo): +return False +return True +except ValueError: +return False + def shortesthexnodeidprefix(repo, node, minlength=1, cache=None): """Find the shortest unambiguous prefix that matches hexnode. @@ -471,28 +484,16 @@ # _partialmatch() of filtered changelog could take O(len(repo)) time, # which would be unacceptably slow. so we look for hash collision in # unfiltered space, which means some hashes may be slightly longer. -cl = repo.unfiltered().changelog - -def isrev(prefix): -try: -i = int(prefix) -# if we are a pure int, then starting with zero will not be -# confused as a rev; or, obviously, if the int is larger -# than the value of the tip rev -if prefix[0:1] == b'0' or i > len(cl): -return False -return True -except ValueError: -return False def disambiguate(prefix): """Disambiguate against revnums.""" hexnode = hex(node) for length in range(len(prefix), len(hexnode) + 1): prefix = hexnode[:length] -if not isrev(prefix): +if not mayberevnum(repo, prefix): return prefix +cl = repo.unfiltered().changelog revset = repo.ui.config('experimental', 'revisions.disambiguatewithin') if revset: revs = None To: martinvonz, #hg-reviewers, lothiraldan, pulkit Cc: yuja, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4042: shortest: use 'x' prefix to disambiguate from revnum if configured
martinvonz updated this revision to Diff 9890. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4042?vs=9758=9890 REVISION DETAIL https://phab.mercurial-scm.org/D4042 AFFECTED FILES mercurial/scmutil.py tests/test-template-functions.t CHANGE DETAILS diff --git a/tests/test-template-functions.t b/tests/test-template-functions.t --- a/tests/test-template-functions.t +++ b/tests/test-template-functions.t @@ -892,6 +892,11 @@ $ hg log -r 4 -T '{rev}:{shortest(node, 0)}\n' --hidden 4:107 + $ hg --config experimental.revisions.prefixhexnode=yes log -r 4 -T '{rev}:{shortest(node, 0)}\n' + 4:x10 + $ hg --config experimental.revisions.prefixhexnode=yes log -r 4 -T '{rev}:{shortest(node, 0)}\n' --hidden + 4:x10 + node 'c562' should be unique if the other 'c562' nodes are hidden (but we don't try the slow path to filter out hidden nodes for now) diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -490,6 +490,12 @@ def disambiguate(prefix): """Disambiguate against revnums.""" +if repo.ui.configbool('experimental', 'revisions.prefixhexnode'): +if mayberevnum(repo, prefix): +return 'x' + prefix +else: +return prefix + hexnode = hex(node) for length in range(len(prefix), len(hexnode) + 1): prefix = hexnode[:length] To: martinvonz, #hg-reviewers, lothiraldan Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4041: revisions: allow "x123" to refer to nodeid prefix "123"
martinvonz updated this revision to Diff 9889. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4041?vs=9757=9889 REVISION DETAIL https://phab.mercurial-scm.org/D4041 AFFECTED FILES mercurial/configitems.py mercurial/scmutil.py tests/test-revset.t CHANGE DETAILS diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -1773,6 +1773,16 @@ Test hexadecimal revision $ log 'id(2)' + $ log 'id(5)' + 2 + $ hg --config experimental.revisions.prefixhexnode=yes log --template '{rev}\n' -r 'id(x5)' + 2 + $ hg --config experimental.revisions.prefixhexnode=yes log --template '{rev}\n' -r 'x5' + 2 + $ hg --config experimental.revisions.prefixhexnode=yes log --template '{rev}\n' -r 'id(x)' + $ hg --config experimental.revisions.prefixhexnode=yes log --template '{rev}\n' -r 'x' + abort: 00changelog.i@: ambiguous identifier! + [255] $ log 'id(23268)' 4 $ log 'id(2785f51eece)' diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -437,6 +437,9 @@ return '%d:%s' % (rev, hexfunc(node)) def resolvehexnodeidprefix(repo, prefix): +if (prefix.startswith('x') and +repo.ui.configbool('experimental', 'revisions.prefixhexnode')): +prefix = prefix[1:] try: # Uses unfiltered repo because it's faster when prefix is ambiguous/ # This matches the shortesthexnodeidprefix() function below. diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -587,6 +587,9 @@ coreconfigitem('experimental', 'removeemptydirs', default=True, ) +coreconfigitem('experimental', 'revisions.prefixhexnode', +default=False, +) coreconfigitem('experimental', 'revlogv2', default=None, ) To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4039: shortest: cache disambiguation revset
martinvonz updated this revision to Diff 9887. martinvonz edited the summary of this revision. martinvonz retitled this revision from "[RFC] shortest: cache disambiguation revset" to "shortest: cache disambiguation revset". REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4039?vs=9755=9887 REVISION DETAIL https://phab.mercurial-scm.org/D4039 AFFECTED FILES mercurial/scmutil.py mercurial/templatefuncs.py CHANGE DETAILS diff --git a/mercurial/templatefuncs.py b/mercurial/templatefuncs.py --- a/mercurial/templatefuncs.py +++ b/mercurial/templatefuncs.py @@ -596,7 +596,7 @@ yield sep yield argstr -@templatefunc('shortest(node, minlength=4)', requires={'repo'}) +@templatefunc('shortest(node, minlength=4)', requires={'repo', 'cache'}) def shortest(context, mapping, args): """Obtain the shortest representation of a node.""" @@ -629,8 +629,9 @@ return hexnode if not node: return hexnode +cache = context.resource(mapping, 'cache') try: -return scmutil.shortesthexnodeidprefix(repo, node, minlength) +return scmutil.shortesthexnodeidprefix(repo, node, minlength, cache) except error.RepoLookupError: return hexnode diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -462,8 +462,12 @@ repo.changelog.rev(node) # make sure node isn't filtered return node -def shortesthexnodeidprefix(repo, node, minlength=1): -"""Find the shortest unambiguous prefix that matches hexnode.""" +def shortesthexnodeidprefix(repo, node, minlength=1, cache=None): +"""Find the shortest unambiguous prefix that matches hexnode. + +If "cache" is not None, it must be a dictionary that can be used for +caching between calls to this method. +""" # _partialmatch() of filtered changelog could take O(len(repo)) time, # which would be unacceptably slow. so we look for hash collision in # unfiltered space, which means some hashes may be slightly longer. @@ -491,7 +495,13 @@ revset = repo.ui.config('experimental', 'revisions.disambiguatewithin') if revset: -revs = repo.anyrevs([revset], user=True) +revs = None +if cache is not None: +revs = cache.get('disambiguationrevset') +if revs is None: +revs = repo.anyrevs([revset], user=True) +if cache is not None: +cache['disambiguationrevset'] = revs if cl.rev(node) in revs: hexnode = hex(node) for length in range(minlength, len(hexnode) + 1): To: martinvonz, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@38840: 4 new changesets
4 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/fa64a229f24b changeset: 38837:fa64a229f24b user:Martin von Zweigbergk date:Fri Aug 03 13:00:14 2018 -0700 summary: tests: avoid unnecessarily looking inside .hg/ in test-narrow* https://www.mercurial-scm.org/repo/hg/rev/8fe62ad9f4ff changeset: 38838:8fe62ad9f4ff user:Pulkit Goyal date:Fri Aug 03 22:24:58 2018 +0530 summary: sparse: add an action argument to parseconfig() https://www.mercurial-scm.org/repo/hg/rev/f64ebe7d2259 changeset: 38839:f64ebe7d2259 user:Pulkit Goyal date:Fri Aug 03 22:29:04 2018 +0530 summary: narrowspec: use sparse.parseconfig() to parse narrowspec file (BC) https://www.mercurial-scm.org/repo/hg/rev/794afa91f0a5 changeset: 38840:794afa91f0a5 bookmark:@ tag: tip user:Pulkit Goyal date:Thu Aug 02 22:44:41 2018 +0300 summary: narrowspec: remove the unused _parsestoredpatterns() function -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4040: shortest: make isrev() a top-level function
martinvonz marked an inline comment as done. martinvonz added a comment. In https://phab.mercurial-scm.org/D4040#63462, @yuja wrote: > > +def mayberevnum(repo, prefix): > > +"""Checks if the given prefix may be mistaken for a revision number""" > > +try: > > +i = int(prefix) > > +# if we are a pure int, then starting with zero will not be > > +# confused as a rev; or, obviously, if the int is larger > > +# than the value of the tip rev > > +if prefix[0:1] == b'0' or i > len(repo.changelog): > > `len(repo)` should be better since `repo.changelog` over repoview isn't > instant. Another option is to pass in an unfiltered repo as before. Good catch, I didn't mean to change that. Will fix. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4040 To: martinvonz, #hg-reviewers, lothiraldan, pulkit Cc: yuja, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4039: [RFC] shortest: cache disambiguation revset
martinvonz added a comment. In https://phab.mercurial-scm.org/D4039#63460, @yuja wrote: > > This doesn't seem like the right way to cache it. Suggestions? > > Suppose the cache exists mainly for templating, templatefuncs.shortest() > can pass in a cached revset to resolvehexnodeidprefix(), and we don't have > to take care of cache invalidation. Yep, it's pretty much only for templating, so that's a good suggestion. I'll start working on that. Thanks! > If we want to cache a prefix tree, maybe it could be turned into a "resolver" > object which the templater creates at the first shortest() call. I have a stack of changes that make the nodetree struct a Python type that can be used for this. I might clean that up and send it another day. I'll try to follow your advice here then (I don't know what a resolver is yet, but I'll figure that out later). REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4039 To: martinvonz, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4022: index: don't include nullid in len()
martinvonz updated this revision to Diff 9885. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4022?vs=9781=9885 REVISION DETAIL https://phab.mercurial-scm.org/D4022 AFFECTED FILES mercurial/cext/revlog.c mercurial/pure/parsers.py mercurial/repoview.py mercurial/revlog.py CHANGE DETAILS diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -791,10 +791,8 @@ indexformatv0_unpack = indexformatv0.unpack class revlogoldindex(list): -def __len__(self): -return list.__len__(self) + 1 def __getitem__(self, i): -if i == -1 or i == len(self) - 1: +if i == -1 or i == len(self): return (0, 0, 0, -1, -1, -1, -1, nullid) return list.__getitem__(self, i) @@ -1066,11 +1064,11 @@ yield fp def tip(self): -return self.node(len(self.index) - 2) +return self.node(len(self.index) - 1) def __contains__(self, rev): return 0 <= rev < len(self) def __len__(self): -return len(self.index) - 1 +return len(self.index) def __iter__(self): return iter(pycompat.xrange(len(self))) def revs(self, start=0, stop=None): @@ -1139,7 +1137,7 @@ i = self.index p = self._nodepos if p is None: -p = len(i) - 2 +p = len(i) - 1 else: assert p < len(i) for r in pycompat.xrange(p, -1, -1): diff --git a/mercurial/repoview.py b/mercurial/repoview.py --- a/mercurial/repoview.py +++ b/mercurial/repoview.py @@ -210,7 +210,7 @@ unfichangelog = unfi.changelog # bypass call to changelog.method unfiindex = unfichangelog.index -unfilen = len(unfiindex) - 1 +unfilen = len(unfiindex) unfinode = unfiindex[unfilen - 1][7] revs = filterrevs(unfi, self.filtername, self._visibilityexceptions) diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py --- a/mercurial/pure/parsers.py +++ b/mercurial/pure/parsers.py @@ -39,20 +39,20 @@ class BaseIndexObject(object): def __len__(self): -return self._lgt + len(self._extra) + 1 +return self._lgt + len(self._extra) def append(self, tup): self._extra.append(tup) def _fix_index(self, i): if not isinstance(i, int): raise TypeError("expecting int indexes") -if i < 0 or i >= len(self): +if i < 0 or i >= len(self) + 1: raise IndexError return i def __getitem__(self, i): -if i == -1 or i == len(self) - 1: +if i == -1 or i == len(self): return (0, 0, 0, -1, -1, -1, -1, nullid) i = self._fix_index(i) if i >= self._lgt: diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -77,8 +77,8 @@ static Py_ssize_t index_length(const indexObject *self) { if (self->added == NULL) - return self->length; - return self->length + PyList_GET_SIZE(self->added); + return self->length - 1; + return self->length + PyList_GET_SIZE(self->added) - 1; } static PyObject *nullentry; @@ -155,7 +155,7 @@ int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2; const char *c_node_id; const char *data; - Py_ssize_t length = index_length(self); + Py_ssize_t length = index_length(self) + 1; PyObject *entry; if (pos == -1 || pos == length - 1) { @@ -225,7 +225,7 @@ */ static const char *index_node(indexObject *self, Py_ssize_t pos) { - Py_ssize_t length = index_length(self); + Py_ssize_t length = index_length(self) + 1; const char *data; if (pos == length - 1 || pos == -1) @@ -286,7 +286,7 @@ if (node_check(PyTuple_GET_ITEM(obj, 7), ) == -1) return NULL; - len = index_length(self); + len = index_length(self) + 1; if (self->added == NULL) { self->added = PyList_New(0); @@ -436,7 +436,7 @@ { PyObject *iter = NULL; PyObject *iter_item = NULL; - Py_ssize_t min_idx = index_length(self) + 1; + Py_ssize_t min_idx = index_length(self) + 2; long iter_item_long; if (PyList_GET_SIZE(list) != 0) { @@ -478,7 +478,7 @@ PyObject *reachable = NULL; PyObject *val; - Py_ssize_t len = index_length(self) - 1; + Py_ssize_t len = index_length(self); long revnum; Py_ssize_t k; Py_ssize_t i; @@ -630,7 +630,7 @@ PyObject *phaseset = NULL; PyObject *phasessetlist = NULL; PyObject *rev = NULL; - Py_ssize_t len = index_length(self) - 1; + Py_ssize_t len = index_length(self); Py_ssize_t numphase = 0; Py_ssize_t minrevallphases = 0; Py_ssize_t minrevphase =
D4023: index: don't allow index[len(index)] to mean nullid
martinvonz updated this revision to Diff 9886. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4023?vs=9782=9886 REVISION DETAIL https://phab.mercurial-scm.org/D4023 AFFECTED FILES mercurial/cext/revlog.c mercurial/revlog.py tests/test-parseindex2.py CHANGE DETAILS diff --git a/tests/test-parseindex2.py b/tests/test-parseindex2.py --- a/tests/test-parseindex2.py +++ b/tests/test-parseindex2.py @@ -61,9 +61,6 @@ e[0] = offset_type(0, type) index[0] = tuple(e) -# add the magic null revision at -1 -index.append((0, 0, 0, -1, -1, -1, -1, nullid)) - return index, cache data_inlined = ( diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -792,7 +792,7 @@ class revlogoldindex(list): def __getitem__(self, i): -if i == -1 or i == len(self): +if i == -1: return (0, 0, 0, -1, -1, -1, -1, nullid) return list.__getitem__(self, i) diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -158,12 +158,12 @@ Py_ssize_t length = index_length(self) + 1; PyObject *entry; - if (pos == -1 || pos == length - 1) { + if (pos == -1) { Py_INCREF(nullentry); return nullentry; } - if (pos < 0 || pos >= length) { + if (pos < 0 || pos >= length - 1) { PyErr_SetString(PyExc_IndexError, "revlog index out of range"); return NULL; } To: martinvonz, indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4021: index: replace insert(-1, e) method by append(e) method
martinvonz updated this revision to Diff 9884. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4021?vs=9780=9884 REVISION DETAIL https://phab.mercurial-scm.org/D4021 AFFECTED FILES mercurial/bundlerepo.py mercurial/cext/revlog.c mercurial/pure/parsers.py mercurial/revlog.py mercurial/unionrepo.py CHANGE DETAILS diff --git a/mercurial/unionrepo.py b/mercurial/unionrepo.py --- a/mercurial/unionrepo.py +++ b/mercurial/unionrepo.py @@ -73,7 +73,7 @@ # I have no idea if csize is valid in the base revlog context. e = (flags, None, rsize, base, link, self.rev(p1node), self.rev(p2node), node) -self.index.insert(-1, e) +self.index.append(e) self.nodemap[node] = n self.bundlerevs.add(n) n += 1 diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -2549,7 +2549,7 @@ e = (offset_type(offset, flags), l, textlen, base, link, p1r, p2r, node) -self.index.insert(-1, e) +self.index.append(e) self.nodemap[node] = curr entry = self._io.packentry(e, self.node, self.version, curr) diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py --- a/mercurial/pure/parsers.py +++ b/mercurial/pure/parsers.py @@ -41,8 +41,7 @@ def __len__(self): return self._lgt + len(self._extra) + 1 -def insert(self, i, tup): -assert i == -1 +def append(self, tup): self._extra.append(tup) def _fix_index(self, i): diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -272,16 +272,12 @@ return -1; } -static PyObject *index_insert(indexObject *self, PyObject *args) + +static PyObject *index_append(indexObject *self, PyObject *obj) { - PyObject *obj; char *node; - int index; Py_ssize_t len; - if (!PyArg_ParseTuple(args, "iO", , )) - return NULL; - if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 8) { PyErr_SetString(PyExc_TypeError, "8-tuple required"); return NULL; @@ -292,15 +288,6 @@ len = index_length(self); - if (index < 0) - index += len; - - if (index != len - 1) { - PyErr_SetString(PyExc_IndexError, - "insert only supported at index -1"); - return NULL; - } - if (self->added == NULL) { self->added = PyList_New(0); if (self->added == NULL) @@ -311,7 +298,7 @@ return NULL; if (self->nt) - nt_insert(self, node, index); + nt_insert(self, node, len - 1); Py_CLEAR(self->headrevs); Py_RETURN_NONE; @@ -2065,8 +2052,8 @@ "get filtered head revisions"}, /* Can always do filtering */ {"deltachain", (PyCFunction)index_deltachain, METH_VARARGS, "determine revisions with deltas to reconstruct fulltext"}, - {"insert", (PyCFunction)index_insert, METH_VARARGS, -"insert an index entry"}, + {"append", (PyCFunction)index_append, METH_O, +"append an index entry"}, {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS, "match a potentially ambiguous node ID"}, {"shortest", (PyCFunction)index_shortest, METH_VARARGS, diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py --- a/mercurial/bundlerepo.py +++ b/mercurial/bundlerepo.py @@ -80,7 +80,7 @@ # start, size, full unc. size, base (unused), link, p1, p2, node e = (revlog.offset_type(start, flags), size, -1, baserev, link, self.rev(p1), self.rev(p2), node) -self.index.insert(-1, e) +self.index.append(e) self.nodemap[node] = n self.bundlerevs.add(n) n += 1 To: martinvonz, indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@38836: 2 new changesets
2 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/a232e6744ba3 changeset: 38835:a232e6744ba3 user:Martin von Zweigbergk date:Fri Aug 03 11:02:34 2018 -0700 summary: narrow: move requirement constant from changegroup to repository https://www.mercurial-scm.org/repo/hg/rev/fed6fe856333 changeset: 38836:fed6fe856333 bookmark:@ tag: tip user:Martin von Zweigbergk date:Fri Aug 03 10:56:07 2018 -0700 summary: narrow: extract part of narrowspec backup to core -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4020: pure: create type for revlog v0 index
martinvonz added a comment. In https://phab.mercurial-scm.org/D4020#63476, @yuja wrote: > Queued up to this, thanks. Can you rebase the remainder? Thanks! Will do right away. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4020 To: martinvonz, indygreg, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4020: pure: create type for revlog v0 index
This revision was automatically updated to reflect the committed changes. Closed by commit rHGda5a666f0f78: pure: create type for revlog v0 index (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4020?vs=9779=9883 REVISION DETAIL https://phab.mercurial-scm.org/D4020 AFFECTED FILES mercurial/revlog.py CHANGE DETAILS diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -790,6 +790,14 @@ indexformatv0_pack = indexformatv0.pack indexformatv0_unpack = indexformatv0.unpack +class revlogoldindex(list): +def __len__(self): +return list.__len__(self) + 1 +def __getitem__(self, i): +if i == -1 or i == len(self) - 1: +return (0, 0, 0, -1, -1, -1, -1, nullid) +return list.__getitem__(self, i) + class revlogoldio(object): def __init__(self): self.size = indexformatv0.size @@ -811,10 +819,7 @@ nodemap[e[6]] = n n += 1 -# add the magic null revision at -1 -index.append((0, 0, 0, -1, -1, -1, -1, nullid)) - -return index, nodemap, None +return revlogoldindex(index), nodemap, None def packentry(self, entry, node, version, rev): if gettype(entry[0]): To: martinvonz, indygreg, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4019: index: drop support for negative indexes into the index
This revision was automatically updated to reflect the committed changes. Closed by commit rHGc0d411ea6639: index: drop support for negative indexes into the index (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4019?vs=9778=9882 REVISION DETAIL https://phab.mercurial-scm.org/D4019 AFFECTED FILES mercurial/cext/revlog.c mercurial/pure/parsers.py CHANGE DETAILS diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py --- a/mercurial/pure/parsers.py +++ b/mercurial/pure/parsers.py @@ -48,8 +48,6 @@ def _fix_index(self, i): if not isinstance(i, int): raise TypeError("expecting int indexes") -if i < 0: -i = len(self) + i if i < 0 or i >= len(self): raise IndexError return i diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -163,9 +163,6 @@ return nullentry; } - if (pos < 0) - pos += length; - if (pos < 0 || pos >= length) { PyErr_SetString(PyExc_IndexError, "revlog index out of range"); return NULL; To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4018: index: handle index[-1] as nullid more explicitly
This revision was automatically updated to reflect the committed changes. Closed by commit rHGf3d394ea17db: index: handle index[-1] as nullid more explicitly (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4018?vs=9777=9881 REVISION DETAIL https://phab.mercurial-scm.org/D4018 AFFECTED FILES mercurial/cext/revlog.c mercurial/pure/parsers.py CHANGE DETAILS diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py --- a/mercurial/pure/parsers.py +++ b/mercurial/pure/parsers.py @@ -55,9 +55,9 @@ return i def __getitem__(self, i): +if i == -1 or i == len(self) - 1: +return (0, 0, 0, -1, -1, -1, -1, nullid) i = self._fix_index(i) -if i == len(self) - 1: -return (0, 0, 0, -1, -1, -1, -1, nullid) if i >= self._lgt: return self._extra[i - self._lgt] index = self._calculate_index(i) diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -158,19 +158,19 @@ Py_ssize_t length = index_length(self); PyObject *entry; + if (pos == -1 || pos == length - 1) { + Py_INCREF(nullentry); + return nullentry; + } + if (pos < 0) pos += length; if (pos < 0 || pos >= length) { PyErr_SetString(PyExc_IndexError, "revlog index out of range"); return NULL; } - if (pos == length - 1) { - Py_INCREF(nullentry); - return nullentry; - } - if (pos >= self->length - 1) { PyObject *obj; obj = PyList_GET_ITEM(self->added, pos - self->length + 1); To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4020: pure: create type for revlog v0 index
yuja added a comment. Queued up to this, thanks. Can you rebase the remainder? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4020 To: martinvonz, indygreg, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: D4020: pure: create type for revlog v0 index
Queued up to this, thanks. Can you rebase the remainder? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4016: revlog: remove some knowledge of sentinel nullid in index
This revision was automatically updated to reflect the committed changes. Closed by commit rHG119d14f41cb2: revlog: remove some knowledge of sentinel nullid in index (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4016?vs=9776=9878 REVISION DETAIL https://phab.mercurial-scm.org/D4016 AFFECTED FILES mercurial/revlog.py CHANGE DETAILS diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -2247,7 +2247,9 @@ revlog has grown too large to be an inline revlog, it will convert it to use multiple index and data files. """ -if not self._inline or (self.start(-2) + self.length(-2)) < _maxinline: +tiprev = len(self) - 1 +if (not self._inline or +(self.start(tiprev) + self.length(tiprev)) < _maxinline): return trinfo = tr.find(self.indexfile) @@ -2261,7 +2263,7 @@ else: # revlog was stripped at start of transaction, use all leftover data trindex = len(self) - 1 -dataoff = self.end(-2) +dataoff = self.end(tiprev) tr.add(self.datafile, dataoff) To: martinvonz, indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4005: index: store nullrev as -1 in nodetree
This revision was automatically updated to reflect the committed changes. Closed by commit rHGf738c502e43b: index: store nullrev as -1 in nodetree (authored by martinvonz, committed by ). CHANGED PRIOR TO COMMIT https://phab.mercurial-scm.org/D4005?vs=9789=9880#toc REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4005?vs=9789=9880 REVISION DETAIL https://phab.mercurial-scm.org/D4005 AFFECTED FILES mercurial/cext/revlog.c CHANGE DETAILS diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -32,7 +32,7 @@ * A base-16 trie for fast node->rev mapping. * * Positive value is index of the next node in the trie - * Negative value is a leaf: -(rev + 1) + * Negative value is a leaf: -(rev + 2) * Zero is empty */ typedef struct { @@ -231,7 +231,7 @@ Py_ssize_t length = index_length(self); const char *data; - if (pos == length - 1 || pos == INT_MAX) + if (pos == length - 1 || pos == -1) return nullid; if (pos >= length) @@ -1008,7 +1008,7 @@ const char *n; Py_ssize_t i; - v = -(v + 1); + v = -(v + 2); n = index_node(self, v); if (n == NULL) return -2; @@ -1060,17 +1060,17 @@ v = n->children[k]; if (v == 0) { - n->children[k] = -rev - 1; + n->children[k] = -rev - 2; return 0; } if (v < 0) { - const char *oldnode = index_node_existing(self, -(v + 1)); + const char *oldnode = index_node_existing(self, -(v + 2)); int noff; if (oldnode == NULL) return -1; if (!memcmp(oldnode, node, 20)) { - n->children[k] = -rev - 1; + n->children[k] = -rev - 2; return 0; } noff = nt_new(self); @@ -1095,8 +1095,8 @@ static int nt_delete_node(indexObject *self, const char *node) { - /* rev==-1 happens to get encoded as 0, which is interpreted as not set */ - return nt_insert(self, node, -1); + /* rev==-2 happens to get encoded as 0, which is interpreted as not set */ + return nt_insert(self, node, -2); } static int nt_init(indexObject *self) @@ -1118,7 +1118,7 @@ self->ntrev = (int)index_length(self) - 1; self->ntlookups = 1; self->ntmisses = 0; - if (nt_insert(self, nullid, INT_MAX) == -1) { + if (nt_insert(self, nullid, -1) == -1) { free(self->nt); self->nt = NULL; return -1; @@ -1290,7 +1290,7 @@ v = n->children[k]; if (v < 0) { const char *n; - v = -(v + 1); + v = -(v + 2); n = index_node_existing(self, v); if (n == NULL) return -3; To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4004: index: create function for deleting node from nodetree
This revision was automatically updated to reflect the committed changes. Closed by commit rHGf9fc59ea3135: index: create function for deleting node from nodetree (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4004?vs=9788=9879 REVISION DETAIL https://phab.mercurial-scm.org/D4004 AFFECTED FILES mercurial/cext/revlog.c CHANGE DETAILS diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c --- a/mercurial/cext/revlog.c +++ b/mercurial/cext/revlog.c @@ -1093,6 +1093,12 @@ return -1; } +static int nt_delete_node(indexObject *self, const char *node) +{ + /* rev==-1 happens to get encoded as 0, which is interpreted as not set */ + return nt_insert(self, node, -1); +} + static int nt_init(indexObject *self) { if (self->nt == NULL) { @@ -1792,7 +1798,7 @@ PyObject *tuple = PyList_GET_ITEM(self->added, i); PyObject *node = PyTuple_GET_ITEM(tuple, 7); - nt_insert(self, PyBytes_AS_STRING(node), -1); + nt_delete_node(self, PyBytes_AS_STRING(node)); } if (start == 0) @@ -1851,7 +1857,7 @@ if (node == NULL) return -1; - nt_insert(self, node, -1); + nt_delete_node(self, node); } if (self->added) nt_invalidate_added(self, 0); @@ -1903,7 +1909,7 @@ return -1; if (value == NULL) - return self->nt ? nt_insert(self, node, -1) : 0; + return self->nt ? nt_delete_node(self, node) : 0; rev = PyInt_AsLong(value); if (rev > INT_MAX || rev < 0) { if (!PyErr_Occurred()) To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4036: revlog: use specialized exception for ambiguous prefix lookup
This revision was automatically updated to reflect the committed changes. Closed by commit rHGdf0873ab5c14: revlog: use specialized exception for ambiguous prefix lookup (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4036?vs=9752=9875 REVISION DETAIL https://phab.mercurial-scm.org/D4036 AFFECTED FILES mercurial/error.py mercurial/localrepo.py mercurial/revlog.py mercurial/scmutil.py CHANGE DETAILS diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -480,8 +480,8 @@ def isrevsymbol(repo, symbol): """Checks if a symbol exists in the repo. -See revsymbol() for details. Raises error.LookupError if the symbol is an -ambiguous nodeid prefix. +See revsymbol() for details. Raises error.AmbiguousPrefixLookupError if the +symbol is an ambiguous nodeid prefix. """ try: revsymbol(repo, symbol) diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -91,6 +91,7 @@ RevlogError = error.RevlogError LookupError = error.LookupError +AmbiguousPrefixLookupError = error.AmbiguousPrefixLookupError CensoredNodeError = error.CensoredNodeError ProgrammingError = error.ProgrammingError @@ -1788,8 +1789,8 @@ # parsers.c radix tree lookup gave multiple matches # fast path: for unfiltered changelog, radix tree is accurate if not getattr(self, 'filteredrevs', None): -raise LookupError(id, self.indexfile, - _('ambiguous identifier')) +raise AmbiguousPrefixLookupError(id, self.indexfile, + _('ambiguous identifier')) # fall through to slow path that filters hidden revisions except (AttributeError, ValueError): # we are pure python, or key was too short to search radix tree @@ -1810,8 +1811,8 @@ if len(nl) == 1 and not maybewdir: self._pcache[id] = nl[0] return nl[0] -raise LookupError(id, self.indexfile, - _('ambiguous identifier')) +raise AmbiguousPrefixLookupError(id, self.indexfile, + _('ambiguous identifier')) if maybewdir: raise error.WdirUnsupported return None diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -860,7 +860,8 @@ def __contains__(self, changeid): """True if the given changeid exists -error.LookupError is raised if an ambiguous node specified. +error.AmbiguousPrefixLookupError is raised if an ambiguous node +specified. """ try: self[changeid] diff --git a/mercurial/error.py b/mercurial/error.py --- a/mercurial/error.py +++ b/mercurial/error.py @@ -58,6 +58,9 @@ def __str__(self): return RevlogError.__str__(self) +class AmbiguousPrefixLookupError(LookupError): +pass + class FilteredLookupError(LookupError): pass To: martinvonz, indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4038: scmutil: make shortest() respect disambiguation revset
This revision was automatically updated to reflect the committed changes. Closed by commit rHG6f7c9527030b: scmutil: make shortest() respect disambiguation revset (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4038?vs=9754=9877 REVISION DETAIL https://phab.mercurial-scm.org/D4038 AFFECTED FILES mercurial/scmutil.py tests/test-revisions.t CHANGE DETAILS diff --git a/tests/test-revisions.t b/tests/test-revisions.t --- a/tests/test-revisions.t +++ b/tests/test-revisions.t @@ -23,6 +23,12 @@ > [experimental] > revisions.disambiguatewithin=:3 > EOF + $ hg l + 4:7ba5d + 3:7b + 2:72 + 1:9 + 0:b 9 was unambiguous and still is $ hg l -r 9 1:9 @@ -32,6 +38,6 @@ [255] 7b is no longer ambiguous $ hg l -r 7b - 3:7ba57 + 3:7b $ cd .. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -489,6 +489,21 @@ if not isrev(prefix): return prefix +revset = repo.ui.config('experimental', 'revisions.disambiguatewithin') +if revset: +revs = repo.anyrevs([revset], user=True) +if cl.rev(node) in revs: +hexnode = hex(node) +for length in range(minlength, len(hexnode) + 1): +matches = [] +prefix = hexnode[:length] +for rev in revs: +otherhexnode = repo[rev].hex() +if prefix == otherhexnode[:length]: +matches.append(otherhexnode) +if len(matches) == 1: +return disambiguate(prefix) + try: return disambiguate(cl.shortest(node, minlength)) except error.LookupError: To: martinvonz, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4037: lookup: add option to disambiguate prefix within revset
This revision was automatically updated to reflect the committed changes. Closed by commit rHG503f936489dd: lookup: add option to disambiguate prefix within revset (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4037?vs=9753=9876 REVISION DETAIL https://phab.mercurial-scm.org/D4037 AFFECTED FILES mercurial/configitems.py mercurial/scmutil.py tests/test-revisions.t CHANGE DETAILS diff --git a/tests/test-revisions.t b/tests/test-revisions.t new file mode 100644 --- /dev/null +++ b/tests/test-revisions.t @@ -0,0 +1,37 @@ + $ hg init repo + $ cd repo + + $ echo 0 > a + $ hg ci -qAm 0 + $ for i in 5 8 14 43; do + > hg up -q 0 + > echo $i > a + > hg ci -qm $i + > done + $ cat <> .hg/hgrc + > [alias] + > l = log -T '{rev}:{shortest(node,1)}\n' + > EOF + + $ hg l + 4:7ba5d + 3:7ba57 + 2:72 + 1:9 + 0:b + $ cat <> .hg/hgrc + > [experimental] + > revisions.disambiguatewithin=:3 + > EOF +9 was unambiguous and still is + $ hg l -r 9 + 1:9 +7 was ambiguous and still is + $ hg l -r 7 + abort: 00changelog.i@7: ambiguous identifier! + [255] +7b is no longer ambiguous + $ hg l -r 7b + 3:7ba57 + + $ cd .. diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -437,9 +437,26 @@ return '%d:%s' % (rev, hexfunc(node)) def resolvehexnodeidprefix(repo, prefix): -# Uses unfiltered repo because it's faster when prefix is ambiguous/ -# This matches the shortesthexnodeidprefix() function below. -node = repo.unfiltered().changelog._partialmatch(prefix) +try: +# Uses unfiltered repo because it's faster when prefix is ambiguous/ +# This matches the shortesthexnodeidprefix() function below. +node = repo.unfiltered().changelog._partialmatch(prefix) +except error.AmbiguousPrefixLookupError: +revset = repo.ui.config('experimental', 'revisions.disambiguatewithin') +if revset: +# Clear config to avoid infinite recursion +configoverrides = {('experimental', +'revisions.disambiguatewithin'): None} +with repo.ui.configoverride(configoverrides): +revs = repo.anyrevs([revset], user=True) +matches = [] +for rev in revs: +node = repo.changelog.node(rev) +if hex(node).startswith(prefix): +matches.append(node) +if len(matches) == 1: +return matches[0] +raise if node is None: return repo.changelog.rev(node) # make sure node isn't filtered diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -590,6 +590,9 @@ coreconfigitem('experimental', 'revlogv2', default=None, ) +coreconfigitem('experimental', 'revisions.disambiguatewithin', +default=None, +) coreconfigitem('experimental', 'single-head-per-branch', default=False, ) To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: D4038: scmutil: make shortest() respect disambiguation revset
Queued up to this patch, thanks. > +revset = repo.ui.config('experimental', 'revisions.disambiguatewithin') > +if revset: > +revs = repo.anyrevs([revset], user=True) > +if cl.rev(node) in revs: > +hexnode = hex(node) > +for length in range(minlength, len(hexnode) + 1): > +matches = [] > +prefix = hexnode[:length] > +for rev in revs: > +otherhexnode = repo[rev].hex() > +if prefix == otherhexnode[:length]: For micro optimization, this could be `hex(cl.node(rev)).startswith(prefix)`. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: D4040: shortest: make isrev() a top-level function
> +def mayberevnum(repo, prefix): > +"""Checks if the given prefix may be mistaken for a revision number""" > +try: > +i = int(prefix) > +# if we are a pure int, then starting with zero will not be > +# confused as a rev; or, obviously, if the int is larger > +# than the value of the tip rev > +if prefix[0:1] == b'0' or i > len(repo.changelog): `len(repo)` should be better since `repo.changelog` over repoview isn't instant. Another option is to pass in an unfiltered repo as before. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: D4039: [RFC] shortest: cache disambiguation revset
> This doesn't seem like the right way to cache it. Suggestions? Suppose the cache exists mainly for templating, templatefuncs.shortest() can pass in a cached revset to resolvehexnodeidprefix(), and we don't have to take care of cache invalidation. If we want to cache a prefix tree, maybe it could be turned into a "resolver" object which the templater creates at the first shortest() call. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4038: scmutil: make shortest() respect disambiguation revset
yuja added a comment. Queued up to this patch, thanks. > +revset = repo.ui.config('experimental', 'revisions.disambiguatewithin') > +if revset: > +revs = repo.anyrevs([revset], user=True) > +if cl.rev(node) in revs: > +hexnode = hex(node) > +for length in range(minlength, len(hexnode) + 1): > +matches = [] > +prefix = hexnode[:length] > +for rev in revs: > +otherhexnode = repo[rev].hex() > +if prefix == otherhexnode[:length]: For micro optimization, this could be `hex(cl.node(rev)).startswith(prefix)`. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4038 To: martinvonz, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4039: [RFC] shortest: cache disambiguation revset
yuja added a comment. > This doesn't seem like the right way to cache it. Suggestions? Suppose the cache exists mainly for templating, templatefuncs.shortest() can pass in a cached revset to resolvehexnodeidprefix(), and we don't have to take care of cache invalidation. If we want to cache a prefix tree, maybe it could be turned into a "resolver" object which the templater creates at the first shortest() call. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4039 To: martinvonz, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4040: shortest: make isrev() a top-level function
yuja added a comment. > +def mayberevnum(repo, prefix): > +"""Checks if the given prefix may be mistaken for a revision number""" > +try: > +i = int(prefix) > +# if we are a pure int, then starting with zero will not be > +# confused as a rev; or, obviously, if the int is larger > +# than the value of the tip rev > +if prefix[0:1] == b'0' or i > len(repo.changelog): `len(repo)` should be better since `repo.changelog` over repoview isn't instant. Another option is to pass in an unfiltered repo as before. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4040 To: martinvonz, #hg-reviewers, lothiraldan, pulkit Cc: yuja, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4099: narrow: move .hg/narrowspec to .hg/store/narrowspec (BC)
martinvonz updated this revision to Diff 9874. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4099?vs=9861=9874 REVISION DETAIL https://phab.mercurial-scm.org/D4099 AFFECTED FILES hgext/narrow/__init__.py hgext/narrow/narrowrepo.py mercurial/localrepo.py mercurial/narrowspec.py mercurial/store.py tests/test-narrow-debugcommands.t tests/test-narrow-pull.t CHANGE DETAILS diff --git a/tests/test-narrow-pull.t b/tests/test-narrow-pull.t --- a/tests/test-narrow-pull.t +++ b/tests/test-narrow-pull.t @@ -166,7 +166,6 @@ We should also be able to unshare without breaking everything: $ hg unshare - devel-warn: write with no wlock: "narrowspec" at: */hgext/narrow/narrowrepo.py:* (unsharenarrowspec) (glob) $ hg verify checking changesets checking manifests diff --git a/tests/test-narrow-debugcommands.t b/tests/test-narrow-debugcommands.t --- a/tests/test-narrow-debugcommands.t +++ b/tests/test-narrow-debugcommands.t @@ -1,7 +1,7 @@ $ . "$TESTDIR/narrow-library.sh" $ hg init repo $ cd repo - $ cat << EOF > .hg/narrowspec + $ cat << EOF > .hg/store/narrowspec > [include] > path:foo > [exclude] diff --git a/mercurial/store.py b/mercurial/store.py --- a/mercurial/store.py +++ b/mercurial/store.py @@ -317,8 +317,8 @@ mode = None return mode -_data = ('data meta 00manifest.d 00manifest.i 00changelog.d 00changelog.i' - ' phaseroots obsstore') +_data = ('narrowspec data meta 00manifest.d 00manifest.i' + ' 00changelog.d 00changelog.i phaseroots obsstore') def isrevlog(f, kind, st): return kind == stat.S_IFREG and f[-2:] in ('.i', '.d') @@ -546,7 +546,7 @@ raise def copylist(self): -d = ('data meta dh fncache phaseroots obsstore' +d = ('narrowspec data meta dh fncache phaseroots obsstore' ' 00manifest.d 00manifest.i 00changelog.d 00changelog.i') return (['requires', '00changelog.i'] + ['store/' + f for f in d.split()]) diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -108,7 +108,7 @@ def load(repo): try: -spec = repo.vfs.read(FILENAME) +spec = repo.svfs.read(FILENAME) except IOError as e: # Treat "narrowspec does not exist" the same as "narrowspec file exists # and is empty". @@ -125,19 +125,19 @@ def save(repo, includepats, excludepats): spec = format(includepats, excludepats) -repo.vfs.write(FILENAME, spec) +repo.svfs.write(FILENAME, spec) def savebackup(repo, backupname): if repository.NARROW_REQUIREMENT not in repo.requirements: return vfs = repo.vfs vfs.tryunlink(backupname) -util.copyfile(vfs.join(FILENAME), vfs.join(backupname), hardlink=True) +util.copyfile(repo.svfs.join(FILENAME), vfs.join(backupname), hardlink=True) def restorebackup(repo, backupname): if repository.NARROW_REQUIREMENT not in repo.requirements: return -repo.vfs.rename(backupname, FILENAME) +util.rename(repo.vfs.join(backupname), repo.svfs.join(FILENAME)) def clearbackup(repo, backupname): if repository.NARROW_REQUIREMENT not in repo.requirements: diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -811,7 +811,7 @@ " working parent %s!\n") % short(node)) return nullid -@repofilecache(narrowspec.FILENAME) +@storecache(narrowspec.FILENAME) def narrowpats(self): """matcher patterns for this repository's narrowspec @@ -823,7 +823,7 @@ source = hg.sharedreposource(self) return narrowspec.load(source) -@repofilecache(narrowspec.FILENAME) +@storecache(narrowspec.FILENAME) def _narrowmatch(self): if repository.NARROW_REQUIREMENT not in self.requirements: return matchmod.always(self.root, '') diff --git a/hgext/narrow/narrowrepo.py b/hgext/narrow/narrowrepo.py --- a/hgext/narrow/narrowrepo.py +++ b/hgext/narrow/narrowrepo.py @@ -7,34 +7,11 @@ from __future__ import absolute_import -from mercurial import ( -hg, -narrowspec, -repository, -) - from . import ( narrowdirstate, narrowrevlog, ) -def wrappostshare(orig, sourcerepo, destrepo, **kwargs): -orig(sourcerepo, destrepo, **kwargs) -if repository.NARROW_REQUIREMENT in sourcerepo.requirements: -with destrepo.wlock(): -with destrepo.vfs('shared', 'a') as fp: -fp.write(narrowspec.FILENAME + '\n') - -def unsharenarrowspec(orig, ui, repo, repopath): -if (repository.NARROW_REQUIREMENT in repo.requirements -and repo.path == repopath and repo.shared()): -srcrepo = hg.sharedreposource(repo) -with srcrepo.vfs(narrowspec.FILENAME) as f: -spec = f.read() -with
D4098: narrow: drop checkambig=True when restoring backup
martinvonz updated this revision to Diff 9873. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4098?vs=9860=9873 REVISION DETAIL https://phab.mercurial-scm.org/D4098 AFFECTED FILES mercurial/narrowspec.py CHANGE DETAILS diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -137,7 +137,7 @@ def restorebackup(repo, backupname): if repository.NARROW_REQUIREMENT not in repo.requirements: return -repo.vfs.rename(backupname, FILENAME, checkambig=True) +repo.vfs.rename(backupname, FILENAME) def clearbackup(repo, backupname): if repository.NARROW_REQUIREMENT not in repo.requirements: To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4097: narrow: remove a repo file-cache invalidation
martinvonz updated this revision to Diff 9872. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4097?vs=9859=9872 REVISION DETAIL https://phab.mercurial-scm.org/D4097 AFFECTED FILES mercurial/narrowspec.py CHANGE DETAILS diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -113,9 +113,6 @@ # Treat "narrowspec does not exist" the same as "narrowspec file exists # and is empty". if e.errno == errno.ENOENT: -# Without this the next call to load will use the cached -# non-existence of the file, which can cause some odd issues. -repo.invalidate(clearfilecache=True) return set(), set() raise # maybe we should care about the profiles returned too To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4096: narrow: call narrowspec.{save,restore,clear}backup directly
martinvonz updated this revision to Diff 9871. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4096?vs=9858=9871 REVISION DETAIL https://phab.mercurial-scm.org/D4096 AFFECTED FILES hgext/narrow/narrowdirstate.py hgext/shelve.py mercurial/dirstateguard.py mercurial/localrepo.py mercurial/narrowspec.py CHANGE DETAILS diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -13,6 +13,7 @@ from . import ( error, match as matchmod, +repository, sparse, util, ) @@ -129,15 +130,22 @@ spec = format(includepats, excludepats) repo.vfs.write(FILENAME, spec) -def savebackup(vfs, backupname): +def savebackup(repo, backupname): +if repository.NARROW_REQUIREMENT not in repo.requirements: +return +vfs = repo.vfs vfs.tryunlink(backupname) util.copyfile(vfs.join(FILENAME), vfs.join(backupname), hardlink=True) -def restorebackup(vfs, backupname): -vfs.rename(backupname, FILENAME, checkambig=True) +def restorebackup(repo, backupname): +if repository.NARROW_REQUIREMENT not in repo.requirements: +return +repo.vfs.rename(backupname, FILENAME, checkambig=True) -def clearbackup(vfs, backupname): -vfs.unlink(backupname) +def clearbackup(repo, backupname): +if repository.NARROW_REQUIREMENT not in repo.requirements: +return +repo.vfs.unlink(backupname) def restrictpatterns(req_includes, req_excludes, repo_includes, repo_excludes): r""" Restricts the patterns according to repo settings, diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1372,6 +1372,7 @@ else: # discard all changes (including ones already written # out) in this transaction +narrowspec.restorebackup(self, 'journal.narrowspec') repo.dirstate.restorebackup(None, 'journal.dirstate') repo.invalidate(clearfilecache=True) @@ -1460,6 +1461,7 @@ @unfilteredmethod def _writejournal(self, desc): self.dirstate.savebackup(None, 'journal.dirstate') +narrowspec.savebackup(self, 'journal.narrowspec') self.vfs.write("journal.branch", encoding.fromlocal(self.dirstate.branch())) self.vfs.write("journal.desc", @@ -1547,6 +1549,7 @@ # prevent dirstateguard from overwriting already restored one dsguard.close() +narrowspec.restorebackup(self, 'undo.narrowspec') self.dirstate.restorebackup(None, 'undo.dirstate') try: branch = self.vfs.read('undo.branch') diff --git a/mercurial/dirstateguard.py b/mercurial/dirstateguard.py --- a/mercurial/dirstateguard.py +++ b/mercurial/dirstateguard.py @@ -11,6 +11,7 @@ from . import ( error, +narrowspec, util, ) @@ -33,7 +34,10 @@ self._active = False self._closed = False self._backupname = 'dirstate.backup.%s.%d' % (name, id(self)) +self._narrowspecbackupname = ('narrowspec.backup.%s.%d' % + (name, id(self))) repo.dirstate.savebackup(repo.currenttransaction(), self._backupname) +narrowspec.savebackup(repo, self._narrowspecbackupname) self._active = True def __del__(self): @@ -52,10 +56,12 @@ self._repo.dirstate.clearbackup(self._repo.currenttransaction(), self._backupname) +narrowspec.clearbackup(self._repo, self._narrowspecbackupname) self._active = False self._closed = True def _abort(self): +narrowspec.restorebackup(self._repo, self._narrowspecbackupname) self._repo.dirstate.restorebackup(self._repo.currenttransaction(), self._backupname) self._active = False diff --git a/hgext/shelve.py b/hgext/shelve.py --- a/hgext/shelve.py +++ b/hgext/shelve.py @@ -41,6 +41,7 @@ lock as lockmod, mdiff, merge, +narrowspec, node as nodemod, patch, phases, @@ -314,10 +315,13 @@ '''Abort current transaction for shelve/unshelve, but keep dirstate ''' tr = repo.currenttransaction() -backupname = 'dirstate.shelve' -repo.dirstate.savebackup(tr, backupname) +dirstatebackupname = 'dirstate.shelve' +narrowspecbackupname = 'narrowspec.shelve' +repo.dirstate.savebackup(tr, dirstatebackupname) +narrowspec.savebackup(repo, narrowspecbackupname) tr.abort() -repo.dirstate.restorebackup(None, backupname) +narrowspec.restorebackup(repo, narrowspecbackupname) +repo.dirstate.restorebackup(None, dirstatebackupname) def createcmd(ui, repo, pats, opts): """subcommand that creates a new shelve""" diff --git a/hgext/narrow/narrowdirstate.py
D4058: narrowspec: remove the unused _parsestoredpatterns() function
This revision was automatically updated to reflect the committed changes. Closed by commit rHG794afa91f0a5: narrowspec: remove the unused _parsestoredpatterns() function (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4058?vs=9830=9870 REVISION DETAIL https://phab.mercurial-scm.org/D4058 AFFECTED FILES mercurial/narrowspec.py CHANGE DETAILS diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -19,29 +19,6 @@ FILENAME = 'narrowspec' -def _parsestoredpatterns(text): -"""Parses the narrowspec format that's stored on disk.""" -patlist = None -includepats = [] -excludepats = [] -for l in text.splitlines(): -if l == '[includes]': -if patlist is None: -patlist = includepats -else: -raise error.Abort(_('narrowspec includes section must appear ' -'at most once, before excludes')) -elif l == '[excludes]': -if patlist is not excludepats: -patlist = excludepats -else: -raise error.Abort(_('narrowspec excludes section must appear ' -'at most once')) -else: -patlist.append(l) - -return set(includepats), set(excludepats) - def parseserverpatterns(text): """Parses the narrowspec format that's returned by the server.""" includepats = set() To: pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4056: sparse: add an action argument to parseconfig()
This revision was automatically updated to reflect the committed changes. Closed by commit rHG8fe62ad9f4ff: sparse: add an action argument to parseconfig() (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4056?vs=9828=9868 REVISION DETAIL https://phab.mercurial-scm.org/D4056 AFFECTED FILES mercurial/sparse.py CHANGE DETAILS diff --git a/mercurial/sparse.py b/mercurial/sparse.py --- a/mercurial/sparse.py +++ b/mercurial/sparse.py @@ -31,9 +31,11 @@ # a per-repo option, possibly a repo requirement. enabled = False -def parseconfig(ui, raw): +def parseconfig(ui, raw, action): """Parse sparse config file content. +action is the command which is trigerring this read, can be narrow, sparse + Returns a tuple of includes, excludes, and profiles. """ includes = set() @@ -54,24 +56,25 @@ elif line == '[include]': if havesection and current != includes: # TODO pass filename into this API so we can report it. -raise error.Abort(_('sparse config cannot have includes ' + -'after excludes')) +raise error.Abort(_('%s config cannot have includes ' + +'after excludes') % action) havesection = True current = includes continue elif line == '[exclude]': havesection = True current = excludes elif line: if current is None: -raise error.Abort(_('sparse config entry outside of ' -'section: %s') % line, +raise error.Abort(_('%s config entry outside of ' +'section: %s') % (action, line), hint=_('add an [include] or [exclude] line ' 'to declare the entry type')) if line.strip().startswith('/'): -ui.warn(_('warning: sparse profile cannot use' + - ' paths starting with /, ignoring %s\n') % line) +ui.warn(_('warning: %s profile cannot use' + + ' paths starting with /, ignoring %s\n') +% (action, line)) continue current.add(line) @@ -102,7 +105,7 @@ raise error.Abort(_('cannot parse sparse patterns from working ' 'directory')) -includes, excludes, profiles = parseconfig(repo.ui, raw) +includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse') ctx = repo[rev] if profiles: @@ -128,7 +131,7 @@ repo.ui.debug(msg) continue -pincludes, pexcludes, subprofs = parseconfig(repo.ui, raw) +pincludes, pexcludes, subprofs = parseconfig(repo.ui, raw, 'sparse') includes.update(pincludes) excludes.update(pexcludes) profiles.update(subprofs) @@ -516,7 +519,7 @@ force=False, removing=False): """Update the sparse config and working directory state.""" raw = repo.vfs.tryread('sparse') -oldincludes, oldexcludes, oldprofiles = parseconfig(repo.ui, raw) +oldincludes, oldexcludes, oldprofiles = parseconfig(repo.ui, raw, 'sparse') oldstatus = repo.status() oldmatch = matcher(repo) @@ -556,7 +559,7 @@ """ with repo.wlock(): raw = repo.vfs.tryread('sparse') -includes, excludes, profiles = parseconfig(repo.ui, raw) +includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse') if not includes and not excludes: return @@ -572,7 +575,7 @@ with repo.wlock(): # read current configuration raw = repo.vfs.tryread('sparse') -includes, excludes, profiles = parseconfig(repo.ui, raw) +includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse') aincludes, aexcludes, aprofiles = activeconfig(repo) # Import rules on top; only take in rules that are not yet @@ -582,7 +585,8 @@ with util.posixfile(util.expandpath(p), mode='rb') as fh: raw = fh.read() -iincludes, iexcludes, iprofiles = parseconfig(repo.ui, raw) +iincludes, iexcludes, iprofiles = parseconfig(repo.ui, raw, + 'sparse') oldsize = len(includes) + len(excludes) + len(profiles) includes.update(iincludes - aincludes) excludes.update(iexcludes - aexcludes) @@ -615,7 +619,8 @@ """ with repo.wlock(): raw = repo.vfs.tryread('sparse') -oldinclude, oldexclude, oldprofiles = parseconfig(repo.ui, raw) +oldinclude, oldexclude, oldprofiles = parseconfig(repo.ui, raw, +
D4057: narrowspec: use sparse.parseconfig() to parse narrowspec file (BC)
This revision was automatically updated to reflect the committed changes. Closed by commit rHGf64ebe7d2259: narrowspec: use sparse.parseconfig() to parse narrowspec file (BC) (authored by pulkit, committed by ). CHANGED PRIOR TO COMMIT https://phab.mercurial-scm.org/D4057?vs=9829=9869#toc REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4057?vs=9829=9869 REVISION DETAIL https://phab.mercurial-scm.org/D4057 AFFECTED FILES mercurial/narrowspec.py tests/test-narrow-debugcommands.t CHANGE DETAILS diff --git a/tests/test-narrow-debugcommands.t b/tests/test-narrow-debugcommands.t --- a/tests/test-narrow-debugcommands.t +++ b/tests/test-narrow-debugcommands.t @@ -2,9 +2,9 @@ $ hg init repo $ cd repo $ cat << EOF > .hg/narrowspec - > [includes] + > [include] > path:foo - > [excludes] + > [exclude] > EOF $ echo treemanifest >> .hg/requires $ echo narrowhg-experimental >> .hg/requires diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -13,6 +13,7 @@ from . import ( error, match as matchmod, +sparse, util, ) @@ -107,10 +108,10 @@ return set(normalizepattern(p) for p in pats) def format(includes, excludes): -output = '[includes]\n' +output = '[include]\n' for i in sorted(includes - excludes): output += i + '\n' -output += '[excludes]\n' +output += '[exclude]\n' for e in sorted(excludes): output += e + '\n' return output @@ -139,7 +140,13 @@ repo.invalidate(clearfilecache=True) return set(), set() raise -return _parsestoredpatterns(spec) +# maybe we should care about the profiles returned too +includepats, excludepats, profiles = sparse.parseconfig(repo.ui, spec, +'narrow') +if profiles: +raise error.Abort(_("including other spec files using '%include' is not" +" suported in narrowspec")) +return includepats, excludepats def save(repo, includepats, excludepats): spec = format(includepats, excludepats) To: pulkit, durin42, #hg-reviewers, martinvonz Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4100: fix: compute changed lines lazily to make whole-file fixer tools faster
hooper created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4100 AFFECTED FILES hgext/fix.py CHANGE DETAILS diff --git a/hgext/fix.py b/hgext/fix.py --- a/hgext/fix.py +++ b/hgext/fix.py @@ -436,8 +436,8 @@ newdata = fixctx[path].data() for fixername, fixer in fixers.iteritems(): if fixer.affects(opts, fixctx, path): -ranges = lineranges(opts, path, basectxs, fixctx, newdata) -command = fixer.command(ui, path, ranges) +rangesfn = lambda: lineranges(opts, path, basectxs, fixctx, newdata) +command = fixer.command(ui, path, rangesfn) if command is None: continue ui.debug('subprocess: %s\n' % (command,)) @@ -582,7 +582,7 @@ """Should this fixer run on the file at the given path and context?""" return scmutil.match(fixctx, [self._fileset], opts)(path) -def command(self, ui, path, ranges): +def command(self, ui, path, rangesfn): """A shell command to use to invoke this fixer on the given file/lines May return None if there is no appropriate command to run for the given @@ -592,6 +592,7 @@ parts = [expand(ui, self._command, {'rootpath': path, 'basename': os.path.basename(path)})] if self._linerange: +ranges = rangesfn() if not ranges: # No line ranges to fix, so don't run the fixer. return None To: hooper, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4057: narrowspec: use sparse.parseconfig() to parse narrowspec file (BC)
martinvonz added a comment. I've rebased this on top of https://phab.mercurial-scm.org/D4093 and resolved the conflicts (simply drop the changes from this patch). I'll push it once tests have finished. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4057 To: pulkit, durin42, #hg-reviewers, martinvonz Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4071: resolve: graduate resolve.mark-check from experimental, add docs
spectral updated this revision to Diff 9866. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4071?vs=9833=9866 REVISION DETAIL https://phab.mercurial-scm.org/D4071 AFFECTED FILES mercurial/commands.py mercurial/configitems.py mercurial/help/config.txt tests/test-resolve.t CHANGE DETAILS diff --git a/tests/test-resolve.t b/tests/test-resolve.t --- a/tests/test-resolve.t +++ b/tests/test-resolve.t @@ -383,7 +383,7 @@ U file1 U file2 $ echo 'remove markers' > file1 - $ hg --config experimental.resolve.mark-check=abort resolve -m + $ hg --config commands.resolve.mark-check=abort resolve -m warning: the following files still have conflict markers: file2 abort: conflict markers detected @@ -393,7 +393,7 @@ U file1 U file2 Try with --all from the hint - $ hg --config experimental.resolve.mark-check=abort resolve -m --all + $ hg --config commands.resolve.mark-check=abort resolve -m --all warning: the following files still have conflict markers: file2 (no more unresolved files) @@ -404,7 +404,7 @@ $ hg resolve -l U file1 U file2 - $ hg --config experimental.resolve.mark-check=warn resolve -m + $ hg --config commands.resolve.mark-check=warn resolve -m warning: the following files still have conflict markers: file2 (no more unresolved files) @@ -416,7 +416,7 @@ $ hg resolve -l U file1 R file2 - $ hg --config experimental.resolve.mark-check=warn resolve -m + $ hg --config commands.resolve.mark-check=warn resolve -m (no more unresolved files) $ hg resolve -l R file1 diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -443,6 +443,16 @@ :hg:`resolve --all`. (default: False) +``resolve.mark-check`` +Determines what level of checking :hg:`resolve --mark` will perform before +marking files as resolved. Valid values are ``none`, ``warn``, and +``abort``. ``warn`` will output a warning listing the file(s) that still +have conflict markers in them, but will still mark everything resolved. +``abort`` will output the same warning but will not mark things as resolved. +If -all is passed and this is set to ``abort``, only a warning will be +shown (an error will not be raised). +(default: ``none``) + ``status.relative`` Make paths in :hg:`status` output relative to the current directory. (default: False) diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -934,7 +934,7 @@ default=True, alias=[('format', 'aggressivemergedeltas')], ) -coreconfigitem('experimental', 'resolve.mark-check', +coreconfigitem('commands', 'resolve.mark-check', default=None, ) coreconfigitem('server', 'bookmarks-pushkey-compat', diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -4603,7 +4603,7 @@ tocomplete = [] hasconflictmarkers = [] if mark: -markcheck = ui.config('experimental', 'resolve.mark-check') +markcheck = ui.config('commands', 'resolve.mark-check') for f in ms: if not m(f): continue To: spectral, #hg-reviewers Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4071: resolve: graduate resolve.mark-check from experimental, add docs
spectral marked an inline comment as done. spectral added inline comments. INLINE COMMENTS > pulkit wrote in config.txt:452 > Maybe rephrase to something like that if `--all` flag is passed, only warning > will be shown and error won't be raised. > (I am not good at english, so feel free to decide how it is better and let me > know, I will push then.) Please take another look. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4071 To: spectral, #hg-reviewers Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3976: grep: add MULTIREV support to --all-files flag
sangeet259 added a comment. > I also expect hg grep --all-files -r0+1 foo will show matches from both rev 0 and 1. Suppose there are ten hits in 0 and the same 10 hits in 1, do you mean we print out all the 20 results, What purpose that would serve? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3976 To: sangeet259, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3976: grep: add MULTIREV support to --all-files flag
sangeet259 added a comment. > Keeping all ctx objects might use too much memory. True I will change it to `files[f] = True` REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3976 To: sangeet259, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3976: grep: add MULTIREV support to --all-files flag
sangeet259 added a comment. > I don't think we should omit files that were seen in earlier revisions If I don't skip that would mean the same file in the same state being searched across all the revisions, and getting repetitive and redundant hits. One way I think to circumvent this is by using something like : `if f not in files or f in ctx.files()` and then checking if the new change corresponds to any match. But then, this makes it more similar to `--diff`. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3976 To: sangeet259, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@38834: 2 new changesets (1 on stable)
2 new changesets (1 on stable) in mercurial: https://www.mercurial-scm.org/repo/hg/rev/c9e6ca31cfe7 changeset: 38833:c9e6ca31cfe7 branch: stable parent: 38779:824636b08400 user:Augie Fackler date:Fri Aug 03 15:09:19 2018 -0400 summary: tests: update test expectations in pre-2.7.9 branch of this test https://www.mercurial-scm.org/repo/hg/rev/c83ad57627ae changeset: 38834:c83ad57627ae bookmark:@ tag: tip parent: 38832:ca4de8ba5b5f parent: 38833:c9e6ca31cfe7 user:Martin von Zweigbergk date:Fri Aug 03 12:35:23 2018 -0700 summary: merge with stable -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4094: narrow: move requirement constant from changegroup to repository
This revision was automatically updated to reflect the committed changes. Closed by commit rHGa232e6744ba3: narrow: move requirement constant from changegroup to repository (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4094?vs=9856=9863 REVISION DETAIL https://phab.mercurial-scm.org/D4094 AFFECTED FILES hgext/narrow/__init__.py hgext/narrow/narrowbundle2.py hgext/narrow/narrowcommands.py hgext/narrow/narrowrepo.py mercurial/changegroup.py mercurial/exchange.py mercurial/localrepo.py mercurial/repository.py CHANGE DETAILS diff --git a/mercurial/repository.py b/mercurial/repository.py --- a/mercurial/repository.py +++ b/mercurial/repository.py @@ -15,6 +15,10 @@ interfaceutil, ) +# When narrowing is finalized and no longer subject to format changes, +# we should move this to just "narrow" or similar. +NARROW_REQUIREMENT = 'narrowhg-experimental' + class ipeerconnection(interfaceutil.Interface): """Represents a "connection" to a repository. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -825,7 +825,7 @@ @repofilecache(narrowspec.FILENAME) def _narrowmatch(self): -if changegroup.NARROW_REQUIREMENT not in self.requirements: +if repository.NARROW_REQUIREMENT not in self.requirements: return matchmod.always(self.root, '') include, exclude = self.narrowpats return narrowspec.match(self.root, include=include, exclude=exclude) diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -34,6 +34,7 @@ phases, pushkey, pycompat, +repository, scmutil, sslutil, streamclone, @@ -1432,7 +1433,7 @@ old_heads = unficl.heads() clstart = len(unficl) _pullbundle2(pullop) -if changegroup.NARROW_REQUIREMENT in repo.requirements: +if repository.NARROW_REQUIREMENT in repo.requirements: # XXX narrow clones filter the heads on the server side during # XXX getbundle and result in partial replies as well. # XXX Disable pull bundles in this case as band aid to avoid diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -26,6 +26,7 @@ mdiff, phases, pycompat, +repository, util, ) @@ -39,10 +40,6 @@ LFS_REQUIREMENT = 'lfs' -# When narrowing is finalized and no longer subject to format changes, -# we should move this to just "narrow" or similar. -NARROW_REQUIREMENT = 'narrowhg-experimental' - readexactly = util.readexactly def getchunk(stream): @@ -914,7 +911,7 @@ # support versions 01 and 02. versions.discard('01') versions.discard('02') -if NARROW_REQUIREMENT in repo.requirements: +if repository.NARROW_REQUIREMENT in repo.requirements: # Versions 01 and 02 don't support revlog flags, and we need to # support that for stripping and unbundling to work. versions.discard('01') diff --git a/hgext/narrow/narrowrepo.py b/hgext/narrow/narrowrepo.py --- a/hgext/narrow/narrowrepo.py +++ b/hgext/narrow/narrowrepo.py @@ -8,9 +8,9 @@ from __future__ import absolute_import from mercurial import ( -changegroup, hg, narrowspec, +repository, ) from . import ( @@ -20,13 +20,13 @@ def wrappostshare(orig, sourcerepo, destrepo, **kwargs): orig(sourcerepo, destrepo, **kwargs) -if changegroup.NARROW_REQUIREMENT in sourcerepo.requirements: +if repository.NARROW_REQUIREMENT in sourcerepo.requirements: with destrepo.wlock(): with destrepo.vfs('shared', 'a') as fp: fp.write(narrowspec.FILENAME + '\n') def unsharenarrowspec(orig, ui, repo, repopath): -if (changegroup.NARROW_REQUIREMENT in repo.requirements +if (repository.NARROW_REQUIREMENT in repo.requirements and repo.path == repopath and repo.shared()): srcrepo = hg.sharedreposource(repo) with srcrepo.vfs(narrowspec.FILENAME) as f: diff --git a/hgext/narrow/narrowcommands.py b/hgext/narrow/narrowcommands.py --- a/hgext/narrow/narrowcommands.py +++ b/hgext/narrow/narrowcommands.py @@ -10,7 +10,6 @@ from mercurial.i18n import _ from mercurial import ( -changegroup, cmdutil, commands, discovery, @@ -24,6 +23,7 @@ pycompat, registrar, repair, +repository, repoview, util, ) @@ -101,7 +101,7 @@ def pullnarrow(orig, repo, *args, **kwargs): if opts_narrow: -repo.requirements.add(changegroup.NARROW_REQUIREMENT) +repo.requirements.add(repository.NARROW_REQUIREMENT) repo._writerequirements() return orig(repo, *args, **kwargs) @@ -114,7 +114,7 @@ def pullnarrowcmd(orig, ui, repo, *args, **opts):
D4093: tests: avoid unnecessarily looking inside .hg/ in test-narrow*
This revision was automatically updated to reflect the committed changes. Closed by commit rHGfa64a229f24b: tests: avoid unnecessarily looking inside .hg/ in test-narrow* (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4093?vs=9862=9865 REVISION DETAIL https://phab.mercurial-scm.org/D4093 AFFECTED FILES tests/test-narrow-clone-no-ellipsis.t tests/test-narrow-clone.t tests/test-narrow-expanddirstate.t tests/test-narrow-patterns.t CHANGE DETAILS diff --git a/tests/test-narrow-patterns.t b/tests/test-narrow-patterns.t --- a/tests/test-narrow-patterns.t +++ b/tests/test-narrow-patterns.t @@ -88,15 +88,13 @@ 4 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd narrow - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirA - path:dir1/dirB - path:dir2/dirA - path:dir2/dirB + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirA + X path:dir1/dirB + X path:dir2/dirA + X path:dir2/dirB $ hg manifest -r tip dir1/bar dir1/dirA/bar @@ -144,14 +142,12 @@ adding file changes added 9 changesets with 6 changes to 6 files new changesets *:* (glob) - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirB - path:dir2/dirA - path:dir2/dirB + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirB + X path:dir2/dirA + X path:dir2/dirB $ find * | sort dir1 dir1/bar @@ -206,14 +202,12 @@ adding file changes added 11 changesets with 7 changes to 7 files new changesets *:* (glob) - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirA/bar - path:dir1/dirB - path:dir2/dirA + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirA/bar + X path:dir1/dirB + X path:dir2/dirA $ find * | sort dir1 dir1/bar @@ -266,14 +260,12 @@ adding file changes added 13 changesets with 8 changes to 8 files new changesets *:* (glob) - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirA - path:dir1/dirA/bar - path:dir1/dirB + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirA + X path:dir1/dirA/bar + X path:dir1/dirB $ find * | sort dir1 dir1/bar @@ -327,13 +319,11 @@ adding file changes added 13 changesets with 9 changes to 9 files new changesets *:* (glob) - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirA/bar - path:dir1/dirB + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirA/bar + X path:dir1/dirB $ find * | sort dir1 dir1/bar diff --git a/tests/test-narrow-expanddirstate.t b/tests/test-narrow-expanddirstate.t --- a/tests/test-narrow-expanddirstate.t +++ b/tests/test-narrow-expanddirstate.t @@ -27,16 +27,16 @@ $ mkdir outside $ echo other_contents > outside/f2 - $ grep outside .hg/narrowspec + $ hg tracked | grep outside [1] - $ grep outside .hg/dirstate + $ hg files | grep outside [1] $ hg status `hg status` did not add outside. - $ grep outside .hg/narrowspec + $ hg tracked | grep outside [1] - $ grep outside .hg/dirstate + $ hg files | grep outside [1] Unfortunately this is not really a candidate for adding to narrowhg proper, @@ -115,12 +115,12 @@ `hg status` will now add outside, but not patchdir. $ DIRSTATEINCLUDES=path:outside hg status M outside/f2 - $ grep outside .hg/narrowspec - path:outside - $ grep outside .hg/dirstate > /dev/null - $ grep patchdir .hg/narrowspec + $ hg tracked | grep outside + I path:outside + $ hg files | grep outside > /dev/null + $ hg tracked | grep patchdir [1] - $ grep patchdir .hg/dirstate + $ hg files | grep patchdir [1] Get rid of the modification to outside/f2. @@ -142,9 +142,9 @@ 1 out of 1 hunks FAILED -- saving rejects to file patchdir/f3.rej abort: patch failed to apply [255] - $ grep patchdir .hg/narrowspec + $ hg tracked | grep patchdir [1] - $ grep patchdir .hg/dirstate > /dev/null + $ hg files | grep patchdir > /dev/null [1] Let's make it apply cleanly and see that it *did* expand properly @@ -159,6 +159,6 @@ applying $TESTTMP/foo.patch $ cat patchdir/f3 patched_this - $ grep patchdir .hg/narrowspec - path:patchdir - $ grep patchdir .hg/dirstate > /dev/null + $ hg tracked | grep patchdir + I path:patchdir + $ hg files | grep patchdir > /dev/null diff --git a/tests/test-narrow-clone.t b/tests/test-narrow-clone.t --- a/tests/test-narrow-clone.t +++ b/tests/test-narrow-clone.t @@ -34,10 +34,8 @@ store testonly-simplestore (reposimplestore !) - $ cat .hg/narrowspec - [includes] - path:dir/src/f10 - [excludes] + $ hg tracked + I path:dir/src/f10 $ hg tracked I path:dir/src/f10 $ hg update @@ -69,11 +67,9 @@ added 21 changesets with 19 changes to 19 files new changesets *:* (glob) $ cd narrowdir -
D4095: narrow: extract part of narrowspec backup to core
This revision was automatically updated to reflect the committed changes. Closed by commit rHGfed6fe856333: narrow: extract part of narrowspec backup to core (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4095?vs=9857=9864 REVISION DETAIL https://phab.mercurial-scm.org/D4095 AFFECTED FILES hgext/narrow/narrowdirstate.py mercurial/narrowspec.py CHANGE DETAILS diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -145,6 +145,16 @@ spec = format(includepats, excludepats) repo.vfs.write(FILENAME, spec) +def savebackup(vfs, backupname): +vfs.tryunlink(backupname) +util.copyfile(vfs.join(FILENAME), vfs.join(backupname), hardlink=True) + +def restorebackup(vfs, backupname): +vfs.rename(backupname, FILENAME, checkambig=True) + +def clearbackup(vfs, backupname): +vfs.unlink(backupname) + def restrictpatterns(req_includes, req_excludes, repo_includes, repo_excludes): r""" Restricts the patterns according to repo settings, results in a logical AND operation diff --git a/hgext/narrow/narrowdirstate.py b/hgext/narrow/narrowdirstate.py --- a/hgext/narrow/narrowdirstate.py +++ b/hgext/narrow/narrowdirstate.py @@ -12,7 +12,6 @@ error, match as matchmod, narrowspec, -util as hgutil, ) def wrapdirstate(repo, dirstate): @@ -79,21 +78,17 @@ super(narrowdirstate, self).rebuild(parent, allfiles, changedfiles) def restorebackup(self, tr, backupname): -self._opener.rename(_narrowbackupname(backupname), -narrowspec.FILENAME, checkambig=True) +narrowspec.restorebackup(self._opener, + _narrowbackupname(backupname)) super(narrowdirstate, self).restorebackup(tr, backupname) def savebackup(self, tr, backupname): super(narrowdirstate, self).savebackup(tr, backupname) - -narrowbackupname = _narrowbackupname(backupname) -self._opener.tryunlink(narrowbackupname) -hgutil.copyfile(self._opener.join(narrowspec.FILENAME), -self._opener.join(narrowbackupname), hardlink=True) +narrowspec.savebackup(self._opener, _narrowbackupname(backupname)) def clearbackup(self, tr, backupname): super(narrowdirstate, self).clearbackup(tr, backupname) -self._opener.unlink(_narrowbackupname(backupname)) +narrowspec.clearbackup(self._opener, _narrowbackupname(backupname)) dirstate.__class__ = narrowdirstate return dirstate To: martinvonz, durin42, #hg-reviewers, pulkit Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4040: shortest: make isrev() a top-level function
martinvonz marked an inline comment as done. martinvonz added inline comments. INLINE COMMENTS > pulkit wrote in scmutil.py:492 > This looks unrelated here. Not completely unrelated. I moved it down here because it's no longer needed until here. It was used on line 478 before (and given Python scoping rules, it could have been moved down even before this patch, but that makes it harder to read IMO). REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4040 To: martinvonz, #hg-reviewers, lothiraldan Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4040: shortest: make isrev() a top-level function
pulkit added inline comments. INLINE COMMENTS > scmutil.py:492 > > +cl = repo.unfiltered().changelog > revset = repo.ui.config('experimental', 'revisions.disambiguatewithin') This looks unrelated here. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4040 To: martinvonz, #hg-reviewers, lothiraldan Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4093: tests: avoid unnecessarily looking inside .hg/ in test-narrow*
martinvonz updated this revision to Diff 9862. martinvonz marked an inline comment as done. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4093?vs=9855=9862 REVISION DETAIL https://phab.mercurial-scm.org/D4093 AFFECTED FILES tests/test-narrow-clone-no-ellipsis.t tests/test-narrow-clone.t tests/test-narrow-expanddirstate.t tests/test-narrow-patterns.t CHANGE DETAILS diff --git a/tests/test-narrow-patterns.t b/tests/test-narrow-patterns.t --- a/tests/test-narrow-patterns.t +++ b/tests/test-narrow-patterns.t @@ -88,15 +88,13 @@ 4 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd narrow - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirA - path:dir1/dirB - path:dir2/dirA - path:dir2/dirB + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirA + X path:dir1/dirB + X path:dir2/dirA + X path:dir2/dirB $ hg manifest -r tip dir1/bar dir1/dirA/bar @@ -144,14 +142,12 @@ adding file changes added 9 changesets with 6 changes to 6 files new changesets *:* (glob) - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirB - path:dir2/dirA - path:dir2/dirB + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirB + X path:dir2/dirA + X path:dir2/dirB $ find * | sort dir1 dir1/bar @@ -206,14 +202,12 @@ adding file changes added 11 changesets with 7 changes to 7 files new changesets *:* (glob) - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirA/bar - path:dir1/dirB - path:dir2/dirA + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirA/bar + X path:dir1/dirB + X path:dir2/dirA $ find * | sort dir1 dir1/bar @@ -266,14 +260,12 @@ adding file changes added 13 changesets with 8 changes to 8 files new changesets *:* (glob) - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirA - path:dir1/dirA/bar - path:dir1/dirB + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirA + X path:dir1/dirA/bar + X path:dir1/dirB $ find * | sort dir1 dir1/bar @@ -327,13 +319,11 @@ adding file changes added 13 changesets with 9 changes to 9 files new changesets *:* (glob) - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirA/bar - path:dir1/dirB + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirA/bar + X path:dir1/dirB $ find * | sort dir1 dir1/bar diff --git a/tests/test-narrow-expanddirstate.t b/tests/test-narrow-expanddirstate.t --- a/tests/test-narrow-expanddirstate.t +++ b/tests/test-narrow-expanddirstate.t @@ -27,16 +27,16 @@ $ mkdir outside $ echo other_contents > outside/f2 - $ grep outside .hg/narrowspec + $ hg tracked | grep outside [1] - $ grep outside .hg/dirstate + $ hg files | grep outside [1] $ hg status `hg status` did not add outside. - $ grep outside .hg/narrowspec + $ hg tracked | grep outside [1] - $ grep outside .hg/dirstate + $ hg files | grep outside [1] Unfortunately this is not really a candidate for adding to narrowhg proper, @@ -115,12 +115,12 @@ `hg status` will now add outside, but not patchdir. $ DIRSTATEINCLUDES=path:outside hg status M outside/f2 - $ grep outside .hg/narrowspec - path:outside - $ grep outside .hg/dirstate > /dev/null - $ grep patchdir .hg/narrowspec + $ hg tracked | grep outside + I path:outside + $ hg files | grep outside > /dev/null + $ hg tracked | grep patchdir [1] - $ grep patchdir .hg/dirstate + $ hg files | grep patchdir [1] Get rid of the modification to outside/f2. @@ -142,9 +142,9 @@ 1 out of 1 hunks FAILED -- saving rejects to file patchdir/f3.rej abort: patch failed to apply [255] - $ grep patchdir .hg/narrowspec + $ hg tracked | grep patchdir [1] - $ grep patchdir .hg/dirstate > /dev/null + $ hg files | grep patchdir > /dev/null [1] Let's make it apply cleanly and see that it *did* expand properly @@ -159,6 +159,6 @@ applying $TESTTMP/foo.patch $ cat patchdir/f3 patched_this - $ grep patchdir .hg/narrowspec - path:patchdir - $ grep patchdir .hg/dirstate > /dev/null + $ hg tracked | grep patchdir + I path:patchdir + $ hg files | grep patchdir > /dev/null diff --git a/tests/test-narrow-clone.t b/tests/test-narrow-clone.t --- a/tests/test-narrow-clone.t +++ b/tests/test-narrow-clone.t @@ -34,10 +34,8 @@ store testonly-simplestore (reposimplestore !) - $ cat .hg/narrowspec - [includes] - path:dir/src/f10 - [excludes] + $ hg tracked + I path:dir/src/f10 $ hg tracked I path:dir/src/f10 $ hg update @@ -69,11 +67,9 @@ added 21 changesets with 19 changes to 19 files new changesets *:* (glob) $ cd narrowdir - $ cat .hg/narrowspec - [includes] - path:dir/tests - [excludes] - path:dir/tests/t19 + $ hg tracked + I
D4093: tests: avoid unnecessarily looking inside .hg/ in test-narrow*
martinvonz marked 2 inline comments as done. martinvonz added inline comments. INLINE COMMENTS > pulkit wrote in test-narrow-expanddirstate.t:32 > Looks like you missed this comment. Yes, I didn't notice that. Sorry about that, and thanks for careful review. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4093 To: martinvonz, durin42, #hg-reviewers Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4093: tests: avoid unnecessarily looking inside .hg/ in test-narrow*
pulkit added inline comments. INLINE COMMENTS > pulkit wrote in test-narrow-expanddirstate.t:32 > This should be `hg files`. Looks like you missed this comment. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4093 To: martinvonz, durin42, #hg-reviewers Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4071: resolve: graduate resolve.mark-check from experimental, add docs
pulkit added inline comments. INLINE COMMENTS > spectral wrote in config.txt:452 > No, I didn't document the ``none`` case explicitly. This is saying that > "even if it's going to abort, adding --all will bypass the error" (this is > part of the hint when it aborts, so maybe it's not useful to mention here?) > > Should I remove this last sentence? Maybe rephrase to something like that if `--all` flag is passed, only warning will be shown and error won't be raised. (I am not good at english, so feel free to decide how it is better and let me know, I will push then.) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4071 To: spectral, #hg-reviewers Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4093: tests: avoid unnecessarily looking inside .hg/ in test-narrow*
martinvonz added a comment. In https://phab.mercurial-scm.org/D4093#63407, @pulkit wrote: > The commit message says you used `hg debugdirstate` but looking at changes, you used `hg files`. I think the commit message needs to be updated. Oops, good catch. Will fix. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4093 To: martinvonz, durin42, #hg-reviewers Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4071: resolve: graduate resolve.mark-check from experimental, add docs
spectral added inline comments. INLINE COMMENTS > pulkit wrote in config.txt:452 > I think here you mean 'none'? No, I didn't document the ``none`` case explicitly. This is saying that "even if it's going to abort, adding --all will bypass the error" (this is part of the hint when it aborts, so maybe it's not useful to mention here?) Should I remove this last sentence? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4071 To: spectral, #hg-reviewers Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4093: tests: avoid unnecessarily looking inside .hg/ in test-narrow*
pulkit added a comment. The commit message says you used `hg debugdirstate` but looking at changes, you used `hg files`. I think the commit message needs to be updated. INLINE COMMENTS > test-narrow-expanddirstate.t:32 >[1] > - $ grep outside .hg/dirstate > + $ hg tracked | grep outside >[1] This should be `hg files`. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4093 To: martinvonz, durin42, #hg-reviewers Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4099: narrow: move .hg/narrowspec to .hg/store/narrowspec (BC)
martinvonz created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The narrowspec is more closely related to the store than to the working copy. For example, if the narrowspec changes, the set of revlogs also needs to change (the working copy may change, but that depends on which commit is checked out). Also, when using the share extension, the narrowspec needs to be shared along with the store. This patch therefore moves the narrowspec into the store/ directory. This is clearly a breaking change, but I haven't bothered trying to fall back to reading the narrowspec from the old location (.hg/), because there are very few users of narrow out there. (We'll add a temporary hack to our Google-internal extension to handle the migration.) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4099 AFFECTED FILES hgext/narrow/__init__.py hgext/narrow/narrowrepo.py mercurial/localrepo.py mercurial/narrowspec.py mercurial/store.py tests/test-narrow-debugcommands.t CHANGE DETAILS diff --git a/tests/test-narrow-debugcommands.t b/tests/test-narrow-debugcommands.t --- a/tests/test-narrow-debugcommands.t +++ b/tests/test-narrow-debugcommands.t @@ -1,7 +1,7 @@ $ . "$TESTDIR/narrow-library.sh" $ hg init repo $ cd repo - $ cat << EOF > .hg/narrowspec + $ cat << EOF > .hg/store/narrowspec > [includes] > path:foo > [excludes] diff --git a/mercurial/store.py b/mercurial/store.py --- a/mercurial/store.py +++ b/mercurial/store.py @@ -317,8 +317,8 @@ mode = None return mode -_data = ('data meta 00manifest.d 00manifest.i 00changelog.d 00changelog.i' - ' phaseroots obsstore') +_data = ('narrowspec data meta 00manifest.d 00manifest.i' + ' 00changelog.d 00changelog.i phaseroots obsstore') def isrevlog(f, kind, st): return kind == stat.S_IFREG and f[-2:] in ('.i', '.d') @@ -546,7 +546,7 @@ raise def copylist(self): -d = ('data meta dh fncache phaseroots obsstore' +d = ('narrowspec data meta dh fncache phaseroots obsstore' ' 00manifest.d 00manifest.i 00changelog.d 00changelog.i') return (['requires', '00changelog.i'] + ['store/' + f for f in d.split()]) diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -130,7 +130,7 @@ def load(repo): try: -spec = repo.vfs.read(FILENAME) +spec = repo.svfs.read(FILENAME) except IOError as e: # Treat "narrowspec does not exist" the same as "narrowspec file exists # and is empty". @@ -141,19 +141,19 @@ def save(repo, includepats, excludepats): spec = format(includepats, excludepats) -repo.vfs.write(FILENAME, spec) +repo.svfs.write(FILENAME, spec) def savebackup(repo, backupname): if repository.NARROW_REQUIREMENT not in repo.requirements: return vfs = repo.vfs vfs.tryunlink(backupname) -util.copyfile(vfs.join(FILENAME), vfs.join(backupname), hardlink=True) +util.copyfile(repo.svfs.join(FILENAME), vfs.join(backupname), hardlink=True) def restorebackup(repo, backupname): if repository.NARROW_REQUIREMENT not in repo.requirements: return -repo.vfs.rename(backupname, FILENAME) +util.rename(repo.vfs.join(backupname), repo.svfs.join(FILENAME)) def clearbackup(repo, backupname): if repository.NARROW_REQUIREMENT not in repo.requirements: diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -811,7 +811,7 @@ " working parent %s!\n") % short(node)) return nullid -@repofilecache(narrowspec.FILENAME) +@storecache(narrowspec.FILENAME) def narrowpats(self): """matcher patterns for this repository's narrowspec @@ -823,7 +823,7 @@ source = hg.sharedreposource(self) return narrowspec.load(source) -@repofilecache(narrowspec.FILENAME) +@storecache(narrowspec.FILENAME) def _narrowmatch(self): if repository.NARROW_REQUIREMENT not in self.requirements: return matchmod.always(self.root, '') diff --git a/hgext/narrow/narrowrepo.py b/hgext/narrow/narrowrepo.py --- a/hgext/narrow/narrowrepo.py +++ b/hgext/narrow/narrowrepo.py @@ -7,34 +7,11 @@ from __future__ import absolute_import -from mercurial import ( -hg, -narrowspec, -repository, -) - from . import ( narrowdirstate, narrowrevlog, ) -def wrappostshare(orig, sourcerepo, destrepo, **kwargs): -orig(sourcerepo, destrepo, **kwargs) -if repository.NARROW_REQUIREMENT in sourcerepo.requirements: -with destrepo.wlock(): -with destrepo.vfs('shared', 'a') as fp: -fp.write(narrowspec.FILENAME + '\n') - -def
D4096: narrow: call narrowspec.{save,restore,clear}backup directly
martinvonz created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY I want to move .hg/narrowspec to .hg/store/narrowspec and we need to decouple the narrowspec update from the dirstate update for that. This patch lets the callers call the narrowspec backup functions directly, in addition to the dirstate backup functions. The narrowspec methods are made to check if narrowing is enabled. For that, a repo instance was needed, which all the callers luckily already had available. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4096 AFFECTED FILES hgext/narrow/narrowdirstate.py hgext/shelve.py mercurial/dirstateguard.py mercurial/localrepo.py mercurial/narrowspec.py CHANGE DETAILS diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -13,6 +13,7 @@ from . import ( error, match as matchmod, +repository, util, ) @@ -145,15 +146,22 @@ spec = format(includepats, excludepats) repo.vfs.write(FILENAME, spec) -def savebackup(vfs, backupname): +def savebackup(repo, backupname): +if repository.NARROW_REQUIREMENT not in repo.requirements: +return +vfs = repo.vfs vfs.tryunlink(backupname) util.copyfile(vfs.join(FILENAME), vfs.join(backupname), hardlink=True) -def restorebackup(vfs, backupname): -vfs.rename(backupname, FILENAME, checkambig=True) +def restorebackup(repo, backupname): +if repository.NARROW_REQUIREMENT not in repo.requirements: +return +repo.vfs.rename(backupname, FILENAME, checkambig=True) -def clearbackup(vfs, backupname): -vfs.unlink(backupname) +def clearbackup(repo, backupname): +if repository.NARROW_REQUIREMENT not in repo.requirements: +return +repo.vfs.unlink(backupname) def restrictpatterns(req_includes, req_excludes, repo_includes, repo_excludes): r""" Restricts the patterns according to repo settings, diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1372,6 +1372,7 @@ else: # discard all changes (including ones already written # out) in this transaction +narrowspec.restorebackup(self, 'journal.narrowspec') repo.dirstate.restorebackup(None, 'journal.dirstate') repo.invalidate(clearfilecache=True) @@ -1460,6 +1461,7 @@ @unfilteredmethod def _writejournal(self, desc): self.dirstate.savebackup(None, 'journal.dirstate') +narrowspec.savebackup(self, 'journal.narrowspec') self.vfs.write("journal.branch", encoding.fromlocal(self.dirstate.branch())) self.vfs.write("journal.desc", @@ -1547,6 +1549,7 @@ # prevent dirstateguard from overwriting already restored one dsguard.close() +narrowspec.restorebackup(self, 'undo.narrowspec') self.dirstate.restorebackup(None, 'undo.dirstate') try: branch = self.vfs.read('undo.branch') diff --git a/mercurial/dirstateguard.py b/mercurial/dirstateguard.py --- a/mercurial/dirstateguard.py +++ b/mercurial/dirstateguard.py @@ -11,6 +11,7 @@ from . import ( error, +narrowspec, util, ) @@ -33,7 +34,10 @@ self._active = False self._closed = False self._backupname = 'dirstate.backup.%s.%d' % (name, id(self)) +self._narrowspecbackupname = ('narrowspec.backup.%s.%d' % + (name, id(self))) repo.dirstate.savebackup(repo.currenttransaction(), self._backupname) +narrowspec.savebackup(repo, self._narrowspecbackupname) self._active = True def __del__(self): @@ -52,10 +56,12 @@ self._repo.dirstate.clearbackup(self._repo.currenttransaction(), self._backupname) +narrowspec.clearbackup(self._repo, self._narrowspecbackupname) self._active = False self._closed = True def _abort(self): +narrowspec.restorebackup(self._repo, self._narrowspecbackupname) self._repo.dirstate.restorebackup(self._repo.currenttransaction(), self._backupname) self._active = False diff --git a/hgext/shelve.py b/hgext/shelve.py --- a/hgext/shelve.py +++ b/hgext/shelve.py @@ -41,6 +41,7 @@ lock as lockmod, mdiff, merge, +narrowspec, node as nodemod, patch, phases, @@ -314,10 +315,13 @@ '''Abort current transaction for shelve/unshelve, but keep dirstate ''' tr = repo.currenttransaction() -backupname = 'dirstate.shelve' -repo.dirstate.savebackup(tr, backupname) +dirstatebackupname = 'dirstate.shelve' +narrowspecbackupname =
D4094: narrow: move requirement constant from changegroup to repository
martinvonz created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY As suggested by Gregory Szorc. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4094 AFFECTED FILES hgext/narrow/__init__.py hgext/narrow/narrowbundle2.py hgext/narrow/narrowcommands.py hgext/narrow/narrowrepo.py mercurial/changegroup.py mercurial/exchange.py mercurial/localrepo.py mercurial/repository.py CHANGE DETAILS diff --git a/mercurial/repository.py b/mercurial/repository.py --- a/mercurial/repository.py +++ b/mercurial/repository.py @@ -15,6 +15,10 @@ interfaceutil, ) +# When narrowing is finalized and no longer subject to format changes, +# we should move this to just "narrow" or similar. +NARROW_REQUIREMENT = 'narrowhg-experimental' + class ipeerconnection(interfaceutil.Interface): """Represents a "connection" to a repository. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -825,7 +825,7 @@ @repofilecache(narrowspec.FILENAME) def _narrowmatch(self): -if changegroup.NARROW_REQUIREMENT not in self.requirements: +if repository.NARROW_REQUIREMENT not in self.requirements: return matchmod.always(self.root, '') include, exclude = self.narrowpats return narrowspec.match(self.root, include=include, exclude=exclude) diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -34,6 +34,7 @@ phases, pushkey, pycompat, +repository, scmutil, sslutil, streamclone, @@ -1432,7 +1433,7 @@ old_heads = unficl.heads() clstart = len(unficl) _pullbundle2(pullop) -if changegroup.NARROW_REQUIREMENT in repo.requirements: +if repository.NARROW_REQUIREMENT in repo.requirements: # XXX narrow clones filter the heads on the server side during # XXX getbundle and result in partial replies as well. # XXX Disable pull bundles in this case as band aid to avoid diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -26,6 +26,7 @@ mdiff, phases, pycompat, +repository, util, ) @@ -39,10 +40,6 @@ LFS_REQUIREMENT = 'lfs' -# When narrowing is finalized and no longer subject to format changes, -# we should move this to just "narrow" or similar. -NARROW_REQUIREMENT = 'narrowhg-experimental' - readexactly = util.readexactly def getchunk(stream): @@ -914,7 +911,7 @@ # support versions 01 and 02. versions.discard('01') versions.discard('02') -if NARROW_REQUIREMENT in repo.requirements: +if repository.NARROW_REQUIREMENT in repo.requirements: # Versions 01 and 02 don't support revlog flags, and we need to # support that for stripping and unbundling to work. versions.discard('01') diff --git a/hgext/narrow/narrowrepo.py b/hgext/narrow/narrowrepo.py --- a/hgext/narrow/narrowrepo.py +++ b/hgext/narrow/narrowrepo.py @@ -8,9 +8,9 @@ from __future__ import absolute_import from mercurial import ( -changegroup, hg, narrowspec, +repository, ) from . import ( @@ -20,13 +20,13 @@ def wrappostshare(orig, sourcerepo, destrepo, **kwargs): orig(sourcerepo, destrepo, **kwargs) -if changegroup.NARROW_REQUIREMENT in sourcerepo.requirements: +if repository.NARROW_REQUIREMENT in sourcerepo.requirements: with destrepo.wlock(): with destrepo.vfs('shared', 'a') as fp: fp.write(narrowspec.FILENAME + '\n') def unsharenarrowspec(orig, ui, repo, repopath): -if (changegroup.NARROW_REQUIREMENT in repo.requirements +if (repository.NARROW_REQUIREMENT in repo.requirements and repo.path == repopath and repo.shared()): srcrepo = hg.sharedreposource(repo) with srcrepo.vfs(narrowspec.FILENAME) as f: diff --git a/hgext/narrow/narrowcommands.py b/hgext/narrow/narrowcommands.py --- a/hgext/narrow/narrowcommands.py +++ b/hgext/narrow/narrowcommands.py @@ -10,7 +10,6 @@ from mercurial.i18n import _ from mercurial import ( -changegroup, cmdutil, commands, discovery, @@ -24,6 +23,7 @@ pycompat, registrar, repair, +repository, repoview, util, ) @@ -101,7 +101,7 @@ def pullnarrow(orig, repo, *args, **kwargs): if opts_narrow: -repo.requirements.add(changegroup.NARROW_REQUIREMENT) +repo.requirements.add(repository.NARROW_REQUIREMENT) repo._writerequirements() return orig(repo, *args, **kwargs) @@ -114,7 +114,7 @@ def pullnarrowcmd(orig, ui, repo, *args, **opts): """Wraps pull command to allow modifying narrow spec.""" wrappedextraprepare =
D4071: resolve: graduate resolve.mark-check from experimental, add docs
pulkit added inline comments. INLINE COMMENTS > config.txt:452 > +``abort`` will output the same warning but will not mark things as > resolved. > +If this is set to ``abort``, :hg:`resolve --mark --all` will bypass the > +error and still mark everything as resolved. I think here you mean 'none'? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4071 To: spectral, #hg-reviewers Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4095: narrow: extract part of narrowspec backup to core
martinvonz created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Just a little preparation for the next patch. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4095 AFFECTED FILES hgext/narrow/narrowdirstate.py mercurial/narrowspec.py CHANGE DETAILS diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -145,6 +145,16 @@ spec = format(includepats, excludepats) repo.vfs.write(FILENAME, spec) +def savebackup(vfs, backupname): +vfs.tryunlink(backupname) +util.copyfile(vfs.join(FILENAME), vfs.join(backupname), hardlink=True) + +def restorebackup(vfs, backupname): +vfs.rename(backupname, FILENAME, checkambig=True) + +def clearbackup(vfs, backupname): +vfs.unlink(backupname) + def restrictpatterns(req_includes, req_excludes, repo_includes, repo_excludes): r""" Restricts the patterns according to repo settings, results in a logical AND operation diff --git a/hgext/narrow/narrowdirstate.py b/hgext/narrow/narrowdirstate.py --- a/hgext/narrow/narrowdirstate.py +++ b/hgext/narrow/narrowdirstate.py @@ -12,7 +12,6 @@ error, match as matchmod, narrowspec, -util as hgutil, ) def wrapdirstate(repo, dirstate): @@ -79,21 +78,17 @@ super(narrowdirstate, self).rebuild(parent, allfiles, changedfiles) def restorebackup(self, tr, backupname): -self._opener.rename(_narrowbackupname(backupname), -narrowspec.FILENAME, checkambig=True) +narrowspec.restorebackup(self._opener, + _narrowbackupname(backupname)) super(narrowdirstate, self).restorebackup(tr, backupname) def savebackup(self, tr, backupname): super(narrowdirstate, self).savebackup(tr, backupname) - -narrowbackupname = _narrowbackupname(backupname) -self._opener.tryunlink(narrowbackupname) -hgutil.copyfile(self._opener.join(narrowspec.FILENAME), -self._opener.join(narrowbackupname), hardlink=True) +narrowspec.savebackup(self._opener, _narrowbackupname(backupname)) def clearbackup(self, tr, backupname): super(narrowdirstate, self).clearbackup(tr, backupname) -self._opener.unlink(_narrowbackupname(backupname)) +narrowspec.clearbackup(self._opener, _narrowbackupname(backupname)) dirstate.__class__ = narrowdirstate return dirstate To: martinvonz, durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4097: narrow: remove a repo file-cache invalidation
martinvonz created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY It's unclear why this was needed. All tests pass without it. I asked Kyle Lippincott (who added the check) and he also doesn't remember what it was for. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4097 AFFECTED FILES mercurial/narrowspec.py CHANGE DETAILS diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -135,9 +135,6 @@ # Treat "narrowspec does not exist" the same as "narrowspec file exists # and is empty". if e.errno == errno.ENOENT: -# Without this the next call to load will use the cached -# non-existence of the file, which can cause some odd issues. -repo.invalidate(clearfilecache=True) return set(), set() raise return _parsestoredpatterns(spec) To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4093: tests: avoid unnecessarily looking inside .hg/ in test-narrow*
martinvonz created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Many of the narrow tests were looking at .hg/narrowspec. I think most of them were written before we added `hg tracked`, but now that we have that command, we should fix the tests. There were also a few instances of tests looking at .hg/dirstate. I fixed those to use `hg debugdirstate` instead. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4093 AFFECTED FILES tests/test-narrow-clone-no-ellipsis.t tests/test-narrow-clone.t tests/test-narrow-expanddirstate.t tests/test-narrow-patterns.t CHANGE DETAILS diff --git a/tests/test-narrow-patterns.t b/tests/test-narrow-patterns.t --- a/tests/test-narrow-patterns.t +++ b/tests/test-narrow-patterns.t @@ -88,15 +88,13 @@ 4 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd narrow - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirA - path:dir1/dirB - path:dir2/dirA - path:dir2/dirB + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirA + X path:dir1/dirB + X path:dir2/dirA + X path:dir2/dirB $ hg manifest -r tip dir1/bar dir1/dirA/bar @@ -144,14 +142,12 @@ adding file changes added 9 changesets with 6 changes to 6 files new changesets *:* (glob) - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirB - path:dir2/dirA - path:dir2/dirB + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirB + X path:dir2/dirA + X path:dir2/dirB $ find * | sort dir1 dir1/bar @@ -206,14 +202,12 @@ adding file changes added 11 changesets with 7 changes to 7 files new changesets *:* (glob) - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirA/bar - path:dir1/dirB - path:dir2/dirA + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirA/bar + X path:dir1/dirB + X path:dir2/dirA $ find * | sort dir1 dir1/bar @@ -266,14 +260,12 @@ adding file changes added 13 changesets with 8 changes to 8 files new changesets *:* (glob) - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirA - path:dir1/dirA/bar - path:dir1/dirB + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirA + X path:dir1/dirA/bar + X path:dir1/dirB $ find * | sort dir1 dir1/bar @@ -327,13 +319,11 @@ adding file changes added 13 changesets with 9 changes to 9 files new changesets *:* (glob) - $ cat .hg/narrowspec - [includes] - path:dir1 - path:dir2 - [excludes] - path:dir1/dirA/bar - path:dir1/dirB + $ hg tracked + I path:dir1 + I path:dir2 + X path:dir1/dirA/bar + X path:dir1/dirB $ find * | sort dir1 dir1/bar diff --git a/tests/test-narrow-expanddirstate.t b/tests/test-narrow-expanddirstate.t --- a/tests/test-narrow-expanddirstate.t +++ b/tests/test-narrow-expanddirstate.t @@ -27,16 +27,16 @@ $ mkdir outside $ echo other_contents > outside/f2 - $ grep outside .hg/narrowspec + $ hg tracked | grep outside [1] - $ grep outside .hg/dirstate + $ hg tracked | grep outside [1] $ hg status `hg status` did not add outside. - $ grep outside .hg/narrowspec + $ hg tracked | grep outside [1] - $ grep outside .hg/dirstate + $ hg files | grep outside [1] Unfortunately this is not really a candidate for adding to narrowhg proper, @@ -115,12 +115,12 @@ `hg status` will now add outside, but not patchdir. $ DIRSTATEINCLUDES=path:outside hg status M outside/f2 - $ grep outside .hg/narrowspec - path:outside - $ grep outside .hg/dirstate > /dev/null - $ grep patchdir .hg/narrowspec + $ hg tracked | grep outside + I path:outside + $ hg files | grep outside > /dev/null + $ hg tracked | grep patchdir [1] - $ grep patchdir .hg/dirstate + $ hg tracked | grep patchdir [1] Get rid of the modification to outside/f2. @@ -142,9 +142,9 @@ 1 out of 1 hunks FAILED -- saving rejects to file patchdir/f3.rej abort: patch failed to apply [255] - $ grep patchdir .hg/narrowspec + $ hg tracked | grep patchdir [1] - $ grep patchdir .hg/dirstate > /dev/null + $ hg files | grep patchdir > /dev/null [1] Let's make it apply cleanly and see that it *did* expand properly @@ -159,6 +159,6 @@ applying $TESTTMP/foo.patch $ cat patchdir/f3 patched_this - $ grep patchdir .hg/narrowspec - path:patchdir - $ grep patchdir .hg/dirstate > /dev/null + $ hg tracked | grep patchdir + I path:patchdir + $ hg files | grep patchdir > /dev/null diff --git a/tests/test-narrow-clone.t b/tests/test-narrow-clone.t --- a/tests/test-narrow-clone.t +++ b/tests/test-narrow-clone.t @@ -34,10 +34,8 @@ store testonly-simplestore (reposimplestore !) - $ cat .hg/narrowspec - [includes] - path:dir/src/f10 - [excludes] + $ hg tracked + I
D4098: narrow: drop checkambig=True when restoring backup
martinvonz created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY IIUC, checkambig is about updating timestamps of the file while renaming. That's important for the dirstate, but we never check the timestamp of the narrowspec file. We can therefore avoid checking passing checkambig=True. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4098 AFFECTED FILES mercurial/narrowspec.py CHANGE DETAILS diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -153,7 +153,7 @@ def restorebackup(repo, backupname): if repository.NARROW_REQUIREMENT not in repo.requirements: return -repo.vfs.rename(backupname, FILENAME, checkambig=True) +repo.vfs.rename(backupname, FILENAME) def clearbackup(repo, backupname): if repository.NARROW_REQUIREMENT not in repo.requirements: To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4048: fix: add a monkey-patchable point after all new revisions have been committed
hooper added inline comments. INLINE COMMENTS > pulkit wrote in fix.py:197 > If the output is not Google specific, we can have that here also under `hg > fix -v` or a config option. Unfortunately, some of it is, though that might just mean we should template it. I think there's also some difficulty around verbosity levels if you don't want to see other modules' verbose output? At the very least I think "hg fix -q" should have no output if it succeeds. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4048 To: hooper, #hg-reviewers, pulkit Cc: pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4089: changegroup: pass ellipsis roots into cgpacker constructor
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY And rename the internal variable to conform with naming conventions. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4089 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -525,7 +525,8 @@ class cgpacker(object): def __init__(self, repo, filematcher, version, allowreorder, useprevdelta, builddeltaheader, manifestsend, - sendtreemanifests, bundlecaps=None, shallow=False): + sendtreemanifests, bundlecaps=None, shallow=False, + ellipsisroots=None): """Given a source repo, construct a bundler. filematcher is a matcher that matches on files to include in the @@ -568,6 +569,9 @@ self._bundlecaps = bundlecaps self._isshallow = shallow +# Maps ellipsis revs to their roots at the changelog level. +self._precomputedellipsis = ellipsisroots + # experimental config: bundle.reorder reorder = repo.ui.config('bundle', 'reorder') if reorder == 'auto': @@ -743,7 +747,7 @@ # we skip some manifest nodes that we should otherwise # have sent. if (x in self._full_nodes -or cl.rev(x) in self._precomputed_ellipsis): +or cl.rev(x) in self._precomputedellipsis): n = c[0] # Record the first changeset introducing this manifest # version. @@ -1089,10 +1093,10 @@ # At this point, a node can either be one we should skip or an # ellipsis. If it's not an ellipsis, bail immediately. -if linkrev not in self._precomputed_ellipsis: +if linkrev not in self._precomputedellipsis: return -linkparents = self._precomputed_ellipsis[linkrev] +linkparents = self._precomputedellipsis[linkrev] def local(clrev): """Turn a changelog revnum into a local revnum. @@ -1136,8 +1140,8 @@ elif p in self._full_nodes: walk.extend([pp for pp in self._repo.changelog.parentrevs(p) if pp != nullrev]) -elif p in self._precomputed_ellipsis: -walk.extend([pp for pp in self._precomputed_ellipsis[p] +elif p in self._precomputedellipsis: +walk.extend([pp for pp in self._precomputedellipsis[p] if pp != nullrev]) else: # In this case, we've got an ellipsis with parents @@ -1191,7 +1195,8 @@ deltachunks=(diffheader, data), ) -def _makecg1packer(repo, filematcher, bundlecaps, shallow=False): +def _makecg1packer(repo, filematcher, bundlecaps, shallow=False, + ellipsisroots=None): builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.linknode) @@ -1202,9 +1207,11 @@ manifestsend=b'', sendtreemanifests=False, bundlecaps=bundlecaps, -shallow=shallow) +shallow=shallow, +ellipsisroots=ellipsisroots) -def _makecg2packer(repo, filematcher, bundlecaps, shallow=False): +def _makecg2packer(repo, filematcher, bundlecaps, shallow=False, + ellipsisroots=None): builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.basenode, d.linknode) @@ -1218,9 +1225,11 @@ manifestsend=b'', sendtreemanifests=False, bundlecaps=bundlecaps, -shallow=shallow) +shallow=shallow, +ellipsisroots=ellipsisroots) -def _makecg3packer(repo, filematcher, bundlecaps, shallow=False): +def _makecg3packer(repo, filematcher, bundlecaps, shallow=False, + ellipsisroots=None): builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) @@ -1231,7 +1240,8 @@ manifestsend=closechunk(), sendtreemanifests=True, bundlecaps=bundlecaps, -shallow=shallow) +shallow=shallow, +ellipsisroots=ellipsisroots) _packermap = {'01': (_makecg1packer, cg1unpacker), # cg2 adds support for exchanging generaldelta @@ -1292,7 +1302,7 @@ return min(versions) def getbundler(version, repo, bundlecaps=None, filematcher=None, - shallow=False): + shallow=False,
D4090: changegroup: specify ellipses mode explicitly
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Currently, code throughout changegroup relies on the presence of self._full_nodes to enable ellipses mode. This is a very tenuous check. And the check may be wrong once we move _full_nodes into cgpacker. Let's capture the enabling of ellipses mode explicitly as a constructor argument and as an instance variable. We could probably derive ellipses mode by presence of other variables. But for now, this explicit approach seems simplest since it is most compatible with existing code. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4090 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -525,8 +525,8 @@ class cgpacker(object): def __init__(self, repo, filematcher, version, allowreorder, useprevdelta, builddeltaheader, manifestsend, - sendtreemanifests, bundlecaps=None, shallow=False, - ellipsisroots=None): + sendtreemanifests, bundlecaps=None, ellipses=False, + shallow=False, ellipsisroots=None): """Given a source repo, construct a bundler. filematcher is a matcher that matches on files to include in the @@ -546,6 +546,8 @@ sendtreemanifests indicates whether tree manifests should be emitted. +ellipses indicates whether ellipsis serving mode is enabled. + bundlecaps is optional and can be used to specify the set of capabilities which can be used to build the bundle. While bundlecaps is unused in core Mercurial, extensions rely on this feature to communicate @@ -562,6 +564,7 @@ self._builddeltaheader = builddeltaheader self._manifestsend = manifestsend self._sendtreemanifests = sendtreemanifests +self._ellipses = ellipses # Set of capabilities we can use to build the bundle. if bundlecaps is None: @@ -631,7 +634,7 @@ # order that they're introduced in dramatis personae by the # changelog, so what we do is we sort the non-changelog histories # by the order in which they are used by the changelog. -if util.safehasattr(self, '_full_nodes') and self._clnodetorev: +if self._ellipses and self._clnodetorev: key = lambda n: self._clnodetorev[lookup(n)] return [store.rev(n) for n in sorted(nodelist, key=key)] @@ -732,16 +735,14 @@ mfrevlog = mfl._revlog changedfiles = set() -ellipsesmode = util.safehasattr(self, '_full_nodes') - # Callback for the changelog, used to collect changed files and # manifest nodes. # Returns the linkrev node (identity in the changelog case). def lookupcl(x): c = cl.read(x) clrevorder[x] = len(clrevorder) -if ellipsesmode: +if self._ellipses: # Only update mfs if x is going to be sent. Otherwise we # end up with bogus linkrevs specified for manifests and # we skip some manifest nodes that we should otherwise @@ -808,7 +809,7 @@ fastpathlinkrev, mfs, fnodes, source): yield chunk -if ellipsesmode: +if self._ellipses: mfdicts = None if self._isshallow: mfdicts = [(self._repo.manifestlog[n].read(), lr) @@ -828,7 +829,7 @@ revs = ((r, llr(r)) for r in filerevlog) return dict((fln(r), cln(lr)) for r, lr in revs if lr in clrevs) -if ellipsesmode: +if self._ellipses: # We need to pass the mfdicts variable down into # generatefiles(), but more than one command might have # wrapped generatefiles so we can't modify the function @@ -985,7 +986,7 @@ return prev # Narrow ellipses mode. -if util.safehasattr(self, '_full_nodes'): +if self._ellipses: # TODO: send better deltas when in narrow mode. # # changegroup.group() loops over revisions to send, @@ -1025,7 +1026,7 @@ return base def _revchunk(self, store, rev, prev, linknode): -if util.safehasattr(self, '_full_nodes'): +if self._ellipses: fn = self._revisiondeltanarrow else: fn = self._revisiondeltanormal @@ -1195,8 +1196,8 @@ deltachunks=(diffheader, data), ) -def _makecg1packer(repo, filematcher, bundlecaps, shallow=False, - ellipsisroots=None): +def _makecg1packer(repo, filematcher, bundlecaps, ellipses=False, + shallow=False, ellipsisroots=None): builddeltaheader = lambda d:
D4088: changegroup: move revision maps to cgpacker
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY And remove the underscores so the variables conform to our naming convention. The logic in _close() should be the only thing warranting scrutiny during review. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4088 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -586,12 +586,21 @@ # controlled via arguments to group() that influence behavior. self._changelogdone = False +# Maps CL revs to per-revlog revisions. Cleared in close() at +# the end of each group. +self._clrevtolocalrev = {} +self._nextclrevtolocalrev = {} + +# Maps changelog nodes to changelog revs. Filled in once +# during changelog stage and then left unmodified. +self._clnodetorev = {} + def _close(self): # Ellipses serving mode. -getattr(self, '_clrev_to_localrev', {}).clear() -if getattr(self, '_next_clrev_to_localrev', {}): -self._clrev_to_localrev = self._next_clrev_to_localrev -del self._next_clrev_to_localrev +self._clrevtolocalrev.clear() +if self._nextclrevtolocalrev: +self.clrevtolocalrev = self._nextclrevtolocalrev +self._nextclrevtolocalrev.clear() self._changelogdone = True return closechunk() @@ -618,8 +627,8 @@ # order that they're introduced in dramatis personae by the # changelog, so what we do is we sort the non-changelog histories # by the order in which they are used by the changelog. -if util.safehasattr(self, '_full_nodes') and self._clnode_to_rev: -key = lambda n: self._clnode_to_rev[lookup(n)] +if util.safehasattr(self, '_full_nodes') and self._clnodetorev: +key = lambda n: self._clnodetorev[lookup(n)] return [store.rev(n) for n in sorted(nodelist, key=key)] # for generaldelta revlogs, we linearize the revs; this will both be @@ -743,8 +752,8 @@ # manifest revnum to look up for this cl revnum. (Part of # mapping changelog ellipsis parents to manifest ellipsis # parents) -self._next_clrev_to_localrev.setdefault(cl.rev(x), -mfrevlog.rev(n)) +self._nextclrevtolocalrev.setdefault(cl.rev(x), + mfrevlog.rev(n)) # We can't trust the changed files list in the changeset if the # client requested a shallow clone. if self._isshallow: @@ -921,7 +930,7 @@ for c in commonctxs: try: fnode = c.filenode(fname) -self._clrev_to_localrev[c.rev()] = flog.rev(fnode) +self._clrevtolocalrev[c.rev()] = flog.rev(fnode) except error.ManifestLookupError: pass links = oldlinknodes(flog, fname) @@ -1066,12 +1075,12 @@ # build up some mapping information that's useful later. See # the local() nested function below. if not self._changelogdone: -self._clnode_to_rev[linknode] = rev +self._clnodetorev[linknode] = rev linkrev = rev -self._clrev_to_localrev[linkrev] = rev +self._clrevtolocalrev[linkrev] = rev else: -linkrev = self._clnode_to_rev[linknode] -self._clrev_to_localrev[linkrev] = rev +linkrev = self._clnodetorev[linknode] +self._clrevtolocalrev[linkrev] = rev # This is a node to send in full, because the changeset it # corresponds to was a full changeset. @@ -1103,9 +1112,9 @@ # need to store some extra mapping information so that # our contained ellipsis nodes will be able to resolve # their parents. -if clrev not in self._clrev_to_localrev: +if clrev not in self._clrevtolocalrev: clnode = store.node(clrev) -self._clnode_to_rev[clnode] = clrev +self._clnodetorev[clnode] = clrev return clrev # Walk the ellipsis-ized changelog breadth-first looking for a @@ -1122,8 +1131,8 @@ while walk: p = walk[0] walk = walk[1:] -if p in self._clrev_to_localrev: -return self._clrev_to_localrev[p] +if p in self._clrevtolocalrev: +return self._clrevtolocalrev[p] elif p in
D4092: changegroup: inline _packellipsischangegroup
indygreg created this revision. Herald added a reviewer: durin42. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY It now does nothing special. The logic is simple enough to inline in the 2 callers in narrow that need it. The changegroup generation APIs could probably be a bit simpler. But that's for another time. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4092 AFFECTED FILES hgext/narrow/narrowbundle2.py mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -1421,18 +1421,3 @@ (f, hex(n))) return revisions, files - -def _packellipsischangegroup(repo, common, match, relevant_nodes, - ellipsisroots, visitnodes, depth, source, version): -# We wrap cg1packer.revchunk, using a side channel to pass -# relevant_nodes into that area. Then if linknode isn't in the -# set, we know we have an ellipsis node and we should defer -# sending that node's data. We override close() to detect -# pending ellipsis nodes and flush them. -packer = getbundler(version, repo, filematcher=match, -ellipses=True, -shallow=depth is not None, -ellipsisroots=ellipsisroots, -fullnodes=relevant_nodes) - -return packer.generate(common, visitnodes, False, source) diff --git a/hgext/narrow/narrowbundle2.py b/hgext/narrow/narrowbundle2.py --- a/hgext/narrow/narrowbundle2.py +++ b/hgext/narrow/narrowbundle2.py @@ -115,10 +115,15 @@ newvisit, newfull, newellipsis = exchange._computeellipsis( repo, set(), common, known, newmatch) if newvisit: -cg = changegroup._packellipsischangegroup( -repo, common, newmatch, newfull, newellipsis, -newvisit, depth, source, version) -part = bundler.newpart('changegroup', data=cg) +packer = changegroup.getbundler(version, repo, +filematcher=newmatch, +ellipses=True, +shallow=depth is not None, +ellipsisroots=newellipsis, +fullnodes=newfull) +cgdata = packer.generate(common, newvisit, False, source) + +part = bundler.newpart('changegroup', data=cgdata) part.addparam('version', version) if 'treemanifest' in repo.requirements: part.addparam('treemanifest', '1') @@ -128,10 +133,15 @@ repo.ui.debug('Found %d relevant revs\n' % len(relevant_nodes)) if visitnodes: -cg = changegroup._packellipsischangegroup( -repo, common, newmatch, relevant_nodes, ellipsisroots, -visitnodes, depth, source, version) -part = bundler.newpart('changegroup', data=cg) +packer = changegroup.getbundler(version, repo, +filematcher=newmatch, +ellipses=True, +shallow=depth is not None, +ellipsisroots=ellipsisroots, +fullnodes=relevant_nodes) +cgdata = packer.generate(common, visitnodes, False, source) + +part = bundler.newpart('changegroup', data=cgdata) part.addparam('version', version) if 'treemanifest' in repo.requirements: part.addparam('treemanifest', '1') To: indygreg, durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4087: changegroup: move changelogdone into cgpacker
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Looking at what it is used for, it feels like there is a better way to implement all this. So recording a TODO to track that. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4087 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -582,13 +582,17 @@ else: self._verbosenote = lambda s: None +# TODO the functionality keyed off of this should probably be +# controlled via arguments to group() that influence behavior. +self._changelogdone = False + def _close(self): # Ellipses serving mode. getattr(self, '_clrev_to_localrev', {}).clear() if getattr(self, '_next_clrev_to_localrev', {}): self._clrev_to_localrev = self._next_clrev_to_localrev del self._next_clrev_to_localrev -self._changelog_done = True +self._changelogdone = True return closechunk() @@ -1061,7 +1065,7 @@ def _revisiondeltanarrow(self, store, rev, prev, linknode): # build up some mapping information that's useful later. See # the local() nested function below. -if not self._changelog_done: +if not self._changelogdone: self._clnode_to_rev[linknode] = rev linkrev = rev self._clrev_to_localrev[linkrev] = rev @@ -1093,7 +1097,7 @@ if clrev == nullrev: return nullrev -if not self._changelog_done: +if not self._changelogdone: # If we're doing the changelog, it's possible that we # have a parent that is already on the client, and we # need to store some extra mapping information so that @@ -1406,6 +1410,5 @@ # Maps changelog nodes to changelog revs. Filled in once # during changelog stage and then left unmodified. packer._clnode_to_rev = {} -packer._changelog_done = False return packer.generate(common, visitnodes, False, source) To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4091: changegroup: move fullnodes into cgpacker
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY And with this change, the narrow packer no longer defines any addition attributes on packer instances! REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4091 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -526,7 +526,7 @@ def __init__(self, repo, filematcher, version, allowreorder, useprevdelta, builddeltaheader, manifestsend, sendtreemanifests, bundlecaps=None, ellipses=False, - shallow=False, ellipsisroots=None): + shallow=False, ellipsisroots=None, fullnodes=None): """Given a source repo, construct a bundler. filematcher is a matcher that matches on files to include in the @@ -555,6 +555,10 @@ shallow indicates whether shallow data might be sent. The packer may need to pack file contents not introduced by the changes being packed. + +fullnodes is the list of nodes which should not be ellipsis nodes. We +store this rather than the set of nodes that should be ellipsis because +for very large histories we expect this to be significantly smaller. """ assert filematcher self._filematcher = filematcher @@ -571,6 +575,7 @@ bundlecaps = set() self._bundlecaps = bundlecaps self._isshallow = shallow +self._fullnodes = fullnodes # Maps ellipsis revs to their roots at the changelog level. self._precomputedellipsis = ellipsisroots @@ -747,7 +752,7 @@ # end up with bogus linkrevs specified for manifests and # we skip some manifest nodes that we should otherwise # have sent. -if (x in self._full_nodes +if (x in self._fullnodes or cl.rev(x) in self._precomputedellipsis): n = c[0] # Record the first changeset introducing this manifest @@ -1089,7 +1094,7 @@ # This is a node to send in full, because the changeset it # corresponds to was a full changeset. -if linknode in self._full_nodes: +if linknode in self._fullnodes: return self._revisiondeltanormal(store, rev, prev, linknode) # At this point, a node can either be one we should skip or an @@ -1138,7 +1143,7 @@ walk = walk[1:] if p in self._clrevtolocalrev: return self._clrevtolocalrev[p] -elif p in self._full_nodes: +elif p in self._fullnodes: walk.extend([pp for pp in self._repo.changelog.parentrevs(p) if pp != nullrev]) elif p in self._precomputedellipsis: @@ -1197,7 +1202,7 @@ ) def _makecg1packer(repo, filematcher, bundlecaps, ellipses=False, - shallow=False, ellipsisroots=None): + shallow=False, ellipsisroots=None, fullnodes=None): builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.linknode) @@ -1210,10 +1215,11 @@ bundlecaps=bundlecaps, ellipses=ellipses, shallow=shallow, -ellipsisroots=ellipsisroots) +ellipsisroots=ellipsisroots, +fullnodes=fullnodes) def _makecg2packer(repo, filematcher, bundlecaps, ellipses=False, - shallow=False, ellipsisroots=None): + shallow=False, ellipsisroots=None, fullnodes=None): builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.basenode, d.linknode) @@ -1229,10 +1235,11 @@ bundlecaps=bundlecaps, ellipses=ellipses, shallow=shallow, -ellipsisroots=ellipsisroots) +ellipsisroots=ellipsisroots, +fullnodes=fullnodes) def _makecg3packer(repo, filematcher, bundlecaps, ellipses=False, - shallow=False, ellipsisroots=None): + shallow=False, ellipsisroots=None, fullnodes=None): builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) @@ -1245,7 +1252,8 @@ bundlecaps=bundlecaps, ellipses=ellipses, shallow=shallow, -ellipsisroots=ellipsisroots) +ellipsisroots=ellipsisroots, +fullnodes=fullnodes) _packermap = {'01': (_makecg1packer, cg1unpacker), # cg2 adds support
D4084: changegroup: rename cg1packer to cgpacker
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY There is now only a single class. We don't need to encode the version in its name since the version is a lie. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4084 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -522,7 +522,7 @@ # Iterable of chunks holding raw delta data. deltachunks = attr.ib() -class cg1packer(object): +class cgpacker(object): def __init__(self, repo, filematcher, version, allowreorder, useprevdelta, builddeltaheader, manifestsend, sendtreemanifests, bundlecaps=None): @@ -1178,37 +1178,40 @@ builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.linknode) -return cg1packer(repo, filematcher, b'01', - useprevdelta=True, - allowreorder=None, - builddeltaheader=builddeltaheader, - manifestsend=b'', sendtreemanifests=False, - bundlecaps=bundlecaps) +return cgpacker(repo, filematcher, b'01', +useprevdelta=True, +allowreorder=None, +builddeltaheader=builddeltaheader, +manifestsend=b'', +sendtreemanifests=False, +bundlecaps=bundlecaps) def _makecg2packer(repo, filematcher, bundlecaps): builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.basenode, d.linknode) # Since generaldelta is directly supported by cg2, reordering # generally doesn't help, so we disable it by default (treating # bundle.reorder=auto just like bundle.reorder=False). -return cg1packer(repo, filematcher, b'02', - useprevdelta=False, - allowreorder=False, - builddeltaheader=builddeltaheader, - manifestsend=b'', sendtreemanifests=False, - bundlecaps=bundlecaps) +return cgpacker(repo, filematcher, b'02', +useprevdelta=False, +allowreorder=False, +builddeltaheader=builddeltaheader, +manifestsend=b'', +sendtreemanifests=False, +bundlecaps=bundlecaps) def _makecg3packer(repo, filematcher, bundlecaps): builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) -return cg1packer(repo, filematcher, b'03', - useprevdelta=False, - allowreorder=False, - builddeltaheader=builddeltaheader, - manifestsend=closechunk(), sendtreemanifests=True, - bundlecaps=bundlecaps) +return cgpacker(repo, filematcher, b'03', +useprevdelta=False, +allowreorder=False, +builddeltaheader=builddeltaheader, +manifestsend=closechunk(), +sendtreemanifests=True, +bundlecaps=bundlecaps) _packermap = {'01': (_makecg1packer, cg1unpacker), # cg2 adds support for exchanging generaldelta To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4083: changegroup: control delta parent behavior via constructor
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The last remaining override on cg2packer related to parent delta computation. We pass a parameter to the constructor to control whether to delta against the previous revision and we inline all parent delta logic into a single function. With this change, cg2packer is empty, so it has been deleted. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4083 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -524,8 +524,8 @@ class cg1packer(object): def __init__(self, repo, filematcher, version, allowreorder, - builddeltaheader, manifestsend, sendtreemanifests, - bundlecaps=None): + useprevdelta, builddeltaheader, manifestsend, + sendtreemanifests, bundlecaps=None): """Given a source repo, construct a bundler. filematcher is a matcher that matches on files to include in the @@ -535,6 +535,9 @@ This value is used when ``bundle.reorder`` is ``auto`` or isn't set. +useprevdelta controls whether revisions should always delta against +the previous revision in the changegroup. + builddeltaheader is a callable that constructs the header for a group delta. @@ -551,6 +554,7 @@ self._filematcher = filematcher self.version = version +self._useprevdelta = useprevdelta self._builddeltaheader = builddeltaheader self._manifestsend = manifestsend self._sendtreemanifests = sendtreemanifests @@ -953,9 +957,51 @@ progress.complete() def deltaparent(self, store, rev, p1, p2, prev): -if not store.candelta(prev, rev): -raise error.ProgrammingError('cg1 should not be used in this case') -return prev +if self._useprevdelta: +if not store.candelta(prev, rev): +raise error.ProgrammingError( +'cg1 should not be used in this case') +return prev + +# Narrow ellipses mode. +if util.safehasattr(self, 'full_nodes'): +# TODO: send better deltas when in narrow mode. +# +# changegroup.group() loops over revisions to send, +# including revisions we'll skip. What this means is that +# `prev` will be a potentially useless delta base for all +# ellipsis nodes, as the client likely won't have it. In +# the future we should do bookkeeping about which nodes +# have been sent to the client, and try to be +# significantly smarter about delta bases. This is +# slightly tricky because this same code has to work for +# all revlogs, and we don't have the linkrev/linknode here. +return p1 + +dp = store.deltaparent(rev) +if dp == nullrev and store.storedeltachains: +# Avoid sending full revisions when delta parent is null. Pick prev +# in that case. It's tempting to pick p1 in this case, as p1 will +# be smaller in the common case. However, computing a delta against +# p1 may require resolving the raw text of p1, which could be +# expensive. The revlog caches should have prev cached, meaning +# less CPU for changegroup generation. There is likely room to add +# a flag and/or config option to control this behavior. +base = prev +elif dp == nullrev: +# revlog is configured to use full snapshot for a reason, +# stick to full snapshot. +base = nullrev +elif dp not in (p1, p2, prev): +# Pick prev when we can't be sure remote has the base revision. +return prev +else: +base = dp + +if base != nullrev and not store.candelta(base, rev): +base = nullrev + +return base def revchunk(self, store, rev, prev, linknode): if util.safehasattr(self, 'full_nodes'): @@ -1128,51 +1174,13 @@ deltachunks=(diffheader, data), ) -class cg2packer(cg1packer): -def deltaparent(self, store, rev, p1, p2, prev): -# Narrow ellipses mode. -if util.safehasattr(self, 'full_nodes'): -# TODO: send better deltas when in narrow mode. -# -# changegroup.group() loops over revisions to send, -# including revisions we'll skip. What this means is that -# `prev` will be a potentially useless delta base for all -# ellipsis nodes, as the client likely won't have it. In -# the future we should do bookkeeping about which nodes -# have been sent to the
D4085: changegroup: make some packer attributes private
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY These methods and attributes are low level and should not be called or outside outside of instances. Indicate as such through naming. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4085 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -578,17 +578,17 @@ else: self._verbosenote = lambda s: None -def close(self): +def _close(self): # Ellipses serving mode. -getattr(self, 'clrev_to_localrev', {}).clear() -if getattr(self, 'next_clrev_to_localrev', {}): -self.clrev_to_localrev = self.next_clrev_to_localrev -del self.next_clrev_to_localrev -self.changelog_done = True +getattr(self, '_clrev_to_localrev', {}).clear() +if getattr(self, '_next_clrev_to_localrev', {}): +self._clrev_to_localrev = self._next_clrev_to_localrev +del self._next_clrev_to_localrev +self._changelog_done = True return closechunk() -def fileheader(self, fname): +def _fileheader(self, fname): return chunkheader(len(fname)) + fname # Extracted both for clarity and for overriding in extensions. @@ -610,8 +610,8 @@ # order that they're introduced in dramatis personae by the # changelog, so what we do is we sort the non-changelog histories # by the order in which they are used by the changelog. -if util.safehasattr(self, 'full_nodes') and self.clnode_to_rev: -key = lambda n: self.clnode_to_rev[lookup(n)] +if util.safehasattr(self, '_full_nodes') and self._clnode_to_rev: +key = lambda n: self._clnode_to_rev[lookup(n)] return [store.rev(n) for n in sorted(nodelist, key=key)] # for generaldelta revlogs, we linearize the revs; this will both be @@ -638,7 +638,7 @@ """ # if we don't have any revisions touched by these changesets, bail if len(nodelist) == 0: -yield self.close() +yield self._close() return revs = self._sortgroup(store, nodelist, lookup) @@ -657,15 +657,15 @@ progress.update(r + 1) prev, curr = revs[r], revs[r + 1] linknode = lookup(store.node(curr)) -for c in self.revchunk(store, curr, prev, linknode): +for c in self._revchunk(store, curr, prev, linknode): yield c if progress: progress.complete() -yield self.close() +yield self._close() # filter any nodes that claim to be part of the known set -def prune(self, store, missing, commonrevs): +def _prune(self, store, missing, commonrevs): # TODO this violates storage abstraction for manifests. if isinstance(store, manifest.manifestrevlog): if not self._filematcher.visitdir(store._dir[:-1] or '.'): @@ -690,7 +690,7 @@ assert self.version == b'03' if dir: -yield self.fileheader(dir) +yield self._fileheader(dir) # TODO violates storage abstractions by assuming revlogs. dirlog = self._repo.manifestlog._revlog.dirlog(dir) @@ -711,7 +711,7 @@ mfrevlog = mfl._revlog changedfiles = set() -ellipsesmode = util.safehasattr(self, 'full_nodes') +ellipsesmode = util.safehasattr(self, '_full_nodes') # Callback for the changelog, used to collect changed files and # manifest nodes. @@ -725,21 +725,21 @@ # end up with bogus linkrevs specified for manifests and # we skip some manifest nodes that we should otherwise # have sent. -if (x in self.full_nodes -or cl.rev(x) in self.precomputed_ellipsis): +if (x in self._full_nodes +or cl.rev(x) in self._precomputed_ellipsis): n = c[0] # Record the first changeset introducing this manifest # version. mfs.setdefault(n, x) # Set this narrow-specific dict so we have the lowest # manifest revnum to look up for this cl revnum. (Part of # mapping changelog ellipsis parents to manifest ellipsis # parents) -self.next_clrev_to_localrev.setdefault(cl.rev(x), - mfrevlog.rev(n)) +self._next_clrev_to_localrev.setdefault(cl.rev(x), +mfrevlog.rev(n)) # We can't trust the changed files list in the
D4086: changegroup: declare shallow flag in constructor
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Thus begins the process of better formalizing ellipses and shallow changegroup generation mode so it is tracked by cgpacker at construction time instead of bolted on after the fact by a wrapper function. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4086 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -525,7 +525,7 @@ class cgpacker(object): def __init__(self, repo, filematcher, version, allowreorder, useprevdelta, builddeltaheader, manifestsend, - sendtreemanifests, bundlecaps=None): + sendtreemanifests, bundlecaps=None, shallow=False): """Given a source repo, construct a bundler. filematcher is a matcher that matches on files to include in the @@ -549,6 +549,9 @@ capabilities which can be used to build the bundle. While bundlecaps is unused in core Mercurial, extensions rely on this feature to communicate capabilities to customize the changegroup packer. + +shallow indicates whether shallow data might be sent. The packer may +need to pack file contents not introduced by the changes being packed. """ assert filematcher self._filematcher = filematcher @@ -563,6 +566,7 @@ if bundlecaps is None: bundlecaps = set() self._bundlecaps = bundlecaps +self._isshallow = shallow # experimental config: bundle.reorder reorder = repo.ui.config('bundle', 'reorder') @@ -739,7 +743,7 @@ mfrevlog.rev(n)) # We can't trust the changed files list in the changeset if the # client requested a shallow clone. -if self._is_shallow: +if self._isshallow: changedfiles.update(mfl[c[0]].read().keys()) else: changedfiles.update(c[3]) @@ -789,7 +793,7 @@ if ellipsesmode: mfdicts = None -if self._is_shallow: +if self._isshallow: mfdicts = [(self._repo.manifestlog[n].read(), lr) for (n, lr) in mfs.iteritems()] @@ -895,7 +899,7 @@ def generatefiles(self, changedfiles, linknodes, commonrevs, source): changedfiles = list(filter(self._filematcher, changedfiles)) -if getattr(self, '_is_shallow', False): +if self._isshallow: # See comment in generate() for why this sadness is a thing. mfdicts = self._mfdicts del self._mfdicts @@ -1174,7 +1178,7 @@ deltachunks=(diffheader, data), ) -def _makecg1packer(repo, filematcher, bundlecaps): +def _makecg1packer(repo, filematcher, bundlecaps, shallow=False): builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.linknode) @@ -1184,9 +1188,10 @@ builddeltaheader=builddeltaheader, manifestsend=b'', sendtreemanifests=False, -bundlecaps=bundlecaps) +bundlecaps=bundlecaps, +shallow=shallow) -def _makecg2packer(repo, filematcher, bundlecaps): +def _makecg2packer(repo, filematcher, bundlecaps, shallow=False): builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.basenode, d.linknode) @@ -1199,9 +1204,10 @@ builddeltaheader=builddeltaheader, manifestsend=b'', sendtreemanifests=False, -bundlecaps=bundlecaps) +bundlecaps=bundlecaps, +shallow=shallow) -def _makecg3packer(repo, filematcher, bundlecaps): +def _makecg3packer(repo, filematcher, bundlecaps, shallow=False): builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) @@ -1211,7 +1217,8 @@ builddeltaheader=builddeltaheader, manifestsend=closechunk(), sendtreemanifests=True, -bundlecaps=bundlecaps) +bundlecaps=bundlecaps, +shallow=shallow) _packermap = {'01': (_makecg1packer, cg1unpacker), # cg2 adds support for exchanging generaldelta @@ -1271,7 +1278,8 @@ assert versions return min(versions) -def getbundler(version, repo, bundlecaps=None, filematcher=None): +def getbundler(version, repo, bundlecaps=None, filematcher=None, + shallow=False): assert version in
D4077: changegroup: pass version into constructor
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Currently, the version is an attribute on each class. Passing the argument into the constructor gets us one step closer to eliminating cg2packer and cg3packer. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4077 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -524,8 +524,8 @@ class cg1packer(object): deltaheader = _CHANGEGROUPV1_DELTA_HEADER -version = '01' -def __init__(self, repo, filematcher, bundlecaps=None): + +def __init__(self, repo, filematcher, version, bundlecaps=None): """Given a source repo, construct a bundler. filematcher is a matcher that matches on files to include in the @@ -539,6 +539,8 @@ assert filematcher self._filematcher = filematcher +self.version = version + # Set of capabilities we can use to build the bundle. if bundlecaps is None: bundlecaps = set() @@ -1103,11 +1105,10 @@ return struct.pack(self.deltaheader, node, p1n, p2n, linknode) class cg2packer(cg1packer): -version = '02' deltaheader = _CHANGEGROUPV2_DELTA_HEADER -def __init__(self, repo, filematcher, bundlecaps=None): -super(cg2packer, self).__init__(repo, filematcher, +def __init__(self, repo, filematcher, version, bundlecaps=None): +super(cg2packer, self).__init__(repo, filematcher, version, bundlecaps=bundlecaps) if self._reorder is None: @@ -1160,7 +1161,6 @@ return struct.pack(self.deltaheader, node, p1n, p2n, basenode, linknode) class cg3packer(cg2packer): -version = '03' deltaheader = _CHANGEGROUPV3_DELTA_HEADER def _packmanifests(self, dir, mfnodes, lookuplinknode): @@ -1180,13 +1180,13 @@ self.deltaheader, node, p1n, p2n, basenode, linknode, flags) def _makecg1packer(repo, filematcher, bundlecaps): -return cg1packer(repo, filematcher, bundlecaps=bundlecaps) +return cg1packer(repo, filematcher, b'01', bundlecaps=bundlecaps) def _makecg2packer(repo, filematcher, bundlecaps): -return cg2packer(repo, filematcher, bundlecaps=bundlecaps) +return cg2packer(repo, filematcher, b'02', bundlecaps=bundlecaps) def _makecg3packer(repo, filematcher, bundlecaps): -return cg3packer(repo, filematcher, bundlecaps=bundlecaps) +return cg3packer(repo, filematcher, b'03', bundlecaps=bundlecaps) _packermap = {'01': (_makecg1packer, cg1unpacker), # cg2 adds support for exchanging generaldelta To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4075: changegroup: capture revision delta in a data structure
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The current changegroup generation code is tightly coupled to the revlog API. This tight coupling makes it difficult to implement alternate storage backends without requiring a large surface area of the revlog API to be exposed. This is not desirable. In order to support changegroup generation with non-revlog storage, we'll need to abstract the concept of delta generation. This commit is the first step down that road. We introduce a data structure for representing a delta in a changegroup. The API still leaves a lot to be desired. But at least we now have separation between data and actions performed on it. As part of this, we tweak behavior slightly: we no longer concatenate the delta prefix with the metadata header. Instead, we track and emit the prefix as a separate chunk. This shouldn't have any meaningful impact since all the chunks just get sent to the wire, the compressor, etc. Because we're introducing a new object, this does add some overhead to changegroup execution. `hg perfchangegroupchangelog` on my clone of the Mercurial repo (~40,000 visible revisions in the changelog) slows down a bit: ! wall 1.268600 comb 1.27 user 1.27 sys 0.00 (best of 8) ! wall 1.419479 comb 1.41 user 1.41 sys 0.00 (best of 8) With for `hg bundle -t none-v2 -a /dev/null`: before: real 6.610 secs (user 6.460+0.000 sys 0.140+0.000) after: real 7.210 secs (user 7.060+0.000 sys 0.140+0.000) I plan to claw back this regression in future commits. And I may even do away with this data structure once the refactor is complete. For now, it makes things easier to comprehend. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4075 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -19,6 +19,10 @@ short, ) +from .thirdparty import ( +attr, +) + from . import ( dagutil, error, @@ -497,6 +501,26 @@ return d return readexactly(self._fh, n) +@attr.s(slots=True, frozen=True) +class revisiondelta(object): +"""Describes a delta entry in a changegroup. + +Captured data is sufficient to serialize the delta into multiple +formats. +""" +# 20 byte node of this revision. +node = attr.ib() +# 20 byte nodes of parent revisions. +p1node = attr.ib() +p2node = attr.ib() +# 20 byte node of node this delta is against. +basenode = attr.ib() +# 20 byte node of changeset revision this delta is associated with. +linknode = attr.ib() +# 2 bytes of flags to apply to revision data. +flags = attr.ib() +# Iterable of chunks holding raw delta data. +deltachunks = attr.ib() class cg1packer(object): deltaheader = _CHANGEGROUPV1_DELTA_HEADER @@ -902,13 +926,25 @@ def revchunk(self, store, rev, prev, linknode): if util.safehasattr(self, 'full_nodes'): -fn = self._revchunknarrow +fn = self._revisiondeltanarrow else: -fn = self._revchunknormal +fn = self._revisiondeltanormal + +delta = fn(store, rev, prev, linknode) +if not delta: +return -return fn(store, rev, prev, linknode) +meta = self.builddeltaheader(delta.node, delta.p1node, delta.p2node, + delta.basenode, delta.linknode, + delta.flags) +l = len(meta) + sum(len(x) for x in delta.deltachunks) -def _revchunknormal(self, store, rev, prev, linknode): +yield chunkheader(l) +yield meta +for x in delta.deltachunks: +yield x + +def _revisiondeltanormal(self, store, rev, prev, linknode): node = store.node(rev) p1, p2 = store.parentrevs(rev) base = self.deltaparent(store, rev, p1, p2, prev) @@ -930,16 +966,18 @@ else: delta = store.revdiff(base, rev) p1n, p2n = store.parents(node) -basenode = store.node(base) -flags = store.flags(rev) -meta = self.builddeltaheader(node, p1n, p2n, basenode, linknode, flags) -meta += prefix -l = len(meta) + len(delta) -yield chunkheader(l) -yield meta -yield delta -def _revchunknarrow(self, store, rev, prev, linknode): +return revisiondelta( +node=node, +p1node=p1n, +p2node=p2n, +basenode=store.node(base), +linknode=linknode, +flags=store.flags(rev), +deltachunks=(prefix, delta), +) + +def _revisiondeltanarrow(self, store, rev, prev, linknode): # build up some mapping information that's
D4078: changegroup: make delta header struct formatters actual structs
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Why we weren't using compiled Struct instances, I don't know. They make code simpler. In theory they are faster. Although I don't believe I was able to measure any meaningful change. That could be because this code is often dominated by compression, deltafication, and function call overhead. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4078 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -39,9 +39,9 @@ stringutil, ) -_CHANGEGROUPV1_DELTA_HEADER = "20s20s20s20s" -_CHANGEGROUPV2_DELTA_HEADER = "20s20s20s20s20s" -_CHANGEGROUPV3_DELTA_HEADER = ">20s20s20s20s20sH" +_CHANGEGROUPV1_DELTA_HEADER = struct.Struct("20s20s20s20s") +_CHANGEGROUPV2_DELTA_HEADER = struct.Struct("20s20s20s20s20s") +_CHANGEGROUPV3_DELTA_HEADER = struct.Struct(">20s20s20s20s20sH") LFS_REQUIREMENT = 'lfs' @@ -122,7 +122,7 @@ bundlerepo and some debug commands - their use is discouraged. """ deltaheader = _CHANGEGROUPV1_DELTA_HEADER -deltaheadersize = struct.calcsize(deltaheader) +deltaheadersize = deltaheader.size version = '01' _grouplistcount = 1 # One list of files after the manifests @@ -195,7 +195,7 @@ if not l: return {} headerdata = readexactly(self._stream, self.deltaheadersize) -header = struct.unpack(self.deltaheader, headerdata) +header = self.deltaheader.unpack(headerdata) delta = readexactly(self._stream, l - self.deltaheadersize) node, p1, p2, deltabase, cs, flags = self._deltaheader(header, prevnode) return (node, p1, p2, cs, deltabase, delta, flags) @@ -454,7 +454,7 @@ remain the same. """ deltaheader = _CHANGEGROUPV2_DELTA_HEADER -deltaheadersize = struct.calcsize(deltaheader) +deltaheadersize = deltaheader.size version = '02' def _deltaheader(self, headertuple, prevnode): @@ -470,7 +470,7 @@ separating manifests and files. """ deltaheader = _CHANGEGROUPV3_DELTA_HEADER -deltaheadersize = struct.calcsize(deltaheader) +deltaheadersize = deltaheader.size version = '03' _grouplistcount = 2 # One list of manifests and one list of files @@ -1102,7 +1102,7 @@ def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags): # do nothing with basenode, it is implicitly the previous one in HG10 # do nothing with flags, it is implicitly 0 for cg1 and cg2 -return struct.pack(self.deltaheader, node, p1n, p2n, linknode) +return self.deltaheader.pack(node, p1n, p2n, linknode) class cg2packer(cg1packer): deltaheader = _CHANGEGROUPV2_DELTA_HEADER @@ -1158,7 +1158,7 @@ def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags): # Do nothing with flags, it is implicitly 0 in cg1 and cg2 -return struct.pack(self.deltaheader, node, p1n, p2n, basenode, linknode) +return self.deltaheader.pack(node, p1n, p2n, basenode, linknode) class cg3packer(cg2packer): deltaheader = _CHANGEGROUPV3_DELTA_HEADER @@ -1176,8 +1176,7 @@ return self.close() def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags): -return struct.pack( -self.deltaheader, node, p1n, p2n, basenode, linknode, flags) +return self.deltaheader.pack(node, p1n, p2n, basenode, linknode, flags) def _makecg1packer(repo, filematcher, bundlecaps): return cg1packer(repo, filematcher, b'01', bundlecaps=bundlecaps) To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4079: changegroup: pass function to build delta header into constructor
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Previously, the delta header struct format was defined on each class and each class had a separate function for building the delta header. We replace both of these with an argument to __init__ containing a callable that can format a delta header given a revisiondelta instance. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4079 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -523,14 +523,16 @@ deltachunks = attr.ib() class cg1packer(object): -deltaheader = _CHANGEGROUPV1_DELTA_HEADER - -def __init__(self, repo, filematcher, version, bundlecaps=None): +def __init__(self, repo, filematcher, version, builddeltaheader, + bundlecaps=None): """Given a source repo, construct a bundler. filematcher is a matcher that matches on files to include in the changegroup. Used to facilitate sparse changegroups. +builddeltaheader is a callable that constructs the header for a group +delta. + bundlecaps is optional and can be used to specify the set of capabilities which can be used to build the bundle. While bundlecaps is unused in core Mercurial, extensions rely on this feature to communicate @@ -540,6 +542,7 @@ self._filematcher = filematcher self.version = version +self._builddeltaheader = builddeltaheader # Set of capabilities we can use to build the bundle. if bundlecaps is None: @@ -936,9 +939,7 @@ if not delta: return -meta = self.builddeltaheader(delta.node, delta.p1node, delta.p2node, - delta.basenode, delta.linknode, - delta.flags) +meta = self._builddeltaheader(delta) l = len(meta) + sum(len(x) for x in delta.deltachunks) yield chunkheader(l) @@ -1099,16 +1100,11 @@ deltachunks=(diffheader, data), ) -def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags): -# do nothing with basenode, it is implicitly the previous one in HG10 -# do nothing with flags, it is implicitly 0 for cg1 and cg2 -return self.deltaheader.pack(node, p1n, p2n, linknode) - class cg2packer(cg1packer): -deltaheader = _CHANGEGROUPV2_DELTA_HEADER - -def __init__(self, repo, filematcher, version, bundlecaps=None): +def __init__(self, repo, filematcher, version, builddeltaheader, + bundlecaps=None): super(cg2packer, self).__init__(repo, filematcher, version, +builddeltaheader, bundlecaps=bundlecaps) if self._reorder is None: @@ -1156,13 +1152,7 @@ base = nullrev return base -def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags): -# Do nothing with flags, it is implicitly 0 in cg1 and cg2 -return self.deltaheader.pack(node, p1n, p2n, basenode, linknode) - class cg3packer(cg2packer): -deltaheader = _CHANGEGROUPV3_DELTA_HEADER - def _packmanifests(self, dir, mfnodes, lookuplinknode): if dir: yield self.fileheader(dir) @@ -1175,17 +1165,26 @@ def _manifestsdone(self): return self.close() -def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags): -return self.deltaheader.pack(node, p1n, p2n, basenode, linknode, flags) +def _makecg1packer(repo, filematcher, bundlecaps): +builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( +d.node, d.p1node, d.p2node, d.linknode) -def _makecg1packer(repo, filematcher, bundlecaps): -return cg1packer(repo, filematcher, b'01', bundlecaps=bundlecaps) +return cg1packer(repo, filematcher, b'01', builddeltaheader, + bundlecaps=bundlecaps) def _makecg2packer(repo, filematcher, bundlecaps): -return cg2packer(repo, filematcher, b'02', bundlecaps=bundlecaps) +builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( +d.node, d.p1node, d.p2node, d.basenode, d.linknode) + +return cg2packer(repo, filematcher, b'02', builddeltaheader, + bundlecaps=bundlecaps) def _makecg3packer(repo, filematcher, bundlecaps): -return cg3packer(repo, filematcher, b'03', bundlecaps=bundlecaps) +builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( +d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) + +return cg3packer(repo, filematcher, b'03', builddeltaheader, + bundlecaps=bundlecaps) _packermap = {'01': (_makecg1packer, cg1unpacker), # cg2 adds support
D4080: changegroup: pass end of manifests marker into constructor
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY cg3 inserts a custom marker in the stream once all manifests have been transferred. This is currently abstracted out by overriding a method. Let's pass the end of manifests marker in as an argument to avoid the extra method. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4080 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -524,6 +524,7 @@ class cg1packer(object): def __init__(self, repo, filematcher, version, builddeltaheader, + manifestsend, bundlecaps=None): """Given a source repo, construct a bundler. @@ -533,6 +534,8 @@ builddeltaheader is a callable that constructs the header for a group delta. +manifestsend is a chunk to send after manifests have been fully emitted. + bundlecaps is optional and can be used to specify the set of capabilities which can be used to build the bundle. While bundlecaps is unused in core Mercurial, extensions rely on this feature to communicate @@ -543,6 +546,7 @@ self.version = version self._builddeltaheader = builddeltaheader +self._manifestsend = manifestsend # Set of capabilities we can use to build the bundle. if bundlecaps is None: @@ -664,9 +668,6 @@ lookuplinknode, units=_('manifests')): yield chunk -def _manifestsdone(self): -return '' - def generate(self, commonrevs, clnodes, fastpathlinkrev, source): '''yield a sequence of changegroup chunks (strings)''' repo = self._repo @@ -857,7 +858,7 @@ size += len(x) yield x self._verbosenote(_('%8.i (manifests)\n') % size) -yield self._manifestsdone() +yield self._manifestsend # The 'source' parameter is useful for extensions def generatefiles(self, changedfiles, linknodes, commonrevs, source): @@ -1102,9 +1103,9 @@ class cg2packer(cg1packer): def __init__(self, repo, filematcher, version, builddeltaheader, - bundlecaps=None): + manifestsend, bundlecaps=None): super(cg2packer, self).__init__(repo, filematcher, version, -builddeltaheader, +builddeltaheader, manifestsend, bundlecaps=bundlecaps) if self._reorder is None: @@ -1162,28 +1163,28 @@ units=_('manifests')): yield chunk -def _manifestsdone(self): -return self.close() - def _makecg1packer(repo, filematcher, bundlecaps): builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.linknode) return cg1packer(repo, filematcher, b'01', builddeltaheader, + manifestsend=b'', bundlecaps=bundlecaps) def _makecg2packer(repo, filematcher, bundlecaps): builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.basenode, d.linknode) return cg2packer(repo, filematcher, b'02', builddeltaheader, + manifestsend=b'', bundlecaps=bundlecaps) def _makecg3packer(repo, filematcher, bundlecaps): builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) return cg3packer(repo, filematcher, b'03', builddeltaheader, + manifestsend=closechunk(), bundlecaps=bundlecaps) _packermap = {'01': (_makecg1packer, cg1unpacker), To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4076: changegroup: define functions for creating changegroup packers
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Currently, we have 3 classes for changegroup generation. Each class handles a specific changegroup format. And each subsequent version's class inherits from the previous one. The interface for the classes is not very well defined and a lot of version-specific behavior is behind overloaded functions. This approach adds complexity and makes changegroup generation difficult to reason about. Upcoming commits will be consolidating these 3 classes so differences between changegroup versions and changegroup generation are controlled by parameters to a single constructor / type rather than by overriding class attributes via inheritance. We begin this process by building dedicated functions for creating each changegroup packer instance. Currently they just call the constructor on the appropriate class. This will soon change. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4076 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -1179,11 +1179,20 @@ return struct.pack( self.deltaheader, node, p1n, p2n, basenode, linknode, flags) -_packermap = {'01': (cg1packer, cg1unpacker), +def _makecg1packer(repo, filematcher, bundlecaps): +return cg1packer(repo, filematcher, bundlecaps=bundlecaps) + +def _makecg2packer(repo, filematcher, bundlecaps): +return cg2packer(repo, filematcher, bundlecaps=bundlecaps) + +def _makecg3packer(repo, filematcher, bundlecaps): +return cg3packer(repo, filematcher, bundlecaps=bundlecaps) + +_packermap = {'01': (_makecg1packer, cg1unpacker), # cg2 adds support for exchanging generaldelta - '02': (cg2packer, cg2unpacker), + '02': (_makecg2packer, cg2unpacker), # cg3 adds support for exchanging revlog flags and treemanifests - '03': (cg3packer, cg3unpacker), + '03': (_makecg3packer, cg3unpacker), } def allsupportedversions(repo): @@ -1252,8 +1261,8 @@ filematcher = matchmod.intersectmatchers(repo.narrowmatch(), filematcher) -return _packermap[version][0](repo, filematcher=filematcher, - bundlecaps=bundlecaps) +fn = _packermap[version][0] +return fn(repo, filematcher, bundlecaps) def getunbundler(version, fh, alg, extras=None): return _packermap[version][1](fh, alg, extras=extras) To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4081: changegroup: consolidate tree manifests sending into cg1packer
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Previously, we overrode a method to control how manifests were serialized. This method was redefined on cg3packer to send tree manifests. This commit moves the tree manifests sending variation to cg1packer and teaches the cgpacker constructor to control which version to use. After these changes, cg3packer was empty. So it has been removed. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4081 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -524,7 +524,7 @@ class cg1packer(object): def __init__(self, repo, filematcher, version, builddeltaheader, - manifestsend, + manifestsend, sendtreemanifests, bundlecaps=None): """Given a source repo, construct a bundler. @@ -536,6 +536,8 @@ manifestsend is a chunk to send after manifests have been fully emitted. +sendtreemanifests indicates whether tree manifests should be emitted. + bundlecaps is optional and can be used to specify the set of capabilities which can be used to build the bundle. While bundlecaps is unused in core Mercurial, extensions rely on this feature to communicate @@ -547,6 +549,7 @@ self.version = version self._builddeltaheader = builddeltaheader self._manifestsend = manifestsend +self._sendtreemanifests = sendtreemanifests # Set of capabilities we can use to build the bundle. if bundlecaps is None: @@ -668,6 +671,23 @@ lookuplinknode, units=_('manifests')): yield chunk +def _packtreemanifests(self, dir, mfnodes, lookuplinknode): +"""Version of _packmanifests that operates on directory manifests. + +Encodes the directory name in the output so multiple manifests +can be sent. +""" +assert self.version == b'03' + +if dir: +yield self.fileheader(dir) + +# TODO violates storage abstractions by assuming revlogs. +dirlog = self._repo.manifestlog._revlog.dirlog(dir) +for chunk in self.group(mfnodes, dirlog, lookuplinknode, +units=_('manifests')): +yield chunk + def generate(self, commonrevs, clnodes, fastpathlinkrev, source): '''yield a sequence of changegroup chunks (strings)''' repo = self._repo @@ -848,13 +868,14 @@ return clnode return lookupmflinknode +fn = (self._packtreemanifests if self._sendtreemanifests + else self._packmanifests) size = 0 while tmfnodes: dir, nodes = tmfnodes.popitem() prunednodes = self.prune(dirlog(dir), nodes, commonrevs) if not dir or prunednodes: -for x in self._packmanifests(dir, prunednodes, - makelookupmflinknode(dir, nodes)): +for x in fn(dir, prunednodes, makelookupmflinknode(dir, nodes)): size += len(x) yield x self._verbosenote(_('%8.i (manifests)\n') % size) @@ -1103,9 +1124,10 @@ class cg2packer(cg1packer): def __init__(self, repo, filematcher, version, builddeltaheader, - manifestsend, bundlecaps=None): + manifestsend, sendtreemanifests, bundlecaps=None): super(cg2packer, self).__init__(repo, filematcher, version, builddeltaheader, manifestsend, +sendtreemanifests, bundlecaps=bundlecaps) if self._reorder is None: @@ -1153,38 +1175,28 @@ base = nullrev return base -class cg3packer(cg2packer): -def _packmanifests(self, dir, mfnodes, lookuplinknode): -if dir: -yield self.fileheader(dir) - -dirlog = self._repo.manifestlog._revlog.dirlog(dir) -for chunk in self.group(mfnodes, dirlog, lookuplinknode, -units=_('manifests')): -yield chunk - def _makecg1packer(repo, filematcher, bundlecaps): builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.linknode) return cg1packer(repo, filematcher, b'01', builddeltaheader, - manifestsend=b'', + manifestsend=b'', sendtreemanifests=False, bundlecaps=bundlecaps) def _makecg2packer(repo, filematcher, bundlecaps): builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.basenode, d.linknode) return
D4082: changegroup: control reordering via constructor argument
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY cg2packer.__init__ exists just to override self._reorder. Let's parameterize this behavior via an argument to the parent's __init__. The logic for self._reorder is kinda wonky. None is used as a special value and the value should be None in some situations. It is probably worth rewriting this logic to make behavior more explicit. This will likely happen as part of future work to control the delta generation process that I have planned. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4082 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -523,14 +523,18 @@ deltachunks = attr.ib() class cg1packer(object): -def __init__(self, repo, filematcher, version, builddeltaheader, - manifestsend, sendtreemanifests, +def __init__(self, repo, filematcher, version, allowreorder, + builddeltaheader, manifestsend, sendtreemanifests, bundlecaps=None): """Given a source repo, construct a bundler. filematcher is a matcher that matches on files to include in the changegroup. Used to facilitate sparse changegroups. +allowreorder controls whether reordering of revisions is allowed. +This value is used when ``bundle.reorder`` is ``auto`` or isn't +set. + builddeltaheader is a callable that constructs the header for a group delta. @@ -555,14 +559,16 @@ if bundlecaps is None: bundlecaps = set() self._bundlecaps = bundlecaps + # experimental config: bundle.reorder reorder = repo.ui.config('bundle', 'reorder') if reorder == 'auto': -reorder = None +self._reorder = allowreorder else: -reorder = stringutil.parsebool(reorder) +self._reorder = stringutil.parsebool(reorder) + self._repo = repo -self._reorder = reorder + if self._repo.ui.verbose and not self._repo.ui.debugflag: self._verbosenote = self._repo.ui.note else: @@ -1123,19 +1129,6 @@ ) class cg2packer(cg1packer): -def __init__(self, repo, filematcher, version, builddeltaheader, - manifestsend, sendtreemanifests, bundlecaps=None): -super(cg2packer, self).__init__(repo, filematcher, version, -builddeltaheader, manifestsend, -sendtreemanifests, -bundlecaps=bundlecaps) - -if self._reorder is None: -# Since generaldelta is directly supported by cg2, reordering -# generally doesn't help, so we disable it by default (treating -# bundle.reorder=auto just like bundle.reorder=False). -self._reorder = False - def deltaparent(self, store, rev, p1, p2, prev): # Narrow ellipses mode. if util.safehasattr(self, 'full_nodes'): @@ -1179,23 +1172,29 @@ builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.linknode) -return cg1packer(repo, filematcher, b'01', builddeltaheader, +return cg1packer(repo, filematcher, b'01', allowreorder=None, + builddeltaheader=builddeltaheader, manifestsend=b'', sendtreemanifests=False, bundlecaps=bundlecaps) def _makecg2packer(repo, filematcher, bundlecaps): builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.basenode, d.linknode) -return cg2packer(repo, filematcher, b'02', builddeltaheader, +# Since generaldelta is directly supported by cg2, reordering +# generally doesn't help, so we disable it by default (treating +# bundle.reorder=auto just like bundle.reorder=False). +return cg2packer(repo, filematcher, b'02', allowreorder=False, + builddeltaheader=builddeltaheader, manifestsend=b'', sendtreemanifests=False, bundlecaps=bundlecaps) def _makecg3packer(repo, filematcher, bundlecaps): builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack( d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags) -return cg2packer(repo, filematcher, b'03', builddeltaheader, +return cg2packer(repo, filematcher, b'03', allowreorder=False, + builddeltaheader=builddeltaheader, manifestsend=closechunk(), sendtreemanifests=True, bundlecaps=bundlecaps) To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing
D4074: changegroup: inline ellipsisdata()
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY There's only one caller of it. I don't think it needs to exist as a standalone function. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4074 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -497,20 +497,6 @@ return d return readexactly(self._fh, n) -def ellipsisdata(packer, rev, revlog_, p1, p2, data, linknode): -n = revlog_.node(rev) -p1n, p2n = revlog_.node(p1), revlog_.node(p2) -flags = revlog_.flags(rev) -flags |= revlog.REVIDX_ELLIPSIS -meta = packer.builddeltaheader( -n, p1n, p2n, nullid, linknode, flags) -# TODO: try and actually send deltas for ellipsis data blocks -diffheader = mdiff.trivialdiffheader(len(data)) -l = len(meta) + len(diffheader) + len(data) -return ''.join((chunkheader(l), -meta, -diffheader, -data)) class cg1packer(object): deltaheader = _CHANGEGROUPV1_DELTA_HEADER @@ -1055,10 +1041,21 @@ p2 = nullrev else: p1, p2 = sorted(local(p) for p in linkparents) + n = store.node(rev) - -yield ellipsisdata( -self, rev, store, p1, p2, store.revision(n), linknode) +p1n, p2n = store.node(p1), store.node(p2) +flags = store.flags(rev) +flags |= revlog.REVIDX_ELLIPSIS +meta = self.builddeltaheader( +n, p1n, p2n, nullid, linknode, flags) +# TODO: try and actually send deltas for ellipsis data blocks +data = store.revision(n) +diffheader = mdiff.trivialdiffheader(len(data)) +l = len(meta) + len(diffheader) + len(data) +yield ''.join((chunkheader(l), + meta, + diffheader, + data)) def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags): # do nothing with basenode, it is implicitly the previous one in HG10 To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4073: changegroup: rename "revlog" variables
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY "revlog" shadows the module import. But more importantly, changegroup generation should be storage agnostic and not assume the existence of revlogs. Let's rename the thing providing revision storage to "store" to reflect this ideal property. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4073 AFFECTED FILES mercurial/changegroup.py CHANGE DETAILS diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -560,7 +560,7 @@ return chunkheader(len(fname)) + fname # Extracted both for clarity and for overriding in extensions. -def _sortgroup(self, revlog, nodelist, lookup): +def _sortgroup(self, store, nodelist, lookup): """Sort nodes for change group and turn them into revnums.""" # Ellipses serving mode. # @@ -580,17 +580,17 @@ # by the order in which they are used by the changelog. if util.safehasattr(self, 'full_nodes') and self.clnode_to_rev: key = lambda n: self.clnode_to_rev[lookup(n)] -return [revlog.rev(n) for n in sorted(nodelist, key=key)] +return [store.rev(n) for n in sorted(nodelist, key=key)] # for generaldelta revlogs, we linearize the revs; this will both be # much quicker and generate a much smaller bundle -if (revlog._generaldelta and self._reorder is None) or self._reorder: -dag = dagutil.revlogdag(revlog) -return dag.linearize(set(revlog.rev(n) for n in nodelist)) +if (store._generaldelta and self._reorder is None) or self._reorder: +dag = dagutil.revlogdag(store) +return dag.linearize(set(store.rev(n) for n in nodelist)) else: -return sorted([revlog.rev(n) for n in nodelist]) +return sorted([store.rev(n) for n in nodelist]) -def group(self, nodelist, revlog, lookup, units=None): +def group(self, nodelist, store, lookup, units=None): """Calculate a delta group, yielding a sequence of changegroup chunks (strings). @@ -609,10 +609,10 @@ yield self.close() return -revs = self._sortgroup(revlog, nodelist, lookup) +revs = self._sortgroup(store, nodelist, lookup) # add the parent of the first rev -p = revlog.parentrevs(revs[0])[0] +p = store.parentrevs(revs[0])[0] revs.insert(0, p) # build deltas @@ -624,22 +624,22 @@ if progress: progress.update(r + 1) prev, curr = revs[r], revs[r + 1] -linknode = lookup(revlog.node(curr)) -for c in self.revchunk(revlog, curr, prev, linknode): +linknode = lookup(store.node(curr)) +for c in self.revchunk(store, curr, prev, linknode): yield c if progress: progress.complete() yield self.close() # filter any nodes that claim to be part of the known set -def prune(self, revlog, missing, commonrevs): +def prune(self, store, missing, commonrevs): # TODO this violates storage abstraction for manifests. -if isinstance(revlog, manifest.manifestrevlog): -if not self._filematcher.visitdir(revlog._dir[:-1] or '.'): +if isinstance(store, manifest.manifestrevlog): +if not self._filematcher.visitdir(store._dir[:-1] or '.'): return [] -rr, rl = revlog.rev, revlog.linkrev +rr, rl = store.rev, store.linkrev return [n for n in missing if rl(rr(n)) not in commonrevs] def _packmanifests(self, dir, mfnodes, lookuplinknode): @@ -909,51 +909,51 @@ self._verbosenote(_('%8.i %s\n') % (size, fname)) progress.complete() -def deltaparent(self, revlog, rev, p1, p2, prev): -if not revlog.candelta(prev, rev): +def deltaparent(self, store, rev, p1, p2, prev): +if not store.candelta(prev, rev): raise error.ProgrammingError('cg1 should not be used in this case') return prev -def revchunk(self, revlog, rev, prev, linknode): +def revchunk(self, store, rev, prev, linknode): if util.safehasattr(self, 'full_nodes'): fn = self._revchunknarrow else: fn = self._revchunknormal -return fn(revlog, rev, prev, linknode) +return fn(store, rev, prev, linknode) -def _revchunknormal(self, revlog, rev, prev, linknode): -node = revlog.node(rev) -p1, p2 = revlog.parentrevs(rev) -base = self.deltaparent(revlog, rev, p1, p2, prev) +def _revchunknormal(self, store, rev, prev, linknode): +node = store.node(rev) +p1, p2 = store.parentrevs(rev) +base = self.deltaparent(store, rev, p1, p2,
D4071: resolve: graduate resolve.mark-check from experimental, add docs
spectral created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Since this hasn't been in a release yet, I'm not bothering to add an alias for the experimental name of the config variable. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4071 AFFECTED FILES mercurial/commands.py mercurial/configitems.py mercurial/help/config.txt tests/test-resolve.t CHANGE DETAILS diff --git a/tests/test-resolve.t b/tests/test-resolve.t --- a/tests/test-resolve.t +++ b/tests/test-resolve.t @@ -383,7 +383,7 @@ U file1 U file2 $ echo 'remove markers' > file1 - $ hg --config experimental.resolve.mark-check=abort resolve -m + $ hg --config commands.resolve.mark-check=abort resolve -m warning: the following files still have conflict markers: file2 abort: conflict markers detected @@ -393,7 +393,7 @@ U file1 U file2 Try with --all from the hint - $ hg --config experimental.resolve.mark-check=abort resolve -m --all + $ hg --config commands.resolve.mark-check=abort resolve -m --all warning: the following files still have conflict markers: file2 (no more unresolved files) @@ -404,7 +404,7 @@ $ hg resolve -l U file1 U file2 - $ hg --config experimental.resolve.mark-check=warn resolve -m + $ hg --config commands.resolve.mark-check=warn resolve -m warning: the following files still have conflict markers: file2 (no more unresolved files) @@ -416,7 +416,7 @@ $ hg resolve -l U file1 R file2 - $ hg --config experimental.resolve.mark-check=warn resolve -m + $ hg --config commands.resolve.mark-check=warn resolve -m (no more unresolved files) $ hg resolve -l R file1 diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -443,6 +443,16 @@ :hg:`resolve --all`. (default: False) +``resolve.mark-check`` +Determines what level of checking :hg:`resolve --mark` will perform before +marking files as resolved. Valid values are ``none`, ``warn``, and +``abort``. ``warn`` will output a warning listing the file(s) that still +have conflict markers in them, but will still mark everything resolved. +``abort`` will output the same warning but will not mark things as resolved. +If this is set to ``abort``, :hg:`resolve --mark --all` will bypass the +error and still mark everything as resolved. +(default: ``none``) + ``status.relative`` Make paths in :hg:`status` output relative to the current directory. (default: False) diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -934,7 +934,7 @@ default=True, alias=[('format', 'aggressivemergedeltas')], ) -coreconfigitem('experimental', 'resolve.mark-check', +coreconfigitem('commands', 'resolve.mark-check', default=None, ) coreconfigitem('server', 'bookmarks-pushkey-compat', diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -4603,7 +4603,7 @@ tocomplete = [] hasconflictmarkers = [] if mark: -markcheck = ui.config('experimental', 'resolve.mark-check') +markcheck = ui.config('commands', 'resolve.mark-check') for f in ms: if not m(f): continue To: spectral, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4072: resolve: add commands.resolve.mark-check=abort to tweakdefaults
spectral created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4072 AFFECTED FILES mercurial/ui.py CHANGE DETAILS diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -67,6 +67,9 @@ update.check = noconflict # Show conflicts information in `hg status` status.verbose = True +# Refuse to perform `hg resolve --mark` on files that still have conflict +# markers +resolve.mark-check = abort [diff] git = 1 To: spectral, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@38832: 33 new changesets
33 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/7790cd70842a changeset: 38800:7790cd70842a user:Yuya Nishihara date:Sun Jul 22 16:03:48 2018 +0900 summary: lfs: remove callstatus property from 'lfs()' fileset https://www.mercurial-scm.org/repo/hg/rev/1d1c1645d7b9 changeset: 38801:1d1c1645d7b9 user:Yuya Nishihara date:Sat Jul 21 14:52:36 2018 +0900 summary: debugfileset: backport --show-stage option from debugrevspec https://www.mercurial-scm.org/repo/hg/rev/f0a574dbfae9 changeset: 38802:f0a574dbfae9 user:Yuya Nishihara date:Sat Jul 21 15:05:40 2018 +0900 summary: debugfileset: add option to show matcher representation https://www.mercurial-scm.org/repo/hg/rev/4dc498d61d86 changeset: 38803:4dc498d61d86 user:Yuya Nishihara date:Sat Jul 21 15:14:38 2018 +0900 summary: fileset: flatten arguments list https://www.mercurial-scm.org/repo/hg/rev/d82c4d42b615 changeset: 38804:d82c4d42b615 user:Yuya Nishihara date:Sat Jul 21 15:23:56 2018 +0900 summary: fileset: flatten 'or' nodes to unnest unionmatchers https://www.mercurial-scm.org/repo/hg/rev/b9162ea1b815 changeset: 38805:b9162ea1b815 user:Yuya Nishihara date:Sun Jul 22 15:50:45 2018 +0900 summary: fileset: extract language processing part to new module (API) https://www.mercurial-scm.org/repo/hg/rev/5742d0428ed9 changeset: 38806:5742d0428ed9 user:Gregory Szorc date:Sat Jul 28 14:52:46 2018 -0700 summary: changegroup: inline prune() logic from narrow https://www.mercurial-scm.org/repo/hg/rev/98df52d5042c changeset: 38807:98df52d5042c user:Gregory Szorc date:Sat Jul 28 17:33:20 2018 -0700 summary: exchange: make narrow ACL presence imply narrow=True https://www.mercurial-scm.org/repo/hg/rev/d99083996398 changeset: 38808:d99083996398 user:Gregory Szorc date:Sat Jul 28 17:42:36 2018 -0700 summary: exchange: move simple narrow changegroup generation from extension https://www.mercurial-scm.org/repo/hg/rev/57af5ee15b35 changeset: 38809:57af5ee15b35 user:Augie Fackler date:Wed Aug 01 23:25:35 2018 -0400 summary: linelog: port to Python 3 https://www.mercurial-scm.org/repo/hg/rev/4fe8d1f077b8 changeset: 38810:4fe8d1f077b8 user:Martin von Zweigbergk date:Thu Aug 02 13:35:13 2018 -0700 summary: help: add quotes to a few commands we point to https://www.mercurial-scm.org/repo/hg/rev/64535d43c103 changeset: 38811:64535d43c103 user:Danny Hooper date:Wed Aug 01 16:03:32 2018 -0700 summary: fix: add a monkey-patchable point after all new revisions have been committed https://www.mercurial-scm.org/repo/hg/rev/9d49bb117dde changeset: 38812:9d49bb117dde user:Martijn Pieters date:Thu Aug 02 20:53:03 2018 +0100 summary: util: make new timedcmstats class Python 3 compatible https://www.mercurial-scm.org/repo/hg/rev/4ca5932065ca changeset: 38813:4ca5932065ca user:FUJIWARA Katsunori date:Thu Aug 02 21:07:30 2018 +0900 summary: i18n: avoid substitution of PYFILES at runtime for readability of output https://www.mercurial-scm.org/repo/hg/rev/96b2e66dfa74 changeset: 38814:96b2e66dfa74 user:FUJIWARA Katsunori date:Mon Jun 11 12:32:16 2018 +0900 summary: i18n: omit redundant translatable synopsis text to avoid xgettext warning https://www.mercurial-scm.org/repo/hg/rev/617ae7e33a65 changeset: 38815:617ae7e33a65 user:FUJIWARA Katsunori date:Mon Jun 11 13:00:15 2018 +0900 summary: i18n: format warning of hggettext in standard compiler error style https://www.mercurial-scm.org/repo/hg/rev/2b728789edfd changeset: 38816:2b728789edfd user:Sushil khanchi date:Fri Aug 03 00:10:52 2018 +0530 summary: rebase: move "backup" flag to rebaseruntime https://www.mercurial-scm.org/repo/hg/rev/32ece991955c changeset: 38817:32ece991955c user:Sushil khanchi date:Tue Jul 10 20:23:55 2018 +0530 summary: amend: support "history-editing-backup" config option https://www.mercurial-scm.org/repo/hg/rev/e411774a2e0f changeset: 38818:e411774a2e0f user:Martin von Zweigbergk date:Thu Aug 02 23:50:47 2018 -0700 summary: narrow: move status-filtering to core and to ctx https://www.mercurial-scm.org/repo/hg/rev/49628742d264 changeset: 38819:49628742d264 user:Martin von Zweigbergk date:Fri Jul 20 23:57:25 2018 -0700 summary: revlog: remove unnecessary output parameter from node_check() https://www.mercurial-scm.org/repo/hg/rev/44bbc89ec5e0 changeset: 38820:44bbc89ec5e0 user:Martin von Zweigbergk date:Sun Jul 08 23:39:32 2018 -0700 summary: revlog: remove micro-optimization for looking up only nullid https://www.mercurial-scm.org/repo/hg/rev/d814bbd22946 changeset: 38821:d814bbd22946 user:
Re: [PATCH 5 of 7] fileset: roughly adjust weights of functions
> On Aug 3, 2018, at 11:01, Yuya Nishihara wrote: > > # HG changeset patch > # User Yuya Nishihara > # Date 1532227649 -32400 > # Sun Jul 22 11:47:29 2018 +0900 > # Node ID 1ec115b2c5525f0507ff7c4dc2019b57ae391911 > # Parent 6c9246c08523616914af131700126cfc408114f7 > fileset: roughly adjust weights of functions > > ... in order to move status predicates far away from basic patterns. I don't > know if each weight is appropriate, but it should be good enough as a start. Maybe it'd be worth having constants in the fileset module for roughly what we think typical weights are? eg _WEIGHT_STATUS = 10 # loads dirstate or stats working copy file _WEIGHT_STATUS_THOROUGH = 50 # might have to enumerate ignored files/dirs _WEIGHT_READ_CONTENTS = 30 # reads the contents of a file _WEIGHT_CHECK_FILENAME=0.5 # only examines a filename (I see you have a comment for that, but maybe even using named constants would be better?) Love the series, btw, good stuff. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4070: tests: update test expectations in pre-2.7.9 branch of this test
This revision was automatically updated to reflect the committed changes. Closed by commit rHGc9e6ca31cfe7: tests: update test expectations in pre-2.7.9 branch of this test (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4070?vs=9831=9832 REVISION DETAIL https://phab.mercurial-scm.org/D4070 AFFECTED FILES tests/test-clonebundles.t CHANGE DETAILS diff --git a/tests/test-clonebundles.t b/tests/test-clonebundles.t --- a/tests/test-clonebundles.t +++ b/tests/test-clonebundles.t @@ -286,6 +286,7 @@ finished applying clone bundle searching for changes no changes found + 2 local changesets published #endif Stream clone bundles are supported To: durin42, #hg-reviewers, martinvonz Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4070: tests: update test expectations in pre-2.7.9 branch of this test
martinvonz accepted this revision. martinvonz added a comment. This revision is now accepted and ready to land. Queued for stable, thanks. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4070 To: durin42, #hg-reviewers, martinvonz Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4070: tests: update test expectations in pre-2.7.9 branch of this test
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY As far as I can tell this is the only spot that got overlooked. Rough test methodology (run inside an hg working copy): docker run --rm -v `pwd`:/hg -it debian:wheezy bash apt-get update apt-get install python python-dev build-essential unzip mercurial \ wget libbz2-dev make testpy-2.7.8 You could try and use the system Python, but it's 2.7.3 and has lots of issues for hg these days that are not worth fixing. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4070 AFFECTED FILES tests/test-clonebundles.t CHANGE DETAILS diff --git a/tests/test-clonebundles.t b/tests/test-clonebundles.t --- a/tests/test-clonebundles.t +++ b/tests/test-clonebundles.t @@ -286,6 +286,7 @@ finished applying clone bundle searching for changes no changes found + 2 local changesets published #endif Stream clone bundles are supported To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[Bug 5951] New: Can't clone from m-s.o with Mercurial 2.2.2
https://bz.mercurial-scm.org/show_bug.cgi?id=5951 Bug ID: 5951 Summary: Can't clone from m-s.o with Mercurial 2.2.2 Product: Mercurial project Version: unspecified Hardware: PC OS: Mac OS Status: UNCONFIRMED Severity: feature Priority: wish Component: infrastructure Assignee: bugzi...@mercurial-scm.org Reporter: duri...@gmail.com CC: kbullock+mercur...@ringworld.org, mercurial-devel@mercurial-scm.org Eg docker run --rm -v `pwd`:/hg -it debian:wheezy bash apt-get update apt-get install mercurial hg clone https://mercurial-scm.org/hg emits real URL is https://www.mercurial-scm.org/repo/hg requesting all changes abort: remote error: incompatible Mercurial client; bundle2 required (see https://www.mercurial-scm.org/wiki/IncompatibleClient) We should fix this so that old clients can still clone hg. -- You are receiving this mail because: You are on the CC list for the bug. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@38799: 20 new changesets
20 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/ddb15a83ae0b changeset: 38780:ddb15a83ae0b parent: 38778:a4d847cea6f8 user:Martijn Pieters date:Tue Jul 31 19:37:48 2018 +0200 summary: debug: allow specifying a manifest node rather than a revision https://www.mercurial-scm.org/repo/hg/rev/0a57945aaf7f changeset: 38781:0a57945aaf7f user:Martijn Pieters date:Tue Jul 31 19:37:54 2018 +0200 summary: manifest: persist the manifestfulltext cache https://www.mercurial-scm.org/repo/hg/rev/7eba8f83129b changeset: 38782:7eba8f83129b user:Gregory Szorc date:Wed Aug 01 12:57:15 2018 -0700 summary: pycompat: add xrange alias for Python 2 https://www.mercurial-scm.org/repo/hg/rev/e7aa113b14f7 changeset: 38783:e7aa113b14f7 user:Gregory Szorc date:Wed Aug 01 13:00:45 2018 -0700 summary: global: use pycompat.xrange() https://www.mercurial-scm.org/repo/hg/rev/882ef6949bdc changeset: 38784:882ef6949bdc user:Gregory Szorc date:Wed Aug 01 13:08:00 2018 -0700 summary: check-code: ban use of bare xrange() https://www.mercurial-scm.org/repo/hg/rev/fb9121ea38c4 changeset: 38785:fb9121ea38c4 user:Gregory Szorc date:Wed Aug 01 13:10:07 2018 -0700 summary: py3: stop rewriting xrange() to pycompat.xrange() https://www.mercurial-scm.org/repo/hg/rev/28d8b5f49b4d changeset: 38786:28d8b5f49b4d user:Martin von Zweigbergk date:Tue Jul 24 22:51:11 2018 -0700 summary: histedit: avoid repeating name of state file in a few places https://www.mercurial-scm.org/repo/hg/rev/5199c5b6fd29 changeset: 38787:5199c5b6fd29 user:Martin von Zweigbergk date:Tue Jul 24 10:22:07 2018 -0700 summary: dispatch: don't show list of commands on bogus command https://www.mercurial-scm.org/repo/hg/rev/a9ff2b0c11dd changeset: 38788:a9ff2b0c11dd user:Martin von Zweigbergk date:Tue Jul 24 10:47:42 2018 -0700 summary: dispatch: show a short error message when invalid global option given https://www.mercurial-scm.org/repo/hg/rev/9b64b73d702b changeset: 38789:9b64b73d702b user:Gregory Szorc date:Sat Jul 28 10:41:23 2018 -0700 summary: exchange: move disabling of rev-branch-cache bundle part out of narrow https://www.mercurial-scm.org/repo/hg/rev/3e7387337a3c changeset: 38790:3e7387337a3c user:Gregory Szorc date:Mon Jul 02 18:24:26 2018 -0700 summary: exchange: move narrow acl functionality into core https://www.mercurial-scm.org/repo/hg/rev/7e66e7999bdd changeset: 38791:7e66e7999bdd user:Gregory Szorc date:Mon Jul 02 18:32:20 2018 -0700 summary: exchange: move _computeellipsis() from narrow https://www.mercurial-scm.org/repo/hg/rev/afb442f58cbf changeset: 38792:afb442f58cbf user:Gregory Szorc date:Mon Jul 02 18:39:48 2018 -0700 summary: exchange: refactor control flow of _getbundlechangegrouppart() https://www.mercurial-scm.org/repo/hg/rev/6c8e3c847977 changeset: 38793:6c8e3c847977 user:Kyle Lippincott date:Thu Jul 26 17:11:03 2018 -0700 summary: resolve: add option to warn/abort on -m with unresolved conflict markers https://www.mercurial-scm.org/repo/hg/rev/1d01cf0416a5 changeset: 38794:1d01cf0416a5 user:Gregory Szorc date:Sat Jul 28 11:40:31 2018 -0700 summary: changegroup: move file matcher from narrow extension https://www.mercurial-scm.org/repo/hg/rev/422d661056be changeset: 38795:422d661056be user:Augie Fackler date:Mon Jul 30 10:42:37 2018 -0400 summary: linelog: add a Python implementation of the linelog datastructure https://www.mercurial-scm.org/repo/hg/rev/f956dc7217fc changeset: 38796:f956dc7217fc user:Augie Fackler date:Wed Aug 01 23:08:18 2018 -0400 summary: linelog: fix import statements to pass the import checker on py3 https://www.mercurial-scm.org/repo/hg/rev/8751d1e2a7ff changeset: 38797:8751d1e2a7ff user:Martijn Pieters date:Wed Aug 01 16:05:41 2018 +0200 summary: util: create a context manager to handle timing https://www.mercurial-scm.org/repo/hg/rev/d58958676b3c changeset: 38798:d58958676b3c user:Martijn Pieters date:Wed Aug 01 16:06:53 2018 +0200 summary: extensions: add detailed loading information https://www.mercurial-scm.org/repo/hg/rev/2002c193f2bc changeset: 38799:2002c193f2bc bookmark:@ tag: tip user:Sushil khanchi date:Thu Jul 05 10:42:48 2018 +0530 summary: rebase: support "history-editing-backup" config option -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 6 of 7] fileset: reorder 'and' expression to evaluate basic patterns first
On Fri 3 Aug, 2018, 6:02 PM Yuya Nishihara, wrote: > # HG changeset patch > # User Yuya Nishihara > # Date 1532158905 -32400 > # Sat Jul 21 16:41:45 2018 +0900 > # Node ID 6a0bf2f620f877d609896f649c0feae09c3f5d2d > # Parent 1ec115b2c5525f0507ff7c4dc2019b57ae391911 > fileset: reorder 'and' expression to evaluate basic patterns first > > Timing of a crafted example (when disk cache is warm): > > $ hg files set:'binary() and path:contrib' > (orig) time: real 0.140 secs (user 0.120+0.000 sys 0.020+0.000) > (new) time: real 0.040 secs (user 0.030+0.000 sys 0.010+0.000) > This looks like performance improvement. How about adding this to 4.8 releasenotes page on wiki? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3988: resolve: add confirm config option
pulkit added inline comments. INLINE COMMENTS > martinvonz wrote in configitems.py:193 > Is this name too generic? It's specifically for confirming re-resolve with > `--all`. I can imagine having confirmation for marking files as resolved and > I'm not sure we'd want to share the config option if we ever added such a > feature. It might also make the name clearer if it was something like > `resolve.confirmreresolve` or `resolve.confirmredo` or > `resolve.confirmoverwrite`. For now, yes the name is generic. My plan with @khanchi97 on this is to respect this option with other flags too. Like `hg resolve -m` will ask before marking as resolve if this config option is set. Once we are done with other flags too, this won't sound generic. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3988 To: khanchi97, #hg-reviewers, pulkit Cc: martinvonz, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3988: resolve: add confirm config option
martinvonz added inline comments. INLINE COMMENTS > configitems.py:193 > ) > +coreconfigitem('commands', 'resolve.confirm', > +default=False, Is this name too generic? It's specifically for confirming re-resolve with `--all`. I can imagine having confirmation for marking files as resolved and I'm not sure we'd want to share the config option if we ever added such a feature. It might also make the name clearer if it was something like `resolve.confirmreresolve` or `resolve.confirmredo` or `resolve.confirmoverwrite`. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3988 To: khanchi97, #hg-reviewers, pulkit Cc: martinvonz, pulkit, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4057: narrowspec: use sparse.parseconfig() to parse narrowspec file (BC)
martinvonz accepted this revision. martinvonz added inline comments. This revision is now accepted and ready to land. INLINE COMMENTS > narrowspec.py:145 > +includepats, excludepats, __ = sparse.parseconfig(repo.ui, spec, > 'narrow') > +if __: > +raise error.Abort(_("including other spec files using '%include' is > not" I'll rename this to `profiles` in flight REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D4057 To: pulkit, durin42, #hg-reviewers, martinvonz Cc: martinvonz, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D4056: sparse: add an action argument to parseconfig()
pulkit updated this revision to Diff 9828. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D4056?vs=9795=9828 REVISION DETAIL https://phab.mercurial-scm.org/D4056 AFFECTED FILES mercurial/sparse.py CHANGE DETAILS diff --git a/mercurial/sparse.py b/mercurial/sparse.py --- a/mercurial/sparse.py +++ b/mercurial/sparse.py @@ -31,9 +31,11 @@ # a per-repo option, possibly a repo requirement. enabled = False -def parseconfig(ui, raw): +def parseconfig(ui, raw, action): """Parse sparse config file content. +action is the command which is trigerring this read, can be narrow, sparse + Returns a tuple of includes, excludes, and profiles. """ includes = set() @@ -54,24 +56,25 @@ elif line == '[include]': if havesection and current != includes: # TODO pass filename into this API so we can report it. -raise error.Abort(_('sparse config cannot have includes ' + -'after excludes')) +raise error.Abort(_('%s config cannot have includes ' + +'after excludes') % action) havesection = True current = includes continue elif line == '[exclude]': havesection = True current = excludes elif line: if current is None: -raise error.Abort(_('sparse config entry outside of ' -'section: %s') % line, +raise error.Abort(_('%s config entry outside of ' +'section: %s') % (action, line), hint=_('add an [include] or [exclude] line ' 'to declare the entry type')) if line.strip().startswith('/'): -ui.warn(_('warning: sparse profile cannot use' + - ' paths starting with /, ignoring %s\n') % line) +ui.warn(_('warning: %s profile cannot use' + + ' paths starting with /, ignoring %s\n') +% (action, line)) continue current.add(line) @@ -102,7 +105,7 @@ raise error.Abort(_('cannot parse sparse patterns from working ' 'directory')) -includes, excludes, profiles = parseconfig(repo.ui, raw) +includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse') ctx = repo[rev] if profiles: @@ -128,7 +131,7 @@ repo.ui.debug(msg) continue -pincludes, pexcludes, subprofs = parseconfig(repo.ui, raw) +pincludes, pexcludes, subprofs = parseconfig(repo.ui, raw, 'sparse') includes.update(pincludes) excludes.update(pexcludes) profiles.update(subprofs) @@ -516,7 +519,7 @@ force=False, removing=False): """Update the sparse config and working directory state.""" raw = repo.vfs.tryread('sparse') -oldincludes, oldexcludes, oldprofiles = parseconfig(repo.ui, raw) +oldincludes, oldexcludes, oldprofiles = parseconfig(repo.ui, raw, 'sparse') oldstatus = repo.status() oldmatch = matcher(repo) @@ -556,7 +559,7 @@ """ with repo.wlock(): raw = repo.vfs.tryread('sparse') -includes, excludes, profiles = parseconfig(repo.ui, raw) +includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse') if not includes and not excludes: return @@ -572,7 +575,7 @@ with repo.wlock(): # read current configuration raw = repo.vfs.tryread('sparse') -includes, excludes, profiles = parseconfig(repo.ui, raw) +includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse') aincludes, aexcludes, aprofiles = activeconfig(repo) # Import rules on top; only take in rules that are not yet @@ -582,7 +585,8 @@ with util.posixfile(util.expandpath(p), mode='rb') as fh: raw = fh.read() -iincludes, iexcludes, iprofiles = parseconfig(repo.ui, raw) +iincludes, iexcludes, iprofiles = parseconfig(repo.ui, raw, + 'sparse') oldsize = len(includes) + len(excludes) + len(profiles) includes.update(iincludes - aincludes) excludes.update(iexcludes - aexcludes) @@ -615,7 +619,8 @@ """ with repo.wlock(): raw = repo.vfs.tryread('sparse') -oldinclude, oldexclude, oldprofiles = parseconfig(repo.ui, raw) +oldinclude, oldexclude, oldprofiles = parseconfig(repo.ui, raw, + 'sparse') if reset: newinclude = set() To: pulkit, #hg-reviewers Cc: mercurial-devel