[PATCH] wireproto: allow unbundle with hashed heads parameter (issue2126)

TAKAHASHI Shuhei takahashi.shuhei at gmail.com
Fri Apr 15 22:19:54 CDT 2011


Thanks for comments, Matt!
I'll re-send an updated patch soon.

Shuhei / nya

On Sat, Apr 16, 2011 at 11:42 AM, Matt Mackall <mpm at selenic.com> wrote:
> On Sat, 2011-04-16 at 00:56 +0900, Shuhei Takahashi wrote:
>> # HG changeset patch
>> # User nya
>
> Please send your email address here
>
>> # Date 1302882677 -32400
>> # Branch nya
>
> Not that it matters for the purposes of sending us a patch, but we don't
> advise using named branches like this:
>
> http://mercurial.selenic.com/wiki/StandardBranching
>
> A bookmark might be better.
>
>> # Node ID 8bd94325c6a8ce894a767d247f02d40a543d0977
>> # Parent  3d83c7d70a98a1fd4ff1ad4f840c8ce82100bfdb
>> wireproto: allow unbundle with hashed heads parameter (issue2126)
>>
>> Current wire protocol of unbundle sends the list of all heads in the remote
>> repository to avoid race condition.  This causes "URL too long" error on HTTP
>> server when the repository has many heads.
>>
>> This change allows clients to send SHA1 hash of heads parameter instead.
>> Also, this introduces "unbundlehash" capability to inform them that the server
>> accepts hashed heads parameter.
>
> Huh, why didn't we think of that.
>
>> diff -r 3d83c7d70a98 -r 8bd94325c6a8 mercurial/wireproto.py
>> --- a/mercurial/wireproto.py  Wed Apr 13 13:06:35 2011 -0500
>> +++ b/mercurial/wireproto.py  Sat Apr 16 00:51:17 2011 +0900
>> @@ -139,7 +139,12 @@
>>          remote server as a bundle. Return an integer indicating the
>>          result of the push (see localrepository.addchangegroup()).'''
>>
>> -        ret, output = self._callpush("unbundle", cg, heads=encodelist(heads))
>> +        if self.capable('unbundlehash'):
>> +            heads = encodelist(['hashed', util.sha1(''.join(heads)).digest()])
>
> We probably want a sorted() in here because I don't think the ordering
> here is stable/defined. Other than that, this patch is great.
>
>> +        else:
>> +            heads = encodelist(heads)
>> +
>> +        ret, output = self._callpush("unbundle", cg, heads=heads)
>>          if ret == "":
>>              raise error.ResponseError(
>>                  _('push failed:'), output)
>> @@ -216,7 +221,8 @@
>>      return "".join(r)
>>
>>  def capabilities(repo, proto):
>> -    caps = 'lookup changegroupsubset branchmap pushkey known getbundle'.split()
>> +    caps = ('lookup changegroupsubset branchmap pushkey known getbundle ' +
>> +            'unbundlehash').split()
>>      if _allowstream(repo.ui):
>>          requiredformats = repo.requirements & repo.supportedformats
>>          # if our local revlogs are just revlogv1, add 'stream' cap
>> @@ -353,7 +359,9 @@
>>
>>      def check_heads():
>>          heads = repo.heads()
>> -        return their_heads == ['force'] or their_heads == heads
>> +        heads_hash = util.sha1(''.join(heads)).digest()
>> +        return (their_heads == ['force'] or their_heads == heads or
>> +                their_heads == ['hashed', heads_hash])
>>
>>      proto.redirect()
>>
>> diff -r 3d83c7d70a98 -r 8bd94325c6a8 tests/test-hgweb-commands.t
>> --- a/tests/test-hgweb-commands.t     Wed Apr 13 13:06:35 2011 -0500
>> +++ b/tests/test-hgweb-commands.t     Sat Apr 16 00:51:17 2011 +0900
>> @@ -943,7 +943,7 @@
>>    $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'; echo
>>    200 Script output follows
>>
>> -  lookup changegroupsubset branchmap pushkey known getbundle unbundle=HG10GZ,HG10BZ,HG10UN
>> +  lookup changegroupsubset branchmap pushkey known getbundle unbundlehash unbundle=HG10GZ,HG10BZ,HG10UN
>>
>>  heads
>>
>> diff -r 3d83c7d70a98 -r 8bd94325c6a8 tests/test-unbundlehash.t
>> --- /dev/null Thu Jan 01 00:00:00 1970 +0000
>> +++ b/tests/test-unbundlehash.t       Sat Apr 16 00:51:17 2011 +0900
>> @@ -0,0 +1,31 @@
>> +
>> +Test wire protocol unbundle with hashed heads (capability: unbundlehash)
>> +
>> +Create a remote repository.
>> +
>> +  $ hg init remote
>> +  $ hg serve -R remote --config web.push_ssl=False --config web.allow_push=* -p $HGPORT -d --pid-file=hg1.pid -E error.log -A access.log
>> +  $ cat hg1.pid >> $DAEMON_PIDS
>> +
>> +Clone the repository and push a change.
>> +
>> +  $ hg clone http://localhost:$HGPORT/ local
>> +  no changes found
>> +  updating to branch default
>> +  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
>> +  $ touch local/README
>> +  $ hg ci -R local -A -m hoge
>> +  adding README
>> +  $ hg push -R local
>> +  pushing to http://localhost:$HGPORT/
>> +  searching for changes
>> +  remote: adding changesets
>> +  remote: adding manifests
>> +  remote: adding file changes
>> +  remote: added 1 changesets with 1 changes to 1 files
>> +
>> +Ensure hashed heads format is used.
>> +The hash here is always the same since the remote repository only has the null head.
>> +
>> +  $ cat access.log | grep unbundle
>> +  * - - [*] "POST /?cmd=unbundle&heads=686173686564+6768033e216468247bd031a0a2d9876d79818f8f HTTP/1.1" 200 - (glob)
>> _______________________________________________
>> Mercurial-devel mailing list
>> Mercurial-devel at selenic.com
>> http://selenic.com/mailman/listinfo/mercurial-devel
>
>
> --
> Mathematics is the supreme nostalgia of our time.
>
>
>

-- 
TAKAHASHI Shuhei <takahashi.shuhei at gmail.com>


More information about the Mercurial-devel mailing list