Re: [PATCH 3 of 3] revset: add a changes(file, fromline, toline[, rev]) revset

2016-12-01 Thread Denis Laxalde

Yuya Nishihara a écrit :

On Mon, 28 Nov 2016 11:12:35 +0100, Denis Laxalde wrote:

Denis Laxalde a écrit :

# HG changeset patch
# User Denis Laxalde 
# Date 1480086890 -3600
#  Fri Nov 25 16:14:50 2016 +0100
# Node ID e88a112076294d9b1639a486e7ef0ec9c1ffa660
# Parent  6dd93ae7b35002531308444c87dcf47beb773648
# EXP-Topic linerange-log/revset
revset: add a changes(file, fromline, toline[, rev]) revset


This is the first step of my work (in progress) about adding a "line
range" filtering for log discussed in
https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-October/088687.html.

I would have liked to add tests for this revset but it seems to me that
the current test repositories are not complex enough for this: I'd need
files with significant content and changes in this content. Any idea how
I could do this?


Maybe we can share some bits with test-annotate.t ?




Repositories in these are indeed more complex. So should I append tests
in this file or reproduce similar repositories in test-revset.t?
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 1 of 3] mdiff: add a "blocksinrange" function to filter diff blocks by line range

2016-12-01 Thread Denis Laxalde

Yuya Nishihara a écrit :

On Mon, 28 Nov 2016 10:54:14 +0100, Denis Laxalde wrote:

# HG changeset patch
# User Denis Laxalde 
# Date 1476279051 -7200
#  Wed Oct 12 15:30:51 2016 +0200
# Node ID 0cf70234a38e47a3f7107611885368db9d52f574
# Parent  342d0cb4f446826169a83a6e773f1c767e0c977b
# EXP-Topic linerange-log/revset
mdiff: add a "blocksinrange" function to filter diff blocks by line range


I haven't read this patch carefully, so I might misunderstand the algorithm.


diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py
--- a/mercurial/mdiff.py
+++ b/mercurial/mdiff.py
@@ -113,6 +113,45 @@ def splitblock(base1, lines1, base2, lin
 s1 = i1
 s2 = i2

+def blocksinrange(blocks, rangeb):
+"""yield ``block = (a1, a2, b1, b2), stype`` items of `blocks` that are
+inside `rangeb` from ``(b1, b2)`` point of view; a block ``(b1, b2)``
+being inside `rangeb` if ``rangeb[0] < b2 and b1 < rangeb[1]``.
+
+Compute `rangea` w.r.t. to ``(a1, a2)`` parts of `blocks`, and bind it to
+the final StopIteration exception.
+"""
+lbb, ubb = rangeb
+lba, uba = None, None
+for block in blocks:
+(a1, a2, b1, b2), stype = block
+if lbb >= b1 and ubb <= b2 and stype == '=':
+# rangeb is within a single "=" hunk, restrict back linerange1
+# by offsetting rangeb
+lba = lbb - b1 + a1
+uba = ubb - b1 + a1
+else:



+if lbb == ubb and b1 <= ubb < b2:
+# oneline range, within (b1, b2) block
+lba = a1
+uba = a2


I'm not sure if this special case is necessary and valid because the condition
"b1 <= ubb (== lbb) < b2" is slightly different from the other common cases.
I don't get why lbb == ubb is special.


According to the tests I introduced, this special case is useless.
(Probably a leftover of algorigthm development.)


+else:
+if b1 <= lbb < b2:
+if stype == '=':
+lba = a2 - (b2 - lbb)
+else:
+lba = a1
+if b1 < ubb <= b2:
+if stype == '=':
+uba = a1 + (ubb - b1)
+else:
+uba = a2
+if lbb < b2 and b1 < ubb:
+yield block


Style nit: I prefer elif over deeply nested if-else.


+if lba is None or uba is None or uba < lba:
+raise ValueError('out of range')
+raise StopIteration((lba, uba))


Is it common to carry values by StopIteration? If not, maybe this could be a
plain function which returns (blocks_in_rangeb, (lba, uba)).



This is what happens in Python 3 (PEP 380) when a generator returns a value.

I originally introduced this mechanism while attempting to propagate
this information up to patch.diff() (through mdiff.unidiff(), etc.) to
avoid making it a plain function (not a generator). Clearly this is not
useful in the scope of this patch set because blocks are always
consumed. So, since the other part of my work is not ready yet, I can
certainly avoid this pattern for now and eventually (re-)introduce it
later when it'd be needed.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 6 of 7] py3: use try/except to check for basestring

2016-12-01 Thread Pulkit Goyal
There is something strange. One of the patch you pushed and replied to
the mail is not the same.

On Wed, Nov 9, 2016 at 6:09 PM, Yuya Nishihara  wrote:
> On Tue, 8 Nov 2016 20:05:51 +0530, Pulkit Goyal wrote:
>> > Can you pick out good ones?
>> These ones!
>
> Pushed some of them, thanks.
>
>> https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-October/089096.html
>
> Already queued.
>
>> https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-October/089097.html
>> https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-October/089098.html
>> https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-October/089100.html
>
> Queued these.
>
>> https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-October/089103.html
>> - You can drop u'' there in flight
>
> Dropped per discussion.

I can't see the u'' dropped.
https://www.mercurial-scm.org/repo/hg-committed/rev/9df29b7c62cf
>
>> https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-October/089102.html
>
> Added comment.

I don't know what you mean here as this is not pushed.
>
>> https://www.mercurial-scm.org/pipermail/mercurial-devel/2016-October/089104.html
>
> Syntax error on Python 2.

But you pushed this one.
https://www.mercurial-scm.org/repo/hg-committed/rev/954002426f78.

I am unsure of whether the reply contained wrong links or you pushed
wrong ones. Let me know so that I can follow up accordingly.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: mercurial@30549: 7 new changesets

2016-12-01 Thread Kevin Bullock
> On Nov 30, 2016, at 01:39, Thomas Arendsen Hein  wrote:
> 
> Hi!
> 
> * Gregory Szorc  [20161130 04:53]:
>> Anyone know what process sends these emails? It would be nice to see the
>> URLs updated to point to https://www.mercurial-scm.org/repo/hg.
> 
> I generate them and just updated the URL.
> 
> Thank you for the reminder!

Thanks! I'd like to make it so that these come directly from the new main repo. 
Could I convince you to send me the [notify] configuration you use to do this?

pacem in terris / мир / शान्ति / ‎‫سَلاَم‬ / 平和
Kevin R. Bullock

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


[PATCH 8 of 8 V12] help: add documentation about bookmark part

2016-12-01 Thread Stanislau Hlebik
# HG changeset patch
# User Stanislau Hlebik 
# Date 1479807361 28800
#  Tue Nov 22 01:36:01 2016 -0800
# Node ID 261bc4a0670a47a8fbe8d633f19f92542be4790c
# Parent  dc34527b28959ef96a4e7b23430ad467b5fbf85e
help: add documentation about bookmark part

diff --git a/mercurial/help/internals/bundles.txt 
b/mercurial/help/internals/bundles.txt
--- a/mercurial/help/internals/bundles.txt
+++ b/mercurial/help/internals/bundles.txt
@@ -92,3 +92,32 @@
 ``HGS1UN`` support was added as an experimental feature in version 3.6
 (released November 2015) as part of the initial offering of the *clone
 bundles* feature.
+
+Bundle2 parts
+=
+
+Bundle2 may contain many different pieces of information. These pieces are
+called parts.
+
+Bookmarks part
+--
+
+This part contains information about bookmarks. Part consists of many entries.
+Each entry describes one bookmark. Entry format:
+
+4 bytes
+  bookmark size
+1 byte
+  boolean. True if node is empty, False otherwise
+20 bytes (optional)
+  node. Present only if previous field is True
+
+Modes:
+
+1. 'ignore' - do not apply any changes to the repo, just decode the passed
+bookmarks. Will be used to list bookmarks in remote repo.
+2. 'diverge' - apply bookmark changes to the repo. Create divergent bookmarks 
if
+there is a non-fastforward move. Will be used during pull.
+3. 'apply' - apply bookmark changes to the repo. Overwrite current bookmark 
node
+if there is a non-fastforward move. Will be used during push.
+
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 4 of 8 V12] bundle2: add `bookmarks` part handler

2016-12-01 Thread Stanislau Hlebik
# HG changeset patch
# User Stanislau Hlebik 
# Date 1479807361 28800
#  Tue Nov 22 01:36:01 2016 -0800
# Node ID 49d598a6db4b0fa63b7a30b55899caa0fa1f9c99
# Parent  81854771326941912a0dfd80f4f0c9d0191eea75
bundle2: add `bookmarks` part handler

