Re: [PATCH] match: adding non-recursive directory matching

2016-11-23 Thread Rodrigo Damazio via Mercurial-devel
Hi guys - any comments on the preferred way forward?

(I do have a follow-up patch for optimizing visitdir accordingly, but don't
want to send it until this one is agreed upon)


On Thu, Nov 17, 2016 at 1:19 PM, Rodrigo Damazio 
wrote:

>
>
> On Thu, Nov 17, 2016 at 7:52 AM, FUJIWARA Katsunori  > wrote:
>
>>
>> (sorry for late reply)
>>
>> At Wed, 26 Oct 2016 14:02:48 -0700,
>> Rodrigo Damazio wrote:
>> >
>> > On Wed, Oct 26, 2016 at 12:17 AM, FUJIWARA Katsunori <
>> fo...@lares.dti.ne.jp>
>> > wrote:
>> >
>> > >
>> > > At Tue, 25 Oct 2016 19:51:59 -0700,
>> > > Rodrigo Damazio wrote:
>> > > >
>> > > > On Tue, Oct 25, 2016 at 4:31 PM, FUJIWARA Katsunori <
>> > > fo...@lares.dti.ne.jp>
>> > > > wrote:
>> > > >
>> > > > >
>> > > > > At Mon, 24 Oct 2016 10:34:52 -0700,
>> > > > > Rodrigo Damazio wrote:
>>
>> [snip]
>>
>> > > > On the other hand, you assume that newly introduced *path syntaxes
>> > > > > will be recursive, as below. Would you assume that default
>> > > > > recursive-ness is different between *glob and *path syntaxes ?
>> > > > >
>> > > >
>> > > > path would be recursive, as will glob that ends with ** or regex
>> that
>> > > ends
>> > > > with .*
>> > > >
>> > > >
>> > > > > > Also, for discussion: I assume the *path patterns will be
>> recursive
>> > > when
>> > > > > > they reference a directory. Do we also want a non-recursive
>> > > equivalent
>> > > > > > (rootexact, rootfiles, rootnonrecursive or something like that)?
>> > >
>> > > How about adding syntax type "file"/"dir" ?
>> > >
>> > >   = = =
>> > >   type  for recursive for non-recursive
>> > >   = = =
>> > >   glob  use "**"  use "*"
>> > >   reomit "$"  append "$"
>> > >   path  always(*1)
>> > >   file    always
>> > >   dir   always(*2)
>> > >   = = =
>> > >
>> > >   (*1) match against both file and directory
>> > >   (*2) match against only directory
>> > >
>> > > "dir" might be overkill, though :-) (is it useful in resolving name
>> > > collision at merging or so ?)
>> > >
>> >
>> > foozy, thanks so much for the review and discussion.
>> > Sounds like we do agree about the glob behavior then, so let me know if
>> > you'd like any changes to the latest version of this patch, other than
>> > improving documentation. I'm happy to send an updated version as soon as
>> > someone is ready to review.
>> >
>> > I understand the difference between dir and path (and between the
>> original
>> > version of this patch and file) would be that they'd validate the type
>> of
>> > entry being matched (so that passing a filename to dir or dir name to
>> file
>> > would be an error) - is that what you have in mind?
>>
>> Yes > "passing a filename to dir or dir name to file would be an error"
>>
>>
>> > The current matchers
>> > don't have a good mechanism to verify the type, so some significant
>> > rewiring would need to be done to pass that information down.
>>
>> Current match implement uses two additional pattern suffix '(?:/|$)'
>> and '$' to control recursive matching of "glob" and "path". The former
>> allows to match recursively (for "glob" and "path"), and the latter
>> doesn't (only for "glob").
>>
>> I simply think using this technique to implement pattern types "file"
>> and "dir".
>>
>> path:PATTERN => ESCAPED-PATTERN(?:/|$)
>> file:PATTERN => ESCAPED-PATTERN$
>> dif:PATTERN  => ESCAPED-PATTERN/
>>
>
> Yes, "files:" was the original version of this patch and the case I really
> care about :) I changed it to rootglob after your comments.
> Which way would be preferred to move forward?
>
>


smime.p7s
Description: S/MIME Cryptographic Signature
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 2] dispatch: move part of callcatch to scmutil

2016-11-23 Thread Jun Wu
That's an interesting idea.

I happened to be interested in the diff algorithm recently and think they
are related. A fundamental problem of the diff algorithm is, it does not
track line moves. As long as our diff algorithm cannot do that, I won't do
the merge thing manually.

Will that kind of "smart" diff algorithm exist? Probably. And if we can have
the diff algorithm which detects moves (I'm in dreaming mode), and new
version of revlog (probably will contain both the new diff algorithm, and
some kind of packing to reduce inode), it will help making deltas smaller.

And I don't think the "move" information has to be hashed / committed. It
could be calculated afterwards and store separately. (this also means I
think the git data model is cleaner). 

Excerpts from timeless's message of 2016-11-23 21:36:02 -0500:
> fwiw, it is possible to keep blame for this if you really wanted to.
> 
> The approach is:
> 7ef2ebf5cdf91192a66b461ff56f653a65e65dd7->x
> x:
>  copy scmutil.py -> scmutil_.py
> 7ef2ebf5cdf91192a66b461ff56f653a65e65dd7->y
> y:
>  copy dispatch.py-> scmutil_.py
>  delete lines from scmutil_.py
> 
> x+y->z
> z:
>  resolve merge conflicts in scmutil_.py as in this patch
>  delete scmutil.py
>  rename scmutil_.py -> scmutil.py
>  delete lines from dispatch.py
>  adjust dispatch.py as in this patch
> 
> If you do it this way, commits `x` and `y` still build (they just have
> temporary files scmutil_.py which isn't used), and you still have
> blame for scmutil.py for both parts.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 2] dispatch: move part of callcatch to scmutil

2016-11-23 Thread timeless
fwiw, it is possible to keep blame for this if you really wanted to.

The approach is:
7ef2ebf5cdf91192a66b461ff56f653a65e65dd7->x
x:
 copy scmutil.py -> scmutil_.py
7ef2ebf5cdf91192a66b461ff56f653a65e65dd7->y
y:
 copy dispatch.py-> scmutil_.py
 delete lines from scmutil_.py

x+y->z
z:
 resolve merge conflicts in scmutil_.py as in this patch
 delete scmutil.py
 rename scmutil_.py -> scmutil.py
 delete lines from dispatch.py
 adjust dispatch.py as in this patch

If you do it this way, commits `x` and `y` still build (they just have
temporary files scmutil_.py which isn't used), and you still have
blame for scmutil.py for both parts.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 7 of 8] crecord: change help text for the space key dynamically

2016-11-23 Thread timeless
Jun Wu wrote:
> +_('space: unselect') if selected else _('space: select'),

I favor deselect (13million) over unselect (2.5million) -- numbers from Google.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 6 of 8] crecord: rewrite status line text (BC)

2016-11-23 Thread timeless
Jun Wu wrote:
>   Select hunks to apply.  [x]=selected **=collapsed  c: confirm  q: abort

That's pretty good, but could we use a pipe* before ` [x]`?
Possibly omitting the `.`, either as:

Select hunks to apply | [x]=selected **=collapsed  c: confirm  q: abort
or
Select hunks to apply. | [x]=selected **=collapsed  c: confirm  q: abort

* possibly a dash (-)...
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH evolve-ext] evolve: improve error message if unstable changes are disallowed

2016-11-23 Thread timeless
Mateusz Kwapich wrote:
> Pulkit wrote:
>> +raise error.Abort(_("cannot prune in the middle of a stack\n"\
>> +"new unstable changesets are not allowed"))
> This error doesn't have hint - maybe we could use it for that purpose.

I should spend some time working on these messages...

>> +_('cannot edit commit information in the middle of a 
>> stack\n'\
>> +'new unstable changesets are not allowed'),
>>  hint=_('%s will be affected') % 
>> repo[newunstable.first()])
> I would change the hint to say something along:
> '%s would become unstable but new unstable commits are not allowed'

I'm tempted to say "and" instead of "but"...

