Re: Switching to a date-based version scheme?

2018-01-12 Thread Anton Shestakov
On Thu, 11 Jan 2018 22:21:50 -0800
Gregory Szorc  wrote:

> Mercurial's version numbers (currently 4.4, soon to be 4.5) mean little to
> nothing. Mercurial's existing .. version scheme
> doesn't honor semantic versioning in the traditional sense. API guarantees
> are that each quarterly X.Y release generally maintains API compatibility
> within the release but there are no guarantees between quarterly releases.
> The  component of the version scheme is incremented when 
> would hit 10 - not when there is a major API change. (This is an arbitrary
> decision since it is technically possible to have version components with
> an absolute value >=10.)
> 
> To the typical user who isn't intimately familiar with Mercurial's
> versioning and release strategy, the existing versioning scheme means
> little to nothing.
> 
> A typical user does care about something: whether their Mercurial is up to
> date.
> 
> One way of determining if something is up to date is asking "how old is it?"

FWIW, here are my thoughts about putting date of release into version.

First, let's consider something that's still active, but not doing
time-based release plan. If a typical user looks at something like TeX
3.1415926, which was last released in January 2014 (let's say they
somehow knew that), how would that help them, what would they think?
"There has to be an update by now, it's been 4 years already", right?
No, it's actually the latest TeX release. So the assumption that some
period of time (now - releasedate) means there's an update available
only works if that user is, well, at least somewhat familiar with
Mercurial's release strategy.

18.2.0 may look like it was released in February 2018, but what does
18.2.1 look like? Was it released February 1st? What about 18.2.2, how
old is it? Would users need to know and remember our versioning scheme
to tell that offhand?

And if we do YY.M (18.2, 18.3, 18.4) instead, that will completely
obfuscate if a version is a feature release or a bug-fix release. I
think at least package maintainers care about that.

Also, users may not realize that 18.2.0 means it was released in
February 2018 at all, unless they also, for example, look at previous
versions... or look it up on our site. In fact, why not just look at
our site to see how old their version is, and, of course, if there's an
update available. Even Wikipedia has this information.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1795: py3: use pycompat.bytestr() instead of str()

2018-01-12 Thread yuja (Yuya Nishihara)
yuja added inline comments.

INLINE COMMENTS

> subrepo.py:392
>  if source.isabs():
> -return str(source)
> +return pycompat.bytestr(source)
>  source.path = posixpath.normpath(source.path)

bytes()

> subrepo.py:399
>  parent.path = posixpath.normpath(parent.path)
> -return str(parent)
> +return pycompat.bytestr(parent)
>  else: # recursion reached top repo

bytes()

> verify.py:110
> +self.warn(_(" (expected %s)") % " ".join
> +  (map(pycompat.bytestr, linkrevs)))
>  lr = None # can't be trusted

'%d', perhaps.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1795

To: pulkit, #hg-reviewers, durin42
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1851: visibilty: fix a comment introduced before which is not up-to-date

2018-01-12 Thread lothiraldan (Boris Feld)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG49e073ea09d6: visibilty: fix a comment introduced before 
which is not up-to-date (authored by lothiraldan, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D1851?vs=4800=4804

REVISION DETAIL
  https://phab.mercurial-scm.org/D1851

AFFECTED FILES
  mercurial/context.py

CHANGE DETAILS

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -439,8 +439,8 @@
 unfilteredrepo = repo.unfiltered()
 ctx = unfilteredrepo[changeid]
 
-# If the changeset is obsolete, enrich the hint with the reason that
-# made this changeset not visible
+# If the changeset is obsolete, enrich the message with the reason
+# that made this changeset not visible
 if ctx.obsolete():
 reason = obsutil._getfilteredreason(unfilteredrepo, ctx)
 msg = _("hidden revision '%s' %s") % (changeid, reason)



To: lothiraldan, #hg-reviewers, yuja
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1853: visiblity: pass a normal repo to _getfilteredreason

2018-01-12 Thread lothiraldan (Boris Feld)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGea9bd35529f2: visiblity: pass a normal repo to 
_getfilteredreason (authored by lothiraldan, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D1853?vs=4802=4806

REVISION DETAIL
  https://phab.mercurial-scm.org/D1853

AFFECTED FILES
  mercurial/context.py
  mercurial/obsutil.py

CHANGE DETAILS

diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py
--- a/mercurial/obsutil.py
+++ b/mercurial/obsutil.py
@@ -875,10 +875,10 @@
   "%d more"),
 }
 
-def _getfilteredreason(unfilteredrepo, changeid, ctx):
+def _getfilteredreason(repo, changeid, ctx):
 """return a human-friendly string on why a obsolete changeset is hidden
 """
-successors = successorssets(unfilteredrepo, ctx.node())
+successors = successorssets(repo, ctx.node())
 fate = _getobsfate(successors)
 
 # Be more precise in case the revision is superseded
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -442,7 +442,7 @@
 # If the changeset is obsolete, enrich the message with the reason
 # that made this changeset not visible
 if ctx.obsolete():
-msg = obsutil._getfilteredreason(unfilteredrepo, changeid, ctx)
+msg = obsutil._getfilteredreason(repo, changeid, ctx)
 else:
 msg = _("hidden revision '%s'") % changeid
 



To: lothiraldan, #hg-reviewers, yuja
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1851: visibilty: fix a comment introduced before which is not up-to-date

2018-01-12 Thread lothiraldan (Boris Feld)
lothiraldan created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  https://phab.mercurial-scm.org/rHG265cd9e19d26dd7f684f660b6c267b45427284e8 
introduced a comment in _filterederror that was not updated with
  the latest iterations of the patch, fix the comment.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1851

AFFECTED FILES
  mercurial/context.py

CHANGE DETAILS

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -439,8 +439,8 @@
 unfilteredrepo = repo.unfiltered()
 ctx = unfilteredrepo[changeid]
 
-# If the changeset is obsolete, enrich the hint with the reason that
-# made this changeset not visible
+# If the changeset is obsolete, enrich the message with the reason
+# that made this changeset not visible
 if ctx.obsolete():
 reason = obsutil._getfilteredreason(unfilteredrepo, ctx)
 msg = _("hidden revision '%s' %s") % (changeid, reason)



To: lothiraldan, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1852: visibility: make the filtered message translatable

2018-01-12 Thread lothiraldan (Boris Feld)
lothiraldan created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Introduce a filtered message table to ease translation of these messages.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1852

AFFECTED FILES
  mercurial/context.py
  mercurial/obsutil.py

CHANGE DETAILS

diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py
--- a/mercurial/obsutil.py
+++ b/mercurial/obsutil.py
@@ -865,33 +865,42 @@
 
 return "".join(line)
 
-def _getfilteredreason(unfilteredrepo, ctx):
+
+filteredmsgtable = {
+"pruned": _("hidden revision '%s' is pruned"),
+"diverged": _("hidden revision '%s' has diverged"),
+"superseded": _("hidden revision '%s' was rewritten as: %s"),
+"superseded_split": _("hidden revision '%s' was split as: %s"),
+"superseded_split_several": _("hidden revision '%s' was split as: %s and "
+  "%d more"),
+}
+
+def _getfilteredreason(unfilteredrepo, changeid, ctx):
 """return a human-friendly string on why a obsolete changeset is hidden
 """
 successors = successorssets(unfilteredrepo, ctx.node())
 fate = _getobsfate(successors)
 
 # Be more precise in case the revision is superseded
 if fate == 'pruned':
-reason = _('is pruned')
+return filteredmsgtable['pruned'] % changeid
 elif fate == 'diverged':
-reason = _('has diverged')
+return filteredmsgtable['diverged'] % changeid
 elif fate == 'superseded':
-reason = _("was rewritten as: %s") % nodemod.short(successors[0][0])
+single_successor = nodemod.short(successors[0][0])
+return filteredmsgtable['superseded'] % (changeid, single_successor)
 elif fate == 'superseded_split':
 
 succs = []
 for node_id in successors[0]:
 succs.append(nodemod.short(node_id))
 
 if len(succs) <= 2:
-reason = _("was split as: %s") % ", ".join(succs)
+fmtsuccs = ', '.join(succs)
+return filteredmsgtable['superseded_split'] % (changeid, fmtsuccs)
 else:
-firstsuccessors = ", ".join(succs[:2])
+firstsuccessors = ', '.join(succs[:2])
 remainingnumber = len(succs) - 2
 
-args = (firstsuccessors, remainingnumber)
-successorsmsg = _("%s and %d more") % args
-reason = _("was split as: %s") % successorsmsg
-
-return reason
+args = (changeid, firstsuccessors, remainingnumber)
+return filteredmsgtable['superseded_split_several'] % args
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -442,8 +442,7 @@
 # If the changeset is obsolete, enrich the message with the reason
 # that made this changeset not visible
 if ctx.obsolete():
-reason = obsutil._getfilteredreason(unfilteredrepo, ctx)
-msg = _("hidden revision '%s' %s") % (changeid, reason)
+msg = obsutil._getfilteredreason(unfilteredrepo, changeid, ctx)
 else:
 msg = _("hidden revision '%s'") % changeid
 



To: lothiraldan, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 2 V2] filterlang: add a small language to filter files

2018-01-12 Thread Yuya Nishihara
On Thu, 11 Jan 2018 11:13:57 -0500, Matt Harbison wrote:
> 
> > On Jan 11, 2018, at 10:16 AM, Yuya Nishihara  wrote:
> > 
> >> On Thu, 11 Jan 2018 00:17:39 -0500, Matt Harbison wrote:
> >> # HG changeset patch
> >> # User Matt Harbison 
> >> # Date 1515641014 18000
> >> #  Wed Jan 10 22:23:34 2018 -0500
> >> # Node ID 548e748cb3f4eea0aedb36a2b2e9fe3b77ffb263
> >> # Parent  962b2bdd70d094ce4bf9a8135495788166b04510
> >> filterlang: add a small language to filter files
> > 
> >> I also made the 'always' token a
> >> predicate for consistency, and introduced 'never' to improve readability.
> > 
> > Perhaps '**' or '.' could be an "always" symbol given patterns are relative
> > to the repository root in filterlang.
> 
> I’m thinking ahead to a tracked file that could be converted to this 
> language, and trying to make it readable. This construct seems weird to me:
> 
>   **.c = !**

Ah, okay. always()/never() or all()/none() makes sense there. I slightly
prefer all()/none() as fileset is the language for set operations, and we
have all() in revset.

> >> diff --git a/mercurial/filterlang.py b/mercurial/filterlang.py
> >> new file mode 100644
> >> --- /dev/null
> >> +++ b/mercurial/filterlang.py
> >> @@ -0,0 +1,73 @@
> >> +# filterlang.py - a simple language to select files
> > 
> > The module name seems too generic.
> > minifileset.py, ufileset.py, etc. or merge these functions into fileset.py?
> 
> minifileset.py I guess?  My concern with putting it in fileset.py is how to 
> enforce the boundary clearly.

Seems fine.

