Merge branch 'bw/ref-prefix-for-configured-refspec'
authorJunio C Hamano <gitster@pobox.com>
Wed, 30 May 2018 12:51:26 +0000 (21:51 +0900)
committerJunio C Hamano <gitster@pobox.com>
Wed, 30 May 2018 12:51:26 +0000 (21:51 +0900)
"git fetch $there $refspec" that talks over protocol v2 can take
advantage of server-side ref filtering; the code has been extended
so that this mechanism triggers also when fetching with configured
refspec.

* bw/ref-prefix-for-configured-refspec: (38 commits)
fetch: generate ref-prefixes when using a configured refspec
refspec: consolidate ref-prefix generation logic
submodule: convert push_unpushed_submodules to take a struct refspec
remote: convert check_push_refs to take a struct refspec
remote: convert match_push_refs to take a struct refspec
http-push: store refspecs in a struct refspec
transport: remove transport_verify_remote_names
send-pack: store refspecs in a struct refspec
transport: convert transport_push to take a struct refspec
push: convert to use struct refspec
push: check for errors earlier
remote: convert match_explicit_refs to take a struct refspec
remote: convert get_ref_match to take a struct refspec
remote: convert query_refspecs to take a struct refspec
remote: convert apply_refspecs to take a struct refspec
remote: convert get_stale_heads to take a struct refspec
fetch: convert prune_refs to take a struct refspec
fetch: convert get_ref_map to take a struct refspec
fetch: convert do_fetch to take a struct refspec
refspec: remove the deprecated functions
...

14 files changed:
1  2 
builtin/clone.c
builtin/fast-export.c
builtin/fetch.c
builtin/merge.c
builtin/pull.c
builtin/remote.c
builtin/submodule--helper.c
http-push.c
remote.c
remote.h
submodule.c
t/t5702-protocol-v2.sh
transport.c
transport.h
diff --cc builtin/clone.c
Simple merge
Simple merge
diff --cc builtin/fetch.c
index 1f037e8e4b8ba41b66314c5dd9633e0164f86c0e,7cc7a52deefd5c490103e4c154e864b211c2bd29..c0d8ad1fe2aa7fe1ddbafa660746418301239463
@@@ -59,10 -60,8 +60,9 @@@ static const char *submodule_prefix = "
  static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
  static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;
  static int shown_url = 0;
- static int refmap_alloc, refmap_nr;
- static const char **refmap_array;
+ static struct refspec refmap = REFSPEC_INIT_FETCH;
  static struct list_objects_filter_options filter_options;
 +static struct string_list server_options = STRING_LIST_INIT_DUP;
  
  static int git_fetch_config(const char *k, const char *v, void *cb)
  {
@@@ -1419,14 -1401,10 +1403,13 @@@ static int fetch_one(struct remote *rem
                }
        }
  
 +      if (server_options.nr)
 +              gtransport->server_options = &server_options;
 +
        sigchain_push_common(unlock_pack_on_signal);
        atexit(unlock_pack);
-       refspec = parse_fetch_refspec(ref_nr, refs);
-       exit_code = do_fetch(gtransport, refspec, ref_nr);
-       free_refspec(ref_nr, refspec);
+       exit_code = do_fetch(gtransport, &rs);
+       refspec_clear(&rs);
        transport_disconnect(gtransport);
        gtransport = NULL;
        return exit_code;
