[PATCH] streamclone: partially encode filename over the wire, not for local read
Greg Ward
greg-hg at gerg.ca
Wed Sep 30 16:01:14 CDT 2009
On Wed, Sep 30, 2009 at 4:22 PM, Matt Mackall <mpm at selenic.com> wrote:
> On Wed, 2009-09-30 at 16:08 -0400, Greg Ward wrote:
>> # HG changeset patch
>> # User Greg Ward <greg-hg at gerg.ca>
>> # Date 1254341291 14400
>> # Node ID 0411fe6a60722535cf44df4ea89b42c82ef96821
>> # Parent b2d65ee49a72f374fd6831f229e03ca723c29c77
>> streamclone: partially encode filename over the wire, not for local read.
>>
>> (Fixes issue1847, which was introduced by 810387f59696: stream clone
>> of a repo with directory named *.d failed: server raises exception
>> "IOError: [Errno 2] No such file or directory:
>> /tmp/test/.hg/store/data/foo.d.hg.hg/foo".)
>
> Not entirely clear to me what's going on in your fix. What happens in
> this matrix?
Quoting my patch:
- # for backwards compat, name was partially encoded
- entries.append((store.encodedir(name), size))
Dir-encoding the name at this point has two side-effects:
1) send dir-encoded name over the wire (presumably correct and intended)
2) pass dir-encoded name to repo.sopener() (bad: that's where the
double escaping comes from, i.e. "foo.d" escaped once to "foo.d.hg"
[for wire protocol] and again to "foo.d.hg.hg" by repo.sopener())
So my patch delays the encodedir() a bit:
- yield '%s\0%d\n' % (name, size)
+ # partially encode name over the wire for backwards compat
+ yield '%s\0%d\n' % (store.encodedir(name), size)
I am *assuming* that dir encoding the name over the wire is the
correct thing to do, because that's what it was doing before. I
believe that the bug is not in the wire protocol, but in passing an
already-direncoded name to repo.sopener().
> old client new client
> old server breaks ?
> new server ? works
>
> If both '?' aren't 'works', then is there anything we can do to fix
> that?
Good question! Old server (that is, hg 1.3 or 1.3.1) will always
break, because the bug is in the server code. Stream cloning a repo
with directories named like *.d does not work with 1.3 on the server,
regardless of the client version.
I just tested (new server, old client) for various values of "old"
(1.2.1, 1.3.1, current crew). All work, where "work" means "can
stream clone repo with *.d directory". So the matrix is
old client new client
old server breaks breaks
new server works works
Greg
More information about the Mercurial-devel
mailing list