> >> +def _compile(tree):
> >> +op = tree[0]
> >> +if op in ('symbol', 'string'):
> >> +name = fileset.getstring(tree, 'invalid file pattern')
> >> +op = name[0]
> >> +if op == '*': # file extension test, ex. "*.tar.gz"
> >> +return lambda n, s: n.endswith(name[1:])
> > 
> > Better to make sure no metacharacters in name[1:].
> 
> Aren’t meta characters allowed in a string, so as to not block certain file 
> names?  Does this mean symbol and string have to be handled separately?

I meant '*.*' shouldn't be translated to n.endswith('.*'), for example.

> >> +elif op in ['or', 'and']:
> >> +funcs = [_compile(t) for t in tree[1:]]
> >> +summary = {'or': any, 'and': all}[op]
> >> +return lambda n, s: summary(f(n, s) for f in funcs)
> > 
> > IIRC, ('or'/'and', x, y) isn't flattened in fileset.py, so the tree would 
> > have
> > exactly 2 operands.
> 
> fileset.andset() calls getset(), which checks the arg, but maybe that’s an 
> artifact of other uses.

That's probably for "()", an empty group.

Here I meant any()/all() always takes a list of two elements. Just for the
record, that isn't a problem.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 2 V2] filterlang: add a small language to filter files

2018-01-12 Thread Yuya Nishihara
On Thu, 11 Jan 2018 21:07:10 -0500, Matt Harbison wrote:
> On Thu, 11 Jan 2018 11:13:57 -0500, Matt Harbison   
> wrote:
> >> Perhaps this could be 'path:'.
> 
> I ended up needing to add this to avoid a parse error.  The "*fileset*"  
> tests run, but I'm not sure if this should be allowed for normal  
> filesets.  The '/' operator works because it is in the globchars string.
> 
> diff --git a/mercurial/fileset.py b/mercurial/fileset.py
> --- a/mercurial/fileset.py
> +++ b/mercurial/fileset.py
> @@ -72,13 +72,13 @@
>   pos += 1
>   else:
>   raise error.ParseError(_("unterminated string"), s)
> -elif c.isalnum() or c in globchars or ord(c) > 127:
> +elif c.isalnum() or c in globchars or ord(c) > 127 or c == ':':

Yep, ':' is reserved. We could instead add ':' operator to separate matcher
kind and pat, but I'm not sure which will be better. For now, we need quotes,
":".
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1852: visibility: make the filtered message translatable

2018-01-12 Thread yuja (Yuya Nishihara)
yuja added a comment.


  Queued, thanks.
  
  FWIW, it might be good idea to move `context._filterederror()` to obsutil.py
  because context.py is painfully big.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1852

To: lothiraldan, #hg-reviewers, yuja
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1813: bookmarks: add bookmarks to hidden revs if directaccess config is set

2018-01-12 Thread pulkit (Pulkit Goyal)
pulkit updated this revision to Diff 4803.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D1813?vs=4754=4803

REVISION DETAIL
  https://phab.mercurial-scm.org/D1813

AFFECTED FILES
  mercurial/bookmarks.py
  tests/test-directaccess.t
  tests/test-log.t
  tests/test-obsolete.t
  tests/test-rebase-obsolete.t

CHANGE DETAILS

diff --git a/tests/test-rebase-obsolete.t b/tests/test-rebase-obsolete.t
--- a/tests/test-rebase-obsolete.t
+++ b/tests/test-rebase-obsolete.t
@@ -1496,6 +1496,7 @@
   $ hg log -r .  # working dir is at rev 3 (successor of 2)
   3:be1832deae9a b (no-eol)
   $ hg book -r 2 mybook --hidden  # rev 2 has a bookmark on it now
+  bookmarking hidden changeset 1e9a3c00cbe9
   $ hg up 2 && hg log -r .  # working dir is at rev 2 again
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   2:1e9a3c00cbe9 b (rewritten using rebase as 3:be1832deae9a) (no-eol)
diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
--- a/tests/test-obsolete.t
+++ b/tests/test-obsolete.t
@@ -1333,6 +1333,7 @@
   $ echo "hello" > b
   $ hg commit --amend -m "message"
   $ hg book bookb -r 13bedc178fce --hidden
+  bookmarking hidden changeset 13bedc178fce
   $ hg log -r 13bedc178fce
   4:13bedc178fce (draft *obsolete*) [ bookb] add b [rewritten using amend as 
5:a9b1f8652753]
   $ hg book -d bookb
diff --git a/tests/test-log.t b/tests/test-log.t
--- a/tests/test-log.t
+++ b/tests/test-log.t
@@ -1851,14 +1851,16 @@
 bookmarks prevent a changeset being hidden
 
   $ hg bookmark --hidden -r 1 X
+  bookmarking hidden changeset a765632148dc
   $ hg log --template '{rev}:{node}\n'
   1:a765632148dc55d38c35c4f247c618701886cb2f
   0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
   $ hg bookmark -d X
 
 divergent bookmarks are not hidden
 
   $ hg bookmark --hidden -r 1 X@foo
+  bookmarking hidden changeset a765632148dc
   $ hg log --template '{rev}:{node}\n'
   1:a765632148dc55d38c35c4f247c618701886cb2f
   0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
diff --git a/tests/test-directaccess.t b/tests/test-directaccess.t
--- a/tests/test-directaccess.t
+++ b/tests/test-directaccess.t
@@ -186,3 +186,11 @@
   abort: hidden revision '2' was rewritten as: 2443a0e66469!
   (use --hidden to access hidden revisions)
   [255]
+
+Setting a bookmark will make that changeset unhidden, so this should come in 
end
+
+  $ hg bookmarks -r 28ad74 book
+  bookmarking hidden changeset 28ad74487de9
+
+  $ hg bookmarks
+ book  2:28ad74487de9
diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py
--- a/mercurial/bookmarks.py
+++ b/mercurial/bookmarks.py
@@ -830,6 +830,7 @@
 cur = repo.changectx('.').node()
 newact = None
 changes = []
+hiddenrevs = set()
 for mark in names:
 mark = checkformat(repo, mark)
 if newact is None:
@@ -839,10 +840,17 @@
 return
 tgt = cur
 if rev:
-tgt = scmutil.revsingle(repo, rev).node()
+repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
+ctx = scmutil.revsingle(repo, rev)
+if ctx.hidden():
+hiddenrevs.add(ctx.hex()[:12])
+tgt = ctx.node()
 for bm in marks.checkconflict(mark, force, tgt):
 changes.append((bm, None))
 changes.append((mark, tgt))
+if hiddenrevs:
+repo.ui.warn(_("bookmarking hidden changeset %s\n") % \
+ (', '.join(hiddenrevs)))
 marks.applychanges(repo, tr, changes)
 if not inactive and cur == marks[newact] and not rev:
 activate(repo, newact)



To: pulkit, #hg-reviewers, yuja
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1853: visiblity: pass a normal repo to _getfilteredreason

2018-01-12 Thread lothiraldan (Boris Feld)
lothiraldan created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  There is no reason to pass an unfiltered-repo to _getfilteredreason and
  successorssets, so use a normal repo instead.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1853

AFFECTED FILES
  mercurial/context.py
  mercurial/obsutil.py

CHANGE DETAILS

diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py
--- a/mercurial/obsutil.py
+++ b/mercurial/obsutil.py
@@ -875,10 +875,10 @@
   "%d more"),
 }
 
-def _getfilteredreason(unfilteredrepo, changeid, ctx):
+def _getfilteredreason(repo, changeid, ctx):
 """return a human-friendly string on why a obsolete changeset is hidden
 """
-successors = successorssets(unfilteredrepo, ctx.node())
+successors = successorssets(repo, ctx.node())
 fate = _getobsfate(successors)
 
 # Be more precise in case the revision is superseded
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -442,7 +442,7 @@
 # If the changeset is obsolete, enrich the message with the reason
 # that made this changeset not visible
 if ctx.obsolete():
-msg = obsutil._getfilteredreason(unfilteredrepo, changeid, ctx)
+msg = obsutil._getfilteredreason(repo, changeid, ctx)
 else:
 msg = _("hidden revision '%s'") % changeid
 



To: lothiraldan, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1795: py3: use pycompat.bytestr() instead of str()

2018-01-12 Thread pulkit (Pulkit Goyal)
pulkit added a comment.


  In https://phab.mercurial-scm.org/D1795#31282, @yuja wrote:
  
  > `bytes()` or `"%d"` is preferred. Can you send a follow up?
  
  
  I am not sure which one needs to be changed.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1795

To: pulkit, #hg-reviewers, durin42
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1694: debugcommands: replace opts.get('foo') by opts['foo']

2018-01-12 Thread yuja (Yuya Nishihara)
yuja added a comment.


  In https://phab.mercurial-scm.org/D1694#31044, @durin42 wrote:
  
  > I think it's probably okay for debug commands, those are pretty rare to use 
as a function aren't they?
  
  
  Yeah, it's okay, but why do we apply a different rule to debug commands?
  
  If we take this, I'd rather replace `.get()` by `[]` everywhere to blame 
third-party
  tools which don't pass all options.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1694

To: martinvonz, #hg-reviewers
Cc: durin42, yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1852: visibility: make the filtered message translatable

2018-01-12 Thread lothiraldan (Boris Feld)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG0e0daf46a30c: visibility: make the filtered message 
translatable (authored by lothiraldan, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D1852?vs=4801=4805

REVISION DETAIL
  https://phab.mercurial-scm.org/D1852

AFFECTED FILES
  mercurial/context.py
  mercurial/obsutil.py

CHANGE DETAILS

diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py
--- a/mercurial/obsutil.py
+++ b/mercurial/obsutil.py
@@ -865,33 +865,42 @@
 
 return "".join(line)
 
-def _getfilteredreason(unfilteredrepo, ctx):
+
+filteredmsgtable = {
+"pruned": _("hidden revision '%s' is pruned"),
+"diverged": _("hidden revision '%s' has diverged"),
+"superseded": _("hidden revision '%s' was rewritten as: %s"),
+"superseded_split": _("hidden revision '%s' was split as: %s"),
+"superseded_split_several": _("hidden revision '%s' was split as: %s and "
+  "%d more"),
+}
+
+def _getfilteredreason(unfilteredrepo, changeid, ctx):
 """return a human-friendly string on why a obsolete changeset is hidden
 """
 successors = successorssets(unfilteredrepo, ctx.node())
 fate = _getobsfate(successors)
 
 # Be more precise in case the revision is superseded
 if fate == 'pruned':
-reason = _('is pruned')
+return filteredmsgtable['pruned'] % changeid
 elif fate == 'diverged':
-reason = _('has diverged')
+return filteredmsgtable['diverged'] % changeid
 elif fate == 'superseded':
-reason = _("was rewritten as: %s") % nodemod.short(successors[0][0])
+single_successor = nodemod.short(successors[0][0])
+return filteredmsgtable['superseded'] % (changeid, single_successor)
 elif fate == 'superseded_split':
 
 succs = []
 for node_id in successors[0]:
 succs.append(nodemod.short(node_id))
 
 if len(succs) <= 2:
-reason = _("was split as: %s") % ", ".join(succs)
+fmtsuccs = ', '.join(succs)
+return filteredmsgtable['superseded_split'] % (changeid, fmtsuccs)
 else:
-firstsuccessors = ", ".join(succs[:2])
+firstsuccessors = ', '.join(succs[:2])
 remainingnumber = len(succs) - 2
 
-args = (firstsuccessors, remainingnumber)
-successorsmsg = _("%s and %d more") % args
-reason = _("was split as: %s") % successorsmsg
-
-return reason
+args = (changeid, firstsuccessors, remainingnumber)
+return filteredmsgtable['superseded_split_several'] % args
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -442,8 +442,7 @@
 # If the changeset is obsolete, enrich the message with the reason
 # that made this changeset not visible
 if ctx.obsolete():
-reason = obsutil._getfilteredreason(unfilteredrepo, ctx)
-msg = _("hidden revision '%s' %s") % (changeid, reason)
+msg = obsutil._getfilteredreason(unfilteredrepo, changeid, ctx)
 else:
 msg = _("hidden revision '%s'") % changeid
 



To: lothiraldan, #hg-reviewers, yuja
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2] rust: convert Unix path to CString transparently