diff --cc builtin/merge.c
Simple merge
diff --cc builtin/pull.c
Simple merge
Simple merge
Simple merge
diff --cc http-push.c
Simple merge
diff --cc remote.c
Simple merge
diff --cc remote.h
Simple merge
diff --cc submodule.c
Simple merge
index 4ad5c5769b4eab56d840709ee0bc0affa8de2e01,b6c72ab51ed2f4ab3012252b70c6b03fafbcaf65..a4fe6508bdd73784758b2ea80ab81752e15c01b3
@@@ -217,134 -201,20 +217,148 @@@ test_expect_success 'ref advertisment i
        ! grep "refs/tags/three" log
  '
  
 +test_expect_success 'server-options are sent when fetching' '
 +      test_when_finished "rm -f log" &&
 +
 +      test_commit -C file_parent four &&
 +
 +      GIT_TRACE_PACKET="$(pwd)/log" git -C file_child -c protocol.version=2 \
 +              fetch -o hello -o world origin master &&
 +
 +      git -C file_child log -1 --format=%s origin/master >actual &&
 +      git -C file_parent log -1 --format=%s >expect &&
 +      test_cmp expect actual &&
 +
 +      grep "server-option=hello" log &&
 +      grep "server-option=world" log
 +'
 +
 +test_expect_success 'upload-pack respects config using protocol v2' '
 +      git init server &&
 +      write_script server/.git/hook <<-\EOF &&
 +              touch hookout
 +              "$@"
 +      EOF
 +      test_commit -C server one &&
 +
 +      test_config_global uploadpack.packobjectshook ./hook &&
 +      test_path_is_missing server/.git/hookout &&
 +      git -c protocol.version=2 clone "file://$(pwd)/server" client &&
 +      test_path_is_file server/.git/hookout
 +'
 +
 +test_expect_success 'setup filter tests' '
 +      rm -rf server client &&
 +      git init server &&
 +
 +      # 1 commit to create a file, and 1 commit to modify it
 +      test_commit -C server message1 a.txt &&
 +      test_commit -C server message2 a.txt &&
 +      git -C server config protocol.version 2 &&
 +      git -C server config uploadpack.allowfilter 1 &&
 +      git -C server config uploadpack.allowanysha1inwant 1 &&
 +      git -C server config protocol.version 2
 +'
 +
 +test_expect_success 'partial clone' '
 +      GIT_TRACE_PACKET="$(pwd)/trace" git -c protocol.version=2 \
 +              clone --filter=blob:none "file://$(pwd)/server" client &&
 +      grep "version 2" trace &&
 +
 +      # Ensure that the old version of the file is missing
 +      git -C client rev-list master --quiet --objects --missing=print \
 +              >observed.oids &&
 +      grep "$(git -C server rev-parse message1:a.txt)" observed.oids &&
 +
 +      # Ensure that client passes fsck
 +      git -C client fsck
 +'
 +
 +test_expect_success 'dynamically fetch missing object' '
 +      rm "$(pwd)/trace" &&
 +      GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \
 +              cat-file -p $(git -C server rev-parse message1:a.txt) &&
 +      grep "version 2" trace
 +'
 +
 +test_expect_success 'partial fetch' '
 +      rm -rf client "$(pwd)/trace" &&
 +      git init client &&
 +      SERVER="file://$(pwd)/server" &&
 +      test_config -C client extensions.partialClone "$SERVER" &&
 +
 +      GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \
 +              fetch --filter=blob:none "$SERVER" master:refs/heads/other &&
 +      grep "version 2" trace &&
 +
 +      # Ensure that the old version of the file is missing
 +      git -C client rev-list other --quiet --objects --missing=print \
 +              >observed.oids &&
 +      grep "$(git -C server rev-parse message1:a.txt)" observed.oids &&
 +
 +      # Ensure that client passes fsck
 +      git -C client fsck
 +'
 +
 +test_expect_success 'do not advertise filter if not configured to do so' '
 +      SERVER="file://$(pwd)/server" &&
 +
 +      rm "$(pwd)/trace" &&
 +      git -C server config uploadpack.allowfilter 1 &&
 +      GIT_TRACE_PACKET="$(pwd)/trace" git -c protocol.version=2 \
 +              ls-remote "$SERVER" &&
 +      grep "fetch=.*filter" trace &&
 +
 +      rm "$(pwd)/trace" &&
 +      git -C server config uploadpack.allowfilter 0 &&
 +      GIT_TRACE_PACKET="$(pwd)/trace" git -c protocol.version=2 \
 +              ls-remote "$SERVER" &&
 +      grep "fetch=" trace >fetch_capabilities &&
 +      ! grep filter fetch_capabilities
 +'
 +
 +test_expect_success 'partial clone warns if filter is not advertised' '
 +      rm -rf client &&
 +      git -C server config uploadpack.allowfilter 0 &&
 +      git -c protocol.version=2 \
 +              clone --filter=blob:none "file://$(pwd)/server" client 2>err &&
 +      test_i18ngrep "filtering not recognized by server, ignoring" err
 +'
 +
 +test_expect_success 'even with handcrafted request, filter does not work if not advertised' '
 +      git -C server config uploadpack.allowfilter 0 &&
 +
 +      # Custom request that tries to filter even though it is not advertised.
 +      test-pkt-line pack >in <<-EOF &&
 +      command=fetch
 +      0001
 +      want $(git -C server rev-parse master)
 +      filter blob:none
 +      0000
 +      EOF
 +
 +      test_must_fail git -C server serve --stateless-rpc <in >/dev/null 2>err &&
 +      grep "unexpected line: .filter blob:none." err &&
 +
 +      # Exercise to ensure that if advertised, filter works
 +      git -C server config uploadpack.allowfilter 1 &&
 +      git -C server serve --stateless-rpc <in >/dev/null
 +'
 +
+ test_expect_success 'default refspec is used to filter ref when fetchcing' '
+       test_when_finished "rm -f log" &&
+       GIT_TRACE_PACKET="$(pwd)/log" git -C file_child -c protocol.version=2 \
+               fetch origin &&
+       git -C file_child log -1 --format=%s three >actual &&
+       git -C file_parent log -1 --format=%s three >expect &&
+       test_cmp expect actual &&
+       grep "ref-prefix refs/heads/" log &&
+       grep "ref-prefix refs/tags/" log
+ '
  # Test protocol v2 with 'http://' transport
  #
  . "$TEST_DIRECTORY"/lib-httpd.sh
diff --cc transport.c
Simple merge
diff --cc transport.h
Simple merge