>> @@ -3299,7 +3301,8 @@
>>  head = repo[heads.first()]
>>  if _disallowednewunstable(repo, revs):
>>  raise error.Abort(_("cannot fold chain not ending with a head "\

"chain not ending with a head" needs work :/

>> +"or with branching\nnew unstable changesets 
>> are"\
>> +" not allowed"))
> I would move this to hint param.

I agree with Mateusz's suggestions in general.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 01 of 10 layering] dirstateguard: move to new module so I can break some layering violations

2016-11-23 Thread timeless
Yuya Nishihara wrote:
> Is copy-and-remove a preferred way for this kind of refactoring? I have
> an unsent patch that splits revset.py, so I want to know which is better.

Augie Fackler wrote:
> I'd prefer it slightly, because it makes the blame history a little bit more 
> intact in the long run.

Me too.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 2] worker: use os._exit for posix worker in all cases

2016-11-23 Thread Jun Wu
The previous version is at 
https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-August/087058.html
It's 3 months ago so I didn't mark the current one as V2. I changed the
title a bit so whatever automation would handle this correctly.

Excerpts from Jun Wu's message of 2016-11-24 01:17:50 +:
> # HG changeset patch
> # User Jun Wu 
> # Date 1479950134 0
> #  Thu Nov 24 01:15:34 2016 +
> # Node ID 6c8735bfbf00b224e3f158242e1078d0fe667a42
> # Parent  c76f0d4bdee6bfbd7bda771d5c05939d1d4cb132
> # Available At https://bitbucket.org/quark-zju/hg-draft 
> #  hg pull https://bitbucket.org/quark-zju/hg-draft  -r 
> 6c8735bfbf00
> worker: use os._exit for posix worker in all cases
> 
> Like commandserver, the worker should never run other resource cleanup logic.
> 
> Previously this is not true for workers if they have exceptions other than
> KeyboardInterrupt.
> 
> This actually caused a real-world deadlock with remotefilelog:
> 
> 1. remotefilelog/fileserverclient creates a sshpeer. pipei/o/e get created.
> 2. worker inherits that sshpeer's pipei/o/e.
> 3. worker runs sshpeer.cleanup (only happens without os._exit)
> 4. worker closes pipeo/i, which will normally make the sshpeer read EOF from
>its stdin and exit. But the master process still have pipeo, so no EOF.
> 5. worker reads pipee (stderr of sshpeer), which never completes because
>the ssh process does not exit, does not close its stderr.
> 6. master waits for all workers, which never completes because they never
>complete sshpeer.cleanup.
> 
> This could also be addressed by closing these fds after fork, which is not
> easy because Python 2.x does not have an official "afterfork" hook. Hacking
> os.fork is also ugly. Besides, sshpeer is probably not the only troublemarker.
> 
> The patch changes _posixworker so all its code paths will use os._exit to
> avoid running unwanted resource clean-ups.
> 
> diff --git a/mercurial/worker.py b/mercurial/worker.py
> --- a/mercurial/worker.py
> +++ b/mercurial/worker.py
> @@ -16,4 +16,5 @@ from .i18n import _
>  from . import (
>  error,
> +scmutil,
>  util,
>  )
> @@ -133,13 +134,24 @@ def _posixworker(ui, func, staticargs, a
>  signal.signal(signal.SIGINT, oldhandler)
>  signal.signal(signal.SIGCHLD, oldchldhandler)
> -try:
> +
> +def workerfunc():
>  os.close(rfd)
>  for i, item in func(*(staticargs + (pargs,))):
>  os.write(wfd, '%d %s\n' % (i, item))
> -os._exit(0)
> +
> +# make sure we use os._exit in all code paths. otherwise the 
> worker
> +# may do some clean-ups which could cause surprises like 
> deadlock.
> +# see sshpeer.cleanup for example.
> +try:
> +scmutil.callcatch(ui, workerfunc)
>  except KeyboardInterrupt:
>  os._exit(255)
> -# other exceptions are allowed to propagate, we rely
> -# on lock.py's pid checks to avoid release callbacks
> +except: # never return, therefore no re-raises
> +try:
> +ui.traceback()
> +finally:
> +os._exit(255)
> +else:
> +os._exit(0)
>  pids.add(pid)
>  os.close(wfd)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 2] worker: use os._exit for posix worker in all cases

2016-11-23 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1479950134 0
#  Thu Nov 24 01:15:34 2016 +
# Node ID 6c8735bfbf00b224e3f158242e1078d0fe667a42
# Parent  c76f0d4bdee6bfbd7bda771d5c05939d1d4cb132
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r 6c8735bfbf00
worker: use os._exit for posix worker in all cases

Like commandserver, the worker should never run other resource cleanup logic.

Previously this is not true for workers if they have exceptions other than
KeyboardInterrupt.

This actually caused a real-world deadlock with remotefilelog:

1. remotefilelog/fileserverclient creates a sshpeer. pipei/o/e get created.
2. worker inherits that sshpeer's pipei/o/e.
3. worker runs sshpeer.cleanup (only happens without os._exit)
4. worker closes pipeo/i, which will normally make the sshpeer read EOF from
   its stdin and exit. But the master process still have pipeo, so no EOF.
5. worker reads pipee (stderr of sshpeer), which never completes because
   the ssh process does not exit, does not close its stderr.
6. master waits for all workers, which never completes because they never
   complete sshpeer.cleanup.

This could also be addressed by closing these fds after fork, which is not
easy because Python 2.x does not have an official "afterfork" hook. Hacking
os.fork is also ugly. Besides, sshpeer is probably not the only troublemarker.

The patch changes _posixworker so all its code paths will use os._exit to
avoid running unwanted resource clean-ups.

diff --git a/mercurial/worker.py b/mercurial/worker.py
--- a/mercurial/worker.py
+++ b/mercurial/worker.py
@@ -16,4 +16,5 @@ from .i18n import _
 from . import (
 error,
+scmutil,
 util,
 )
@@ -133,13 +134,24 @@ def _posixworker(ui, func, staticargs, a
 signal.signal(signal.SIGINT, oldhandler)
 signal.signal(signal.SIGCHLD, oldchldhandler)
-try:
+
+def workerfunc():
 os.close(rfd)
 for i, item in func(*(staticargs + (pargs,))):
 os.write(wfd, '%d %s\n' % (i, item))
-os._exit(0)
+
+# make sure we use os._exit in all code paths. otherwise the worker
+# may do some clean-ups which could cause surprises like deadlock.
+# see sshpeer.cleanup for example.
+try:
+scmutil.callcatch(ui, workerfunc)
 except KeyboardInterrupt:
 os._exit(255)
-# other exceptions are allowed to propagate, we rely
-# on lock.py's pid checks to avoid release callbacks
+except: # never return, therefore no re-raises
+try:
+ui.traceback()
+finally:
+os._exit(255)
+else:
+os._exit(0)
 pids.add(pid)
 os.close(wfd)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[Bug 5432] New: record/hunk selector help mention "record" instead of the operation name.

2016-11-23 Thread bugzilla
https://bz.mercurial-scm.org/show_bug.cgi?id=5432

Bug ID: 5432
   Summary: record/hunk selector help mention "record" instead of
the operation name.
   Product: Mercurial
   Version: default branch
  Hardware: PC
OS: Linux
Status: UNCONFIRMED
  Severity: bug
  Priority: wish
 Component: record
  Assignee: bugzi...@selenic.com
  Reporter: pierre-yves.da...@ens-lyon.org
CC: mercurial-de...@selenic.com

The detailed help use "record" in all case, not propagating the "operation"
name. This can be confusing for user.

The following display the issue for the old/default record UI. I've not checked
the crecord ui yet.

examine changes to 'contrib/chg/Makefile'? [Ynesfdaq?] 

@@ -40,6 +40,7 @@ serve:
[ -d $(CHGSOCKDIR) ] || ( umask 077; mkdir $(CHGSOCKDIR) )
$(HG) serve --cwd / --cmdserver chgunix \
--address $(CHGSOCKNAME) \
+   --config extensions.chgserver= \
--config cmdserver.log=/dev/stderr

 .PHONY: clean
discard change 1/14 to 'contrib/chg/Makefile'? [Ynesfdaq?] ?

y - yes, record this change
n - no, skip this change
e - edit this change manually
s - skip remaining changes to this file
f - record remaining changes to this file
d - done, skip remaining changes and files
a - record all changes to all remaining files
q - quit, recording no changes
? - ? (display help)

-- 
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


Re: [PATCH RESEND] revert: do not reverse hunks in interactive when REV is not parent (issue5096)

2016-11-23 Thread Pierre-Yves David



On 11/23/2016 04:01 PM, Jun Wu wrote:

Excerpts from Martin von Zweigbergk's message of 2016-11-14 15:57:30 -0800:

Pierre-Yves reached out and reminded me that he actually frequently
uses "hg revert -i -r .~1" to undo changes since that commit. Also, I
still personally feel that the people who want to undo changes since a
revision and the people who want to get changes from a revision are
thinking about it differently enough that they should be using
different commands. I think it would be good if we could find good


There are other commands:
- For picking what should be undone: "hg uncommit -i"
- For picking what to kept: "hg split". (We can enhance it so it's possible
  to abort and drop the remaining changes)

Those commands sound more intuitive to me and could probably fit marmoute's
use-case.


These does not really fits my usecase, a frequent use of 'hg revert -i 
-r .~x' to temporarily revert some change and check if it responsible 
for a crash/change in test. I don't want to touch history yet at that 
point. I want to check the check between my current state and an earlier 
point and revert some of these change. So neither 'uncommit' or 'split' 
are adequate here.



I also sometime use it to just drop a hunk I commited by mistake, in 
this case a combination of 'hg uncommit -i + hg revert -i' (or some kind 
of 'hg uncommit -i --revert') could do it. Not that we do not have '-i' 
for 'hg uncommit' yet (that would be handy).




On the contrary, it seems to me 'hg split' could cover some of the 
usecase of other people in this thread.




names for both of those operations. In my mind, "revert" is a good
word for the former (i.e. undoing), and I'm not sure what's a good
word for the latter (i.e. getting state from). It's still unclear to
me if others were turned off mostly by my proposed name ("apply") or
the idea of them being different operations.

I'll de-queue this patch for now, and we can talk (even) more about it :-/


An internal user just complained about the confusing behavior. I think an
easy change we would all agree is to make the curses UI to use the same verb
as the text UI does.

Before:

  SELECT CHUNKS:  toggle hunk/all; (e)dit hunk;
   (f)old/unfold; (c)onfirm applied; ... [X]=hunk applied 
^^^   ^^^
After:

  SELECT CHUNKS:  toggle hunk/all; (e)dit hunk;
   (f)old/unfold; (c)onfirm revert; ... [X]=hunk to revert 
^^   ^

If there is no objection, I could prepare the patch.


+1 for having curse using the proper action/verb, that would for sure 
help the situation.


Cheers,

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH RESEND] revert: do not reverse hunks in interactive when REV is not parent (issue5096)

2016-11-23 Thread Pierre-Yves David



On 11/15/2016 09:24 AM, Denis Laxalde wrote:

Pierre-Yves David a écrit :

We can extract two main points in the section you reply to and I'm not
sure which one you address in your reply. I'm going to re-emit them in a
simplified/modified form to clarify

First important point
=

In the following case:
* `hg revert -i`
* `hg revert -i -r ancestor`
* `hg revert -i -r precursor`
* `hg revert -i -r background` #combination of the above,

Seeing the hunk the way they are currently is exactly what I want to
see. These hunks are shown that way by all other commands (diff, commit,
amend, shelve) and not seeing the same thing in revert is super
confusing to me.


There's an essential different with these "other commands"
(commit/shelve) and revert: the former operate on the repository history
while the latter operates on the working directory. In this respect,
when interactively applying changes to the repository (commit-like
commands, former case), one gets prompted with a diff as it would apply
to the current revision. This patch essentially proposes to apply the
same logic to the revert command (i.e. prompt the user with a change
that would be applied to the working directory) and to prompt the user
with an intelligible action (avoid double negation).


I don't really follow all your logic here. For example `hg shelve` is 
touching the working directory (by removing change in it, much like what 
`hg revert` does).


To me, for the way I use `hg revert -i --rev` the current direction is 
an intelligible action. I understand and recognize that some other 
people use it in a way where the other direction is more intelligible to 
them. This is why I suggest we get a way for the UI to offer both 
direction, there is probably always going to be a case where someone 
legitimately wants one of the two specific directions.



For me, as a user, REV being in the "background" or not is not
particularly relevant.


To me, REV being in the background is relevant (as I'm currently using 
it that way) and seeing the diff that I discard is the information 
intelligible to me. It was the other way for a brief period, that was 
confusing and made the command unhelpful to me. After discussing it with 
Laurent he made dcc56e10c23b. The commit you are trying to revert here.



I sometimes use -r REV with REV being on some
"unrelated" branch. More often do I use -r REV with REV being a
descendant changeset (for instance to extract a refactoring that I
committed together with a functional change -- hg up REV^; hg rev -i -r
REV; then commit/rebase).


By the way, did you gave a shot to `hg split` for this very usecase?


I can't figure out how your reasoning would
apply in this case, but I'm certain that being prompted with changes as
they would apply to the working directory won't be confusing for me.


The things I'm pointing out as confusing¹ here is the change in diff 
direction given the command invocation:


For example `hg revert -i` show different diff that `hg revert -i -r .`, 
And if we keep the direction for `--rev BACKGROUND` we end up with even 
subtler change from.


This is explained in more detailed in my previous email.



 (typical, (use hg diff, see something to drop; use hg
revert, drop the same thing at the same spot).


That one (which corresponds to `hg revert -i [-r .]`) already works that
way, only it shows a "discard this hunk" prompt.



An excellent example for such case is `hg revert -i -r .~1`, associate
with `hg pdif `(hg diff -r .~1) and amend I'm a bit user of it.


These two sentences of mine works together:

Your proposal breaks it for `hg diff -r .~1 # hg pdiff` and associated 
`hg revert -i --rev .~1`. (or any further ancestors/precursors). 
Something I'm already using very frequently while developing.


(also, reiteration of my point that the switch in direction between even 
`hg revert -i` and `hg revert -ir .` is too subtle with just a small 
wording changes. I don't expect user to read wording in place they are 
familiar with.



In that case, I'm not "worried it will be confusing" I know from
experience that I'm greatly confused by it. This was one of the
motivation of dcc56e10c23b;

The fact "hg revert -i" display the right thing in these situation is
partly validated by the fact this patch for not change the direction for
the first item in my list (plain `hg revert -i`)


Without -r REV, `hg revert -i` is basically a "discard uncommitted
changes" command. So ones gets prompted with these uncommitted changes
and whether to discard them or not. Sure the diff is reversed with
respected to other cases, but the fundamental idea is that the
combination of "diff direction" and "operation" (discard or apply) is
consistent.


Just to make sure I'm clear:

 * I use `hg revert -i -r BACKGROUND` to 'discard' hunk. I need the 
appropriate direction and action to do so.


 * I think the 'operation' change is going to be too subtle for user to 
avoid large amount of confusion.




[PATCH 7 of 8] crecord: change help text for the space key dynamically

2016-11-23 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1479941166 0
#  Wed Nov 23 22:46:06 2016 +
# Node ID 18b6dea42fcdf5922926d6a0ab84f09c0cf5bd1a
# Parent  9e7850a8ae79f7ccf1855a489d42d66dc1d949db
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r 18b6dea42fcd
crecord: change help text for the space key dynamically

A follow-up of the previous patch, to make the text simple and clear about
whether it's to "select" or "unselect".

diff --git a/mercurial/crecord.py b/mercurial/crecord.py
--- a/mercurial/crecord.py
+++ b/mercurial/crecord.py
@@ -949,4 +949,5 @@ class curseschunkselector(object):
 def _getstatuslinesegments(self):
 """-> [str]. return segments"""
+selected = self.currentselecteditem.applied
 segments = [
 _('Select hunks to record.'),
@@ -955,5 +956,5 @@ class curseschunkselector(object):
 _('q: abort'),
 _('arrow keys: move/expand/collapse'),
-_('space: select'),
+_('space: unselect') if selected else _('space: select'),
 _('?: help'),
 ]
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 8 of 8] crecord: change the verb according to the operation

2016-11-23 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1479942213 0
#  Wed Nov 23 23:03:33 2016 +
# Node ID a25fb0c50bc0ad20511621d15e1cc7c6478528c1
# Parent  18b6dea42fcdf5922926d6a0ab84f09c0cf5bd1a
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r a25fb0c50bc0
crecord: change the verb according to the operation

This will make crecord consistent with record when being used in the revert
situation. It will say "Select hunks to revert / discard" accordingly.

This should make the revert crecord interface less confusing.

diff --git a/mercurial/crecord.py b/mercurial/crecord.py
--- a/mercurial/crecord.py
+++ b/mercurial/crecord.py
@@ -502,4 +502,10 @@ def testchunkselector(testfn, ui, header
 return chunkselector.opts
 
+_headermessages = { # {operation: text}
+'revert': _('Select hunks to revert.'),
+'discard': _('Select hunks to discard.'),
+None: _('Select hunks to record.'),
+}
+
 class curseschunkselector(object):
 def __init__(self, headerlist, ui, operation=None):
@@ -558,4 +564,6 @@ class curseschunkselector(object):
 
 # affects some ui text
+if operation not in _headermessages:
+raise RuntimeError('unexpected operation: %s' % operation)
 self.operation = operation
 
@@ -951,5 +959,5 @@ class curseschunkselector(object):
 selected = self.currentselecteditem.applied
 segments = [
-_('Select hunks to record.'),
+_headermessages[self.operation],
 _('[x]=selected **=collapsed'),
 _('c: confirm'),
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 8] crecord: make _getstatuslines update numstatuslines

2016-11-23 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1479939795 0
#  Wed Nov 23 22:23:15 2016 +
# Node ID d84ab5920899a914a225319130937befc6402d8a
# Parent  5894c146af1e3154f7b327dce54a779bb419811a
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r d84ab5920899
crecord: make _getstatuslines update numstatuslines

We are going to make the text in the status window dynamically generated,
so its size would be dynamic. Change getstatuslines to update
"numstatuslines" automatically. Fix an issue where "numstatuslines" being 1
makes the chunkpad disappear.

diff --git a/mercurial/crecord.py b/mercurial/crecord.py
--- a/mercurial/crecord.py
+++ b/mercurial/crecord.py
@@ -542,5 +542,5 @@ class curseschunkselector(object):
 self.numpadlines = None
 
-self.numstatuslines = 2
+self.numstatuslines = 1
 
 # keep a running count of the number of lines printed to the pad
@@ -956,4 +956,7 @@ class curseschunkselector(object):
  _(" (f)old/unfold; (c)onfirm applied; (q)uit; (?) help "
"| [X]=hunk applied **=folded, toggle [a]mend mode")]
+if len(lines) != self.numstatuslines:
+self.numstatuslines = len(lines)
+self.statuswin.resize(self.numstatuslines, self.xscreensize)
 return [util.ellipsis(l, self.xscreensize - 1) for l in lines]
 
@@ -979,5 +982,5 @@ class curseschunkselector(object):
 self.chunkpad.refresh(self.firstlineofpadtoprint, 0,
   self.numstatuslines, 0,
-  self.yscreensize + 1 - self.numstatuslines,
+  self.yscreensize - self.numstatuslines,
   self.xscreensize)
 except curses.error:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 6 of 8] crecord: rewrite status line text (BC)

2016-11-23 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1479940063 0
#  Wed Nov 23 22:27:43 2016 +
# Node ID 9e7850a8ae79f7ccf1855a489d42d66dc1d949db
# Parent  d84ab5920899a914a225319130937befc6402d8a
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r 9e7850a8ae79
crecord: rewrite status line text (BC)

Previously, we display fixed text in the 2-line status header. Now we want
to customize some word there to make the "revert" action clear. However, if
we simply replace the verb using '%s' like this:

  "SELECT CHUNKS: (j/k/up/dn/pgup/pgdn) move cursor; "
  "(space/A) toggle hunk/all; (e)dit hunk;"),
  " (f)old/unfold; (c)onfirm %s; (q)uit; (?) help " % verb
  "| [X]=hunk %s **=folded, toggle [a]mend mode" % verb

It could cause trouble ofr i18n - some languages may expect things like
"%(verb) confirm", for example.

Therefore, this patch chooses to break the hard-coded 2-line sentences into
"segment"s which could be translated (and replaced) separately.

To make my work easier, I'm also changing the content being displayed, to
make it cleaner and more friendly to (new) users, namely:

  - Replace "SELECT CHUNKS" to "Select hunks to record". Because:
- To eliminate "hunk" / "chunk" inconsistency.
- "record" is used in the "text" UI. Do not use "apply", to make it
  consistent.
- To make it clear you are choosing what to apply, not revert, or
  discard etc. This is probably the most important information the user
  should know. So let's put it first.
- "to apply" could be replaced to others depending on the operation.
  The follow-up patches will address them.
  - Move "[x]" and "**" legends first to explain the current interface. New
users should understand what the legends mean, followed by what they can
do in the interface.
  - Replace "j/k/up/dn/pgup/pgdn" with "arrow keys". Because:
- "arrow keys" is more friendly to new users.
- Mentioning "j/k" first may make emacs users angry. We should stay
  neutral about editors.
- "pgup/pgdn" actually don't work very well. For example, within a hunk
  of 100-line insertion, "pgdn" just moves one single line.
- Left/Right arrow keys are useful for movement and discovery of
  "expanding" a block.
  - Replace "fold/unfold" with "collapse/expand", "fold" is well known as
a different meaning in histedit and evolve.
  - Replace "(space/A) toggle hunk/all" to "space: select". Because:
- "A: toggle all" is not that useful
- It's unclear how "hunk" could be "toggled" to a dumb user. Let's
  make it clear it's all about "select".
- A follow-up will make it use "unselect" when we know the current item
  is selected.
  - Remove "(f)old". Use arrow keys instead.
  - Remove "toggle [a]mend mode". It's just confusing and could be useless.
  - Remove "(e)dit hunk". It's powerful but not friendly to new users.
  - Replace "(q)uit" to "q: abort" to make it clear you will lose changes.

The result looks like the following in a 72-char terminal:

  Select hunks to apply.  [x]=selected **=collapsed  c: confirm  q: abort
  arrow keys: move/expand/collapse  space: select  ?: help

If the terminal is 132-char wide, the text could fit in a single line.

diff --git a/mercurial/crecord.py b/mercurial/crecord.py
--- a/mercurial/crecord.py
+++ b/mercurial/crecord.py
@@ -947,4 +947,17 @@ class curseschunkselector(object):
 return t
 
