Merge branch 'jk/maint-push-progress'
authorJunio C Hamano <gitster@pobox.com>
Thu, 3 May 2012 22:13:55 +0000 (15:13 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 3 May 2012 22:13:55 +0000 (15:13 -0700)
"git push" over smart-http lost progress output and this resurrects it.

By Jeff King
* jk/maint-push-progress:
t5541: test more combinations of --progress
teach send-pack about --[no-]progress
send-pack: show progress when isatty(2)

1  2 
remote-curl.c
t/t5541-http-push.sh
diff --combined remote-curl.c
index 08962214db6f715c0416c61ce0ab70b50b7888fc,e5e9490be7b246e06a849b3d35485fc3a9903abe..04a9d6277db8fac78cb223a906b12744aab32193
@@@ -290,7 -290,6 +290,7 @@@ static void output_refs(struct ref *ref
  struct rpc_state {
        const char *service_name;
        const char **argv;
 +      struct strbuf *stdin_preamble;
        char *service_url;
        char *hdr_content_type;
        char *hdr_accept;
@@@ -536,7 -535,6 +536,7 @@@ static int rpc_service(struct rpc_stat
  {
        const char *svc = rpc->service_name;
        struct strbuf buf = STRBUF_INIT;
 +      struct strbuf *preamble = rpc->stdin_preamble;
        struct child_process client;
        int err = 0;
  
        client.argv = rpc->argv;
        if (start_command(&client))
                exit(1);
 +      if (preamble)
 +              write_or_die(client.in, preamble->buf, preamble->len);
        if (heads)
                write_or_die(client.in, heads->buf, heads->len);
  
@@@ -630,14 -626,13 +630,14 @@@ static int fetch_git(struct discovery *
        int nr_heads, struct ref **to_fetch)
  {
        struct rpc_state rpc;
 +      struct strbuf preamble = STRBUF_INIT;
        char *depth_arg = NULL;
 -      const char **argv;
        int argc = 0, i, err;
 +      const char *argv[15];
  
 -      argv = xmalloc((15 + nr_heads) * sizeof(char*));
        argv[argc++] = "fetch-pack";
        argv[argc++] = "--stateless-rpc";
 +      argv[argc++] = "--stdin";
        argv[argc++] = "--lock-pack";
        if (options.followtags)
                argv[argc++] = "--include-tag";
                argv[argc++] = depth_arg;
        }
        argv[argc++] = url;
 +      argv[argc++] = NULL;
 +
        for (i = 0; i < nr_heads; i++) {
                struct ref *ref = to_fetch[i];
                if (!ref->name || !*ref->name)
                        die("cannot fetch by sha1 over smart http");
 -              argv[argc++] = ref->name;
 +              packet_buf_write(&preamble, "%s\n", ref->name);
        }
 -      argv[argc++] = NULL;
 +      packet_buf_flush(&preamble);
  
        memset(&rpc, 0, sizeof(rpc));
        rpc.service_name = "git-upload-pack",
        rpc.argv = argv;
 +      rpc.stdin_preamble = &preamble;
        rpc.gzip_request = 1;
  
        err = rpc_service(&rpc, heads);
        if (rpc.result.len)
                safe_write(1, rpc.result.buf, rpc.result.len);
        strbuf_release(&rpc.result);
 -      free(argv);
 +      strbuf_release(&preamble);
        free(depth_arg);
        return err;
  }
@@@ -782,6 -774,7 +782,7 @@@ static int push_git(struct discovery *h
                argv[argc++] = "--quiet";
        else if (options.verbosity > 1)
                argv[argc++] = "--verbose";
+       argv[argc++] = options.progress ? "--progress" : "--no-progress";
        argv[argc++] = url;
        for (i = 0; i < nr_spec; i++)
                argv[argc++] = specs[i];
diff --combined t/t5541-http-push.sh
index 5b170be2c0a8a97b5d7a0bc1a980afa4da9c40bd,363beaf5dd673b523970d226fca49eaf38fcdfae..312e484090d1ceb392399768f2229ae553182fe7
@@@ -30,7 -30,6 +30,7 @@@ test_expect_success 'setup remote repos
        git clone --bare test_repo test_repo.git &&
        cd test_repo.git &&
        git config http.receivepack true &&
 +      git config core.logallrefupdates true &&
        ORIG_HEAD=$(git rev-parse --verify HEAD) &&
        cd - &&
        mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH"
@@@ -107,7 -106,7 +107,7 @@@ cat >exp <<EO
  remote: error: hook declined to update refs/heads/dev2
  To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git
   ! [remote rejected] dev2 -> dev2 (hook declined)
 -error: failed to push some refs to 'http://127.0.0.1:5541/smart/test_repo.git'
 +error: failed to push some refs to 'http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'
  EOF
  
  test_expect_success 'rejected update prints status' '
@@@ -168,7 -167,7 +168,7 @@@ test_expect_success 'push fails for non
  '
  
  test_expect_success 'push fails for non-fast-forward refs unmatched by remote helper: our output' '
 -      test_i18ngrep "To prevent you from losing history, non-fast-forward updates were rejected" \
 +      test_i18ngrep "Updates were rejected because" \
                output
  '
  
@@@ -216,32 -215,35 +216,55 @@@ test_expect_success 'push --mirror to r
        git push --mirror "$HTTPD_URL"/smart/alternates-mirror.git
  '
  
- test_expect_success TTY 'quiet push' '
+ test_expect_success TTY 'push shows progress when stderr is a tty' '
+       cd "$ROOT_PATH"/test_repo_clone &&
+       test_commit noisy &&
+       test_terminal git push >output 2>&1 &&
+       grep "^Writing objects" output
+ '
+ test_expect_success TTY 'push --quiet silences status and progress' '
        cd "$ROOT_PATH"/test_repo_clone &&
        test_commit quiet &&
-       test_terminal git push --quiet --no-progress 2>&1 | tee output &&
+       test_terminal git push --quiet >output 2>&1 &&
        test_cmp /dev/null output
  '
  
+ test_expect_success TTY 'push --no-progress silences progress but not status' '
+       cd "$ROOT_PATH"/test_repo_clone &&
+       test_commit no-progress &&
+       test_terminal git push --no-progress >output 2>&1 &&
+       grep "^To http" output &&
+       ! grep "^Writing objects"
+ '
+ test_expect_success 'push --progress shows progress to non-tty' '
+       cd "$ROOT_PATH"/test_repo_clone &&
+       test_commit progress &&
+       git push --progress >output 2>&1 &&
+       grep "^To http" output &&
+       grep "^Writing objects" output
+ '
 +test_expect_success 'http push gives sane defaults to reflog' '
 +      cd "$ROOT_PATH"/test_repo_clone &&
 +      test_commit reflog-test &&
 +      git push "$HTTPD_URL"/smart/test_repo.git &&
 +      git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
 +              log -g -1 --format="%gn <%ge>" >actual &&
 +      echo "anonymous <anonymous@http.127.0.0.1>" >expect &&
 +      test_cmp expect actual
 +'
 +
 +test_expect_success 'http push respects GIT_COMMITTER_* in reflog' '
 +      cd "$ROOT_PATH"/test_repo_clone &&
 +      test_commit custom-reflog-test &&
 +      git push "$HTTPD_URL"/smart_custom_env/test_repo.git &&
 +      git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
 +              log -g -1 --format="%gn <%ge>" >actual &&
 +      echo "Custom User <custom@example.com>" >expect &&
 +      test_cmp expect actual
 +'
 +
  stop_httpd
  test_done