2018-01-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1515763122 -32400
#  Fri Jan 12 22:18:42 2018 +0900
# Node ID 4ca3b26ca272cf8c24b34deee8bc2530a8eccada
# Parent  44289d889542a3c559c424fa1f2d85cb7e16
rust: convert Unix path to CString transparently

On Unix, path is just a sequence of bytes. We shouldn't convert it to UTF-8
string.

diff --git a/rust/hgcli/src/main.rs b/rust/hgcli/src/main.rs
--- a/rust/hgcli/src/main.rs
+++ b/rust/hgcli/src/main.rs
@@ -16,7 +16,7 @@ use std::env;
 use std::path::PathBuf;
 use std::ffi::{CString, OsStr};
 #[cfg(target_family = "unix")]
-use std::os::unix::ffi::OsStringExt;
+use std::os::unix::ffi::{OsStrExt, OsStringExt};
 
 #[derive(Debug)]
 struct Environment {
@@ -62,6 +62,14 @@ fn get_environment() -> Environment {
 }
 }
 
+// On UNIX, platform string is just bytes and should not contain NUL.
+#[cfg(target_family = "unix")]
+fn cstring_from_os>(s: T) -> CString {
+CString::new(s.as_ref().as_bytes()).unwrap()
+}
+
+// TODO convert to ANSI characters?
+#[cfg(target_family = "windows")]
 fn cstring_from_os>(s: T) -> CString {
 CString::new(s.as_ref().to_str().unwrap()).unwrap()
 }
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 2] rust: extract function to convert Path to platform CString

2018-01-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1515762574 -32400
#  Fri Jan 12 22:09:34 2018 +0900
# Node ID 44289d889542a3c559c424fa1f2d85cb7e16
# Parent  ea9bd35529f231c438630071119a309ba84dcc77
rust: extract function to convert Path to platform CString

It can be better on Unix.

diff --git a/rust/hgcli/src/main.rs b/rust/hgcli/src/main.rs
--- a/rust/hgcli/src/main.rs
+++ b/rust/hgcli/src/main.rs
@@ -14,7 +14,7 @@ use libc::{c_char, c_int};
 
 use std::env;
 use std::path::PathBuf;
-use std::ffi::CString;
+use std::ffi::{CString, OsStr};
 #[cfg(target_family = "unix")]
 use std::os::unix::ffi::OsStringExt;
 
@@ -62,6 +62,10 @@ fn get_environment() -> Environment {
 }
 }
 
+fn cstring_from_os>(s: T) -> CString {
+CString::new(s.as_ref().to_str().unwrap()).unwrap()
+}
+
 // On UNIX, argv starts as an array of char*. So it is easy to convert
 // to C strings.
 #[cfg(target_family = "unix")]
@@ -86,9 +90,7 @@ fn args_to_cstrings() -> Vec {
 }
 
 fn set_python_home(env: ) {
-let raw = CString::new(env.python_home.to_str().unwrap())
-.unwrap()
-.into_raw();
+let raw = cstring_from_os(_home).into_raw();
 unsafe {
 python27_sys::Py_SetPythonHome(raw);
 }
@@ -133,9 +135,7 @@ fn run() -> Result<(), i32> {
 // Python files. Apparently we could define our own ``Py_GetPath()``
 // implementation. But this may require statically linking Python, which is
 // not desirable.
-let program_name = CString::new(env.python_exe.to_str().unwrap())
-.unwrap()
-.as_ptr();
+let program_name = cstring_from_os(_exe).as_ptr();
 unsafe {
 python27_sys::Py_SetProgramName(program_name as *mut i8);
 }
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1855: explicitly kill server processes

2018-01-12 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger 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/D1855

AFFECTED FILES
  tests/test-pull-r.t

CHANGE DETAILS

diff --git a/tests/test-pull-r.t b/tests/test-pull-r.t
--- a/tests/test-pull-r.t
+++ b/tests/test-pull-r.t
@@ -144,3 +144,4 @@
   
 
   $ cd ..
+  $ killdaemons.py



To: joerg.sonnenberger, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1856: wireproto: server-side support for pullbundles

2018-01-12 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Pullbundles are similar to clonebundles, but served as normal inline
  bundle streams. They are almost transparent to the client -- the only
  visible effect is that the client might get less changes than what it
  asked for, i.e. not all requested head revisions are provided. The
  missing client-side logic is to retry a pull in that case.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1856

AFFECTED FILES
  mercurial/configitems.py
  mercurial/help/config.txt
  mercurial/wireproto.py
  tests/test-pull-r.t

CHANGE DETAILS

diff --git a/tests/test-pull-r.t b/tests/test-pull-r.t
--- a/tests/test-pull-r.t
+++ b/tests/test-pull-r.t
@@ -145,3 +145,59 @@
 
   $ cd ..
   $ killdaemons.py
+
+Test pullbundle functionality
+
+  $ cd repo
+  $ cat < .hg/hgrc
+  > [server]
+  > pullbundle = True
+  > EOF
+  $ hg bundle --base null -r 0 .hg/0.hg
+  1 changesets found
+  $ hg bundle --base 0 -r 1 .hg/1.hg
+  1 changesets found
+  $ hg bundle --base 1 -r 2 .hg/2.hg
+  1 changesets found
+  $ cat < .hg/pullbundles.manifest
+  > 2.hg heads=effea6de0384e684f44435651cb7bd70b8735bd4 
base=bbd179dfa0a71671c253b3ae0aa1513b60d199fa
+  > 1.hg heads=ed1b79f46b9a29f5a6efa59cf12fcfca43bead5a 
base=bbd179dfa0a71671c253b3ae0aa1513b60d199fa
+  > 0.hg heads=bbd179dfa0a71671c253b3ae0aa1513b60d199fa
+  > EOF
+  $ hg serve --debug -p $HGPORT2 --pid-file=../repo.pid > ../repo-server.txt 
2>&1 &
+  $ while ! grep listening ../repo-server.txt > /dev/null; do sleep 1; done
+  $ cat ../repo.pid >> $DAEMON_PIDS
+  $ cd ..
+  $ hg clone -r 0 http://localhost:$HGPORT2/ repo.pullbundle
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets bbd179dfa0a7
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd repo.pullbundle
+  $ hg pull -r 1
+  pulling from http://localhost:$HGPORT2/
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets ed1b79f46b9a
+  (run 'hg update' to get a working copy)
+  $ hg pull -r 2
+  pulling from http://localhost:$HGPORT2/
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  new changesets effea6de0384
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ cd ..
+  $ killdaemons.py
+  $ grep 'sending pullbundle ' repo-server.txt
+  sending pullbundle "0.hg"
+  sending pullbundle "1.hg"
+  sending pullbundle "2.hg"
diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -831,6 +831,65 @@
 opts = options('debugwireargs', ['three', 'four'], others)
 return repo.debugwireargs(one, two, **pycompat.strkwargs(opts))
 
+def find_pullbundle(repo, opts, clheads, heads, common):
+def decodehexstring(s):
+return set([h.decode('hex') for h in s.split(':')])
+
+def hasdescendant(ancestor, revs):
+# Quick path for exact match
+if ancestor in revs:
+return True
+for rev in revs:
+if repo.changelog.isancestor(ancestor, rev):
+return True
+return False
+def hasancestor(descendant, revs):
+if descendant in revs:
+return True
+for rev in revs:
+if repo.changelog.isancestor(rev, descendant):
+return True
+return False
+
+manifest = repo.vfs.tryread('pullbundles.manifest')
+res = exchange.parseclonebundlesmanifest(repo, manifest)
+res = exchange.filterclonebundleentries(repo, res)
+for entry in res:
+if 'heads' in entry:
+try:
+bundle_heads = decodehexstring(entry['heads'])
+except TypeError:
+# Bad heads entry
+continue
+if len(bundle_heads) > len(heads):
+# Client wants less heads than the bundle contains
+continue
+if bundle_heads.issubset(common):
+continue # Nothing new
+if all(hasdescendant(rev, common) for rev in bundle_heads):
+continue # Still nothing new
+if any(not hasdescendant(rev, heads) for rev in bundle_heads):
+continue
+if 'bases' in entry:
+try:
+bundle_bases = decodehexstring(entry['bases'])
+except TypeError:
+# Bad bases entry
+continue
+if len(bundle_bases) < len(common):
+# Client is missing a revision the bundle requires
+continue
+if all(hasdescendant(rev, common) for rev in bundle_bases):
+continue
+path = 

D1850: hgweb: when no agreement on compression can be found, fail for v2

2018-01-12 Thread indygreg (Gregory Szorc)
indygreg requested changes to this revision.
indygreg added a comment.
This revision now requires changes to proceed.


  We're not using the `Accept*` HTTP headers, so the use of HTTP `406` is not 
appropriate. See https://tools.ietf.org/html/rfc7231#section-6.5.6. I believe 
if you scour the mailing list or even the commit messages, you'll find text 
explaining why we explicitly chose to not use the `Accept` headers for protocol 
negotiation.
  
  I do think I'm OK with aborting the request if the client request is 
"malformed." Although it's a BC break and needs to be called out as such. Since 
we already shipped forgiving code, others may insist we keep the existing 
behavior. They have a point.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1850

To: joerg.sonnenberger, #hg-reviewers, indygreg
Cc: indygreg, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 2 V3] fileset: split the logic for matching a size expression to a separate method

2018-01-12 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1515641708 18000
#  Wed Jan 10 22:35:08 2018 -0500
# Node ID 2201fc4fd6d3d9dda72459c6642c16acbe6fc0a4
# Parent  24b5106e3e1e265cb60258b314ae2b774610de81
fileset: split the logic for matching a size expression to a separate method

This will be used in the next patch to build a simple filtering language, but
where we won't have an mctx.

diff --git a/mercurial/fileset.py b/mercurial/fileset.py
--- a/mercurial/fileset.py
+++ b/mercurial/fileset.py
@@ -344,6 +344,35 @@
 except ValueError:
 raise error.ParseError(_("couldn't parse size: %s") % s)
 
+def sizematcher(x):
+"""Return a function(size) -> bool from the ``size()`` expression"""
+
+# i18n: "size" is a keyword
+expr = getstring(x, _("size requires an expression")).strip()
+if '-' in expr: # do we have a range?
+a, b = expr.split('-', 1)
+a = util.sizetoint(a)
+b = util.sizetoint(b)
+return lambda x: x >= a and x <= b
+elif expr.startswith("<="):
+a = util.sizetoint(expr[2:])
+return lambda x: x <= a
+elif expr.startswith("<"):
+a = util.sizetoint(expr[1:])
+return lambda x: x < a
+elif expr.startswith(">="):
+a = util.sizetoint(expr[2:])
+return lambda x: x >= a
+elif expr.startswith(">"):
+a = util.sizetoint(expr[1:])
+return lambda x: x > a
+elif expr[0].isdigit or expr[0] == '.':
+a = util.sizetoint(expr)
+b = _sizetomax(expr)
+return lambda x: x >= a and x <= b
+else:
+raise error.ParseError(_("couldn't parse size: %s") % expr)
+
 @predicate('size(expression)', callexisting=True)
 def size(mctx, x):
 """File size matches the given expression. Examples:
@@ -353,33 +382,7 @@
 - size('>= .5MB') - files at least 524288 bytes
 - size('4k - 1MB') - files from 4096 bytes to 1048576 bytes
 """
-
-# i18n: "size" is a keyword
-expr = getstring(x, _("size requires an expression")).strip()
-if '-' in expr: # do we have a range?
-a, b = expr.split('-', 1)
-a = util.sizetoint(a)
-b = util.sizetoint(b)
-m = lambda x: x >= a and x <= b
-elif expr.startswith("<="):
-a = util.sizetoint(expr[2:])
-m = lambda x: x <= a
-elif expr.startswith("<"):
-a = util.sizetoint(expr[1:])
-m = lambda x: x < a
-elif expr.startswith(">="):
-a = util.sizetoint(expr[2:])
-m = lambda x: x >= a
-elif expr.startswith(">"):
-a = util.sizetoint(expr[1:])
-m = lambda x: x > a
-elif expr[0].isdigit or expr[0] == '.':
-a = util.sizetoint(expr)
-b = _sizetomax(expr)
-m = lambda x: x >= a and x <= b
-else:
-raise error.ParseError(_("couldn't parse size: %s") % expr)
-
+m = sizematcher(x)
 return [f for f in mctx.existing() if m(mctx.ctx[f].size())]
 
 @predicate('encoding(name)', callexisting=True)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 2] fileset: make it robust for bad function calls