+def _getstatuslinesegments(self):
+"""-> [str]. return segments"""
+segments = [
+_('Select hunks to record.'),
+_('[x]=selected **=collapsed'),
+_('c: confirm'),
+_('q: abort'),
+_('arrow keys: move/expand/collapse'),
+_('space: select'),
+_('?: help'),
+]
+return segments
+
 def _getstatuslines(self):
 """() -> [str]. return short help used in the top status window"""
@@ -952,8 +965,17 @@ class curseschunkselector(object):
 lines = [self.errorstr, _('Press any key to continue')]
 else:
-lines = [_("SELECT CHUNKS: (j/k/up/dn/pgup/pgdn) move cursor; "
-   "(space/A) toggle hunk/all; (e)dit hunk;"),
- _(" (f)old/unfold; (c)onfirm applied; (q)uit; (?) help "
-   "| [X]=hunk applied **=folded, toggle [a]mend mode")]
+# wrap segments to lines
+segments = self._getstatuslinesegments()
+width = self.xscreensize
+lines = []
+lastwidth = width
+for s in segments:
+w = encoding.colwidth(s)
+if lastwidth + w + 2 >= width:
+lines.append(s)
+lastwidth = w
+else:
+lines[-1] += '  ' + s
+lastwidth += w + 2
 if len(lines) != self.numstatuslines:
 

[PATCH 2 of 8] revert: pass operation to crecord

2016-11-23 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1479927804 0
#  Wed Nov 23 19:03:24 2016 +
# Node ID d4c7651935165820d8bfe363c8cae95e0192af1f
# Parent  c1aa248a8bc0fac647a1f849ed25c31291edce64
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r d4c765193516
revert: pass operation to crecord

So crecord would know what to display

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -85,5 +85,5 @@ def filterchunks(ui, originalhunks, usec
 recordfn = crecordmod.chunkselector
 
-return crecordmod.filterpatch(ui, originalhunks, recordfn)
+return crecordmod.filterpatch(ui, originalhunks, recordfn, operation)
 
 else:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 8] crecord: filter text via i18n

2016-11-23 Thread Jun Wu
# HG changeset patch
# User Jun Wu 
# Date 1479924791 0
#  Wed Nov 23 18:13:11 2016 +
# Node ID ed629f77d3616013c8216d99e90e02c47eccdb4f
# Parent  d4c7651935165820d8bfe363c8cae95e0192af1f
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r ed629f77d361
crecord: filter text via i18n

There are some text in the user interface that are not filtered by i18n.
This patch adds the missing "_" call. So the text could be translated.

diff --git a/mercurial/crecord.py b/mercurial/crecord.py
--- a/mercurial/crecord.py
+++ b/mercurial/crecord.py
@@ -961,8 +961,8 @@ class curseschunkselector(object):
 self.statuswin.refresh()
 return
-line1 = ("SELECT CHUNKS: (j/k/up/dn/pgup/pgdn) move cursor; "
-   "(space/A) toggle hunk/all; (e)dit hunk;")
-line2 = (" (f)old/unfold; (c)onfirm applied; (q)uit; (?) help "
-   "| [X]=hunk applied **=folded, toggle [a]mend mode")
+line1 = _("SELECT CHUNKS: (j/k/up/dn/pgup/pgdn) move cursor; "
+  "(space/A) toggle hunk/all; (e)dit hunk;")
+line2 = _(" (f)old/unfold; (c)onfirm applied; (q)uit; (?) help "
+  "| [X]=hunk applied **=folded, toggle [a]mend mode")
 
 printstring(self.statuswin,
@@ -1306,5 +1306,6 @@ class curseschunkselector(object):
 def helpwindow(self):
 "print a help window to the screen.  exit after any keypress."
-helptext = """[press any key to return to the 
patch-display]
+helptext = _(
+"""[press any key to return to the patch-display]
 
 crecord allows you to interactively choose among the changes you have made,
@@ -1330,5 +1331,5 @@ the following are valid keystrokes:
   r : review/edit and confirm selected changes
   q : quit without confirming (no changes will be made)
-  ? : help (what you're currently reading)"""
+  ? : help (what you're currently reading)""")
 
 helpwin = curses.newwin(self.yscreensize, 0, 0, 0)
@@ -1369,5 +1370,5 @@ the following are valid keystrokes:
 """ask for 'y' to be pressed to confirm selected. return True if
 confirmed."""
-confirmtext = (
+confirmtext = _(
 """if you answer yes to the following, the your currently chosen patch chunks
 will be loaded into an editor.  you may modify the patch from the editor, and
@@ -1401,17 +1402,17 @@ are you sure you want to review/edit and
 ver = 1
 if ver < 2.19:
-msg = ("The amend option is unavailable with hg versions < 2.2\n\n"
-   "Press any key to continue.")
+msg = _("The amend option is unavailable with hg versions < 
2.2\n\n"
+"Press any key to continue.")
 elif opts.get('amend') is None:
 opts['amend'] = True
-msg = ("Amend option is turned on -- committing the currently "
-   "selected changes will not create a new changeset, but "
-   "instead update the most recently committed changeset.\n\n"
-   "Press any key to continue.")
+msg = _("Amend option is turned on -- committing the currently "
+"selected changes will not create a new changeset, but "
+"instead update the most recently committed changeset.\n\n"
+"Press any key to continue.")
 elif opts.get('amend') is True:
 opts['amend'] = None
-msg = ("Amend option is turned off -- committing the currently "
-   "selected changes will create a new changeset.\n\n"
-   "Press any key to continue.")
+msg = _("Amend option is turned off -- committing the currently "
+"selected changes will create a new changeset.\n\n"
+"Press any key to continue.")
 if not test:
 self.confirmationwindow(msg)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] posix: _really_ make sure .hg/cache/checklink points at a real file

2016-11-23 Thread Pierre-Yves David



On 11/24/2016 12:15 AM, Mads Kiilerich wrote:

On 11/23/2016 11:24 PM, Pierre-Yves David wrote:



On 11/23/2016 11:09 PM, Mads Kiilerich wrote:

# HG changeset patch
# User Mads Kiilerich 
# Date 1479938505 -3600
#  Wed Nov 23 23:01:45 2016 +0100
# Node ID 2841e0a6f97ba09dff5ffe7f42ac8c6e1b23338f
# Parent  8836f13e3c5b8eae765372708b659c55a044cbb4
posix: _really_ make sure .hg/cache/checklink points at a real file

8836f13e3c5b failed to do what it said; it did leave a dangling
symlink. As
promised, that broke setup.py sdist. It also broke stuff on Solaris
where "cp
-r" by default follows symlinks.

Instead, make it point at ../00changelog.i, which is the file that is
most
likely to exist. This adds some extra layering violation ... but not
much, in
an innocent way, and it works ...


Could we just create a empty file right next to this symlink and point
to that? That would seems more independant/robust.



Right.

Playing more around with this raise the question: Generally, when
running hg commands that create/write files, how do we make sure that
nobody fooled us and placed a symlink that can trick us to overwrite
arbitrary files? Should we and do we always take precautions for that?


Don't we have a whole vfs auditing layer especially to protect us of 
this class of issue? I think we should should always take precautions.


I'm not too sure how this relate to the current specific issue. Did I 
miss something or are you expanding the discussion (which would be fine)


Cheers,

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] posix: _really_ make sure .hg/cache/checklink points at a real file

2016-11-23 Thread Mads Kiilerich

On 11/23/2016 11:24 PM, Pierre-Yves David wrote:



On 11/23/2016 11:09 PM, Mads Kiilerich wrote:

# HG changeset patch
# User Mads Kiilerich 
# Date 1479938505 -3600
#  Wed Nov 23 23:01:45 2016 +0100
# Node ID 2841e0a6f97ba09dff5ffe7f42ac8c6e1b23338f
# Parent  8836f13e3c5b8eae765372708b659c55a044cbb4
posix: _really_ make sure .hg/cache/checklink points at a real file

8836f13e3c5b failed to do what it said; it did leave a dangling 
symlink. As
promised, that broke setup.py sdist. It also broke stuff on Solaris 
where "cp

-r" by default follows symlinks.

Instead, make it point at ../00changelog.i, which is the file that is 
most
likely to exist. This adds some extra layering violation ... but not 
much, in

an innocent way, and it works ...


Could we just create a empty file right next to this symlink and point 
to that? That would seems more independant/robust.



Right.

Playing more around with this raise the question: Generally, when 
running hg commands that create/write files, how do we make sure that 
nobody fooled us and placed a symlink that can trick us to overwrite 
arbitrary files? Should we and do we always take precautions for that?


/Mads

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


[PATCH shelve-ext v2] shelve: make --keep option survive user intevention (issue5431)

2016-11-23 Thread Kostia Balytskyi
# HG changeset patch
# User Kostia Balytskyi 
# Date 1479941932 28800
#  Wed Nov 23 14:58:52 2016 -0800
# Node ID 00a022e44b62cb9340dfac94096b14f77407cefb
# Parent  db897ddf3a8ebb8df9556ce97de11f6380a9ef0b
shelve: make --keep option survive user intevention (issue5431)

Currently if user runs 'hg unshelve --keep' and merge conflicts
occur, the information about --keep provided by user is lost and
shelf is deleted after 'hg unshelve --continue'. This is obviously
not desired, so this patch fixes it.

diff --git a/hgext/shelve.py b/hgext/shelve.py
--- a/hgext/shelve.py
+++ b/hgext/shelve.py
@@ -159,6 +159,8 @@ class shelvedstate(object):
 """
 _version = 1
 _filename = 'shelvedstate'
+_keep = 'keep'
+_nokeep = 'nokeep'
 
 @classmethod
 def load(cls, repo):
@@ -175,6 +177,7 @@ class shelvedstate(object):
 parents = [nodemod.bin(h) for h in fp.readline().split()]
 stripnodes = [nodemod.bin(h) for h in fp.readline().split()]
 branchtorestore = fp.readline().strip()
+keep = fp.readline().strip() == cls._keep
 except (ValueError, TypeError) as err:
 raise error.CorruptedState(str(err))
 finally:
@@ -188,6 +191,7 @@ class shelvedstate(object):
 obj.parents = parents
 obj.stripnodes = stripnodes
 obj.branchtorestore = branchtorestore
+obj.keep = keep
 except error.RepoLookupError as err:
 raise error.CorruptedState(str(err))
 
@@ -195,7 +199,7 @@ class shelvedstate(object):
 
 @classmethod
 def save(cls, repo, name, originalwctx, pendingctx, stripnodes,
- branchtorestore):
+ branchtorestore, keep=False):
 fp = repo.vfs(cls._filename, 'wb')
 fp.write('%i\n' % cls._version)
 fp.write('%s\n' % name)
@@ -206,6 +210,7 @@ class shelvedstate(object):
 fp.write('%s\n' %
  ' '.join([nodemod.hex(n) for n in stripnodes]))
 fp.write('%s\n' % branchtorestore)
+fp.write('%s\n' % (cls._keep if keep else cls._nokeep))
 fp.close()
 
 @classmethod
@@ -680,7 +685,7 @@ def _rebaserestoredcommit(ui, repo, opts
 stripnodes = [repo.changelog.node(rev)
   for rev in xrange(oldtiprev, len(repo))]
 shelvedstate.save(repo, basename, pctx, tmpwctx, stripnodes,
-  branchtorestore)
+  branchtorestore, opts.get('keep'))
 
 util.rename(repo.join('rebasestate'),
 repo.join('unshelverebasestate'))
@@ -782,6 +787,8 @@ def _dounshelve(ui, repo, *shelved, **op
 
 try:
 state = shelvedstate.load(repo)
+if opts['keep'] is None:
+opts['keep'] = state.keep
 except IOError as err:
 if err.errno != errno.ENOENT:
 raise
diff --git a/tests/test-shelve.t b/tests/test-shelve.t
--- a/tests/test-shelve.t
+++ b/tests/test-shelve.t
@@ -1622,3 +1622,31 @@ progress
   abort: no unshelve in progress
   [255]
   $ cd ..
+
+Unshelve respects --keep even if user intervention is needed
+  $ hg init unshelvekeep
+  $ echo 1 > file && hg ci -Am 1
+  adding file
+  $ echo 2 >> file
+  $ hg shelve
+  shelved as default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo 3 >> file && hg ci -Am 13
+  $ hg shelve --list
+  default (1s ago)changes to: 1
+  $ hg unshelve --keep
+  unshelving change 'default'
+  rebasing shelved changes
+  rebasing 3:1d24e58054c8 "changes to: 1" (tip)
+  merging file
+  warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
+  unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
+  [1]
+  $ hg resolve --mark file
+  (no more unresolved files)
+  continue: hg unshelve --continue
+  $ hg unshelve --continue
+  rebasing 3:1d24e58054c8 "changes to: 1" (tip)
+  unshelve of 'default' complete
+  $ hg shelve --list
+  default (1s ago)changes to: 1
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] merge: use original file extension for temporary files

2016-11-23 Thread Mads Kiilerich
# HG changeset patch
# User Mads Kiilerich 
# Date 1479941258 -3600
#  Wed Nov 23 23:47:38 2016 +0100
# Node ID 9cee175ec5a6e2530190a120244c0d210c469dd8
# Parent  b3808b2f2e8758f5c763344ce4b81dcf723028ae
merge: use original file extension for temporary files

Some merge tools (like Araxis?) can pick merge mode based on the file
extension. That didn't work well when temporary files were given random
suffixes. It seems to work better when the random part is before the extension.

As usual, when using $output, $local will have the .orig extension. That could
perhaps be the subject of another change another day.

diff --git a/mercurial/filemerge.py b/mercurial/filemerge.py
--- a/mercurial/filemerge.py
+++ b/mercurial/filemerge.py
@@ -576,8 +576,9 @@ def _filemerge(premerge, repo, mynode, o
 a boolean indicating whether the file was deleted from disk."""
 
 def temp(prefix, ctx):
-pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
-(fd, name) = tempfile.mkstemp(prefix=pre)
+fullbase, ext = os.path.splitext(ctx.path())
+pre = "%s~%s." % (os.path.basename(fullbase), prefix)
+(fd, name) = tempfile.mkstemp(prefix=pre, suffix=ext)
 data = repo.wwritedata(ctx.path(), ctx.data())
 f = os.fdopen(fd, "wb")
 f.write(data)
diff --git a/tests/test-merge-tools.t b/tests/test-merge-tools.t
--- a/tests/test-merge-tools.t
+++ b/tests/test-merge-tools.t
@@ -1209,3 +1209,15 @@ internal merge cannot handle symlinks an
   [1]
 
 #endif
+
+Verify naming of temporary files and that extension is preserved:
+
+  $ hg update -q -C 1
+  $ hg mv f f.txt
+  $ hg ci -qm "f.txt"
+  $ hg update -q -C 2
+  $ hg merge -y -r tip --tool echo --config merge-tools.echo.args='$base 
$local $other $output'
+  merging f and f.txt to f.txt
+  */f~base.?? $TESTTMP/f.txt.orig */f~other.??.txt $TESTTMP/f.txt 
(glob)
+  0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH shelve-ext] shelve: make --keep option survive user intevention (issue5431)

2016-11-23 Thread Mateusz Kwapich
One less footgun in unshelve. Nice!

Excerpts from Kostia Balytskyi's message of 2016-11-23 10:51:47 -0800:
> diff --git a/hgext/shelve.py b/hgext/shelve.py
> --- a/hgext/shelve.py
> +++ b/hgext/shelve.py
> @@ -782,6 +787,7 @@ def _dounshelve(ui, repo, *shelved, **op
>  
>  try:
>  state = shelvedstate.load(repo)
> +opts['keep'] = opts.get('keep') or state.keep
>  except IOError as err:
>  if err.errno != errno.ENOENT:
>  raise
Respecting the "hg unshelve --continue --keep" while ignoring the
"hg unshelve --continue --no-keep" seems confusing to me. Either
we should always respoect the options provided to continue or we
should make them invalid.

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


[PATCH shelve-ext] shelve: make --keep option survive user intevention (issue5431)

2016-11-23 Thread Kostia Balytskyi
# HG changeset patch
# User Kostia Balytskyi 
# Date 1479926825 28800
#  Wed Nov 23 10:47:05 2016 -0800
# Node ID 90b1e0d3e7daaf489428e0b9028cd7b32f37ea70
# Parent  db897ddf3a8ebb8df9556ce97de11f6380a9ef0b
shelve: make --keep option survive user intevention (issue5431)

Currently if user runs 'hg unshelve --keep' and merge conflicts
occur, the information about --keep provided by user is lost and
shelf is deleted after 'hg unshelve --continue'. This is obviously
not desired, so this patch fixes it.

diff --git a/hgext/shelve.py b/hgext/shelve.py
--- a/hgext/shelve.py
+++ b/hgext/shelve.py
@@ -159,6 +159,8 @@ class shelvedstate(object):
 """
 _version = 1
 _filename = 'shelvedstate'
+_keep = 'keep'
+_nokeep = 'nokeep'
 
 @classmethod
 def load(cls, repo):
@@ -175,6 +177,7 @@ class shelvedstate(object):
 parents = [nodemod.bin(h) for h in fp.readline().split()]
 stripnodes = [nodemod.bin(h) for h in fp.readline().split()]
 branchtorestore = fp.readline().strip()
+keep = fp.readline().strip() == cls._keep
 except (ValueError, TypeError) as err:
 raise error.CorruptedState(str(err))
 finally:
@@ -188,6 +191,7 @@ class shelvedstate(object):
 obj.parents = parents
 obj.stripnodes = stripnodes
 obj.branchtorestore = branchtorestore
+obj.keep = keep
 except error.RepoLookupError as err:
 raise error.CorruptedState(str(err))
 
@@ -195,7 +199,7 @@ class shelvedstate(object):
 
 @classmethod
 def save(cls, repo, name, originalwctx, pendingctx, stripnodes,
- branchtorestore):
+ branchtorestore, keep=False):
 fp = repo.vfs(cls._filename, 'wb')
 fp.write('%i\n' % cls._version)
 fp.write('%s\n' % name)
@@ -206,6 +210,7 @@ class shelvedstate(object):
 fp.write('%s\n' %
  ' '.join([nodemod.hex(n) for n in stripnodes]))
 fp.write('%s\n' % branchtorestore)
+fp.write('%s\n' % (cls._keep if keep else cls._nokeep))
 fp.close()
 
 @classmethod
@@ -680,7 +685,7 @@ def _rebaserestoredcommit(ui, repo, opts
 stripnodes = [repo.changelog.node(rev)
   for rev in xrange(oldtiprev, len(repo))]
 shelvedstate.save(repo, basename, pctx, tmpwctx, stripnodes,
-  branchtorestore)
+  branchtorestore, opts.get('keep'))
 
 util.rename(repo.join('rebasestate'),
 repo.join('unshelverebasestate'))
@@ -782,6 +787,7 @@ def _dounshelve(ui, repo, *shelved, **op
 
 try:
 state = shelvedstate.load(repo)
+opts['keep'] = opts.get('keep') or state.keep
 except IOError as err:
 if err.errno != errno.ENOENT:
 raise
diff --git a/tests/test-shelve.t b/tests/test-shelve.t
--- a/tests/test-shelve.t
+++ b/tests/test-shelve.t
@@ -1622,3 +1622,31 @@ progress
   abort: no unshelve in progress
   [255]
   $ cd ..
+
+Unshelve respects --keep even if user intervention is needed
+  $ hg init unshelvekeep
+  $ echo 1 > file && hg ci -Am 1
+  adding file
+  $ echo 2 >> file
+  $ hg shelve
+  shelved as default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo 3 >> file && hg ci -Am 13
+  $ hg shelve --list
+  default (1s ago)changes to: 1
+  $ hg unshelve --keep
+  unshelving change 'default'
+  rebasing shelved changes
+  rebasing 3:1d24e58054c8 "changes to: 1" (tip)
+  merging file
+  warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
+  unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
+  [1]
+  $ hg resolve --mark file
+  (no more unresolved files)
+  continue: hg unshelve --continue
+  $ hg unshelve --continue
+  rebasing 3:1d24e58054c8 "changes to: 1" (tip)
+  unshelve of 'default' complete
+  $ hg shelve --list
+  default (1s ago)changes to: 1
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 08 of 10] repair: migrate revlogs during upgrade

2016-11-23 Thread Augie Fackler

> On Nov 23, 2016, at 10:36 AM, Pierre-Yves David 
>  wrote:
> 
> Silly idea: We could add a "requirement" to the repository while doing this. 
> So that reading client would just be rejected (in most case) with a proper 
> message while this happens.

I like it. Maybe something like ‘upgradingrepo=$PID’ so then we can help users 
figure out if the upgrade crashed.


signature.asc
Description: Message signed with OpenPGP using GPGMail
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH v2] censor: flag internal documentation

2016-11-23 Thread Remi Chaintron
# HG changeset patch
# User Remi Chaintron 
# Date 1479922595 0
#  Wed Nov 23 17:36:35 2016 +
# Branch stable
# Node ID 24bcb76c5e6633e740f7dcec8f1ca96b06bcc536
# Parent  819f96b82fa4c4c6d07840a2b180d112b524103f
censor: flag internal documentation

diff --git a/mercurial/help/internals/revlogs.txt 
b/mercurial/help/internals/revlogs.txt
--- a/mercurial/help/internals/revlogs.txt
+++ b/mercurial/help/internals/revlogs.txt
@@ -88,7 +88,8 @@
 0-5 (6 bytes)
Absolute offset of revision data from beginning of revlog.
 6-7 (2 bytes)
-   Bit flags impacting revision behavior.
+   Bit flags impacting revision behavior. The following bit offsets define:
+   0: 'censor' extension flag.
 8-11 (4 bytes)
Compressed length of revision data / chunk as stored in revlog.
 12-15 (4 bytes)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 5 v4] changegroup3: enable on 'lfs' repo requirements

2016-11-23 Thread Remi Chaintron
# HG changeset patch
# User Remi Chaintron 
# Date 1479916365 0
#  Wed Nov 23 15:52:45 2016 +
# Branch stable
# Node ID b421c16161aed491fec20b600df5f1278b07bc1a
# Parent  75ee4746c198f039a39400e855e9335afc34f1dd
changegroup3: enable on 'lfs' repo requirements

`changegroup3` is required by the `lfs` extension in order to send flags for
revlog objects over the wire.

diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py
--- a/mercurial/changegroup.py
+++ b/mercurial/changegroup.py
@@ -879,14 +879,16 @@
 # Changegroup versions that can be applied to the repo
 def supportedincomingversions(repo):
 versions = allsupportedversions(repo.ui)
-if 'treemanifest' in repo.requirements:
+if ('treemanifest' in repo.requirements or
+'lfs' in repo.requirements):
 versions.add('03')
 return versions
 
 # Changegroup versions that can be created from the repo
 def supportedoutgoingversions(repo):
 versions = allsupportedversions(repo.ui)
-if 'treemanifest' in repo.requirements:
+if ('treemanifest' in repo.requirements or
+'lfs' in repo.requirements):
 # Versions 01 and 02 support only flat manifests and it's just too
 # expensive to convert between the flat manifest and tree manifest on
 # the fly. Since tree manifests are hashed differently, all of history
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -238,7 +238,7 @@
 class localrepository(object):
 
 supportedformats = set(('revlogv1', 'generaldelta', 'treemanifest',
-'manifestv2'))
+'manifestv2', 'lfs'))
 _basesupported = supportedformats | set(('store', 'fncache', 'shared',
  'dotencode'))
 openerreqs = set(('revlogv1', 'generaldelta', 'treemanifest', 
'manifestv2'))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 1 of 5 v4] revlog: merge hash checking subfunctions

