Merge branch 'jt/clone-server-option'
authorJunio C Hamano <gitster@pobox.com>
Wed, 8 May 2019 15:37:25 +0000 (00:37 +0900)
committerJunio C Hamano <gitster@pobox.com>
Wed, 8 May 2019 15:37:25 +0000 (00:37 +0900)
"git clone" learned a new --server-option option when talking over
the protocol version 2.

* jt/clone-server-option:
clone: send server options when using protocol v2
transport: die if server options are unsupported

1  2 
t/t5702-protocol-v2.sh
transport.c
diff --combined t/t5702-protocol-v2.sh
index a0896593375803eb79782705a21d673c72172c83,9b048f6c8bc82852f52bf03baf33f174d99f23b7..dbb4cf8881490282a9f55f596a97b908db73df69
@@@ -182,6 -182,13 +182,13 @@@ test_expect_success 'server-options ar
        grep "server-option=world" log
  '
  
+ test_expect_success 'warn if using server-option with ls-remote with legacy protocol' '
+       test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -c protocol.version=0 \
+               ls-remote -o hello -o world "file://$(pwd)/file_parent" master 2>err &&
+       test_i18ngrep "see protocol.version in" err &&
+       test_i18ngrep "server options require protocol version 2 or later" err
+ '
  
  test_expect_success 'clone with file:// using protocol v2' '
        test_when_finished "rm -f log" &&
@@@ -251,6 -258,40 +258,40 @@@ test_expect_success 'server-options ar
        grep "server-option=world" log
  '
  
+ test_expect_success 'warn if using server-option with fetch with legacy protocol' '
+       test_when_finished "rm -rf temp_child" &&
+       git init temp_child &&
+       test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -C temp_child -c protocol.version=0 \
+               fetch -o hello -o world "file://$(pwd)/file_parent" master 2>err &&
+       test_i18ngrep "see protocol.version in" err &&
+       test_i18ngrep "server options require protocol version 2 or later" err
+ '
+ test_expect_success 'server-options are sent when cloning' '
+       test_when_finished "rm -rf log myclone" &&
+       GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+               clone --server-option=hello --server-option=world \
+               "file://$(pwd)/file_parent" myclone &&
+       grep "server-option=hello" log &&
+       grep "server-option=world" log
+ '
+ test_expect_success 'warn if using server-option with clone with legacy protocol' '
+       test_when_finished "rm -rf myclone" &&
+       test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -c protocol.version=0 \
+               clone --server-option=hello --server-option=world \
+               "file://$(pwd)/file_parent" myclone 2>err &&
+       test_i18ngrep "see protocol.version in" err &&
+       test_i18ngrep "server options require protocol version 2 or later" err
+ '
  test_expect_success 'upload-pack respects config using protocol v2' '
        git init server &&
        write_script server/.git/hook <<-\EOF &&
@@@ -542,38 -583,7 +583,38 @@@ test_expect_success 'clone with http:/
        # Client requested to use protocol v2
        grep "Git-Protocol: version=2" log &&
        # Server responded using protocol v2
 -      grep "git< version 2" log
 +      grep "git< version 2" log &&
 +      # Verify that the chunked encoding sending codepath is NOT exercised
 +      ! grep "Send header: Transfer-Encoding: chunked" log
 +'
 +
 +test_expect_success 'clone big repository with http:// using protocol v2' '
 +      test_when_finished "rm -f log" &&
 +
 +      git init "$HTTPD_DOCUMENT_ROOT_PATH/big" &&
 +      # Ensure that the list of wants is greater than http.postbuffer below
 +      for i in $(test_seq 1 1500)
 +      do
 +              # do not use here-doc, because it requires a process
 +              # per loop iteration
 +              echo "commit refs/heads/too-many-refs-$i" &&
 +              echo "committer git <git@example.com> $i +0000" &&
 +              echo "data 0" &&
 +              echo "M 644 inline bla.txt" &&
 +              echo "data 4" &&
 +              echo "bla"
 +      done | git -C "$HTTPD_DOCUMENT_ROOT_PATH/big" fast-import &&
 +
 +      GIT_TRACE_PACKET="$(pwd)/log" GIT_TRACE_CURL="$(pwd)/log" git \
 +              -c protocol.version=2 -c http.postbuffer=65536 \
 +              clone "$HTTPD_URL/smart/big" big_child &&
 +
 +      # Client requested to use protocol v2
 +      grep "Git-Protocol: version=2" log &&
 +      # Server responded using protocol v2
 +      grep "git< version 2" log &&
 +      # Verify that the chunked encoding sending codepath is exercised
 +      grep "Send header: Transfer-Encoding: chunked" log
  '
  
  test_expect_success 'fetch with http:// using protocol v2' '
@@@ -687,4 -697,6 +728,4 @@@ test_expect_success 'when server does n
        test_i18ngrep "expected no other sections to be sent after no .ready." err
  '
  
 -stop_httpd
 -
  test_done
diff --combined transport.c
index 365ea574c7b52e0fc4381295eed6650ca5f67a87,77446119da5d5d6ebb3e0431c855c2b6022ba6b0..f1fcd2c4b006dc2ece2019ac91f73a2f42bbf6bd
@@@ -252,6 -252,14 +252,14 @@@ static int connect_setup(struct transpo
        return 0;
  }
  
+ static void die_if_server_options(struct transport *transport)
+ {
+       if (!transport->server_options || !transport->server_options->nr)
+               return;
+       advise(_("see protocol.version in 'git help config' for more details"));
+       die(_("server options require protocol version 2 or later"));
+ }
  /*
   * Obtains the protocol version from the transport and writes it to
   * transport->data->version, first connecting if not already connected.
@@@ -286,6 -294,7 +294,7 @@@ static struct ref *handshake(struct tra
                break;
        case protocol_v1:
        case protocol_v0:
+               die_if_server_options(transport);
                get_remote_heads(&reader, &refs,
                                 for_push ? REF_NORMAL : 0,
                                 &data->extra_have,
@@@ -314,6 -323,7 +323,6 @@@ static int fetch_refs_via_pack(struct t
        int ret = 0;
        struct git_transport_data *data = transport->data;
        struct ref *refs = NULL;
 -      char *dest = xstrdup(transport->url);
        struct fetch_pack_args args;
        struct ref *refs_tmp = NULL;
  
  
        switch (data->version) {
        case protocol_v2:
 -              refs = fetch_pack(&args, data->fd, data->conn,
 +              refs = fetch_pack(&args, data->fd,
                                  refs_tmp ? refs_tmp : transport->remote_refs,
 -                                dest, to_fetch, nr_heads, &data->shallow,
 +                                to_fetch, nr_heads, &data->shallow,
                                  &transport->pack_lockfile, data->version);
                break;
        case protocol_v1:
        case protocol_v0:
 -              refs = fetch_pack(&args, data->fd, data->conn,
+               die_if_server_options(transport);
 +              refs = fetch_pack(&args, data->fd,
                                  refs_tmp ? refs_tmp : transport->remote_refs,
 -                                dest, to_fetch, nr_heads, &data->shallow,
 +                                to_fetch, nr_heads, &data->shallow,
                                  &transport->pack_lockfile, data->version);
                break;
        case protocol_unknown_version:
  
        free_refs(refs_tmp);
        free_refs(refs);
 -      free(dest);
        return ret;
  }
  
@@@ -1060,7 -1072,6 +1070,7 @@@ static int run_pre_push_hook(struct tra
  
        proc.argv = argv;
        proc.in = -1;
 +      proc.trace2_hook_name = "pre-push";
  
        if (start_command(&proc)) {
                finish_command(&proc);