2018-01-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1515823657 -32400
#  Sat Jan 13 15:07:37 2018 +0900
# Node ID 7a283960200aedf4461273ebc0c90f6f677c4a59
# Parent  706aa203b3961372f359df16214b4c10bc8a66fa
fileset: make it robust for bad function calls

Before, it could crash or show cryptic message.

diff --git a/mercurial/fileset.py b/mercurial/fileset.py
--- a/mercurial/fileset.py
+++ b/mercurial/fileset.py
@@ -99,6 +99,11 @@ def parse(expr):
 raise error.ParseError(_("invalid token"), pos)
 return tree
 
+def getsymbol(x):
+if x and x[0] == 'symbol':
+return x[1]
+raise error.ParseError(_('not a symbol'))
+
 def getstring(x, err):
 if x and (x[0] == 'string' or x[0] == 'symbol'):
 return x[1]
@@ -225,8 +230,8 @@ def clean(mctx, x):
 return [f for f in mctx.subset if f in s]
 
 def func(mctx, a, b):
-if a[0] == 'symbol' and a[1] in symbols:
-funcname = a[1]
+funcname = getsymbol(a)
+if funcname in symbols:
 enabled = mctx._existingenabled
 mctx._existingenabled = funcname in _existingcallers
 try:
@@ -237,7 +242,7 @@ def func(mctx, a, b):
 keep = lambda fn: getattr(fn, '__doc__', None) is not None
 
 syms = [s for (s, fn) in symbols.items() if keep(fn)]
-raise error.UnknownIdentifier(a[1], syms)
+raise error.UnknownIdentifier(funcname, syms)
 
 def getlist(x):
 if not x:
diff --git a/mercurial/minifileset.py b/mercurial/minifileset.py
--- a/mercurial/minifileset.py
+++ b/mercurial/minifileset.py
@@ -56,9 +56,8 @@ def _compile(tree):
 'size': lambda n, s: fileset.sizematcher(tree[2])(s),
 }
 
-x = tree[1]
-name = x[1]
-if x[0] == 'symbol' and name in symbols:
+name = fileset.getsymbol(tree[1])
+if name in symbols:
 return symbols[name]
 
 raise error.UnknownIdentifier(name, symbols.keys())
diff --git a/tests/test-fileset.t b/tests/test-fileset.t
--- a/tests/test-fileset.t
+++ b/tests/test-fileset.t
@@ -53,6 +53,22 @@ Test operators and basic patterns
   hg: parse error: invalid \x escape
   [255]
 
+Test invalid syntax
+
+  $ fileset -v '"added"()'
+  (func
+(string 'added')
+None)
+  hg: parse error: not a symbol
+  [255]
+  $ fileset -v '()()'
+  (func
+(group
+  None)
+None)
+  hg: parse error: not a symbol
+  [255]
+
 Test files status
 
   $ rm a1
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2] fileset: do not crash by unary negate operation

2018-01-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1515824009 -32400
#  Sat Jan 13 15:13:29 2018 +0900
# Node ID ae8b3e1707597343265e2d2cbc99a665942a76df
# Parent  7a283960200aedf4461273ebc0c90f6f677c4a59
fileset: do not crash by unary negate operation

Backported from minifileset.py.

diff --git a/mercurial/fileset.py b/mercurial/fileset.py
--- a/mercurial/fileset.py
+++ b/mercurial/fileset.py
@@ -136,6 +136,9 @@ def minusset(mctx, x, y):
 yl = set(getset(mctx, y))
 return [f for f in xl if f not in yl]
 
+def negateset(mctx, x):
+raise error.ParseError(_("can't use negate operator in this context"))
+
 def listset(mctx, a, b):
 raise error.ParseError(_("can't use a list in this context"),
hint=_('see hg help "filesets.x or y"'))
@@ -523,6 +526,7 @@ methods = {
 'and': andset,
 'or': orset,
 'minus': minusset,
+'negate': negateset,
 'list': listset,
 'group': getset,
 'not': notset,
diff --git a/tests/test-fileset.t b/tests/test-fileset.t
--- a/tests/test-fileset.t
+++ b/tests/test-fileset.t
@@ -68,6 +68,17 @@ Test invalid syntax
 None)
   hg: parse error: not a symbol
   [255]
+  $ fileset -v -- '-x'
+  (negate
+(symbol 'x'))
+  hg: parse error: can't use negate operator in this context
+  [255]
+  $ fileset -v -- '-()'
+  (negate
+(group
+  None))
+  hg: parse error: can't use negate operator in this context
+  [255]
 
 Test files status
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1855: explicitly kill server processes

2018-01-12 Thread joerg.sonnenberger (Joerg Sonnenberger)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG5bda7bd29688: explicitly kill server processes (authored by 
joerg.sonnenberger, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D1855?vs=4809=4814

REVISION DETAIL
  https://phab.mercurial-scm.org/D1855

AFFECTED FILES
  tests/test-pull-r.t

CHANGE DETAILS

diff --git a/tests/test-pull-r.t b/tests/test-pull-r.t
--- a/tests/test-pull-r.t
+++ b/tests/test-pull-r.t
@@ -144,3 +144,4 @@
   
 
   $ cd ..
+  $ killdaemons.py



To: joerg.sonnenberger, #hg-reviewers, indygreg
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2 V3] fileset: add a lightweight file filtering language

2018-01-12 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1515641014 18000
#  Wed Jan 10 22:23:34 2018 -0500
# Node ID b66e906f11f758eb3b3b0f5bc56cf66229f343b7
# Parent  2201fc4fd6d3d9dda72459c6642c16acbe6fc0a4
fileset: add a lightweight file filtering language

This patch was inspired by one that Jun Wu authored for the fb-experimental
repo, to avoid using matcher for efficiency[1].  We want a way to specify what
files will be converted to LFS at commit time.  And per discussion, we also want
to specify what files to skip, text diff, or merge in another config option.
The current `lfs.threshold` config option could not satisfy complex needs.  I'm
putting it in a core package because Augie floated the idea of also using it for
narrow and sparse.

Yuya suggested farming out to fileset.parse(), which added support for more
symbols.  The only fileset element not supported here is 'negate'.  (List isn't
supported by filesets either.)  I also changed the 'always' token to the 'all()'
predicate for consistency, and introduced 'none()' to improve readability in a
future tracked file based config.  The extension operator was changed from '.'
to '**', to match how recursive path globs are specified.  Finally, I changed
the path matcher from '/' to 'path:' at Yuya's suggestion, for consistency with
matcher.  Unfortunately, ':' is currently reserved in filesets, so this has to
be quoted to be processed as a string instead of a symbol[2].  We should
probably revisit that, because it's seriously ugly.  But it's only used by an
experimental extension, and I think using a file based config for LFS may drive
some more tweaks, so I'm settling for this for now.

I reserved all of the glob characters in fileset except '.' and '_' for the
extension test because those are likely valid extension characters.

Sample filter settings:

  all()# everything
  size(">20MB")# larger than 20MB
  !**.txt  # except for .txt files
  **.zip | **.tar.gz | **.7z   # some types of compressed files
  "path:bin"   # files under "bin" in the project root

[1] 
https://www.mercurial-scm.org/pipermail/mercurial-devel/2017-December/109387.html
[2] 
https://www.mercurial-scm.org/pipermail/mercurial-devel/2018-January/109729.html

diff --git a/mercurial/minifileset.py b/mercurial/minifileset.py
new file mode 100644
--- /dev/null
+++ b/mercurial/minifileset.py
@@ -0,0 +1,94 @@
+# minifileset.py - a simple language to select files
+#
+# Copyright 2017 Facebook, Inc.
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from __future__ import absolute_import
+
+from .i18n import _
+from . import (
+error,
+fileset,
+util,
+)
+
+def _compile(tree):
+if not tree:
+raise error.ParseError(_("missing argument"))
+op = tree[0]
+if op == 'symbol':
+name = fileset.getstring(tree, _('invalid file pattern'))
+if name.startswith('**'): # file extension test, ex. "**.tar.gz"
+ext = name[2:]
+for c in ext:
+if c in '*{}[]?/\\':
+raise error.ParseError(_('reserved character: %s') % c)
+return lambda n, s: n.endswith(ext)
+else:
+raise error.ParseError(_('invalid symbol: %s') % name)
+elif op == 'or':
+func1 = _compile(tree[1])
+func2 = _compile(tree[2])
+return lambda n, s: func1(n, s) or func2(n, s)
+elif op == 'and':
+func1 = _compile(tree[1])
+func2 = _compile(tree[2])
+return lambda n, s: func1(n, s) and func2(n, s)
+elif op == 'not':
+return lambda n, s: not _compile(tree[1])(n, s)
+elif op == 'group':
+return _compile(tree[1])
+elif op == 'func':
+symbols = {
+'all': lambda n, s: True,
+'none': lambda n, s: False,
+'size': lambda n, s: fileset.sizematcher(tree[2])(s),
+}
+
+x = tree[1]
+name = x[1]
+if x[0] == 'symbol' and name in symbols:
+return symbols[name]
+
+raise error.UnknownIdentifier(name, symbols.keys())
+elif op == 'minus': # equivalent to 'x and not y'
+func1 = _compile(tree[1])
+func2 = _compile(tree[2])
+return lambda n, s: func1(n, s) and not func2(n, s)
+elif op == 'negate':
+raise error.ParseError(_("can't use negate operator in this context"))
+elif op == 'string':
+# TODO: teach fileset about 'path:', so that this can be a symbol and
+# not require quoting.
+name = fileset.getstring(tree, _('invalid path literal'))
+if name.startswith('path:'): # directory or full path test
+p = name[5:] # prefix
+pl = len(p)
+f = lambda n, s: n.startswith(p) and (len(n) == pl or n[pl] == '/')
+return f
+raise 