2016-11-23 Thread Remi Chaintron
# HG changeset patch
# User Remi Chaintron 
# Date 1479916365 0
#  Wed Nov 23 15:52:45 2016 +
# Branch stable
# Node ID e908dd63d485424df4c4a4482b742d82652e2893
# Parent  24bcb76c5e6633e740f7dcec8f1ca96b06bcc536
revlog: merge hash checking subfunctions

This patch factors the behavior of both methods into 'checkhash' and returns the
text in order to allow subclasses of revlog and extensions to extend hash
computation and handle hash mismatches.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -861,7 +861,7 @@
 def dohash(text):
 if not cache:
 r.clearcaches()
-r._checkhash(text, node, rev)
+r.checkhash(text, node, rev=rev)
 
 def dorevision():
 if not cache:
diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py
--- a/mercurial/bundlerepo.py
+++ b/mercurial/bundlerepo.py
@@ -147,7 +147,7 @@
 delta = self._chunk(chain.pop())
 text = mdiff.patches(text, [delta])
 
-self._checkhash(text, node, rev)
+self.checkhash(text, node, rev=rev)
 self._cache = (node, rev, text)
 return text
 
diff --git a/mercurial/filelog.py b/mercurial/filelog.py
--- a/mercurial/filelog.py
+++ b/mercurial/filelog.py
@@ -104,9 +104,9 @@
 
 return True
 
-def checkhash(self, text, p1, p2, node, rev=None):
+def checkhash(self, text, node, p1=None, p2=None, rev=None):
 try:
-super(filelog, self).checkhash(text, p1, p2, node, rev=rev)
+super(filelog, self).checkhash(text, node, p1=p1, p2=p2, rev=rev)
 except error.RevlogError:
 if _censoredtext(text):
 raise error.CensoredNodeError(self.indexfile, node, text)
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -1221,9 +1221,7 @@
 bins = bins[1:]
 
 text = mdiff.patches(text, bins)
-
-text = self._checkhash(text, node, rev)
-
+self.checkhash(text, node, rev=rev)
 self._cache = (node, rev, text)
 return text
 
@@ -1235,12 +1233,14 @@
 """
 return hash(text, p1, p2)
 
-def _checkhash(self, text, node, rev):
-p1, p2 = self.parents(node)
-self.checkhash(text, p1, p2, node, rev)
-return text
+def checkhash(self, text, node, p1=None, p2=None, rev=None):
+"""Check node hash integrity.
 