Applies bookmarks part to the local repo. `processbookmarksmode` determines
how remote bookmarks are handled. They are either ignored ('ignore' mode),
diverged ('diverge' mode) or applied ('apply' mode).

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -155,6 +155,7 @@
 
 from .i18n import _
 from . import (
+bookmarks as bookmod,
 changegroup,
 error,
 obsolete,
@@ -287,13 +288,19 @@
 * a way to construct a bundle response when applicable.
 """
 
-def __init__(self, repo, transactiongetter, captureoutput=True):
+def __init__(self, repo, transactiongetter, captureoutput=True,
+ behavior=None):
+"""
+`behavior` is a dictionary that is passed to part handlers to tweak
+their behaviour
+"""
 self.repo = repo
 self.ui = repo.ui
 self.records = unbundlerecords()
 self.gettransaction = transactiongetter
 self.reply = None
 self.captureoutput = captureoutput
+self.behavior = behavior or {}
 
 class TransactionUnavailable(RuntimeError):
 pass
@@ -1616,3 +1623,35 @@
 
 cache.write()
 op.ui.debug('applied %i hgtags fnodes cache entries\n' % count)
+
+@parthandler('bookmarks')
+def handlebookmarks(op, inpart):
+"""Processes bookmarks part.
+
+`processbookmarksmode` determines how remote bookmarks are handled. They 
are
+either ignored ('ignore' mode), diverged ('diverge' mode) or applied
+('apply' mode). 'ignore' mode is used to get bookmarks and process them
+later, 'diverge' mode is used to process bookmarks during pull, 'apply'
+mode is used during push.
+"""
+
+bookmarks = bookmod.decodebookmarks(inpart.read())
+processbookmarksmode = op.behavior.get('processbookmarksmode', 'ignore')
+if processbookmarksmode == 'apply':
+for bookmark, node in bookmarks.items():
+if node:
+op.repo._bookmarks[bookmark] = node
+else:
+try:
+del op.repo._bookmarks[bookmark]
+except KeyError:
+# ignore if bookmark does not exist
+pass
+op.repo._bookmarks.recordchange(op.gettransaction())
+elif processbookmarksmode == 'diverge':
+remotepath = op.behavior.get('remotepath', '')
+explicitbookmarks = op.behavior.get('explicitbookmarks', ())
+bookmod.updatefromremote(op.ui, op.repo, bookmarks,
+ remotepath, op.gettransaction,
+ explicit=explicitbookmarks)
+op.records.add('bookmarks', bookmarks)
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 8 V12] bookmarks: rename `compare()` to `comparebookmarks()` (API)

2016-12-01 Thread Stanislau Hlebik
# HG changeset patch
# User Stanislau Hlebik 
# Date 1479807211 28800
#  Tue Nov 22 01:33:31 2016 -0800
# Node ID 0fd97a0c043a3f5c1d4ba050435d86e09dbd0f54
# Parent  d184b91890ae3cbd21f656847b6b2728892b2425
bookmarks: rename `compare()` to `comparebookmarks()` (API)

Next commit will remove optional parameters from `compare()` function.
Let's rename `compare()` to `comparebookmarks()` to avoid ambiguity from
callers from external extensions.

diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py
--- a/mercurial/bookmarks.py
+++ b/mercurial/bookmarks.py
@@ -391,8 +391,8 @@
 finally:
 lockmod.release(tr, l, w)
 
-def compare(repo, srcmarks, dstmarks,
-srchex=None, dsthex=None, targets=None):
+def comparebookmarks(repo, srcmarks, dstmarks,
+ srchex=None, dsthex=None, targets=None):
 '''Compare bookmarks between srcmarks and dstmarks
 
 This returns tuple "(addsrc, adddst, advsrc, advdst, diverge,
@@ -511,7 +511,7 @@
 ui.debug("checking for updated bookmarks\n")
 localmarks = repo._bookmarks
 (addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same
- ) = compare(repo, remotemarks, localmarks, dsthex=hex)
+ ) = comparebookmarks(repo, remotemarks, localmarks, dsthex=hex)
 
 status = ui.status
 warn = ui.warn
@@ -573,8 +573,8 @@
 '''
 ui.status(_("searching for changed bookmarks\n"))
 
-r = compare(repo, other.listkeys('bookmarks'), repo._bookmarks,
-dsthex=hex)
+r = comparebookmarks(repo, other.listkeys('bookmarks'), repo._bookmarks,
+ dsthex=hex)
 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
 
 incomings = []
@@ -615,8 +615,8 @@
 '''
 ui.status(_("searching for changed bookmarks\n"))
 
-r = compare(repo, repo._bookmarks, other.listkeys('bookmarks'),
-srchex=hex)
+r = comparebookmarks(repo, repo._bookmarks, other.listkeys('bookmarks'),
+ srchex=hex)
 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
 
 outgoings = []
@@ -660,8 +660,8 @@
 
 This returns "(# of incoming, # of outgoing)" tuple.
 '''
-r = compare(repo, other.listkeys('bookmarks'), repo._bookmarks,
-dsthex=hex)
+r = comparebookmarks(repo, other.listkeys('bookmarks'), repo._bookmarks,
+ dsthex=hex)
 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
 return (len(addsrc), len(adddst))
 
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -603,7 +603,8 @@
 explicit = set([repo._bookmarks.expandname(bookmark)
 for bookmark in pushop.bookmarks])
 
-comp = bookmod.compare(repo, repo._bookmarks, remotebookmark, srchex=hex)
+comp = bookmod.comparebookmarks(repo, repo._bookmarks,
+remotebookmark, srchex=hex)
 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = comp
 for b, scid, dcid in advsrc:
 if b in explicit:
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 5 of 8 V12] exchange: getbundle `bookmarks` part generator

2016-12-01 Thread Stanislau Hlebik
# HG changeset patch
# User Stanislau Hlebik 
# Date 1479807361 28800
#  Tue Nov 22 01:36:01 2016 -0800
# Node ID b08e4f9ed873bb9b6bd8e170401a150f9b094bfd
# Parent  49d598a6db4b0fa63b7a30b55899caa0fa1f9c99
exchange: getbundle `bookmarks` part generator

This generator will be used during pull operation.

diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -1675,6 +1675,21 @@
 if chunks:
 bundler.newpart('hgtagsfnodes', data=''.join(chunks))
 
+@getbundle2partsgenerator('bookmarks')
+def _getbundlebookmarkspart(bundler, repo, source, bundlecaps=None,
+b2caps=None, heads=None, common=None,
+**kwargs):
+if not kwargs.get('bookmarks'):
+return
+if 'bookmarks' not in b2caps:
+raise ValueError(
+_('bookmarks are requested but client is not capable '
+  'of receiving it'))
+
+bookmarks = _getbookmarks(repo, **kwargs)
+encodedbookmarks = bookmod.encodebookmarks(bookmarks)
+bundler.newpart('bookmarks', data=encodedbookmarks)
+
 def _getbookmarks(repo, **kwargs):
 """Returns bookmark to node mapping.
 
diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -212,7 +212,9 @@
  'bundlecaps': 'scsv',
  'listkeys': 'csv',
  'cg': 'boolean',
- 'cbattempted': 'boolean'}
+ 'cbattempted': 'boolean',
+ 'bookmarks': 'boolean',
+}
 
 # client side
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 7 of 8 V12] bundle2: advertise bookmark capability

