Merge branch 'kg/gc-auto-windows-workaround'
authorJunio C Hamano <gitster@pobox.com>
Thu, 2 Aug 2018 22:30:43 +0000 (15:30 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 2 Aug 2018 22:30:43 +0000 (15:30 -0700)
"git gc --auto" opens file descriptors for the packfiles before
spawning "git repack/prune", which would upset Windows that does
not want a process to work on a file that is open by another
process. The issue has been worked around.

* kg/gc-auto-windows-workaround:
gc --auto: release pack files before auto packing

1  2 
builtin/gc.c
t/t5510-fetch.sh
diff --combined builtin/gc.c
index e103f0f85d7995999fbd7e52057e563005ae819e,63b62ab57c297d1873a529b9c55768eebca999b1..57069442b0dc1297366e29b1fbf0e6ee70377146
@@@ -20,7 -20,6 +20,7 @@@
  #include "sigchain.h"
  #include "argv-array.h"
  #include "commit.h"
 +#include "commit-graph.h"
  #include "packfile.h"
  #include "object-store.h"
  #include "pack.h"
@@@ -41,7 -40,6 +41,7 @@@ static int aggressive_depth = 50
  static int aggressive_window = 250;
  static int gc_auto_threshold = 6700;
  static int gc_auto_pack_limit = 50;
 +static int gc_write_commit_graph;
  static int detach_auto = 1;
  static timestamp_t gc_log_expire_time;
  static const char *gc_log_expire = "1.day.ago";
@@@ -131,7 -129,6 +131,7 @@@ static void gc_config(void
        git_config_get_int("gc.aggressivedepth", &aggressive_depth);
        git_config_get_int("gc.auto", &gc_auto_threshold);
        git_config_get_int("gc.autopacklimit", &gc_auto_pack_limit);
 +      git_config_get_bool("gc.writecommitgraph", &gc_write_commit_graph);
        git_config_get_bool("gc.autodetach", &detach_auto);
        git_config_get_expiry("gc.pruneexpire", &prune_expire);
        git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
@@@ -615,6 -612,7 +615,7 @@@ int cmd_gc(int argc, const char **argv
                return -1;
  
        if (!repository_format_precious_objects) {
+               close_all_packs(the_repository->objects);
                if (run_command_v_opt(repack.argv, RUN_GIT_CMD))
                        return error(FAILED_RUN, repack.argv[0]);
  
        if (pack_garbage.nr > 0)
                clean_pack_garbage();
  
 +      if (gc_write_commit_graph)
 +              write_commit_graph_reachable(get_object_directory(), 0);
 +
        if (auto_gc && too_many_loose_objects())
                warning(_("There are too many unreachable loose objects; "
                        "run 'git prune' to remove them."));
diff --combined t/t5510-fetch.sh
index 4e6d049b94c686c7d1830c8e3ad0fcea0a00a605,6f1450eb698fa5563528f2437375681577647690..62308be499ffd862484eb23de61850d00f80720c
@@@ -828,9 -828,11 +828,11 @@@ test_expect_success 'fetching with auto
        test_commit test2 &&
        (
                cd auto-gc &&
+               git config fetch.unpackLimit 1 &&
                git config gc.autoPackLimit 1 &&
                git config gc.autoDetach false &&
                GIT_ASK_YESNO="$D/askyesno" git fetch >fetch.out 2>&1 &&
+               test_i18ngrep "Auto packing the repository" fetch.out &&
                ! grep "Should I try again" fetch.out
        )
  '
@@@ -865,82 -867,4 +867,82 @@@ test_expect_success C_LOCALE_OUTPUT 'fe
        test_cmp expect actual
  '
  
 +setup_negotiation_tip () {
 +      SERVER="$1"
 +      URL="$2"
 +      USE_PROTOCOL_V2="$3"
 +
 +      rm -rf "$SERVER" client trace &&
 +      git init "$SERVER" &&
 +      test_commit -C "$SERVER" alpha_1 &&
 +      test_commit -C "$SERVER" alpha_2 &&
 +      git -C "$SERVER" checkout --orphan beta &&
 +      test_commit -C "$SERVER" beta_1 &&
 +      test_commit -C "$SERVER" beta_2 &&
 +
 +      git clone "$URL" client &&
 +
 +      if test "$USE_PROTOCOL_V2" -eq 1
 +      then
 +              git -C "$SERVER" config protocol.version 2 &&
 +              git -C client config protocol.version 2
 +      fi &&
 +
 +      test_commit -C "$SERVER" beta_s &&
 +      git -C "$SERVER" checkout master &&
 +      test_commit -C "$SERVER" alpha_s &&
 +      git -C "$SERVER" tag -d alpha_1 alpha_2 beta_1 beta_2
 +}
 +
 +check_negotiation_tip () {
 +      # Ensure that {alpha,beta}_1 are sent as "have", but not {alpha_beta}_2
 +      ALPHA_1=$(git -C client rev-parse alpha_1) &&
 +      grep "fetch> have $ALPHA_1" trace &&
 +      BETA_1=$(git -C client rev-parse beta_1) &&
 +      grep "fetch> have $BETA_1" trace &&
 +      ALPHA_2=$(git -C client rev-parse alpha_2) &&
 +      ! grep "fetch> have $ALPHA_2" trace &&
 +      BETA_2=$(git -C client rev-parse beta_2) &&
 +      ! grep "fetch> have $BETA_2" trace
 +}
 +
 +test_expect_success '--negotiation-tip limits "have" lines sent' '
 +      setup_negotiation_tip server server 0 &&
 +      GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch \
 +              --negotiation-tip=alpha_1 --negotiation-tip=beta_1 \
 +              origin alpha_s beta_s &&
 +      check_negotiation_tip
 +'
 +
 +test_expect_success '--negotiation-tip understands globs' '
 +      setup_negotiation_tip server server 0 &&
 +      GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch \
 +              --negotiation-tip=*_1 \
 +              origin alpha_s beta_s &&
 +      check_negotiation_tip
 +'
 +
 +test_expect_success '--negotiation-tip understands abbreviated SHA-1' '
 +      setup_negotiation_tip server server 0 &&
 +      GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch \
 +              --negotiation-tip=$(git -C client rev-parse --short alpha_1) \
 +              --negotiation-tip=$(git -C client rev-parse --short beta_1) \
 +              origin alpha_s beta_s &&
 +      check_negotiation_tip
 +'
 +
 +. "$TEST_DIRECTORY"/lib-httpd.sh
 +start_httpd
 +
 +test_expect_success '--negotiation-tip limits "have" lines sent with HTTP protocol v2' '
 +      setup_negotiation_tip "$HTTPD_DOCUMENT_ROOT_PATH/server" \
 +              "$HTTPD_URL/smart/server" 1 &&
 +      GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch \
 +              --negotiation-tip=alpha_1 --negotiation-tip=beta_1 \
 +              origin alpha_s beta_s &&
 +      check_negotiation_tip
 +'
 +
 +stop_httpd
 +
  test_done