-def checkhash(self, text, p1, p2, node, rev=None):
+Available as a function so that subclasses can extend hash mismatch
+behaviors as needed.
+"""
+if p1 is None and p2 is None:
+p1, p2 = self.parents(node)
 if node != self.hash(text, p1, p2):
 revornode = rev
 if revornode is None:
@@ -1415,7 +1415,7 @@
 basetext = self.revision(self.node(baserev), _df=fh)
 btext[0] = mdiff.patch(basetext, delta)
 try:
-self.checkhash(btext[0], p1, p2, node)
+self.checkhash(btext[0], node, p1=p1, p2=p2)
 if flags & REVIDX_ISCENSORED:
 raise RevlogError(_('node %s is not censored') % node)
 except CensoredNodeError:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 5 v4] revlog: add flagprocessor

2016-11-23 Thread Remi Chaintron
# HG changeset patch
# User Remi Chaintron 
# Date 1479916365 0
#  Wed Nov 23 15:52:45 2016 +
# Branch stable
# Node ID eb24cc60a279d614b3181a84464200bbcf5f6bb4
# Parent  e908dd63d485424df4c4a4482b742d82652e2893
revlog: add flagprocessor

Add a mechanism for extensions/subclasses of revlog to register transforms on
revlog operations, based on the revision flags.
Due to some operations being non-commutative, transforms applied in a specific
order when writing the contents of the revlog need to be applied in the reverse
order when reading.
In order to allow the composition of such operations, the flagprocessor applies
flags in the stable order defined by REVIDX_FLAGS_PROCESSING_ORDER constant.

Due to the fact storing flags on the server side might not be enabled, the
flagprocessor class also handles the case when no flags are set. In such a case,
it defers to enabled extensions to register default transformations and use
heuristics to determine what to do with the observed contents.

diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py
--- a/mercurial/bundlerepo.py
+++ b/mercurial/bundlerepo.py
@@ -147,7 +147,9 @@
 delta = self._chunk(chain.pop())
 text = mdiff.patches(text, [delta])
 
-self.checkhash(text, node, rev=rev)
+text, validatehash = self.processflags(node, text, self.flags(rev))
+if validatehash is True:
+self.checkhash(text, node, rev=rev)
 self._cache = (node, rev, text)
 return text
 
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -56,6 +56,10 @@
 REVIDX_ISCENSORED = (1 << 15) # revision has censor metadata, must be verified
 REVIDX_DEFAULT_FLAGS = 0
 REVIDX_KNOWN_FLAGS = REVIDX_ISCENSORED
+# stable order in which flags need to be processed by the flagprocessor
+REVIDX_FLAGS_PROCESSING_ORDER = [
+REVIDX_ISCENSORED,
+]
 
 # max size of revlog with inline data
 _maxinline = 131072
@@ -76,6 +80,76 @@
 
 _nullhash = hashlib.sha1(nullid)
 
+class flagprocessor(object):
+"""process revlog objects contents based on flags
+
+flagprocessor objects are the interface between revlog objects and
+subclasses/extensions needing to change or update the contents of revlog
+objects, based on flags.
+
+The role of the flagprocessor is to apply transforms registered by
+extensions and revlog subclasses in the order defined by
+REVIDX_FLAGS_PROCESSING_ORDER and the type (read or write) of operation.
+This allows the flag processor to modify the contents of revlog objects and
+handle the composition of non-commutative operations.
+"""
+
+def __init__(self, revlogobject):
+self.transformmap = {}
+self.revlogobject = revlogobject
+
+def register(self, transformmap):
+"""Register transforms to be applied for flags.
+
+``transformmap`` - a map of flag to transform
+"""
+for flag in transformmap:
+if flag in REVIDX_FLAGS_PROCESSING_ORDER:
+self.transformmap[flag] = transformmap[flag]
+
+def unregister(self, transformmap):
+"""Unregister transforms for flags."""
+for flag in transformmap:
+if flag in REVIDX_FLAGS_PROCESSING_ORDER:
+self.transformmap[flag] = None
+
+def processflags(self, node, text, revisionflags, reverse=False):
+"""Process flags and apply registered transforms.
+
+``node`` - the noideid of revision
+``text`` - the revision data to process
+``revisionflags`` - the flags applied to the revision
+``reverse`` - an optional argument describing whether the flags should
+  be processed in order according to the ``flagprocessor`` flag
+  priority. The flags should be processed in order of priority when
+  reading revisions, and in reverse order when writing revisions.
+
+Returns a 2-tuple of ``(text, validatehash)`` where ``text`` is the
+processed text and ``validatehash`` is a bool indicating whether the
+returned text should be checked for hash integrity.
+"""
+validatehash = True
+
+# Depending on the operation (read or write), the order might be
+# reversed due to non-commutative transforms.
+orderedflags = REVIDX_FLAGS_PROCESSING_ORDER
+if reverse is True:
+orderedflags = reversed(orderedflags)
+
+for flag in orderedflags:
+# If a transform has been registered for a known flag, apply it and
+# update the result tuple.
+# If no flag is set but transforms have been registered, it is
+# assumed that the repository does not send flags over the wire and
+# the extensions implement heuristics to determine what to do based
+# on the contents of the filelog.
+if flag & revisionflags or revisionflags == REVIDX_DEFAULT_FLAGS:
+

[PATCH 4 of 5 v4] revlog: REVIDX_ISLARGEFILE flag

2016-11-23 Thread Remi Chaintron
# HG changeset patch
# User Remi Chaintron 
# Date 1479922644 0
#  Wed Nov 23 17:37:24 2016 +
# Branch stable
# Node ID 75ee4746c198f039a39400e855e9335afc34f1dd
# Parent  da91f91e979d6bf807912e956cf2f29573ede56f
revlog: REVIDX_ISLARGEFILE flag

Add the REVIDX_ISLARGEFILE flag for the `lfs` extension to interact with
revisions by registering transforms in the flagprocessor.

diff --git a/mercurial/help/internals/revlogs.txt 
b/mercurial/help/internals/revlogs.txt
--- a/mercurial/help/internals/revlogs.txt
+++ b/mercurial/help/internals/revlogs.txt
@@ -90,6 +90,7 @@
 6-7 (2 bytes)
Bit flags impacting revision behavior. The following bit offsets define:
0: 'censor' extension flag.
+   1: 'lfs' extension flag.
 8-11 (4 bytes)
Compressed length of revision data / chunk as stored in revlog.
 12-15 (4 bytes)
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -54,11 +54,13 @@
 
 # revlog index flags
 REVIDX_ISCENSORED = (1 << 15) # revision has censor metadata, must be verified
+REVIDX_ISLARGEFILE = (1 << 14)
 REVIDX_DEFAULT_FLAGS = 0
-REVIDX_KNOWN_FLAGS = REVIDX_ISCENSORED
+REVIDX_KNOWN_FLAGS = REVIDX_ISCENSORED | REVIDX_ISLARGEFILE
 # stable order in which flags need to be processed by the flagprocessor
 REVIDX_FLAGS_PROCESSING_ORDER = [
 REVIDX_ISCENSORED,
+REVIDX_ISLARGEFILE,
 ]
 
 # max size of revlog with inline data
@@ -1773,6 +1775,10 @@
 """Check if a file revision is censored."""
 return False
 
+def islargefile(self, rev):
+"""Check if a file revision is flagged as large."""
+return self.flags(rev) & REVIDX_ISLARGEFILE
+
 def _peek_iscensored(self, baserev, delta, flush):
 """Quickly check if a delta produces a censored revision."""
 return False
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 8 of 8 chgtocore] chgserver: make it a core module and drop extension flags

2016-11-23 Thread Pierre-Yves David



On 11/23/2016 04:33 PM, Jun Wu wrote:

This series look good to me. Thanks for the clean up!
I'll continue my chg work on top of this.


This looks great, I've pushed it.

Thanks Jun for the review, this significantly lowered the latency of my 
review.


Cheers,



Excerpts from Yuya Nishihara's message of 2016-11-23 01:00:01 +0900:

# HG changeset patch
# User Yuya Nishihara 
# Date 1476509416 -32400
#  Sat Oct 15 14:30:16 2016 +0900
# Node ID fd00c0d94a008dd533b99d15873320ee7e8c7286
# Parent  c0640366366cf076e2641ae53948be0770154611
chgserver: make it a core module and drop extension flags

It was an extension just because there were several dependency cycles I
needed to address.

I don't add 'chgserver' to extensions._builtin since chgserver is considered
an internal extension so nobody should enable it by their config.

diff --git a/contrib/chg/Makefile b/contrib/chg/Makefile
--- a/contrib/chg/Makefile
+++ b/contrib/chg/Makefile
@@ -40,7 +40,6 @@ serve:
 [ -d $(CHGSOCKDIR) ] || ( umask 077; mkdir $(CHGSOCKDIR) )
 $(HG) serve --cwd / --cmdserver chgunix \
 --address $(CHGSOCKNAME) \
---config extensions.chgserver= \
 --config cmdserver.log=/dev/stderr

 .PHONY: clean
diff --git a/contrib/chg/chg.c b/contrib/chg/chg.c
--- a/contrib/chg/chg.c
+++ b/contrib/chg/chg.c
@@ -225,7 +225,6 @@ static void execcmdserver(const struct c
 "--cmdserver", "chgunix",
 "--address", opts->sockname,
 "--daemon-postexec", "chdir:/",
-"--config", "extensions.chgserver=",
 };
 size_t baseargvsize = sizeof(baseargv) / sizeof(baseargv[0]);
 size_t argsize = baseargvsize + opts->argsize + 1;
diff --git a/hgext/chgserver.py b/mercurial/chgserver.py
rename from hgext/chgserver.py
rename to mercurial/chgserver.py
--- a/hgext/chgserver.py
+++ b/mercurial/chgserver.py
@@ -5,7 +5,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.

-"""command server extension for cHg (EXPERIMENTAL)
+"""command server extension for cHg

 'S' channel (read/write)
 propagate ui.system() request to client
@@ -50,24 +50,17 @@ import struct
 import sys
 import time

-from mercurial.i18n import _
+from .i18n import _

-from mercurial import (
+from . import (
 cmdutil,
 commandserver,
 error,
 extensions,
 osutil,
-server,
 util,
 )

-# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' 
for
-# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
-# be specifying the version(s) of Mercurial they are tested with, or
-# leave the attribute unspecified.
-testedwith = 'ships-with-hg-core'
-
 _log = commandserver.log

 def _hashlist(items):
@@ -123,7 +116,7 @@ def _getmtimepaths(ui):
 """
 modules = [m for n, m in extensions.extensions(ui)]
 try:
-from mercurial import __version__
+from . import __version__
 modules.append(__version__)
 except ImportError:
 pass
@@ -179,7 +172,7 @@ class hashstate(object):

 # copied from hgext/pager.py:uisetup()
 def _setuppagercmd(ui, options, cmd):
-from mercurial import commands  # avoid cycle
+from . import commands  # avoid cycle

 if not ui.formatted():
 return
@@ -260,7 +253,7 @@ def _newchgui(srcui, csystem):
 return chgui(srcui)

 def _loadnewui(srcui, args):
-from mercurial import dispatch  # avoid cycle
+from . import dispatch  # avoid cycle

 newui = srcui.__class__()
 for a in ['fin', 'fout', 'ferr', 'environ']:
@@ -268,10 +261,6 @@ def _loadnewui(srcui, args):
 if util.safehasattr(srcui, '_csystem'):
 newui._csystem = srcui._csystem

-# internal config: extensions.chgserver
-newui.setconfig('extensions', 'chgserver',
-srcui.config('extensions', 'chgserver'), '--config')
-
 # command line args
 args = args[:]
 dispatch._parseconfig(newui, dispatch._earlygetopt(['--config'], args))
@@ -441,7 +430,7 @@ class chgcmdserver(commandserver.server)
 list, the client can continue with this server after completing all
 the instructions.
 """
-from mercurial import dispatch  # avoid cycle
+from . import dispatch  # avoid cycle

 args = self._readlist()
 try:
@@ -490,7 +479,7 @@ class chgcmdserver(commandserver.server)
 If pager isn't enabled, this writes '\0' because channeledoutput
 does not allow to write empty data.
 """
-from mercurial import dispatch  # avoid cycle
+from . import dispatch  # avoid cycle

 args = self._readlist()
 try:
@@ -645,6 +634,3 @@ def chgunixservice(ui, repo, opts):
 ui.setconfig('bundle', 'mainreporoot', '', 'repo')
 h = chgunixservicehandler(ui)
 return commandserver.unixforkingservice(ui, repo=None, opts=opts, 
handler=h)
-
-def uisetup(ui):
-

Re: [PATCH] censor: flag internal documentation

2016-11-23 Thread Pierre-Yves David



On 11/23/2016 04:43 PM, Remi Chaintron wrote:

# HG changeset patch
# User Remi Chaintron 
# Date 1479915779 0
#  Wed Nov 23 15:42:59 2016 +
# Branch stable
# Node ID f9ec5cd22586138cdcf5cfebc88f1bcba41a2a20
# Parent  819f96b82fa4c4c6d07840a2b180d112b524103f
censor: flag internal documentation

diff --git a/mercurial/help/internals/revlogs.txt 
b/mercurial/help/internals/revlogs.txt
--- a/mercurial/help/internals/revlogs.txt
+++ b/mercurial/help/internals/revlogs.txt
@@ -88,7 +88,9 @@
 0-5 (6 bytes)
Absolute offset of revision data from beginning of revlog.
 6-7 (2 bytes)
-   Bit flags impacting revision behavior.
+   Bit flags impacting revision behavior. The following bit offsets define:
+   0
+  'censor' extension flag.


The formating is a bit strange here, it seems like it is matching the 
outer layer formatting but it seems less necessary for this 1 digit 
data. Is there any formal reason we need it this way? Or could we move 
to "0: 'censor' flag"



 8-11 (4 bytes)
Compressed length of revision data / chunk as stored in revlog.
 12-15 (4 bytes)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel



--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 2] debugcommands: introduce standalone module for debug commands

2016-11-23 Thread Pierre-Yves David



On 11/10/2016 06:50 PM, Gregory Szorc wrote:

I started this series a few months ago, told Pierre-Yves about it, and
he encouraged me to start patchbombing.

While I haven't completed the work, the remainder of what I've started
can be pulled from
https://hg.mozilla.org/users/gszorc_mozilla.com/hg/rev/916144fdac95. I
don't plan on patchbombing the rest, as I don't want to be distracted
from other work.


I've pushed 5 more of these move. I'll keep pushing small piece of it 
from time to time.


Cheers,

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: Fixing .hg file open ordering

2016-11-23 Thread Bryan O'Sullivan
Yep, your reasoning here makes sense. While I'm glad that you discovered
after some investigation that we're doing the right thing already, it's a
little troubling that this wasn't easy to understand from reading the code,
and that (from my interpretation of what you wrote) you had to think and
rethink your reading a couple of times to figure out what was going on.
Sounds a bit like a latent future bug, doesn't it?

On Tue, Nov 22, 2016 at 12:19 PM, Ryan McElroy  wrote:

> I think that fixing the read open ordering is not sufficient.
>
> I was just chatting with Jun Wu (quark) about this, and after that
> discussion, it seems that we also have to ensure the write order is
> correct. Specifically, bookmarks must be written only after the changelog
> is written, otherwise, regardless of the order that we open files for read,
> we can have a bookmarks file that points to commits that no reader can see
> yet.
>
> Based on a very quick look at the transaction code, it looks like
> filegenerators in transactions are stored in a dict, so we have no
> guarantees about what order they will be called in, so it's very likely
> that we often call the write of the bookmarks file before the write of the
> changelog, making it so that no read-side fix alone can be sufficient to
> solve this problem.
>
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 03 of 10] commands: stub for debugupgraderepo command

2016-11-23 Thread Pierre-Yves David



On 11/22/2016 06:15 AM, Gregory Szorc wrote:



On Mon, Nov 21, 2016 at 6:05 PM, Pierre-Yves David
>
wrote:



On 11/06/2016 05:40 AM, Gregory Szorc wrote:

# HG changeset patch
# User Gregory Szorc >
# Date 1478391613 25200
#  Sat Nov 05 17:20:13 2016 -0700
# Node ID 9daec9c7adabe8c84cf2c01fc938e010ee4884d6
# Parent  ed3241d8b00e476818ff1aec3db0136bf960de35
commands: stub for debugupgraderepo command

Currently, if Mercurial introduces a new repository/store feature or
changes behavior of an existing feature, users must perform an
`hg clone` to create a new repository with hopefully the
correct/optimal settings. Unfortunately, even `hg clone` may not
give the correct results. For example, if you do a local `hg clone`,
you may get hardlinks to revlog files that inherit the old state.
If you `hg clone` from a remote or `hg clone --pull`, changegroup
application may bypass some optimization, such as converting to
generaldelta.

Optimizing a repository is harder than it seems and requires more
than a simple `hg` command invocation.

This patch starts the process of changing that. We introduce
`hg debugupgraderepo`, a command that performs an in-place upgrade
of a repository to use new, optimal features. The command is just
a stub right now. Features will be added in subsequent patches.


I had a similar series in progress which a slightly different
naming/behavior.

* 'hg debugformat' list details about the current repository format
(and possible upgrade)

* 'hg debugformat --upgrade' performs actual upgrade (more on this
in the next patch)

I'm not saying you should restart your whole series to match this,
but I'll most probably submit a rename proposal to match the above
once this is in.


TBH, I'm not a fan of "debugformat." The main reason is "format" isn't
exactly unambiguous: it can mean several things from deleting all data
(i.e. "formatting a disk") to UI presentation options. If I weren't
aware that the [format] config section existed, I'd have no clue that
"format" referred to the on-disk repository "format."


As I know the "format" config for a long time, the "debugformat" name 
was natural to me. I'm not sure how the naming is important, user are 
not really expected to go hunting for debug command themselve, and if 
they do a proper help is probably enough. I won't have a too strong 
opinion about the name but I see a good feedback cycle between 
"debugformat" and "[format]" knowing/finding one help to find the other.



I think having "upgrade" in the name is beneficial because it says what
the command does ("upgrade" the repository to a new and more modern
format). That being said, I would be open to the idea of naming it
"debugreformat." That "re" there is important: it tells a user not
familiar with the "format" terminology that it changes something.


I would expect mentioning "upgrade" in the first line of the help (shown 
by `hg help debug`) to be enough. "reformat" reads a bit strange to me 
but that could be a good middle ground. (Also, I'm not a native speaker)



Another thing I like about your proposal is that `hg debugformat` is
read-only by default. While I typically don't like commands that are
both read-only and perform modifications, I think "upgrade/format" is
special enough that it really should require positive affirmation /
consent before doing anything. So I think I'll change the behavior in V2
to print possible upgrades by default and only take action if a flag is
specified. I'll have to think a bit more about this...


I think the ability to access what is the current format of various 
repositories will be really useful. This will allow inventory of 
existing repositories to better plan the upgrades.


Looking forward for your V2!

Cheers,

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 3 of 5 v3] revlog: pass flags to addrevision

2016-11-23 Thread Remi Chaintron
# HG changeset patch
# User Remi Chaintron 
# Date 1479916365 0
#  Wed Nov 23 15:52:45 2016 +
# Branch stable
# Node ID 2b21a1071ab3003f9ce145620e0e888d41742b80
# Parent  f45a31268675da806e7f9569b569aec8fefb29d5
revlog: pass flags to addrevision

Add the ability to pass known revision flags to `revlog.addrevision`. This
allows to ensure present flags are propagated and usable by the extensions
relying on the flagprocessor, such as `lfs`.

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -1401,7 +1401,7 @@
 self._chunkclear()
 
 def addrevision(self, text, transaction, link, p1, p2, cachedelta=None,
-node=None):
+node=None, flags=REVIDX_DEFAULT_FLAGS):
 """add a revision to the log
 
 text - the revision data to add
@@ -1412,6 +1412,7 @@
 node - nodeid of revision; typically node is not specified, and it is
 computed by default as hash(text, p1, p2), however subclasses might
 use different hashing method (and override checkhash() in such 
case)
+flags - the known flags to set on the revision
 """
 if link == nullrev:
 raise RevlogError(_("attempted to add linkrev -1 to %s")
@@ -1432,7 +1433,7 @@
 ifh = self.opener(self.indexfile, "a+", checkambig=self._checkambig)
 try:
 return self._addrevision(node, text, transaction, link, p1, p2,
- REVIDX_DEFAULT_FLAGS, cachedelta, ifh, 
dfh)
+ flags, cachedelta, ifh, dfh)
 finally:
 if dfh:
 dfh.close()
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 5 v3] changegroup3: enable on 'lfs' repo requirements