2016-12-01 Thread Stanislau Hlebik
# HG changeset patch
# User Stanislau Hlebik 
# Date 1479807361 28800
#  Tue Nov 22 01:36:01 2016 -0800
# Node ID dc34527b28959ef96a4e7b23430ad467b5fbf85e
# Parent  be39a83d5cb8c60e9b9a2a1b58b4b0dde833c77b
bundle2: advertise bookmark capability

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -1265,6 +1265,7 @@
 'digests': tuple(sorted(util.DIGESTS.keys())),
 'remote-changegroup': ('http', 'https'),
 'hgtagsfnodes': (),
+'bookmarks': (),
}
 
 def getrepocaps(repo, allowpushback=False):
diff --git a/tests/test-acl.t b/tests/test-acl.t
--- a/tests/test-acl.t
+++ b/tests/test-acl.t
@@ -92,13 +92,13 @@
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   bundle2-output-bundle: "HG20", 4 parts total
-  bundle2-output-part: "replycaps" 155 bytes payload
+  bundle2-output-part: "replycaps" 165 bytes payload
   bundle2-output-part: "check:heads" streamed payload
   bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
   bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
   bundle2-input-bundle: with-transaction
   bundle2-input-part: "replycaps" supported
-  bundle2-input-part: total payload size 155
+  bundle2-input-part: total payload size 165
   bundle2-input-part: "check:heads" supported
   bundle2-input-part: total payload size 20
   bundle2-input-part: "changegroup" (params: 1 mandatory) supported