D1855: explicitly kill server processes

2018-01-12 Thread yuja (Yuya Nishihara)
yuja added a comment.


  Just for the record, explicit killdaemon isn't needed unless you want
  to do something (e.g. checking server logs) after that. Daemons are
  kill by the test runner.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1855

To: joerg.sonnenberger, #hg-reviewers, indygreg
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1854: py3: use bytes instead of pycompat.bytestr

2018-01-12 Thread pulkit (Pulkit Goyal)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG991f0be9dc39: py3: use bytes instead of pycompat.bytestr 
(authored by pulkit, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D1854?vs=4808=4815

REVISION DETAIL
  https://phab.mercurial-scm.org/D1854

AFFECTED FILES
  mercurial/subrepo.py

CHANGE DETAILS

diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -389,14 +389,14 @@
 if util.safehasattr(repo, '_subparent'):
 source = util.url(repo._subsource)
 if source.isabs():
-return pycompat.bytestr(source)
+return bytes(source)
 source.path = posixpath.normpath(source.path)
 parent = _abssource(repo._subparent, push, abort=False)
 if parent:
 parent = util.url(util.pconvert(parent))
 parent.path = posixpath.join(parent.path or '', source.path)
 parent.path = posixpath.normpath(parent.path)
-return pycompat.bytestr(parent)
+return bytes(parent)
 else: # recursion reached top repo
 if util.safehasattr(repo, '_subtoppath'):
 return repo._subtoppath



To: pulkit, #hg-reviewers, yuja
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 7] share: use context manager or utility function to write file

2018-01-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1515817396 -32400
#  Sat Jan 13 13:23:16 2018 +0900
# Node ID 2eeaf96c20fce19c8edccf4936aceee4ce651de9
# Parent  991f0be9dc39c402d63a4a8f19cde052095c4689
share: use context manager or utility function to write file

diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -307,16 +307,13 @@ def postshare(sourcerepo, destrepo, book
 """
 default = defaultpath or sourcerepo.ui.config('paths', 'default')
 if default:
-fp = destrepo.vfs("hgrc", "w", text=True)
-fp.write("[paths]\n")
-fp.write("default = %s\n" % default)
-fp.close()
+with destrepo.vfs("hgrc", "w", text=True) as fp:
+fp.write("[paths]\n")
+fp.write("default = %s\n" % default)
 
 with destrepo.wlock():
 if bookmarks:
-fp = destrepo.vfs('shared', 'w')
-fp.write(sharedbookmarks + '\n')
-fp.close()
+destrepo.vfs.write('shared', sharedbookmarks + '\n')
 
 def _postshareupdate(repo, update, checkout=None):
 """Maybe perform a working directory update after a shared repo is created.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 7] share: convert EOL of hgrc before writing to bytes IO

2018-01-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1515817887 -32400
#  Sat Jan 13 13:31:27 2018 +0900
# Node ID c4ecde5fbf1e40f0c918c9b4f6c1215b2cbebb7c
# Parent  41f5fc043698f6c8ff042ebb7d380f76a68a006b
share: convert EOL of hgrc before writing to bytes IO

Text IO is useless on Python 3 as it must be a unicode stream.

diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -307,9 +307,9 @@ def postshare(sourcerepo, destrepo, book
 """
 default = defaultpath or sourcerepo.ui.config('paths', 'default')
 if default:
-with destrepo.vfs("hgrc", "w", text=True) as fp:
-fp.write("[paths]\n")
-fp.write("default = %s\n" % default)
+template = ('[paths]\n'
+'default = %s\n')
+destrepo.vfs.write('hgrc', util.tonativeeol(template % default))
 
 with destrepo.wlock():
 if bookmarks:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 7] lfs: convert EOL of hgrc before appending to bytes IO

2018-01-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1515818471 -32400
#  Sat Jan 13 13:41:11 2018 +0900
# Node ID 2a43867d18dfedd0708a6dfb87ab2fc80e5c
# Parent  6f68aa0c4c0aa59dd651e81e813c1a11e4761889
lfs: convert EOL of hgrc before appending to bytes IO

Text IO is useless on Python 3 as it must be a unicode stream.

diff --git a/hgext/lfs/wrapper.py b/hgext/lfs/wrapper.py
--- a/hgext/lfs/wrapper.py
+++ b/hgext/lfs/wrapper.py
@@ -197,8 +197,8 @@ def convertsink(orig, sink):
 self.repo._writerequirements()
 
 # Permanently enable lfs locally
-with self.repo.vfs('hgrc', 'a', text=True) as fp:
-fp.write('\n[extensions]\nlfs=\n')
+self.repo.vfs.append(
+'hgrc', util.tonativeeol('\n[extensions]\nlfs=\n'))
 
 return node
 
@@ -232,8 +232,8 @@ def hgclone(orig, ui, opts, *args, **kwa
 
 # If lfs is required for this repo, permanently enable it locally
 if 'lfs' in repo.requirements:
-with repo.vfs('hgrc', 'a', text=True) as fp:
-fp.write('\n[extensions]\nlfs=\n')
+repo.vfs.append('hgrc',
+util.tonativeeol('\n[extensions]\nlfs=\n'))
 
 return result
 
@@ -242,8 +242,7 @@ def hgpostshare(orig, sourcerepo, destre
 
 # If lfs is required for this repo, permanently enable it locally
 if 'lfs' in destrepo.requirements:
-with destrepo.vfs('hgrc', 'a', text=True) as fp:
-fp.write('\n[extensions]\nlfs=\n')
+destrepo.vfs.append('hgrc', util.tonativeeol('\n[extensions]\nlfs=\n'))
 
 def _canskipupload(repo):
 # if remotestore is a null store, upload is a no-op and can be skipped
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 7] vfs: drop text mode flag (API)

2018-01-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1515818830 -32400
#  Sat Jan 13 13:47:10 2018 +0900
# Node ID 1cd98d602f7a3d4dac3b1327278a29d50c2c0a3c
# Parent  2a43867d18dfedd0708a6dfb87ab2fc80e5c
vfs: drop text mode flag (API)

It's useless on Python 3.

.. api::

   ``text=False|True`` option is dropped from the vfs interface because of
   Python 3 compatibility issue. Use ``util.tonativeeol/fromnativeeol()`` to
   convert EOL manually.

diff --git a/mercurial/vfs.py b/mercurial/vfs.py
--- a/mercurial/vfs.py
+++ b/mercurial/vfs.py
@@ -170,9 +170,9 @@ class abstractvfs(object):
 def mkdir(self, path=None):
 return os.mkdir(self.join(path))
 
-def mkstemp(self, suffix='', prefix='tmp', dir=None, text=False):
+def mkstemp(self, suffix='', prefix='tmp', dir=None):
 fd, name = tempfile.mkstemp(suffix=suffix, prefix=prefix,
-dir=self.join(dir), text=text)
+dir=self.join(dir))
 dname, fname = util.split(name)
 if dir:
 return fd, os.path.join(dir, fname)
@@ -333,9 +333,8 @@ class vfs(abstractvfs):
 return
 os.chmod(name, self.createmode & 0o666)
 
-def __call__(self, path, mode="r", text=False, atomictemp=False,
- notindexed=False, backgroundclose=False, checkambig=False,
- auditpath=True):
+def __call__(self, path, mode="r", atomictemp=False, notindexed=False,
+ backgroundclose=False, checkambig=False, auditpath=True):
 '''Open ``path`` file, which is relative to vfs root.
 
 Newly created directories are marked as "not to be indexed by
@@ -373,7 +372,7 @@ class vfs(abstractvfs):
 self.audit(path, mode=mode)
 f = self.join(path)
 
-if not text and "b" not in mode:
+if "b" not in mode:
 mode += "b" # for that other OS
 
 nlink = -1
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 7] clone: use utility function to write hgrc

2018-01-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1515817457 -32400
#  Sat Jan 13 13:24:17 2018 +0900
# Node ID f5558d75ef44a2db64131b4e5bca98102542f13b
# Parent  2eeaf96c20fce19c8edccf4936aceee4ce651de9
clone: use utility function to write hgrc

diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -681,13 +681,10 @@ def clone(ui, peeropts, source, dest=Non
 destrepo = destpeer.local()
 if destrepo:
 template = uimod.samplehgrcs['cloned']
-fp = destrepo.vfs("hgrc", "wb")
 u = util.url(abspath)
 u.passwd = None
 defaulturl = bytes(u)
-fp.write(util.tonativeeol(template % defaulturl))
-fp.close()
-
+destrepo.vfs.write('hgrc', util.tonativeeol(template % defaulturl))
 destrepo.ui.setconfig('paths', 'default', defaulturl, 'clone')
 
 if ui.configbool('experimental', 'remotenames'):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 7] subrepo: convert EOL of hgrc before writing to bytes IO

2018-01-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1515817692 -32400
#  Sat Jan 13 13:28:12 2018 +0900
# Node ID 41f5fc043698f6c8ff042ebb7d380f76a68a006b
# Parent  f5558d75ef44a2db64131b4e5bca98102542f13b
subrepo: convert EOL of hgrc before writing to bytes IO

Follows up f2f0a777b2e2. Text IO is useless on Python 3 as it must be a
unicode stream.

diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -841,11 +841,7 @@ class hgsubrepo(abstractsubrepo):
 if defpath != defpushpath:
 addpathconfig('default-push', defpushpath)
 
-fp = self._repo.vfs("hgrc", "wb", text=True)
-try:
-fp.write(''.join(lines))
-finally:
-fp.close()
+self._repo.vfs.write('hgrc', util.tonativeeol(''.join(lines)))
 
 @annotatesubrepoerror
 def add(self, ui, match, prefix, explicitonly, **opts):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 7] largefiles: convert EOL of hgrc before appending to bytes IO

2018-01-12 Thread Yuya Nishihara
# HG changeset patch
# User Yuya Nishihara 
# Date 1515818035 -32400
#  Sat Jan 13 13:33:55 2018 +0900
# Node ID 6f68aa0c4c0aa59dd651e81e813c1a11e4761889
# Parent  c4ecde5fbf1e40f0c918c9b4f6c1215b2cbebb7c
largefiles: convert EOL of hgrc before appending to bytes IO

Text IO is useless on Python 3 as it must be a unicode stream.

diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -888,8 +888,8 @@ def hgclone(orig, ui, opts, *args, **kwa
 
 # If largefiles is required for this repo, permanently enable it 
locally
 if 'largefiles' in repo.requirements:
-with repo.vfs('hgrc', 'a', text=True) as fp:
-fp.write('\n[extensions]\nlargefiles=\n')
+repo.vfs.append('hgrc',
+util.tonativeeol('\n[extensions]\nlargefiles=\n'))
 
 # Caching is implicitly limited to 'rev' option, since the dest repo 
was
 # truncated at that point.  The user may expect a download count with
@@ -907,8 +907,8 @@ def hgpostshare(orig, sourcerepo, destre
 
 # If largefiles is required for this repo, permanently enable it locally
 if 'largefiles' in destrepo.requirements:
-with destrepo.vfs('hgrc', 'a+', text=True) as fp:
-fp.write('\n[extensions]\nlargefiles=\n')
+destrepo.vfs.append('hgrc',
+util.tonativeeol('\n[extensions]\nlargefiles=\n'))
 
 def overriderebase(orig, ui, repo, **opts):
 if not util.safehasattr(repo, '_largefilesenabled'):
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] lfs: drop deprecated remote store config options

2018-01-12 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1515816818 18000
#  Fri Jan 12 23:13:38 2018 -0500
# Node ID a461399d0ac31e3c4ebc8dee10ea0ac46843fa07
# Parent  b66e906f11f758eb3b3b0f5bc56cf66229f343b7
lfs: drop deprecated remote store config options

The last of these were removed from fb-experimental in 86884a51e9aa, and we
might as well clean this up before the freeze.

diff --git a/hgext/lfs/__init__.py b/hgext/lfs/__init__.py
--- a/hgext/lfs/__init__.py
+++ b/hgext/lfs/__init__.py
@@ -71,7 +71,7 @@
 )
 
 configitem('lfs', 'url',
-default=configitem.dynamicdefault,
+default=None,
 )
 configitem('lfs', 'usercache',
 default=None,
@@ -82,18 +82,6 @@
 configitem('lfs', 'retry',
 default=5,
 )
-# Deprecated
-configitem('lfs', 'remotestore',
-default=None,
-)
-# Deprecated
-configitem('lfs', 'dummy',
-default=None,
-)
-# Deprecated
-configitem('lfs', 'git-lfs',
-default=None,
-)
 
 cmdtable = {}
 command = registrar.command(cmdtable)
diff --git a/hgext/lfs/blobstore.py b/hgext/lfs/blobstore.py
--- a/hgext/lfs/blobstore.py
+++ b/hgext/lfs/blobstore.py
@@ -445,22 +445,7 @@
 
 def remote(repo):
 """remotestore factory. return a store in _storemap depending on config"""
-defaulturl = ''
-
-# convert deprecated configs to the new url. TODO: remove this if other
-# places are migrated to the new url config.
-# deprecated config: lfs.remotestore
-deprecatedstore = repo.ui.config('lfs', 'remotestore')
-if deprecatedstore == 'dummy':
-# deprecated config: lfs.remotepath
-defaulturl = 'file://' + repo.ui.config('lfs', 'remotepath')
-elif deprecatedstore == 'git-lfs':
-# deprecated config: lfs.remoteurl
-defaulturl = repo.ui.config('lfs', 'remoteurl')
-elif deprecatedstore == 'null':
-defaulturl = 'null://'
-
-url = util.url(repo.ui.config('lfs', 'url', defaulturl))
+url = util.url(repo.ui.config('lfs', 'url') or '')
 scheme = url.scheme
 if scheme not in _storemap:
 raise error.Abort(_('lfs: unknown url scheme: %s') % scheme)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] lfs: drop deprecated remote store config options

2018-01-12 Thread Yuya Nishihara
On Fri, 12 Jan 2018 23:28:41 -0500, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison 
> # Date 1515816818 18000
> #  Fri Jan 12 23:13:38 2018 -0500
> # Node ID a461399d0ac31e3c4ebc8dee10ea0ac46843fa07
> # Parent  b66e906f11f758eb3b3b0f5bc56cf66229f343b7
> lfs: drop deprecated remote store config options

Queued, thanks.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 2 V3] fileset: add a lightweight file filtering language

2018-01-12 Thread Yuya Nishihara
On Fri, 12 Jan 2018 22:21:59 -0500, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison 
> # Date 1515641014 18000
> #  Wed Jan 10 22:23:34 2018 -0500
> # Node ID b66e906f11f758eb3b3b0f5bc56cf66229f343b7
> # Parent  2201fc4fd6d3d9dda72459c6642c16acbe6fc0a4
> fileset: add a lightweight file filtering language

Also queued, thanks.

> +def _compile(tree):
> +if not tree:
> +raise error.ParseError(_("missing argument"))
> +op = tree[0]
> +if op == 'symbol':
> +name = fileset.getstring(tree, _('invalid file pattern'))
> +if name.startswith('**'): # file extension test, ex. "**.tar.gz"
> +ext = name[2:]
> +for c in ext:
> +if c in '*{}[]?/\\':
> +raise error.ParseError(_('reserved character: %s') % c)
> +return lambda n, s: n.endswith(ext)
> +else:
> +raise error.ParseError(_('invalid symbol: %s') % name)

> +elif op == 'string':
> +# TODO: teach fileset about 'path:', so that this can be a symbol and
> +# not require quoting.
> +name = fileset.getstring(tree, _('invalid path literal'))
> +if name.startswith('path:'): # directory or full path test
> +p = name[5:] # prefix
> +pl = len(p)
> +f = lambda n, s: n.startswith(p) and (len(n) == pl or n[pl] == 
> '/')
> +return f
> +raise error.ParseError(_("invalid string"),
> +   hint=_('paths must be prefixed with "path:"'))

I've moved op == 'string' next to 'symbol' as they'll have to be merged later.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2] lfs: migrate most file filtering from threshold to custom filter

2018-01-12 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1514706889 18000
#  Sun Dec 31 02:54:49 2017 -0500
# Node ID 66976f55793cced57929dedc8993204be340c717
# Parent  868cc63bfe9d7d7f5b40bc8cd70175cf1a608a95
lfs: migrate most file filtering from threshold to custom filter

Migrate `lfs.threshold` to more powerful `lfs.filter` added by D4990618 so
people can specify what files to be stored in LFS with more flexibility.

This patch was authored by Jun Wu for the fb-experimental repo, to avoid using
matcher for efficiency[1].  All I've changed here is to register the new
'lfs.track' default so that the tests run cleanly, and adapt the subsequent
language changes.  Migrating the remaining uses of 'lfs.threshold' can be done
separately since there's a fallback in place.

[1] 
https://www.mercurial-scm.org/pipermail/mercurial-devel/2017-December/109388.html

diff --git a/hgext/lfs/__init__.py b/hgext/lfs/__init__.py
--- a/hgext/lfs/__init__.py
+++ b/hgext/lfs/__init__.py
@@ -19,8 +19,23 @@
 # (default: unset)
 url = https://example.com/lfs
 
-# size of a file to make it use LFS
-threshold = 10M
+# Which files to track in LFS.  Path tests are "**.extname" for file
+# extensions, and "path:under/some/directory" for path prefix.  Both
+# are relative to the repository root, and the latter must be quoted.
+# File size can be tested with the "size()" fileset, and tests can be
+# joined with fileset operators.  (See "hg help filesets.operators".)
+#
+# Some examples:
+# - all()   # everything
+# - none()  # nothing
+# - size(">20MB")   # larger than 20MB
+# - !**.txt # anything not a *.txt file
+# - **.zip | **.tar.gz | **.7z  # some types of compressed files
+# - "path:bin"  # files under "bin" in the project root
+# - (**.php & size(">2MB")) | (**.js & size(">5MB")) | **.tar.gz
+# | ("path:bin" & !"path:/bin/README") | size(">1GB")
+# (default: none())
+track = size(">10M")
 
 # how many times to retry before giving up on transferring an object
 retry = 5
@@ -43,6 +58,7 @@
 filelog,
 hg,
 localrepo,
+minifileset,
 node,
 registrar,
 revlog,
@@ -76,9 +92,13 @@
 configitem('lfs', 'usercache',
 default=None,
 )
+# Deprecated
 configitem('lfs', 'threshold',
 default=None,
 )
+configitem('lfs', 'track',
+default='none()',
+)
 configitem('lfs', 'retry',
 default=5,
 )
@@ -100,9 +120,14 @@
 if not repo.local():
 return
 
-threshold = repo.ui.configbytes('lfs', 'threshold')
+trackspec = repo.ui.config('lfs', 'track')
 
-repo.svfs.options['lfsthreshold'] = threshold
+# deprecated config: lfs.threshold
+threshold = repo.ui.configbytes('lfs', 'threshold')
+if threshold:
+trackspec = "(%s) | size('>%s')" % (trackspec, threshold)
+
+repo.svfs.options['lfstrack'] = minifileset.compile(trackspec)
 repo.svfs.lfslocalblobstore = blobstore.local(repo)
 repo.svfs.lfsremoteblobstore = blobstore.remote(repo)
 
diff --git a/hgext/lfs/wrapper.py b/hgext/lfs/wrapper.py
--- a/hgext/lfs/wrapper.py
+++ b/hgext/lfs/wrapper.py
@@ -123,14 +123,14 @@
 def filelogaddrevision(orig, self, text, transaction, link, p1, p2,
cachedelta=None, node=None,
flags=revlog.REVIDX_DEFAULT_FLAGS, **kwds):
-threshold = self.opener.options['lfsthreshold']
 textlen = len(text)
 # exclude hg rename meta from file size
 meta, offset = filelog.parsemeta(text)
 if offset:
 textlen -= offset
 
-if threshold and textlen > threshold:
+lfstrack = self.opener.options['lfstrack']
+if lfstrack(self.filename, textlen):
 flags |= revlog.REVIDX_EXTSTORED
 
 return orig(self, text, transaction, link, p1, p2, cachedelta=cachedelta,
diff --git a/tests/test-lfs-test-server.t b/tests/test-lfs-test-server.t
--- a/tests/test-lfs-test-server.t
+++ b/tests/test-lfs-test-server.t
@@ -30,7 +30,7 @@
   > lfs=
   > [lfs]
   > url=http://foo:bar@$LFS_HOST/
-  > threshold=1
+  > track=all()
   > EOF
 
   $ hg init repo1
diff --git a/tests/test-lfs.t b/tests/test-lfs.t
--- a/tests/test-lfs.t
+++ b/tests/test-lfs.t
@@ -4,6 +4,7 @@
   > [extensions]
   > lfs=
   > [lfs]
+  > # Test deprecated config
   > threshold=1000B
   > EOF
 
@@ -140,7 +141,7 @@
   $ cd repo3
   $ cat >> .hg/hgrc << EOF
   > [lfs]
-  > threshold=10B
+  > track=size(">10B")
   > EOF
 
   $ echo LONGER-THAN-TEN-BYTES-WILL-TRIGGER-LFS > large
@@ -203,7 +204,7 @@
   $ cd repo6
   $ cat >> .hg/hgrc << EOF
   > [lfs]
-  > threshold=30B
+  > track=size(">30B")
   > EOF
 
   $ echo LARGE-BECAUSE-IT-IS-MORE-THAN-30-BYTES > large
@@ -239,7 +240,7 @@
   $ cd repo8
   $ cat >> .hg/hgrc << EOF
   > [lfs]
-  > threshold=10B
+  > track=size(">10B")
   > EOF
 
   $ echo THIS-IS-LFS-BECAUSE-10-BYTES > a1
@@ -320,7 +321,7 @@
   $ cd repo9
   

[PATCH 1 of 2] test-lfs: bump the number on test repo11 and higher

2018-01-12 Thread Matt Harbison
# HG changeset patch
# User Matt Harbison 
# Date 1514742456 18000
#  Sun Dec 31 12:47:36 2017 -0500
# Node ID 868cc63bfe9d7d7f5b40bc8cd70175cf1a608a95
# Parent  706aa203b3961372f359df16214b4c10bc8a66fa
test-lfs: bump the number on test repo11 and higher

This will allow a Facebook patch that creates 'repo11' to be imported without
breaking a bunch of tests, or requiring edits on the fly.

diff --git a/tests/test-lfs.t b/tests/test-lfs.t
--- a/tests/test-lfs.t
+++ b/tests/test-lfs.t
@@ -489,8 +489,8 @@
 
 # Test fctx.cmp fastpath - diff without LFS blobs
 
-  $ hg init repo11
-  $ cd repo11
+  $ hg init repo12
+  $ cd repo12
   $ cat >> .hg/hgrc < [lfs]
   > threshold=1
@@ -520,8 +520,8 @@
 
   $ cd ..
 
-  $ hg clone repo11 repo12 --noupdate
-  $ cd repo12
+  $ hg clone repo12 repo13 --noupdate
+  $ cd repo13
   $ hg log --removed -p a -T '{desc}\n' --config diff.nobinary=1 --git
   2
   diff --git a/a b/a
@@ -590,37 +590,37 @@
   repo: repo9
   repo: repo10
 
-repo12 doesn't have any cached lfs files and its source never pushed its
+repo13 doesn't have any cached lfs files and its source never pushed its
 files.  Therefore, the files don't exist in the remote store.  Use the files in
 the user cache.
 
-  $ test -d $TESTTMP/repo12/.hg/store/lfs/objects
+  $ test -d $TESTTMP/repo13/.hg/store/lfs/objects
   [1]
 
-  $ hg --config extensions.share= share repo12 repo13
+  $ hg --config extensions.share= share repo13 repo14
   updating working directory
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg -R repo13 -q verify
+  $ hg -R repo14 -q verify
 
-  $ hg clone repo12 repo14
+  $ hg clone repo13 repo15
   updating to branch default
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg -R repo14 -q verify
+  $ hg -R repo15 -q verify
 
 If the source repo doesn't have the blob (maybe it was pulled or cloned with
 --noupdate), the blob is still accessible via the global cache to send to the
 remote store.
 
-  $ rm -rf $TESTTMP/repo14/.hg/store/lfs
-  $ hg init repo15
-  $ hg -R repo14 push repo15
-  pushing to repo15
+  $ rm -rf $TESTTMP/repo15/.hg/store/lfs
+  $ hg init repo16
+  $ hg -R repo15 push repo16
+  pushing to repo16
   searching for changes
   adding changesets
   adding manifests
   adding file changes
   added 3 changesets with 2 changes to 1 files
-  $ hg -R repo14 -q verify
+  $ hg -R repo15 -q verify
 
 Test damaged file scenarios.  (This also damages the usercache because of the
 hardlinks.)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1857: pull: re-run discovery and pullbundle2 if server didn't send all heads

2018-01-12 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger added a comment.


  This is a proof-of-concept. There is an interaction with obsoletion that I am 
still trying to understand (and fix).

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1857

To: joerg.sonnenberger, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1857: pull: re-run discovery and pullbundle2 if server didn't send all heads

2018-01-12 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger updated this revision to Diff 4813.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D1857?vs=4812=4813

REVISION DETAIL
  https://phab.mercurial-scm.org/D1857

AFFECTED FILES
  mercurial/exchange.py
  tests/test-pull-r.t

CHANGE DETAILS

diff --git a/tests/test-pull-r.t b/tests/test-pull-r.t
--- a/tests/test-pull-r.t
+++ b/tests/test-pull-r.t
@@ -201,3 +201,40 @@
   sending pullbundle "0.hg"
   sending pullbundle "1.hg"
   sending pullbundle "2.hg"
+
+Test pullbundle functionality for incremental pulls
+
+  $ cd repo
+  $ hg serve --debug -p $HGPORT2 --pid-file=../repo.pid > ../repo-server.txt 
2>&1 &
+  $ while ! grep listening ../repo-server.txt > /dev/null; do sleep 1; done
+  $ cat ../repo.pid >> $DAEMON_PIDS
+  $ cd ..
+  $ hg clone http://localhost:$HGPORT2/ repo.pullbundle2
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets bbd179dfa0a7:66e3ba28d0d7
+  updating to branch default
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ killdaemons.py
+  $ grep 'sending pullbundle ' repo-server.txt
+  sending pullbundle "0.hg"
+  sending pullbundle "2.hg"
+  sending pullbundle "1.hg"
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -1351,9 +1351,16 @@
 # before discovery to avoid extra work.
 _maybeapplyclonebundle(pullop)
 streamclone.maybeperformlegacystreamclone(pullop)
-_pulldiscovery(pullop)
-if pullop.canusebundle2:
+while True:
+_pulldiscovery(pullop)
+if not pullop.canusebundle2:
+break
 _pullbundle2(pullop)
+if not pullop.cgresult or not pullop.rheads:
+break
+unficl = repo.unfiltered().changelog
+if all(unficl.hasnode(n) for n in pullop.rheads):
+break
 _pullchangeset(pullop)
 _pullphase(pullop)
 _pullbookmarks(pullop)



To: joerg.sonnenberger, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1856: wireproto: server-side support for pullbundles

2018-01-12 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger updated this revision to Diff 4811.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D1856?vs=4810=4811

REVISION DETAIL
  https://phab.mercurial-scm.org/D1856

AFFECTED FILES
  mercurial/configitems.py
  mercurial/help/config.txt
  mercurial/wireproto.py
  tests/test-pull-r.t

CHANGE DETAILS

diff --git a/tests/test-pull-r.t b/tests/test-pull-r.t
--- a/tests/test-pull-r.t
+++ b/tests/test-pull-r.t
@@ -145,3 +145,59 @@
 
   $ cd ..
   $ killdaemons.py
+
+Test pullbundle functionality
+
+  $ cd repo
+  $ cat < .hg/hgrc
+  > [server]
+  > pullbundle = True
+  > EOF
+  $ hg bundle --base null -r 0 .hg/0.hg
+  1 changesets found
+  $ hg bundle --base 0 -r 1 .hg/1.hg
+  1 changesets found
+  $ hg bundle --base 1 -r 2 .hg/2.hg
+  1 changesets found
+  $ cat < .hg/pullbundles.manifest
+  > 2.hg heads=effea6de0384e684f44435651cb7bd70b8735bd4 
bases=bbd179dfa0a71671c253b3ae0aa1513b60d199fa
+  > 1.hg heads=ed1b79f46b9a29f5a6efa59cf12fcfca43bead5a 
bases=bbd179dfa0a71671c253b3ae0aa1513b60d199fa
+  > 0.hg heads=bbd179dfa0a71671c253b3ae0aa1513b60d199fa
+  > EOF
+  $ hg serve --debug -p $HGPORT2 --pid-file=../repo.pid > ../repo-server.txt 
2>&1 &
+  $ while ! grep listening ../repo-server.txt > /dev/null; do sleep 1; done
+  $ cat ../repo.pid >> $DAEMON_PIDS
+  $ cd ..
+  $ hg clone -r 0 http://localhost:$HGPORT2/ repo.pullbundle
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets bbd179dfa0a7
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd repo.pullbundle
+  $ hg pull -r 1
+  pulling from http://localhost:$HGPORT2/
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets ed1b79f46b9a
+  (run 'hg update' to get a working copy)
+  $ hg pull -r 2
+  pulling from http://localhost:$HGPORT2/
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  new changesets effea6de0384
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ cd ..
+  $ killdaemons.py
+  $ grep 'sending pullbundle ' repo-server.txt
+  sending pullbundle "0.hg"
+  sending pullbundle "1.hg"
+  sending pullbundle "2.hg"
diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -831,6 +831,65 @@
 opts = options('debugwireargs', ['three', 'four'], others)
 return repo.debugwireargs(one, two, **pycompat.strkwargs(opts))
 
+def find_pullbundle(repo, opts, clheads, heads, common):
+def decodehexstring(s):
+return set([h.decode('hex') for h in s.split(':')])
+
+def hasdescendant(ancestor, revs):
+# Quick path for exact match
+if ancestor in revs:
+return True
+for rev in revs:
+if repo.changelog.isancestor(ancestor, rev):
+return True
+return False
+def hasancestor(descendant, revs):
+if descendant in revs:
+return True
+for rev in revs:
+if repo.changelog.isancestor(rev, descendant):
+return True
+return False
+
+manifest = repo.vfs.tryread('pullbundles.manifest')
+res = exchange.parseclonebundlesmanifest(repo, manifest)
+res = exchange.filterclonebundleentries(repo, res)
+for entry in res:
+if 'heads' in entry:
+try:
+bundle_heads = decodehexstring(entry['heads'])
+except TypeError:
+# Bad heads entry
+continue
+if len(bundle_heads) > len(heads):
+# Client wants less heads than the bundle contains
+continue
+if bundle_heads.issubset(common):
+continue # Nothing new
+if all(hasdescendant(rev, common) for rev in bundle_heads):
+continue # Still nothing new
+if any(not hasdescendant(rev, heads) for rev in bundle_heads):
+continue
+if 'bases' in entry:
+try:
+bundle_bases = decodehexstring(entry['bases'])
+except TypeError:
+# Bad bases entry
+continue
+if len(bundle_bases) > len(common):
+# Client is missing a revision the bundle requires
+continue
+if not all(hasdescendant(rev, common) for rev in bundle_bases):
+continue
+path = entry['URL']
+repo.ui.debug('sending pullbundle "%s"\n' % path)
+try:
+return repo.vfs.open(path)
+except IOError:
+repo.ui.debug('pullbundle "%s" not accessible\n' % path)
+continue
+return None
+
 @wireprotocommand('getbundle', '*')
 def getbundle(repo, proto, others):
 opts = 

D1857: pull: re-run discovery and pullbundle2 if server didn't send all heads

2018-01-12 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger 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/D1857

AFFECTED FILES
  mercurial/exchange.py
  tests/test-pull-r.t

CHANGE DETAILS

diff --git a/tests/test-pull-r.t b/tests/test-pull-r.t
--- a/tests/test-pull-r.t
+++ b/tests/test-pull-r.t
@@ -201,3 +201,40 @@
   sending pullbundle "0.hg"
   sending pullbundle "1.hg"
   sending pullbundle "2.hg"
+
+Test pullbundle functionality for incremental pulls
+
+  $ cd repo
+  $ hg serve --debug -p $HGPORT2 --pid-file=../repo.pid > ../repo-server.txt 
2>&1 &
+  $ while ! grep listening ../repo-server.txt > /dev/null; do sleep 1; done
+  $ cat ../repo.pid >> $DAEMON_PIDS
+  $ cd ..
+  $ hg clone http://localhost:$HGPORT2/ repo.pullbundle2
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets bbd179dfa0a7:66e3ba28d0d7
+  updating to branch default
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ killdaemons.py
+  $ grep 'sending pullbundle ' repo-server.txt
+  sending pullbundle "0.hg"
+  sending pullbundle "2.hg"
+  sending pullbundle "1.hg"
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -1351,9 +1351,15 @@
 # before discovery to avoid extra work.
 _maybeapplyclonebundle(pullop)
 streamclone.maybeperformlegacystreamclone(pullop)
-_pulldiscovery(pullop)
-if pullop.canusebundle2:
+while True:
+_pulldiscovery(pullop)
+if not pullop.canusebundle2:
+break
 _pullbundle2(pullop)
+if not pullop.cgresult or not pullop.rheads:
+break
+if all(repo.changelog.hasnode(n) for n in pullop.rheads):
+break
 _pullchangeset(pullop)
 _pullphase(pullop)
 _pullbookmarks(pullop)



To: joerg.sonnenberger, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1850: hgweb: when no agreement on compression can be found, fail for v2

2018-01-12 Thread joerg.sonnenberger (Joerg Sonnenberger)
joerg.sonnenberger created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  When the client supports v2 responses, the fallback to the legacy
  response is undesirable. If the zlib is acceptable for the client,
  it should have said so in first place.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1850

AFFECTED FILES
  mercurial/hgweb/common.py
  mercurial/hgweb/protocol.py
  tests/test-http-protocol.t

CHANGE DETAILS

diff --git a/tests/test-http-protocol.t b/tests/test-http-protocol.t
--- a/tests/test-http-protocol.t
+++ b/tests/test-http-protocol.t
@@ -78,14 +78,15 @@
   server: * (glob)
   transfer-encoding: chunked
 
-Requesting a compression format that server doesn't support results will fall 
back to 0.1
+Server should fail when it can't agree with client on a compression format
 
   $ get-with-headers.py --hgproto '0.2 comp=aa' --headeronly $LOCALIP:$HGPORT 
'?cmd=getbundle=e93700bd72895c5addab234c56d4024b487a362f='
 -
-  200 Script output follows
+  406 No common compression format
+  content-length: 31
   content-type: application/mercurial-0.1
   date: * (glob)
   server: * (glob)
-  transfer-encoding: chunked
+  [1]
 
 #if zstd
 zstd is used if available
diff --git a/mercurial/hgweb/protocol.py b/mercurial/hgweb/protocol.py
--- a/mercurial/hgweb/protocol.py
+++ b/mercurial/hgweb/protocol.py
@@ -11,6 +11,8 @@
 import struct
 
 from .common import (
+ErrorResponse,
+HTTP_NOT_ACCEPTABLE,
 HTTP_OK,
 )
 
@@ -140,8 +142,8 @@
 
 return HGTYPE2, engine, opts
 
-# No mutually supported compression format. Fall back to the
-# legacy protocol.
+raise ErrorResponse(HTTP_NOT_ACCEPTABLE,
+'No common compression format')
 
 # Don't allow untrusted settings because disabling compression or
 # setting a very high compression level could lead to flooding
diff --git a/mercurial/hgweb/common.py b/mercurial/hgweb/common.py
--- a/mercurial/hgweb/common.py
+++ b/mercurial/hgweb/common.py
@@ -28,6 +28,7 @@
 HTTP_FORBIDDEN = 403
 HTTP_NOT_FOUND = 404
 HTTP_METHOD_NOT_ALLOWED = 405
+HTTP_NOT_ACCEPTABLE = 406
 HTTP_SERVER_ERROR = 500
 
 



To: joerg.sonnenberger, #hg-reviewers
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1813: bookmarks: add bookmarks to hidden revs if directaccess config is set

2018-01-12 Thread yuja (Yuya Nishihara)
yuja added a comment.


  Queued, thanks.

INLINE COMMENTS

> bookmarks.py:853
> +repo.ui.warn(_("bookmarking hidden changeset %s\n") % \
> + (', '.join(hiddenrevs)))
>  marks.applychanges(repo, tr, changes)

FYI, it loops over bookmark names with the same `rev`, so
`hiddenrevs` would have at most one element, and the second
`unhidehashlikerevs()` call would be unnecessary.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1813

To: pulkit, #hg-reviewers, yuja
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1795: py3: use pycompat.bytestr() instead of str()

2018-01-12 Thread pulkit (Pulkit Goyal)
pulkit added inline comments.

INLINE COMMENTS

> yuja wrote in verify.py:110
> '%d', perhaps.

Looks like we cannot use "%d" here as None can be possible value also and 
test-treemanifest.t has tests with None as a part of output.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1795

To: pulkit, #hg-reviewers, durin42
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1813: bookmarks: add bookmarks to hidden revs if directaccess config is set

2018-01-12 Thread pulkit (Pulkit Goyal)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG53c0526b6484: bookmarks: add bookmarks to hidden revs if 
directaccess config is set (authored by pulkit, committed by ).

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D1813?vs=4803=4807#toc

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D1813?vs=4803=4807

REVISION DETAIL
  https://phab.mercurial-scm.org/D1813

AFFECTED FILES
  mercurial/bookmarks.py
  tests/test-directaccess.t
  tests/test-log.t
  tests/test-obsolete.t
  tests/test-rebase-obsolete.t

CHANGE DETAILS

diff --git a/tests/test-rebase-obsolete.t b/tests/test-rebase-obsolete.t
--- a/tests/test-rebase-obsolete.t
+++ b/tests/test-rebase-obsolete.t
@@ -1496,6 +1496,7 @@
   $ hg log -r .  # working dir is at rev 3 (successor of 2)
   3:be1832deae9a b (no-eol)
   $ hg book -r 2 mybook --hidden  # rev 2 has a bookmark on it now
+  bookmarking hidden changeset 1e9a3c00cbe9
   $ hg up 2 && hg log -r .  # working dir is at rev 2 again
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   2:1e9a3c00cbe9 b (rewritten using rebase as 3:be1832deae9a) (no-eol)
diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
--- a/tests/test-obsolete.t
+++ b/tests/test-obsolete.t
@@ -1333,6 +1333,7 @@
   $ echo "hello" > b
   $ hg commit --amend -m "message"
   $ hg book bookb -r 13bedc178fce --hidden
+  bookmarking hidden changeset 13bedc178fce
   $ hg log -r 13bedc178fce
   4:13bedc178fce (draft *obsolete*) [ bookb] add b [rewritten using amend as 
5:a9b1f8652753]
   $ hg book -d bookb
diff --git a/tests/test-log.t b/tests/test-log.t
--- a/tests/test-log.t
+++ b/tests/test-log.t
@@ -1851,14 +1851,16 @@
 bookmarks prevent a changeset being hidden
 
   $ hg bookmark --hidden -r 1 X
+  bookmarking hidden changeset a765632148dc
   $ hg log --template '{rev}:{node}\n'
   1:a765632148dc55d38c35c4f247c618701886cb2f
   0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
   $ hg bookmark -d X
 
 divergent bookmarks are not hidden
 
   $ hg bookmark --hidden -r 1 X@foo
+  bookmarking hidden changeset a765632148dc
   $ hg log --template '{rev}:{node}\n'
   1:a765632148dc55d38c35c4f247c618701886cb2f
   0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
diff --git a/tests/test-directaccess.t b/tests/test-directaccess.t
--- a/tests/test-directaccess.t
+++ b/tests/test-directaccess.t
@@ -186,3 +186,11 @@
   abort: hidden revision '2' was rewritten as: 2443a0e66469!
   (use --hidden to access hidden revisions)
   [255]
+
+Setting a bookmark will make that changeset unhidden, so this should come in 
end
+
+  $ hg bookmarks -r 28ad74 book
+  bookmarking hidden changeset 28ad74487de9
+
+  $ hg bookmarks
+ book  2:28ad74487de9
diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py
--- a/mercurial/bookmarks.py
+++ b/mercurial/bookmarks.py
@@ -830,6 +830,7 @@
 cur = repo.changectx('.').node()
 newact = None
 changes = []
+hiddenrevs = set()
 for mark in names:
 mark = checkformat(repo, mark)
 if newact is None:
@@ -839,10 +840,17 @@
 return
 tgt = cur
 if rev:
-tgt = scmutil.revsingle(repo, rev).node()
+repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
+ctx = scmutil.revsingle(repo, rev)
+if ctx.hidden():
+hiddenrevs.add(ctx.hex()[:12])
+tgt = ctx.node()
 for bm in marks.checkconflict(mark, force, tgt):
 changes.append((bm, None))
 changes.append((mark, tgt))
+if hiddenrevs:
+repo.ui.warn(_("bookmarking hidden changeset %s\n") %
+ ', '.join(hiddenrevs))
 marks.applychanges(repo, tr, changes)
 if not inactive and cur == marks[newact] and not rev:
 activate(repo, newact)



To: pulkit, #hg-reviewers, yuja
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1795: py3: use pycompat.bytestr() instead of str()

2018-01-12 Thread yuja (Yuya Nishihara)
yuja added inline comments.

INLINE COMMENTS

> pulkit wrote in verify.py:110
> Looks like we cannot use "%d" here as None can be possible value also and 
> test-treemanifest.t has tests with None as a part of output.

Ugh, it smells, but let's just leave it for now.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1795

To: pulkit, #hg-reviewers, durin42
Cc: yuja, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D1854: py3: use bytes instead of pycompat.bytestr

2018-01-12 Thread pulkit (Pulkit Goyal)
pulkit created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Follow up for https://phab.mercurial-scm.org/D1795.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1854

AFFECTED FILES
  mercurial/subrepo.py

CHANGE DETAILS

diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -389,14 +389,14 @@
 if util.safehasattr(repo, '_subparent'):
 source = util.url(repo._subsource)
 if source.isabs():
-return pycompat.bytestr(source)
+return bytes(source)
 source.path = posixpath.normpath(source.path)
 parent = _abssource(repo._subparent, push, abort=False)
 if parent:
 parent = util.url(util.pconvert(parent))
 parent.path = posixpath.join(parent.path or '', source.path)
 parent.path = posixpath.normpath(parent.path)
-return pycompat.bytestr(parent)
+return bytes(parent)
 else: # recursion reached top repo
 if util.safehasattr(repo, '_subtoppath'):
 return repo._subtoppath



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