2016-11-23 Thread Remi Chaintron
# HG changeset patch
# User Remi Chaintron 
# Date 1479916365 0
#  Wed Nov 23 15:52:45 2016 +
# Branch stable
# Node ID ee76def8400e7003daca04dd0985af77cc925348
# Parent  1d0b60b267fabedc683bd53a880abc0b8e75badb
changegroup3: enable on 'lfs' repo requirements

`changegroup3` is required by the `lfs` extension in order to send flags for
revlog objects over the wire.

diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py
--- a/mercurial/changegroup.py
+++ b/mercurial/changegroup.py
@@ -879,14 +879,16 @@
 # Changegroup versions that can be applied to the repo
 def supportedincomingversions(repo):
 versions = allsupportedversions(repo.ui)
-if 'treemanifest' in repo.requirements:
+if ('treemanifest' in repo.requirements or
+'lfs' in repo.requirements):
 versions.add('03')
 return versions
 
 # Changegroup versions that can be created from the repo
 def supportedoutgoingversions(repo):
 versions = allsupportedversions(repo.ui)
-if 'treemanifest' in repo.requirements:
+if ('treemanifest' in repo.requirements or
+'lfs' in repo.requirements):
 # Versions 01 and 02 support only flat manifests and it's just too
 # expensive to convert between the flat manifest and tree manifest on
 # the fly. Since tree manifests are hashed differently, all of history
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -238,7 +238,7 @@
 class localrepository(object):
 
 supportedformats = set(('revlogv1', 'generaldelta', 'treemanifest',
-'manifestv2'))
+'manifestv2', 'lfs'))
 _basesupported = supportedformats | set(('store', 'fncache', 'shared',
  'dotencode'))
 openerreqs = set(('revlogv1', 'generaldelta', 'treemanifest', 
'manifestv2'))
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 5 v3] revlog: REVIDX_ISLARGEFILE flag

2016-11-23 Thread Remi Chaintron
# HG changeset patch
# User Remi Chaintron 
# Date 1479917845 0
#  Wed Nov 23 16:17:25 2016 +
# Branch stable
# Node ID 1d0b60b267fabedc683bd53a880abc0b8e75badb
# Parent  2b21a1071ab3003f9ce145620e0e888d41742b80
revlog: REVIDX_ISLARGEFILE flag

Add the REVIDX_ISLARGEFILE flag for the `lfs` extension to interact with
revisions by registering transforms in the flagprocessor.

diff --git a/mercurial/help/internals/revlogs.txt 
b/mercurial/help/internals/revlogs.txt
--- a/mercurial/help/internals/revlogs.txt
+++ b/mercurial/help/internals/revlogs.txt
@@ -91,6 +91,8 @@
Bit flags impacting revision behavior. The following bit offsets define:
0
   'censor' extension flag.
+   1
+  'lfs' extension flag.
 8-11 (4 bytes)
Compressed length of revision data / chunk as stored in revlog.
 12-15 (4 bytes)
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -54,11 +54,13 @@
 
 # revlog index flags
 REVIDX_ISCENSORED = (1 << 15) # revision has censor metadata, must be verified
+REVIDX_ISLARGEFILE = (1 << 14)
 REVIDX_DEFAULT_FLAGS = 0
-REVIDX_KNOWN_FLAGS = REVIDX_ISCENSORED
+REVIDX_KNOWN_FLAGS = REVIDX_ISCENSORED | REVIDX_ISLARGEFILE
 # stable order in which flags need to be processed by the flagprocessor
 REVIDX_FLAGS_PROCESSING_ORDER = [
 REVIDX_ISCENSORED,
+REVIDX_ISLARGEFILE,
 ]
 
 # max size of revlog with inline data
@@ -1773,6 +1775,10 @@
 """Check if a file revision is censored."""
 return False
 
+def islargefile(self, rev):
+"""Check if a file revision is flagged as large."""
+return self.flags(rev) & REVIDX_ISLARGEFILE
+
 def _peek_iscensored(self, baserev, delta, flush):
 """Quickly check if a delta produces a censored revision."""
 return False
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 5 v3] revlog: add flagprocessor

2016-11-23 Thread Remi Chaintron
# HG changeset patch
# User Remi Chaintron 
# Date 1479916365 0
#  Wed Nov 23 15:52:45 2016 +
# Branch stable
# Node ID f45a31268675da806e7f9569b569aec8fefb29d5
# Parent  fe4fefc6aba95f613dba4ebff3abd38205fdd74f
revlog: add flagprocessor

Add a mechanism for extensions/subclasses of revlog to register transforms on
revlog operations, based on the revision flags.
Due to some operations being non-commutative, transforms applied in a specific
order when writing the contents of the revlog need to be applied in the reverse
order when reading.
In order to allow the composition of such operations, the flagprocessor applies
flags in the stable order defined by REVIDX_FLAGS_PROCESSING_ORDER constant.

Due to the fact storing flags on the server side might not be enabled, the
flagprocessor class also handles the case when no flags are set. In such a case,
it defers to enabled extensions to register default transformations and use
heuristics to determine what to do with the observed contents.

diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py
--- a/mercurial/bundlerepo.py
+++ b/mercurial/bundlerepo.py
@@ -147,7 +147,9 @@
 delta = self._chunk(chain.pop())
 text = mdiff.patches(text, [delta])
 
-self.checkhash(text, node, rev=rev)
+text, validatehash = self.processflags(node, text, self.flags(rev))
+if validatehash is True:
+self.checkhash(text, node, rev=rev)
 self._cache = (node, rev, text)
 return text
 
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -56,6 +56,10 @@
 REVIDX_ISCENSORED = (1 << 15) # revision has censor metadata, must be verified
 REVIDX_DEFAULT_FLAGS = 0
 REVIDX_KNOWN_FLAGS = REVIDX_ISCENSORED
+# stable order in which flags need to be processed by the flagprocessor
+REVIDX_FLAGS_PROCESSING_ORDER = [
+REVIDX_ISCENSORED,
+]
 
 # max size of revlog with inline data
 _maxinline = 131072
@@ -76,6 +80,76 @@
 
 _nullhash = hashlib.sha1(nullid)
 
+class flagprocessor(object):
+"""process revlog objects contents based on flags
+
+flagprocessor objects are the interface between revlog objects and
+subclasses/extensions needing to change or update the contents of revlog
+objects, based on flags.
+
+The role of the flagprocessor is to apply transforms registered by
+extensions and revlog subclasses in the order defined by
+REVIDX_FLAGS_PROCESSING_ORDER and the type (read or write) of operation.
+This allows the flag processor to modify the contents of revlog objects and
+handle the composition of non-commutative operations.
+"""
+
+def __init__(self, revlogobject):
+self.transformmap = {}
+self.revlogobject = revlogobject
+
+def register(self, transformmap):
+"""Register transforms to be applied for flags.
+
+``transformmap`` - a map of flag to transform
+"""
+for flag in transformmap:
+if flag in REVIDX_FLAGS_PROCESSING_ORDER:
+self.transformmap[flag] = transformmap[flag]
+
+def unregister(self, transformmap):
+"""Unregister transforms for flags."""
+for flag in transformmap:
+if flag in REVIDX_FLAGS_PROCESSING_ORDER:
+self.transformmap[flag] = None
+
+def processflags(self, node, text, revisionflags, reverse=False):
+"""Process flags and apply registered transforms.
+
+``node`` - the noideid of revision
+``text`` - the revision data to process
+``revisionflags`` - the flags applied to the revision
+``reverse`` - an optional argument describing whether the flags should
+  be processed in order according to the ``flagprocessor`` flag
+  priority. The flags should be processed in order of priority when
+  reading revisions, and in reverse order when writing revisions.
+
+Returns a 2-tuple of ``(text, validatehash)`` where ``text`` is the
+processed text and ``validatehash`` is a bool indicating whether the
+returned text should be checked for hash integrity.
+"""
+validatehash = True
+
+# Depending on the operation (read or write), the order might be
+# reversed due to non-commutative transforms.
+orderedflags = REVIDX_FLAGS_PROCESSING_ORDER
+if reverse is True:
+orderedflags = reversed(orderedflags)
+
+for flag in orderedflags:
+# If a transform has been registered for a known flag, apply it and
+# update the result tuple.
+# If no flag is set but transforms have been registered, it is
+# assumed that the repository does not send flags over the wire and
+# the extensions implement heuristics to determine what to do based
+# on the contents of the filelog.
+if flag & revisionflags or revisionflags == REVIDX_DEFAULT_FLAGS:
+

[PATCH 1 of 5 v3] revlog: merge hash checking subfunctions

2016-11-23 Thread Remi Chaintron
# HG changeset patch
# User Remi Chaintron 
# Date 1479916365 0
#  Wed Nov 23 15:52:45 2016 +
# Branch stable
# Node ID fe4fefc6aba95f613dba4ebff3abd38205fdd74f
# Parent  f9ec5cd22586138cdcf5cfebc88f1bcba41a2a20
revlog: merge hash checking subfunctions

This patch factors the behavior of both methods into 'checkhash' and returns the
text in order to allow subclasses of revlog and extensions to extend hash
computation and handle hash mismatches.

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -861,7 +861,7 @@
 def dohash(text):
 if not cache:
 r.clearcaches()
-r._checkhash(text, node, rev)
+r.checkhash(text, node, rev=rev)
 
 def dorevision():
 if not cache:
diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py
--- a/mercurial/bundlerepo.py
+++ b/mercurial/bundlerepo.py
@@ -147,7 +147,7 @@
 delta = self._chunk(chain.pop())
 text = mdiff.patches(text, [delta])
 
-self._checkhash(text, node, rev)
+self.checkhash(text, node, rev=rev)
 self._cache = (node, rev, text)
 return text
 
diff --git a/mercurial/filelog.py b/mercurial/filelog.py
--- a/mercurial/filelog.py
+++ b/mercurial/filelog.py
@@ -104,9 +104,9 @@
 
 return True
 
-def checkhash(self, text, p1, p2, node, rev=None):
+def checkhash(self, text, node, p1=None, p2=None, rev=None):
 try:
-super(filelog, self).checkhash(text, p1, p2, node, rev=rev)
+super(filelog, self).checkhash(text, node, p1=p1, p2=p2, rev=rev)
 except error.RevlogError:
 if _censoredtext(text):
 raise error.CensoredNodeError(self.indexfile, node, text)
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -1221,9 +1221,7 @@
 bins = bins[1:]
 
 text = mdiff.patches(text, bins)
-
-text = self._checkhash(text, node, rev)
-
+self.checkhash(text, node, rev=rev)
 self._cache = (node, rev, text)
 return text
 
@@ -1235,12 +1233,14 @@
 """
 return hash(text, p1, p2)
 
-def _checkhash(self, text, node, rev):
-p1, p2 = self.parents(node)
-self.checkhash(text, p1, p2, node, rev)
-return text
+def checkhash(self, text, node, p1=None, p2=None, rev=None):
+"""Check node hash integrity.
 