@@ -155,13 +155,13 @@
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   bundle2-output-bundle: "HG20", 4 parts total
-  bundle2-output-part: "replycaps" 155 bytes payload
+  bundle2-output-part: "replycaps" 165 bytes payload
   bundle2-output-part: "check:heads" streamed payload
   bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
   bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
   bundle2-input-bundle: with-transaction
   bundle2-input-part: "replycaps" supported
-  bundle2-input-part: total payload size 155
+  bundle2-input-part: total payload size 165
   bundle2-input-part: "check:heads" supported
   bundle2-input-part: total payload size 20
   bundle2-input-part: "changegroup" (params: 1 mandatory) supported
@@ -221,13 +221,13 @@
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   bundle2-output-bundle: "HG20", 4 parts total
-  bundle2-output-part: "replycaps" 155 bytes payload
+  bundle2-output-part: "replycaps" 165 bytes payload
   bundle2-output-part: "check:heads" streamed payload
   bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
   bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
   bundle2-input-bundle: with-transaction
   bundle2-input-part: "replycaps" supported
-  bundle2-input-part: total payload size 155
+  bundle2-input-part: total payload size 165
   bundle2-input-part: "check:heads" supported
   bundle2-input-part: total payload size 20
   bundle2-input-part: "changegroup" (params: 1 mandatory) supported
@@ -297,13 +297,13 @@
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   bundle2-output-bundle: "HG20", 4 parts total
-  bundle2-output-part: "replycaps" 155 bytes payload
+  bundle2-output-part: "replycaps" 165 bytes payload
   bundle2-output-part: "check:heads" streamed payload
   bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
   bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
   bundle2-input-bundle: with-transaction
   bundle2-input-part: "replycaps" supported
-  bundle2-input-part: total payload size 155
+  bundle2-input-part: total payload size 165
   bundle2-input-part: "check:heads" supported
   bundle2-input-part: total payload size 20
   bundle2-input-part: "changegroup" (params: 1 mandatory) supported
@@ -362,13 +362,13 @@
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   bundle2-output-bundle: "HG20", 4 parts total
-  bundle2-output-part: "replycaps" 155 bytes payload
+  bundle2-output-part: "replycaps" 165 bytes payload
   bundle2-output-part: "check:heads" streamed payload
   bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
   bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
   bundle2-input-bundle: with-transaction
   bundle2-input-part: "replycaps" supported
-  bundle2-input-part: total payload size 155
+  bundle2-input-part: total payload size 165
   bundle2-input-part: "check:heads" supported
   bundle2-input-part: total payload size 20
   bundle2-input-part: "changegroup" (params: 1 mandatory) supported
@@ -432,13 +432,13 @@
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
   911600dab2ae7a9baff75958b84fe606851ce955
   bundle2-output-bundle: "HG20", 4 parts total
-  bundle2-output-part: "replycaps" 155 bytes 

[PATCH 1 of 8 V12] bookmarks: introduce binary encoding

2016-12-01 Thread Stanislau Hlebik
# HG changeset patch
# User Stanislau Hlebik 
# Date 1479807211 28800
#  Tue Nov 22 01:33:31 2016 -0800
# Node ID d184b91890ae3cbd21f656847b6b2728892b2425
# Parent  9e29d4e4e08b5996adda49cdd0b497d89e2b16ee
bookmarks: introduce binary encoding

Bookmarks binary encoding will be used for `bookmarks` bundle2 part.
The format is: <4 bytes - bookmark size, big-endian>
   <1 byte - 0 if node is empty 1 otherwise><20 bytes node>
BookmarksEncodeError and BookmarksDecodeError maybe thrown if input is
incorrect.

diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py
--- a/mercurial/bookmarks.py
+++ b/mercurial/bookmarks.py
@@ -8,7 +8,9 @@
 from __future__ import absolute_import
 
 import errno
