Re: [PATCH v2 7/9] connect: tell server that the client understands v1
- From
- Brandon Williams <bmwill@google.com>
- Date
- Sep 28, 2017, 22:20 UTC
- Message-ID
- <20170928222009.GD177031@google.com>
- In-Reply-To
- <xmqqk20k64r4.fsf@gitster.mtv.corp.google.com>
On 09/27, Junio C Hamano wrote:
Show 33 quoted lines
> Brandon Williams <bmwill@google.com> writes: > > > Teach the connection logic to tell a serve that it understands protocol > > v1. This is done in 2 different ways for the built in protocols. > > > > 1. git:// > > A normal request is structured as "command path/to/repo\0host=..\0" > > and due to a bug in an old version of git-daemon 73bb33a94 (daemon: > > Strictly parse the "extra arg" part of the command, 2009-06-04) we > > aren't able to place any extra args (separated by NULs) besides the > > host. In order to get around this limitation put protocol version > > information after a second NUL byte so the request is structured > > like: "command path/to/repo\0host=..\0\0version=1\0". git-daemon can > > then parse out the version number and set GIT_PROTOCOL. > > Same question as a previous step, wrt the cited commit. It reads as > if we are saying that the commit introduced a bug and left it there, > that we cannot use \0host=..\0version=..\0other=..\0 until that bug > is fixed, and that in the meantime we use \0host=..\0\0version=.. as > a workaround, but that reading leaves readers wondering if we want > to eventually drop this double-NUL workaround. I am guessing that > we want to declare that the current protocol has a glitch that > prevents us to use \0host=..\0version=..\0 but we accept that and > plan to keep it that way, and we'll use the double-NUL for anything > other than host from now on, as it is compatible with the current > version of Git before this patch (the extras are safely ignored), > but then it still leaves readers wonder if the mention of the > old commit from 2009 means that this double-NUL would not even work > if the other end is running a version of Git before that commit, or > we are safe to talk with versions of Git even older than that. > > I do not think it is a showstopper if we did not work with v1.6.4, > but it still needs to be clarified.
I wrote an updated commit msg for the daemon change, I can make a similar change here. And this mechanism shouldn't cause any issues with both the pre and post 73bb33a94 git-daemon servers.
Show 11 quoted lines
> > > 2. ssh://, file:// > > Set GIT_PROTOCOL envvar with the desired protocol version. The > > envvar can be sent across ssh by using '-o SendEnv=GIT_PROTOCOL' and > > having the server whitelist this envvar. > > OpenSSH lets us do this, but I do not know how well this works with > other implementations of SSH clients. The log message perhaps needs > to ask for volunteers to check if it is OK with the implementations > they use, and offer conditional code (just like we have for putty > and plink customizations) otherwise.
I'll make a comment indicating that
Show 44 quoted lines
> > Other than that, the code changes looked good. > > > diff --git a/t/t5700-protocol-v1.sh b/t/t5700-protocol-v1.sh > > new file mode 100755 > > index 000000000..1988bbce6 > > --- /dev/null > > +++ b/t/t5700-protocol-v1.sh > > @@ -0,0 +1,223 @@ > > +#!/bin/sh > > + > > +test_description='test git wire-protocol transition' > > + > > +TEST_NO_CREATE_REPO=1 > > + > > +. ./test-lib.sh > > + > > +# Test protocol v1 with 'git://' transport > > +# > > +. "$TEST_DIRECTORY"/lib-git-daemon.sh > > +start_git_daemon --export-all --enable=receive-pack > > +daemon_parent=$GIT_DAEMON_DOCUMENT_ROOT_PATH/parent > > + > > +test_expect_success 'create repo to be served by git-daemon' ' > > + git init "$daemon_parent" && > > + test_commit -C "$daemon_parent" one > > +' > > + > > +test_expect_success 'clone with git:// using protocol v1' ' > > + GIT_TRACE_PACKET=1 git -c protocol.version=1 \ > > + clone "$GIT_DAEMON_URL/parent" daemon_child 2>log && > > + > > + git -C daemon_child log -1 --format=%s >actual && > > + git -C "$daemon_parent" log -1 --format=%s >expect && > > + test_cmp expect actual && > > + > > + # Client requested to use protocol v1 > > + grep "version=1" log && > > + # Server responded using protocol v1 > > + grep "clone< version 1" log > > This looked a bit strange to check "clone< version 1" for one > direction, but did not check "$something> version 1" for the other > direction. Doesn't "version=1" end up producing 2 hits?
I think you discovered this in your next email but the "version=1" check is to check for the request sent to git-daemon, the "command path/to/repo\0host=blah\0\0version=1\0" one. While the "clone< version 1" check is to make sure that the server responded with the correct version.
Show 24 quoted lines
> > Not a complaint, but wondering if we can write it in such a way that > does not have to make readers wonder. > > > +' > > + > > +test_expect_success 'fetch with git:// using protocol v1' ' > > + test_commit -C "$daemon_parent" two && > > + > > + GIT_TRACE_PACKET=1 git -C daemon_child -c protocol.version=1 \ > > + fetch 2>log && > > + > > + git -C daemon_child log -1 --format=%s FETCH_HEAD >actual && > > + git -C "$daemon_parent" log -1 --format=%s >expect && > > + test_cmp expect actual && > > OK. So the origin repository gained one commit on the 'master' > branch (and a tag 'two'). By fetching, but not pulling, our > 'master' would not advance, and that is where check on FETCH_HEAD > comes from. I suspect that the tag 'two' is also auto-followed with > this operation and would be in FETCH_HEAD; is that something we want > to check? Alternatively, the "actual" log may want to see what the > remote tracking branch for their 'master' has---then we do not have > to worry about "FETCH_HEAD has two refs---which one are we checking?"
Yeah I can do that instead if you would prefer.
Show 22 quoted lines
> > > + > > + # Client requested to use protocol v1 > > + grep "version=1" log && > > + # Server responded using protocol v1 > > + grep "fetch< version 1" log > > +' > > Same "version=1" vs "fetch< version 1" strangeness appears here. > > > +test_expect_success 'pull with git:// using protocol v1' ' > > + GIT_TRACE_PACKET=1 git -C daemon_child -c protocol.version=1 \ > > + pull 2>log && > > + > > + git -C daemon_child log -1 --format=%s >actual && > > + git -C "$daemon_parent" log -1 --format=%s >expect && > > + test_cmp expect actual && > > Here we can check our 'master', as we pulled their 'master' into it. > What is this testing, though? The fact that protocol.version=1 > given via "git -c var=val" mechanism is propagated to the underlying > fetch?
Yeah, i guess we could realistically drop either the fetch or pull test as they essentially do the same thing. I was just being overly cautious.
Show 19 quoted lines
> > > + # Client requested to use protocol v1 > > + grep "version=1" log && > > + # Server responded using protocol v1 > > + grep "fetch< version 1" log > > +' > > + > > +test_expect_success 'push with git:// using protocol v1' ' > > + test_commit -C daemon_child three && > > + > > + # Since the repository being served isnt bare we need to push to > > + # another branch explicitly to avoid mangling the master branch > > The other end avoids mangling the master just fine without us doing > anything special ;-). You are pushing to another branch because you > cannot push into a branch that is currently checked out. > > # Push to another branch, as the target repository has the > # master branch checked out and we cannot push into it.
Sounds good I'll change that.
Show 38 quoted lines
>
> perhaps?
>
> The tests for file:// looked identical, so the same set of comments
> apply.
>
> > +# Test protocol v1 with 'ssh://' transport
> > +#
> > +test_expect_success 'setup ssh wrapper' '
> > + GIT_SSH="$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" &&
> > + export GIT_SSH &&
> > + export TRASH_DIRECTORY &&
> > + >"$TRASH_DIRECTORY"/ssh-output
> > +'
> > +
> > +expect_ssh () {
> > + test_when_finished '(cd "$TRASH_DIRECTORY" && rm -f ssh-expect && >ssh-output)' &&
> > + echo "ssh: -o SendEnv=GIT_PROTOCOL myhost $1 '$PWD/ssh_parent'" >"$TRASH_DIRECTORY/ssh-expect" &&
> > + (cd "$TRASH_DIRECTORY" && test_cmp ssh-expect ssh-output)
> > +}
> > +
> > +test_expect_success 'create repo to be served by ssh:// transport' '
> > + git init ssh_parent &&
> > + test_commit -C ssh_parent one
> > +'
> > +
> > +test_expect_success 'clone with ssh:// using protocol v1' '
> > + GIT_TRACE_PACKET=1 git -c protocol.version=1 \
> > + clone "ssh://myhost:$(pwd)/ssh_parent" ssh_child 2>log &&
>
> Hmm, this is a fun one, as we deliberately make $(pwd) to have
> whitespace in the test setup. I am impressed/kinda surprised that
> this works ;-)
>
> Other than that, these also look more or less identical to file://
> and git:// tests, so the same set of comments apply.
>
> Overall very nicely done.Thanks! :D
> > Thanks.
-- Brandon Williams