-def checkhash(self, text, p1, p2, node, rev=None):
+Available as a function so that subclasses can extend hash mismatch
+behaviors as needed.
+"""
+if p1 is None and p2 is None:
+p1, p2 = self.parents(node)
 if node != self.hash(text, p1, p2):
 revornode = rev
 if revornode is None:
@@ -1415,7 +1415,7 @@
 basetext = self.revision(self.node(baserev), _df=fh)
 btext[0] = mdiff.patch(basetext, delta)
 try:
-self.checkhash(btext[0], p1, p2, node)
+self.checkhash(btext[0], node, p1=p1, p2=p2)
 if flags & REVIDX_ISCENSORED:
 raise RevlogError(_('node %s is not censored') % node)
 except CensoredNodeError:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH evolve-ext] evolve: improve error message if unstable changes are disallowed

2016-11-23 Thread Mateusz Kwapich
Excerpts from Pulkit Goyal's message of 2016-11-23 21:06:29 +0530:
> # HG changeset patch
> # User Pulkit Goyal <7895pul...@gmail.com>
> # Date 1479915042 -19800
> #  Wed Nov 23 21:00:42 2016 +0530
> # Node ID 32083f1f0c67341e5b4c22e880b70ccc4e0fc088
> # Parent  cb2bac3253fbd52894ffcb4719a148fe6a3da38b
> evolve: improve error message if unstable changes are disallowed
> 
> I saw a question on stackoverflow why evolve reports something like cannot
> fold chain not ending with head. Even I was confused the first time about the
> behavior. The error message can be improved to avoid confusion to people who
> are unaware about the config in future.

That sounds like a very useful information. It sucks that the errors
have newlines in them. I think we can avoid it - see my inline comments.

> 
> diff -r cb2bac3253fb -r 32083f1f0c67 hgext/evolve.py
> --- a/hgext/evolve.pyWed Nov 02 18:56:44 2016 +0100
> +++ b/hgext/evolve.pyWed Nov 23 21:00:42 2016 +0530
> @@ -2514,7 +2514,8 @@
>  raise error.Abort('nothing to prune')
>  
>  if _disallowednewunstable(repo, revs):
> -raise error.Abort(_("cannot prune in the middle of a stack"))
> +raise error.Abort(_("cannot prune in the middle of a stack\n"\
> +"new unstable changesets are not allowed"))
This error doesn't have hint - maybe we could use it for that purpose.
>  
>  # defines successors changesets
>  sucs = scmutil.revrange(repo, succs)
> @@ -3234,7 +3235,8 @@
>  newunstable = _disallowednewunstable(repo, revs)
>  if newunstable:
>  raise error.Abort(
> -_('cannot edit commit information in the middle of a 
> stack'),
> +_('cannot edit commit information in the middle of a 
> stack\n'\
> +'new unstable changesets are not allowed'),
>  hint=_('%s will be affected') % 
> repo[newunstable.first()])
I would change the hint to say something along:
'%s would become unstable but new unstable commits are not allowed'
>  root = head = repo[revs.first()]
>  
> @@ -3299,7 +3301,8 @@
>  head = repo[heads.first()]
>  if _disallowednewunstable(repo, revs):
>  raise error.Abort(_("cannot fold chain not ending with a head "\
> -"or with branching"))
> +"or with branching\nnew unstable changesets are"\
> +" not allowed"))
I would move this to hint param.
>  return root, head
>  
>  def _disallowednewunstable(repo, revs):
> diff -r cb2bac3253fb -r 32083f1f0c67 tests/test-evolve.t
> --- a/tests/test-evolve.tWed Nov 02 18:56:44 2016 +0100
> +++ b/tests/test-evolve.tWed Nov 23 21:00:42 2016 +0530
> @@ -1301,9 +1301,11 @@
>created new head
>$ hg prune '26 + 27'
>abort: cannot prune in the middle of a stack
> +  new unstable changesets are not allowed
>[255]
>$ hg prune '19::28'
>abort: cannot prune in the middle of a stack
> +  new unstable changesets are not allowed
>[255]
>$ hg prune '26::'
>3 changesets pruned
> @@ -1338,9 +1340,11 @@
>  
>$ hg fold --exact "19 + 18"
>abort: cannot fold chain not ending with a head or with branching
> +  new unstable changesets are not allowed
>[255]
>$ hg fold --exact "18::29"
>abort: cannot fold chain not ending with a head or with branching
> +  new unstable changesets are not allowed
>[255]
>$ hg fold --exact "19::"
>2 changesets folded
> @@ -1483,10 +1487,12 @@
>  check that metaedit respects allowunstable
>$ hg metaedit '.^' --config 'experimental.evolution=createmarkers, 
> allnewcommands'
>abort: cannot edit commit information in the middle of a stack
> +  new unstable changesets are not allowed
>(c904da5245b0 will be affected)
>[255]
>$ hg metaedit '18::20' --fold --config 
> 'experimental.evolution=createmarkers, allnewcommands'
>abort: cannot fold chain not ending with a head or with branching
> +  new unstable changesets are not allowed
>[255]
>$ hg metaedit --user foobar
>0 files updated, 0 files merged, 0 files removed, 0 files unresolved

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


Re: [PATCH 01 of 10 layering] dirstateguard: move to new module so I can break some layering violations

2016-11-23 Thread Augie Fackler

> On Nov 22, 2016, at 09:09, Yuya Nishihara  wrote:
> 
> On Mon, 21 Nov 2016 22:05:16 -0500, Augie Fackler wrote:
>> # HG changeset patch
>> # User Augie Fackler 
>> # Date 1479781772 18000
>> #  Mon Nov 21 21:29:32 2016 -0500
>> # Node ID 459f26a431fe7d04f7f935ccf46a3aec66956d84
>> # Parent  c84baff8c3d45579fc0cb03492ced5c8f745749c
>> dirstateguard: move to new module so I can break some layering violations
>> 
>> Recently in a review I noticed that localrepo almost has no reason to
>> import cmdutil anymore. Also, cmdutil is a little on the enormous
>> side, so breaking this class out strikes me as a win.
> 
> I'm not super excited about the new dirstateguard module, but the overall
> changes are great. So queued these, thanks.
> 
>> diff --git a/mercurial/cmdutil.py b/mercurial/dirstateguard.py
>> copy from mercurial/cmdutil.py
>> copy to mercurial/dirstateguard.py
>> --- a/mercurial/cmdutil.py
>> +++ b/mercurial/dirstateguard.py
> 
> Is copy-and-remove a preferred way for this kind of refactoring? I have
> an unsent patch that splits revset.py, so I want to know which is better.

I'd prefer it slightly, because it makes the blame history a little bit more 
intact in the long run.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: Can we automatically recognize when we should be fulfilling our deprecation promsie?

2016-11-23 Thread Augie Fackler

> On Nov 22, 2016, at 23:35, timeless  wrote:
> 
> Augie Fackler wrote:
>> We said we'd delete this after 3.8. It's time.
>> -ui.deprecwarn("missing attribute '%s', use @command decorator "
>> -  "to register '%s'" % (attr, cmd), '3.8')
> 
> It feels like we should be able to have a test which complains if we
> have deprecwarns for version X and our version is > X.
> 
> Offhand, I think it should probably be of the form:
> 
> $ magic $(hg version)
> found the following deprecation warnings which are acceptable as of 4.0:
> ...
> 
> When $(hg version) changes to 4.1, the output would change to only
> list items expiring after 4.1, thus changing the output, and any
> things that are from 4.0 but wouldn't be tolerated by 4.1 wouldn't be
> printed, and would thus disappear from the output and trigger a test
> failure.

Yep, I agree this should be doable, but I haven't had the time or motivation to 
do so. It's probably easiest to just do with a new item on the release 
checklist, as most deprecations are removing a forwarding method.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 04 of 10] repair: identify repository deficiencies

2016-11-23 Thread Pierre-Yves David



On 11/22/2016 07:02 AM, Gregory Szorc wrote:

On Mon, Nov 21, 2016 at 6:14 PM, Pierre-Yves David
>
wrote:

On 11/06/2016 05:40 AM, Gregory Szorc wrote:

# HG changeset patch
# User Gregory Szorc >
# Date 1478382332 25200
#  Sat Nov 05 14:45:32 2016 -0700
# Node ID 7518e68e2f8276e85fb68174b3055a9dd16c665d
# Parent  9daec9c7adabe8c84cf2c01fc938e010ee4884d6
repair: identify repository deficiencies

A command that upgrades repositories but doesn't say what it is
doing
or why it is doing it is less helpful than a command that does. So,
we start the implementation of repository upgrades by introducing
detection of sub-optimal repository state. Deficiencies with the
existing repository are now printed at the beginning of command
execution.

The added function returns a set of planned upgrade actions. This
variable will be used by subsequent patches.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3756,7 +3756,7 @@ def debugupgraderepo(ui, repo, **opts):

 At times during the upgrade, the repository may not be
readable.
 """
-raise error.Abort(_('not yet implemented'))
+return repair.upgraderepo(ui, repo, dryrun=opts.get('dry_run'))

 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'),
inferrepo=True)
 def debugwalk(ui, repo, *pats, **opts):
diff --git a/mercurial/repair.py b/mercurial/repair.py
--- a/mercurial/repair.py
+++ b/mercurial/repair.py
@@ -360,3 +360,57 @@ def deleteobsmarkers(obsstore, indices):
 newobsstorefile.write(bytes)
 newobsstorefile.close()
 return n
+
+def upgradefinddeficiencies(repo):
+"""Obtain deficiencies with the existing repo and planned
actions to fix.
+
+Returns a list of strings that will be printed to the user
and a set
+of machine-readable actions that will be acted on later.
+"""
+l = []
+actions = set()
+
+# We could detect lack of revlogv1 and store here, but they
were added
+# in 0.9.2 and we don't support upgrading repos without these
+# requirements, so let's not bother.
+
+if 'fncache' not in repo.requirements:
+l.append(_('not using fncache; long and reserved
filenames '
+   'may not work correctly'))



notes: I like the idea of explaining the benefit of each upgrade.

+actions.add('fncache')
+
+if 'dotencode' not in repo.requirements:
+l.append(_('not using dotencode; filenames beginning with '
+   'a period or space may not work correctly'))
+actions.add('dotencode')
+
+if 'generaldelta' not in repo.requirements:
+l.append(_('not using generaldelta storage; repository
is larger '
+   'and slower than it could be, pulling from '
+   'generaldelta repositories will be slow'))
+actions.add('generaldelta')
+
+cl = repo.changelog
+for rev in cl:
+chainbase = cl.chainbase(rev)
+if chainbase != rev:
+l.append(_('changelog using delta chains; changelog
reading '
+   'is slower than it could be'))
+actions.add('removecldeltachain')
+break
+
+return l, actions


At some point we probably needs this to be extensible for extension
to be able to extend the list of format variant detection. But this
can come later.


I kinda bent over backwards in this series to isolate each step to its
own function explicitly so extensions could inject code at the
appropriate point. I'm not too worried about this not being extensible :)


My experience is that extensions writter always end up having baroque 
needs like inserting themself between two steps or collaborating with 
others wrapper. This led to the current paranoid setup seen in 
exchange.py. This is probably less critical for format upgrade as less 
people will touch it but I would encourage you to consider it anyway.



This version if performing unconditional upgrade of all features.
Will be quite unhandy in some case (eg: cohabitation with older
versions, experimental format, etc). The approach have been using on
my side was to use three points of data for each variants:

  

Re: [PATCH 2 of 2 V2] rebase: calculate ancestors for --base separately (issue5420)

2016-11-23 Thread Pierre-Yves David



On 11/19/2016 02:40 AM, Augie Fackler wrote:

On Thu, Nov 17, 2016 at 11:49:58PM +, Jun Wu wrote:

# HG changeset patch
# User Jun Wu 
# Date 1479426495 0
#  Thu Nov 17 23:48:15 2016 +
# Node ID e5451a607d1ca53b2446ab049375e5dd5a055bb8
# Parent  87e0edc93d87b88e2925877469d8c142e01737fc
# Available At https://bitbucket.org/quark-zju/hg-draft
#  hg pull https://bitbucket.org/quark-zju/hg-draft -r e5451a607d1c
rebase: calculate ancestors for --base separately (issue5420)


These are queued, thanks.


I'm a bit concerned about the lack of test covering situation with merge 
commit. There could be pathological case lurking there. I'll try to a 
have a deeper look at what this change imply is that case before giving 
it a second accept stamp.



Previously, the --base option only works with a single "branch" - if there
are multiple branching points, "rebase" will error out with:

  abort: source is ancestor of destination

This happens if the user has multiple draft branches with different
branching points, and uses "hg rebase -b 'draft()' -d master". The error
message looks cryptic to users who don't know the implementation detail.

This patch changes the logic to calculate ancestors for each "base" branch
so it would work in the multiple branching points case.

Note: if there are multiple bases where some of them are rebasable, while
some of them aren't because the branching point is the destination, the
current behavior is to abort with "nothing to rebase", which seems wrong.
However, that issue is not introduced by this patch - it exists for "-s" as
well. I have reported it as issue5422 and should be solved separately.

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -722,10 +722,17 @@ def _definesets(ui, repo, destf=None, sr
 destf = str(dest)

-commonanc = repo.revs('ancestor(%ld, %d)', base, dest).first()
-if commonanc is not None:
-rebaseset = repo.revs('(%d::(%ld) - %d)::',
-  commonanc, base, commonanc)
-else:
-rebaseset = []
+# calculate ancestors for individual bases
+realbases = []
+for b in repo.revs('roots(%ld)', base):
+# branching point
+bp = repo.revs('ancestor(%d, %d)', b, dest).first()
+if bp is None:
+continue
+# move b to be the direct child of the branching point
+b = repo.revs('%d::%d - %d', bp, b, bp).first()
+if b is not None:
+realbases.append(b)
+
+rebaseset = repo.revs('%ld::', realbases)

 if not rebaseset:
diff --git a/tests/test-rebase-base.t b/tests/test-rebase-base.t
new file mode 100644
--- /dev/null
+++ b/tests/test-rebase-base.t
@@ -0,0 +1,94 @@
+  $ cat >> $HGRCPATH < [extensions]
+  > rebase=
+  > drawdag=$TESTDIR/drawdag.py
+  >
+  > [phases]
+  > publish=False
+  >
+  > [alias]
+  > tglog = log -G --template "{rev}: {desc}"
+  > EOF
+
+  $ hg init a
+  $ cd a
+
+  $ hg debugdrawdag < g f
+  > |/
+  > e c d
+  > | |/
+  > | b
+  > |/
+  > a
+  > EOS
+
+  $ cd ..
+
+Pick a single base:
+
+  $ cp -a a a1 && cd a1
+  $ hg rebase -b c -d g -q
+  $ hg tglog
+  o  6: d
+  |
+  | o  5: c
+  |/
+  o  4: b
+  |
+  o  3: g
+  |
+  | o  2: f
+  |/
+  o  1: e
+  |
+  o  0: a
+
+  $ cd ..
+
+Pick a base that is already an descendant of dest:
+
+  $ cp -a a a2 && cd a2
+  $ hg rebase -b g -d e
+  nothing to rebase
+  [1]
+  $ hg rebase -b d -d a
+  nothing to rebase
+  [1]
+  $ hg rebase -b d+c+f+e -d a
+  nothing to rebase
+  [1]
+  $ cd ..
+
+Pick multiple bases (issue5420):
+
+  $ cp -a a a3 && cd a3
+  $ hg rebase -b d+f -d g -q
+  $ hg tglog
+  o  6: f
+  |
+  | o  5: d
+  | |
+  | | o  4: c
+  | |/
+  | o  3: b
+  |/
+  o  2: g
+  |
+  o  1: e
+  |
+  o  0: a
+
+  $ cd ..
+
+Mixed rebasable and non-rebasable bases (unresolved, issue5422):
+
+  $ cp -a a a4 && cd a4
+  $ hg debugdrawdag < h
+  > |
+  > g
+  > EOS
+  $ hg rebase -b d+f+h -d g
+  nothing to rebase
+  [1]
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

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



--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 10 of 10] repair: clean up stale lock file from store backup

2016-11-23 Thread Pierre-Yves David



On 11/22/2016 04:09 AM, Augie Fackler wrote:



On Nov 21, 2016, at 9:27 PM, Pierre-Yves David  
wrote:



On 11/06/2016 05:40 AM, Gregory Szorc wrote:

# HG changeset patch
# User Gregory Szorc 
# Date 1478392394 25200
#  Sat Nov 05 17:33:14 2016 -0700
# Node ID 0e130e8d2156d9f2523c711ef4fefe4ba33e6818
# Parent  3d4dd237b705479f8c7475b821ae719893381fa8
repair: clean up stale lock file from store backup

So inline comment for reasons.

diff --git a/mercurial/repair.py b/mercurial/repair.py
--- a/mercurial/repair.py
+++ b/mercurial/repair.py
@@ -716,6 +716,12 @@ def _upgraderepo(ui, srcrepo, dstrepo, r
ui.write(_('store replacement complete; repository was inconsistent for '
   '%0.1fs\n') % elapsed)

+# The lock file from the old store won't be removed because nothing has a
+# reference to its new location. So clean it up manually. Alternatively, we
+# could update srcrepo.svfs and other variables to point to the new
+# location. This is simpler.
+backupvfs.unlink('store/lock')


I think I get why we need to clean the old lock, however I'm not sure how the 
rest of the old store directory get handled ? Why do we need a special case for 
the lock file itself?


He’s built up a new store directory over the course of _upgradrepo, and then does `mv 
store store.old && mv store.new store` (conceptually) once the upgrade process 
is done.


Okay, the part which failed to connect in my head was the fact we were 
keeping the old data around (but we want to nuke the irrelevant lock 
file within it). There does not seems to be any message about this old 
data remaining in the repository. We should probably informs the user so 
that he can avoid having a twice as big repository after the upgrade.


Cheers,

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH] censor: flag internal documentation

2016-11-23 Thread Remi Chaintron
# HG changeset patch
# User Remi Chaintron 
# Date 1479915779 0
#  Wed Nov 23 15:42:59 2016 +
# Branch stable
# Node ID f9ec5cd22586138cdcf5cfebc88f1bcba41a2a20
# Parent  819f96b82fa4c4c6d07840a2b180d112b524103f
censor: flag internal documentation

diff --git a/mercurial/help/internals/revlogs.txt 
b/mercurial/help/internals/revlogs.txt
--- a/mercurial/help/internals/revlogs.txt
+++ b/mercurial/help/internals/revlogs.txt
@@ -88,7 +88,9 @@
 0-5 (6 bytes)
Absolute offset of revision data from beginning of revlog.
 6-7 (2 bytes)
-   Bit flags impacting revision behavior.
+   Bit flags impacting revision behavior. The following bit offsets define:
+   0
+  'censor' extension flag.
 8-11 (4 bytes)
Compressed length of revision data / chunk as stored in revlog.
 12-15 (4 bytes)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] help: clarify contents of revlog index

2016-11-23 Thread Pierre-Yves David



On 11/23/2016 03:13 AM, Gregory Szorc wrote:

# HG changeset patch
# User Gregory Szorc 
# Date 1479867182 28800
#  Tue Nov 22 18:13:02 2016 -0800
# Node ID 96679cda009dfad247dc50013165d08093dc2737
# Parent  01d8600955ccbc8cd53db2c1613ec7c3f7913ee2
help: clarify contents of revlog index


This one is pushed, thanks.

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH evolve-ext] evolve: improve error message if unstable changes are disallowed