+import io
 import os
+import struct
 
 from .i18n import _
 from .node import (
@@ -23,6 +25,72 @@
 util,
 )
 
+_NONEMPTYNODE = struct.pack('?', False)
+_EMPTYNODE = struct.pack('?', True)
+
+def _unpackbookmarksize(stream):
+"""Returns 0 if stream is empty.
+"""
+
+intstruct = struct.Struct('>i')
+expectedsize = intstruct.size
+encodedbookmarksize = stream.read(expectedsize)
+if not encodedbookmarksize:
+return 0
+if len(encodedbookmarksize) != expectedsize:
+raise ValueError(
+_('cannot decode bookmark size: '
+  'expected size: %d, actual size: %d') %
+(expectedsize, len(encodedbookmarksize)))
+return intstruct.unpack(encodedbookmarksize)[0]
+
+def encodebookmarks(bookmarks):
+"""Encodes bookmark to node mapping to the byte string.
+
+Format: <4 bytes - bookmark size>
+<1 byte - 0 if node is empty 1 otherwise><20 bytes node>
+Node may be 20 byte binary string or empty
+"""
+
+intstruct = struct.Struct('>i')
+for bookmark, node in sorted(bookmarks.iteritems()):
+encodedbookmark = encoding.fromlocal(bookmark)
+yield intstruct.pack(len(encodedbookmark))
+yield encodedbookmark
+if node:
+if len(node) != 20:
+raise ValueError(_('node must be 20 or bytes long'))
+yield _NONEMPTYNODE
+yield node
+else:
+yield _EMPTYNODE
+
+def decodebookmarks(buf):
+"""Decodes buffer into bookmark to node mapping.
+
+Node is either 20 bytes or empty.
+"""
+
+stream = io.BytesIO(buf)
+bookmarks = {}
+bookmarksize = _unpackbookmarksize(stream)
+boolstruct = struct.Struct('?')
+while bookmarksize:
+bookmark = stream.read(bookmarksize)
+if len(bookmark) != bookmarksize:
+raise ValueError(
+_('cannot decode bookmark: expected size: %d, '
+'actual size: %d') % (bookmarksize, len(bookmark)))
+bookmark = encoding.tolocal(bookmark)
+packedemptynodeflag = stream.read(boolstruct.size)
+emptynode = boolstruct.unpack(packedemptynodeflag)[0]
+node = ''
+if not emptynode:
+node = stream.read(20)
+bookmarks[bookmark] = node
+bookmarksize = _unpackbookmarksize(stream)
+return bookmarks
+
 def _getbkfile(repo):
 """Hook so that extensions that mess with the store can hook bm storage.
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH] posix: give the cached symlink a real target

2016-12-01 Thread Mateusz Kwapich
What Jun said. All the rest looks good to me.

Excerpts from Martijn Pieters's message of 2016-11-30 16:51:41 +:
> # HG changeset patch
> # User Martijn Pieters 
> # Date 1480523976 0
> #  Wed Nov 30 16:39:36 2016 +
> # Node ID 4053f60f77657f8f54afc72d00bf629b75d0b4b9
> # Parent  9e29d4e4e08b5996adda49cdd0b497d89e2b16ee
> posix: give the cached symlink a real target
> 
> The NamedTemporaryFile file is cleared up so checklink ends up as a dangling
> symlink, causing cp -r in tests to complain on both Solaris and OS X. Use
> a permanent file instead when there is a .hg/cache directory.
> 
> diff --git a/mercurial/posix.py b/mercurial/posix.py
> --- a/mercurial/posix.py
> +++ b/mercurial/posix.py
> @@ -231,10 +231,18 @@
>  cachedir = None
>  name = tempfile.mktemp(dir=checkdir, prefix='checklink-')
>  try:
> -fd = tempfile.NamedTemporaryFile(dir=checkdir,
> - prefix='hg-checklink-')
> +fd = None
> +if cachedir is None:
> +fd = tempfile.NamedTemporaryFile(dir=checkdir,
> + prefix='hg-checklink-')
> +target = os.path.basename(fd.name)
> +else:
> +# create a fixed file to link to; doesn't matter if it
> +# already exists.
> +target = 'checklink-target'
> +open(os.path.join(cachedir, target), 'w')
>  try:
> -os.symlink(os.path.basename(fd.name), name)
> +os.symlink(target, name)
>  if cachedir is None:
>  os.unlink(name)
>  else:
> @@ -249,7 +257,8 @@
>  continue
>  raise
>  finally:
> -fd.close()
> +if fd is not None:
> +fd.close()
>  except AttributeError:
>  return False
>  except OSError as inst:
> diff --git a/tests/test-clone.t b/tests/test-clone.t
> --- a/tests/test-clone.t
> +++ b/tests/test-clone.t
> @@ -33,6 +33,7 @@
>branch2-served
>checkisexec
>checklink
> +  checklink-target
>checknoexec
>rbc-names-v1
>rbc-revs-v1
> @@ -50,6 +51,7 @@
>branch2-served
>checkisexec
>checklink
> +  checklink-target
>  
>$ cat a
>a
> diff --git a/tests/test-hardlinks.t b/tests/test-hardlinks.t
> --- a/tests/test-hardlinks.t
> +++ b/tests/test-hardlinks.t
> @@ -212,6 +212,8 @@
>2 r4/.hg/branch
>2 r4/.hg/cache/branch2-served
>2 r4/.hg/cache/checkisexec
> +  3 r4/.hg/cache/checklink (?)
> +  ? r4/.hg/cache/checklink-target (glob)
>2 r4/.hg/cache/checknoexec
>2 r4/.hg/cache/rbc-names-v1
>2 r4/.hg/cache/rbc-revs-v1
> @@ -250,6 +252,7 @@
>1 r4/.hg/branch
>2 r4/.hg/cache/branch2-served
>2 r4/.hg/cache/checkisexec
> +  2 r4/.hg/cache/checklink-target
>2 r4/.hg/cache/checknoexec
>2 r4/.hg/cache/rbc-names-v1
>2 r4/.hg/cache/rbc-revs-v1
> diff --git a/tests/test-tags.t b/tests/test-tags.t
> --- a/tests/test-tags.t
> +++ b/tests/test-tags.t
> @@ -674,6 +674,7 @@
>branch2-served
>checkisexec
>checklink
> +  checklink-target
>hgtagsfnodes1
>rbc-names-v1
>rbc-revs-v1
> @@ -700,6 +701,7 @@
>branch2-served
>checkisexec
>checklink
> +  checklink-target
>hgtagsfnodes1
>rbc-names-v1
>rbc-revs-v1

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


Re: [PATCH 7 of 7] py3: use encoding.environ in ui.py

2016-12-01 Thread Yuya Nishihara
On Wed, 30 Nov 2016 23:46:37 +0530, Pulkit Goyal wrote:
> Can you elaborate on how we can use ui.environ because I will like to
> change all os.environ things because they are source of errors on
> Python 3.

I had fuzzy feeling that ui.environ could be a source of environ dict. It was
introduced by 38170eeed18c, but appears not (or barely?) used. OTOH, doing that
might cause httpoxy vulnerability.

So, I have no concrete idea how we should handle ui.environ.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: a changeset belongs to two branches?

2016-12-01 Thread Uwe Brauer
>>> "Uwe" == Uwe Brauer  writes:

   > Hi

   > In my repo I have to branches, 

   > -  the default

   > -  the branch Uwe.

   > However I just realized that

   >  hg log -G

   > Gave me

   >  o  changeset:   68:1ec5162467a7
   > | |  branch:  Uwe
   > | |  branch:  default/Uwe
   > | |  parent:  66:ce46517fd6e4
   > | |  user:Uwe Brauer 
   > | |  date:Mon Nov 28 12:13:06 2016 +
   > | |  summary: Typos

   > What the heck is the branch
   > default/Uwe


This is caused by the use of the extension remotenames.
I think I will deactivate for the moment, since right now I find it confusing,
sorry Sean.


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


a changeset belongs to two branches?

2016-12-01 Thread Uwe Brauer

Hi

In my repo I have to branches, 

-  the default

-  the branch Uwe.

However I just realized that

 hg log -G

Gave me

 o  changeset:   68:1ec5162467a7
| |  branch:  Uwe
| |  branch:  default/Uwe
| |  parent:  66:ce46517fd6e4
| |  user:Uwe Brauer 
| |  date:Mon Nov 28 12:13:06 2016 +
| |  summary: Typos

What the heck is the branch
default/Uwe


Uwe Brauer

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