2016-11-23 Thread Pulkit Goyal
# HG changeset patch
# User Pulkit Goyal <7895pul...@gmail.com>
# Date 1479915042 -19800
#  Wed Nov 23 21:00:42 2016 +0530
# Node ID 32083f1f0c67341e5b4c22e880b70ccc4e0fc088
# Parent  cb2bac3253fbd52894ffcb4719a148fe6a3da38b
evolve: improve error message if unstable changes are disallowed

I saw a question on stackoverflow why evolve reports something like cannot
fold chain not ending with head. Even I was confused the first time about the
behavior. The error message can be improved to avoid confusion to people who
are unaware about the config in future.

diff -r cb2bac3253fb -r 32083f1f0c67 hgext/evolve.py
--- a/hgext/evolve.py   Wed Nov 02 18:56:44 2016 +0100
+++ b/hgext/evolve.py   Wed Nov 23 21:00:42 2016 +0530
@@ -2514,7 +2514,8 @@
 raise error.Abort('nothing to prune')
 
 if _disallowednewunstable(repo, revs):
-raise error.Abort(_("cannot prune in the middle of a stack"))
+raise error.Abort(_("cannot prune in the middle of a stack\n"\
+"new unstable changesets are not allowed"))
 
 # defines successors changesets
 sucs = scmutil.revrange(repo, succs)
@@ -3234,7 +3235,8 @@
 newunstable = _disallowednewunstable(repo, revs)
 if newunstable:
 raise error.Abort(
-_('cannot edit commit information in the middle of a 
stack'),
+_('cannot edit commit information in the middle of a 
stack\n'\
+'new unstable changesets are not allowed'),
 hint=_('%s will be affected') % repo[newunstable.first()])
 root = head = repo[revs.first()]
 
@@ -3299,7 +3301,8 @@
 head = repo[heads.first()]
 if _disallowednewunstable(repo, revs):
 raise error.Abort(_("cannot fold chain not ending with a head "\
-"or with branching"))
+"or with branching\nnew unstable changesets are"\
+" not allowed"))
 return root, head
 
 def _disallowednewunstable(repo, revs):
diff -r cb2bac3253fb -r 32083f1f0c67 tests/test-evolve.t
--- a/tests/test-evolve.t   Wed Nov 02 18:56:44 2016 +0100
+++ b/tests/test-evolve.t   Wed Nov 23 21:00:42 2016 +0530
@@ -1301,9 +1301,11 @@
   created new head
   $ hg prune '26 + 27'
   abort: cannot prune in the middle of a stack
+  new unstable changesets are not allowed
   [255]
   $ hg prune '19::28'
   abort: cannot prune in the middle of a stack
+  new unstable changesets are not allowed
   [255]
   $ hg prune '26::'
   3 changesets pruned
@@ -1338,9 +1340,11 @@
 
   $ hg fold --exact "19 + 18"
   abort: cannot fold chain not ending with a head or with branching
+  new unstable changesets are not allowed
   [255]
   $ hg fold --exact "18::29"
   abort: cannot fold chain not ending with a head or with branching
+  new unstable changesets are not allowed
   [255]
   $ hg fold --exact "19::"
   2 changesets folded
@@ -1483,10 +1487,12 @@
 check that metaedit respects allowunstable
   $ hg metaedit '.^' --config 'experimental.evolution=createmarkers, 
allnewcommands'
   abort: cannot edit commit information in the middle of a stack
+  new unstable changesets are not allowed
   (c904da5245b0 will be affected)
   [255]
   $ hg metaedit '18::20' --fold --config 
'experimental.evolution=createmarkers, allnewcommands'
   abort: cannot fold chain not ending with a head or with branching
+  new unstable changesets are not allowed
   [255]
   $ hg metaedit --user foobar
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 08 of 10] repair: migrate revlogs during upgrade

2016-11-23 Thread Pierre-Yves David



On 11/06/2016 05:40 AM, Gregory Szorc wrote:

# HG changeset patch
# User Gregory Szorc 
# Date 1478393405 25200
#  Sat Nov 05 17:50:05 2016 -0700
# Node ID d2261c558ca9639fb81c182de15d75151cbad0f9
# Parent  958bcf2577608bbb6d8ae078cde0ca451f3ab31a
repair: migrate revlogs during upgrade

Our next step for in-place upgrade is to migrate store data. Revlogs
are the biggest source of data within the store and a store is useless
without them, so we implement their migration first.

Our strategy for migrating revlogs is to walk the store and call
`revlog.copy()` on each revlog. There are some minor complications.

Because revlogs have different storage options (e.g. changelog has
generaldelta and delta chains disabled), we need to obtain the
correct class of revlog so inserted data is encoded properly for its
type.

Because manifests are converted after filelogs and because manifest
conversion can take a long time when large manifests are in play,
a naive progress bar for revlog count was misleading, as it effectively
got to 99% and froze there when processing the manifest. So, there is
a first pass to count revisions and use revisions in the progress bar.
The extra code is somewhat annoying. But this pass serves a secondary
useful purpose: ensuring we can open all revlogs that will be copied.
We don't want to spend several minutes copying revlogs only to
encounter a permissions error or some such later.

As part of this change, we also add swapping of the store directory
to the upgrade function. After revlogs are converted, we move the
old store into the backup directory then move the temporary repo's
store into the old store's location. On well-behaved systems, this
should be 2 atomic operations and the window of inconsistency show be
very narrow.


Silly idea: We could add a "requirement" to the repository while doing 
this. So that reading client would just be rejected (in most case) with 
a proper message while this happens.


--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 8 of 8 chgtocore] chgserver: make it a core module and drop extension flags

2016-11-23 Thread Jun Wu
This series look good to me. Thanks for the clean up!
I'll continue my chg work on top of this.

Excerpts from Yuya Nishihara's message of 2016-11-23 01:00:01 +0900:
> # HG changeset patch
> # User Yuya Nishihara 
> # Date 1476509416 -32400
> #  Sat Oct 15 14:30:16 2016 +0900
> # Node ID fd00c0d94a008dd533b99d15873320ee7e8c7286
> # Parent  c0640366366cf076e2641ae53948be0770154611
> chgserver: make it a core module and drop extension flags
> 
> It was an extension just because there were several dependency cycles I
> needed to address.
> 
> I don't add 'chgserver' to extensions._builtin since chgserver is considered
> an internal extension so nobody should enable it by their config.
> 
> diff --git a/contrib/chg/Makefile b/contrib/chg/Makefile
> --- a/contrib/chg/Makefile
> +++ b/contrib/chg/Makefile
> @@ -40,7 +40,6 @@ serve:
>  [ -d $(CHGSOCKDIR) ] || ( umask 077; mkdir $(CHGSOCKDIR) )
>  $(HG) serve --cwd / --cmdserver chgunix \
>  --address $(CHGSOCKNAME) \
> ---config extensions.chgserver= \
>  --config cmdserver.log=/dev/stderr
>  
>  .PHONY: clean
> diff --git a/contrib/chg/chg.c b/contrib/chg/chg.c
> --- a/contrib/chg/chg.c
> +++ b/contrib/chg/chg.c
> @@ -225,7 +225,6 @@ static void execcmdserver(const struct c
>  "--cmdserver", "chgunix",
>  "--address", opts->sockname,
>  "--daemon-postexec", "chdir:/",
> -"--config", "extensions.chgserver=",
>  };
>  size_t baseargvsize = sizeof(baseargv) / sizeof(baseargv[0]);
>  size_t argsize = baseargvsize + opts->argsize + 1;
> diff --git a/hgext/chgserver.py b/mercurial/chgserver.py
> rename from hgext/chgserver.py
> rename to mercurial/chgserver.py
> --- a/hgext/chgserver.py
> +++ b/mercurial/chgserver.py
> @@ -5,7 +5,7 @@
>  # This software may be used and distributed according to the terms of the
>  # GNU General Public License version 2 or any later version.
>  
> -"""command server extension for cHg (EXPERIMENTAL)
> +"""command server extension for cHg
>  
>  'S' channel (read/write)
>  propagate ui.system() request to client
> @@ -50,24 +50,17 @@ import struct
>  import sys
>  import time
>  
> -from mercurial.i18n import _
> +from .i18n import _
>  
> -from mercurial import (
> +from . import (
>  cmdutil,
>  commandserver,
>  error,
>  extensions,
>  osutil,
> -server,
>  util,
>  )
>  
> -# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' 
> for
> -# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
> -# be specifying the version(s) of Mercurial they are tested with, or
> -# leave the attribute unspecified.
> -testedwith = 'ships-with-hg-core'
> -
>  _log = commandserver.log
>  
>  def _hashlist(items):
> @@ -123,7 +116,7 @@ def _getmtimepaths(ui):
>  """
>  modules = [m for n, m in extensions.extensions(ui)]
>  try:
> -from mercurial import __version__
> +from . import __version__
>  modules.append(__version__)
>  except ImportError:
>  pass
> @@ -179,7 +172,7 @@ class hashstate(object):
>  
>  # copied from hgext/pager.py:uisetup()
>  def _setuppagercmd(ui, options, cmd):
> -from mercurial import commands  # avoid cycle
> +from . import commands  # avoid cycle
>  
>  if not ui.formatted():
>  return
> @@ -260,7 +253,7 @@ def _newchgui(srcui, csystem):
>  return chgui(srcui)
>  
>  def _loadnewui(srcui, args):
> -from mercurial import dispatch  # avoid cycle
> +from . import dispatch  # avoid cycle
>  
>  newui = srcui.__class__()
>  for a in ['fin', 'fout', 'ferr', 'environ']:
> @@ -268,10 +261,6 @@ def _loadnewui(srcui, args):
>  if util.safehasattr(srcui, '_csystem'):
>  newui._csystem = srcui._csystem
>  
> -# internal config: extensions.chgserver
> -newui.setconfig('extensions', 'chgserver',
> -srcui.config('extensions', 'chgserver'), '--config')
> -
>  # command line args
>  args = args[:]
>  dispatch._parseconfig(newui, dispatch._earlygetopt(['--config'], args))
> @@ -441,7 +430,7 @@ class chgcmdserver(commandserver.server)
>  list, the client can continue with this server after completing all
>  the instructions.
>  """
> -from mercurial import dispatch  # avoid cycle
> +from . import dispatch  # avoid cycle
>  
>  args = self._readlist()
>  try:
> @@ -490,7 +479,7 @@ class chgcmdserver(commandserver.server)
>  If pager isn't enabled, this writes '\0' because channeledoutput
>  does not allow to write empty data.
>  """
> -from mercurial import dispatch  # avoid cycle
> +from . import dispatch  # avoid cycle
>  
>  args = self._readlist()
>  try:
> @@ -645,6 +634,3 @@ def chgunixservice(ui, repo, opts):
>  ui.setconfig('bundle', 'mainreporoot', '', 'repo')
>  h = chgunixservicehandler(ui)
>  return 

Re: [PATCH 1 of 3 V2] cmdutil: add support for evolution "troubles" display in changeset_printer

2016-11-23 Thread Pierre-Yves David



On 11/16/2016 03:42 PM, Kevin Bullock wrote:

On Nov 10, 2016, at 09:47, Pierre-Yves David  
wrote:

On 11/08/2016 04:07 PM, Augie Fackler wrote:


I'm -0 on the word "troubles": it feels wrong in a way I'm having
trouble describing. It definitely feels odd to have a plural for the
label (the line for tags is "tag:" after all) - maybe "trouble:" would
be better?


Apparently the usage is to use singular even when there might be multiples (eg: bookmark, 
tag) so we should me to "trouble:"


(I'm very open to better word choices here than trouble, but I have
none to offer.)


As for the word "trouble", people have been voicing concern for about 5 years without significant 
counter-proposal, so I'm moving forward with that word. For my part, I'm not a native speaker and 
"trouble" works fine for me, exchanging mutable changeset can lead to some 
"unavoidable/intrinsic troubles".

Because anyway, Evolution is still an experimental feature and is therefor still subject 
to possible wording and feature changes. So this "trouble:" line could change 
in the future if someone eventually make progress here


I'm also not keen on 'troubles'. For this purpose, I'd suggest 'evolution:' by analogy to 
'bisect:'. That won't work for referring to the combined set of {divergences, bumps, 
...}, but for labelling "this changeset's evolution status" I think it works.


'Evolution' is an interesting proposal. It could be nice as generic 
terms in multiple place. However, we still need a proper terms to refer 
to "trouble" in the documentation/etc…. I do not feel like "evolution 
status" is appropriate. I do not see "status" appropriate for "a 0-n 
list of things" and, to me, it also fails to carry out the fact 
"trouble" are problems that needs to get fixed.


Cheers,

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 3 V2] cmdutil: add support for evolution "troubles" display in changeset_printer

2016-11-23 Thread Pierre-Yves David



On 11/14/2016 09:10 AM, Denis Laxalde wrote:

Pierre-Yves David a écrit :

How about "stability"? If it feels strange to only have it displayed
when there are "troubles", we may also insert it in the debug section as
`stability: stable`.


I do not think it is suitable, stability does not really fit for
"divergent" or "bumped" and too linked to "unstable"

In addition, trouble is really a list of 0-N element, "stable" have
nothing to do in it and imply a more binary "stable/unstable" mode.


Of course "stable" couldn't be listed as a trouble, but my proposal was
to introduce a term to qualify the stability state (or whatever you
prefer to name it) of a changeset. In other words, a changeset may be in
state that is either ""
or not. Having a name for this boolean state along with a name for the
not-troubled state would be useful in general I think.


We had something a bit similar as a template for a while (but not 
exactly that irc), this end up confusing people from Google more than 
bringing benefit so Martin and I scrapped it a couple of month back. We 
could give is a second "better" try if you have a good usecase at hand,


For now that would be "troubled/untroubled" until we find something better


I really advise we move forward with trouble and have naming
discussion on another thread/wiki page.


I'm fine with this as well. Will send a V2 with the singular "trouble"
label.


I saw your V4, I'll get to it.

--
Pierre-Yves David
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH RESEND] revert: do not reverse hunks in interactive when REV is not parent (issue5096)

2016-11-23 Thread Jun Wu
Excerpts from Martin von Zweigbergk's message of 2016-11-14 15:57:30 -0800:
> Pierre-Yves reached out and reminded me that he actually frequently
> uses "hg revert -i -r .~1" to undo changes since that commit. Also, I
> still personally feel that the people who want to undo changes since a
> revision and the people who want to get changes from a revision are
> thinking about it differently enough that they should be using
> different commands. I think it would be good if we could find good

There are other commands:
- For picking what should be undone: "hg uncommit -i"
- For picking what to kept: "hg split". (We can enhance it so it's possible
  to abort and drop the remaining changes)

Those commands sound more intuitive to me and could probably fit marmoute's
use-case.

> names for both of those operations. In my mind, "revert" is a good
> word for the former (i.e. undoing), and I'm not sure what's a good
> word for the latter (i.e. getting state from). It's still unclear to
> me if others were turned off mostly by my proposed name ("apply") or
> the idea of them being different operations.
> 
> I'll de-queue this patch for now, and we can talk (even) more about it :-/

An internal user just complained about the confusing behavior. I think an
easy change we would all agree is to make the curses UI to use the same verb
as the text UI does.

Before:

  SELECT CHUNKS:  toggle hunk/all; (e)dit hunk;
   (f)old/unfold; (c)onfirm applied; ... [X]=hunk applied 
^^^   ^^^
After:

  SELECT CHUNKS:  toggle hunk/all; (e)dit hunk;
   (f)old/unfold; (c)onfirm revert; ... [X]=hunk to revert 
^^   ^

If there is no objection, I could prepare the patch.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel