From patchwork Wed Feb 19 14:30:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Toon Claes X-Patchwork-Id: 13982365 Received: from out-187.mta1.migadu.com (out-187.mta1.migadu.com [95.215.58.187]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8CF621EE033 for ; Wed, 19 Feb 2025 14:30:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.187 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975433; cv=none; b=qM00pQE+NVmaUuBnXd6o+YzYn3fjzFCafAuod7V9moFLvtK505v9suW1pXj0DupEXX+Yz0D2v6lI9PdFrEMtfxDam5c5QkGQrbtZW8h73NW61uv+TcbknkCKo1BHUHkRPcbKFC0LgzpS4vGGtaYRvNawTiVsrCN2FZDUD99xBDo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975433; c=relaxed/simple; bh=ck2NaxiBtNSGrjFUCxhbgr3gx5cLAQ4U9aiCK0etdHU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jI3axIzGX1qrIAx32kkvaBa3jmRyOdViXV5ozvJ/T0nzLcuF2U/R9f9CMIpM2c+KBbUjzh7OiPfwoxSgZ59CU5mg1MOSlrIOMYe8H6vPfz1sGL7dojMzll/R2O0dbM1g45Z6ptRLH+iClAIciJNdP+q3X99kfK3Ntjx4+aOJSFw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com; spf=fail smtp.mailfrom=iotcl.com; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b=W3FVYySh; arc=none smtp.client-ip=95.215.58.187 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=iotcl.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b="W3FVYySh" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iotcl.com; s=key1; t=1739975427; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CyZ49PjE5mJs6PKOchVpXIREqu9Yt/p3wuGT8XVdAdA=; b=W3FVYyShzLnrfs2EzSYMV0q0ckC1b6t1VkaZf1NHDGzD4SPW4zwrwzQs4wn+3xfqQZh3n2 4ypj6627s/5wYYyJC9UuudbduMAoIUMbwS3eAAIbAdnKfG18RedHKV1FtgvfwD/BIRgQaB QcV6OKLPjZLwwW3Q3qqNL0jp/mJ0zkQ= From: Toon Claes Date: Wed, 19 Feb 2025 15:30:19 +0100 Subject: [PATCH v2 1/7] progress: add function to set total Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250219-toon-bundleuri-progress-v2-1-a84e7ffa921a@iotcl.com> References: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> In-Reply-To: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> To: git@vger.kernel.org Cc: Toon Claes X-Migadu-Flow: FLOW_OUT We're about to add the use of progress through curl. Although, curl doesn't know the total at the start of the download, but might receive this information in the Content-Length header when the download starts. To allow users set the total size after calling start_progress(), add a function progress_set_total(). Signed-off-by: Toon Claes --- progress.c | 6 ++++++ progress.h | 1 + t/helper/test-progress.c | 5 +++++ t/t0500-progress-display.sh | 24 ++++++++++++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/progress.c b/progress.c index 8d5ae70f3a..e254877d2c 100644 --- a/progress.c +++ b/progress.c @@ -276,6 +276,12 @@ static struct progress *start_progress_delay(struct repository *r, return progress; } +void progress_set_total(struct progress *progress, uint64_t total) +{ + if (progress) + progress->total = total; +} + static int get_default_delay(void) { static int delay_in_secs = -1; diff --git a/progress.h b/progress.h index ed068c7bab..2e1bd738c2 100644 --- a/progress.h +++ b/progress.h @@ -15,6 +15,7 @@ void progress_test_force_update(void); void display_throughput(struct progress *progress, uint64_t total); void display_progress(struct progress *progress, uint64_t n); +void progress_set_total(struct progress *progress, uint64_t total); struct progress *start_progress(struct repository *r, const char *title, uint64_t total); struct progress *start_sparse_progress(struct repository *r, diff --git a/t/helper/test-progress.c b/t/helper/test-progress.c index 1f75b7bd19..3a73d6fe0a 100644 --- a/t/helper/test-progress.c +++ b/t/helper/test-progress.c @@ -74,6 +74,11 @@ int cmd__progress(int argc, const char **argv) if (*end != '\0') die("invalid input: '%s'", line.buf); display_progress(progress, item_count); + } else if (skip_prefix(line.buf, "total ", (const char **) &end)) { + uint64_t total = strtoull(end, &end, 10); + if (*end != '\0') + die("invalid input: '%s'\n", line.buf); + progress_set_total(progress, total); } else if (skip_prefix(line.buf, "throughput ", (const char **) &end)) { uint64_t byte_count, test_ms; diff --git a/t/t0500-progress-display.sh b/t/t0500-progress-display.sh index d1a498a216..b7ed1db3a0 100755 --- a/t/t0500-progress-display.sh +++ b/t/t0500-progress-display.sh @@ -55,6 +55,30 @@ test_expect_success 'progress display with total' ' test_cmp expect out ' +test_expect_success 'progress display modify total' ' + cat >expect <<-\EOF && + Working hard: 1 + Working hard: 66% (2/3) + Working hard: 100% (3/3) + Working hard: 100% (3/3), done. + EOF + + cat >in <<-\EOF && + start 0 + update + progress 1 + update + total 3 + progress 2 + progress 3 + stop + EOF + test-tool progress stderr && + + show_cr out && + test_cmp expect out +' + test_expect_success 'progress display breaks long lines #1' ' sed -e "s/Z$//" >expect <<\EOF && Working hard.......2.........3.........4.........5.........6: 0% (100/100000) From patchwork Wed Feb 19 14:30:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Toon Claes X-Patchwork-Id: 13982366 Received: from out-177.mta0.migadu.com (out-177.mta0.migadu.com [91.218.175.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BEAAF1EFFB6 for ; Wed, 19 Feb 2025 14:30:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975435; cv=none; b=a9y2ngWU0AdXcaQUp3u2PkcKU/fJctsJxo6WMCRc1zJt8fUZvJyfOI/RACN+3zuJRoB6Q5qoHdyK6oJ2NG2yNUcsLQDGt7GLnD2g76ISk0bV/XDiqp2pZByJ4G3HlXe6Rmo1oxdIb7gYmmmEijkrIMPI8VZ9LqWFQOYMJulqTQk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975435; c=relaxed/simple; bh=rPk043vlhaQH9ChEkN8EBTp896ZI8/rPEQOyQpiQF88=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Pscyc4vFudKbRGoJ2ypz9uB3BskVbuERiiftdbDo3OHFzzkt/E3AzCciVS/02MiX1AlQ+SinZsuiPE76XvNH/LhOd3nc33v/BCN6qOhnoYaRGWA1NAHGa1rzLUv5f7CZlPOd546YtZaDLTXWuBAqA+54J1PBoOzqJKY0sXanhwY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com; spf=fail smtp.mailfrom=iotcl.com; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b=fqNzdPvc; arc=none smtp.client-ip=91.218.175.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=iotcl.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b="fqNzdPvc" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iotcl.com; s=key1; t=1739975430; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GO7ErZSa54MYeNSwHlazE0OuP8ObuUFXmROnJRJvYC4=; b=fqNzdPvcT+6TNH1mfgIbOuvXu8QnB9gGdYAsyJhX1LenpEZNSeLGlegD93B4h+AYkLoVnN 2jUSLcUs16ZG1YzHhr80gwLdAMRkxSH/douzkhF1KrRP8Tag8blMbOw8Uo/6Dt3uxfiBrY jt6vg5AFFpHyOUUXyN23J7psDQtwoOI= From: Toon Claes Date: Wed, 19 Feb 2025 15:30:20 +0100 Subject: [PATCH v2 2/7] progress: allow pure-throughput progress meters Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250219-toon-bundleuri-progress-v2-2-a84e7ffa921a@iotcl.com> References: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> In-Reply-To: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> To: git@vger.kernel.org Cc: Toon Claes , Jeff King X-Migadu-Flow: FLOW_OUT From: Jeff King The progress code assumes we are counting something (usually objects), even if we are measuring throughput. This works for fetching packfiles, since they show us the object count alongside the throughput, like: Receiving objects: 2% (301/11968), 22.00 MiB | 10.97 MiB/s You can also tell the progress code you don't know how many items you have (by specifying a total of 0), and it looks like: Counting objects: 34957 However, if you're fetching a single large item, you want throughput but you might not have a meaningful count. You can say you are getting item 0 or 1 out of 1 total, but then the percent meter is misleading: Downloading: 0% (0/1), 22.00 MiB | 10.97 MiB/s or Downloading: 100% (0/1), 22.00 MiB | 10.97 MiB/s Neither of those is accurate. You are probably somewhere between zero and 100 percent through the operation, but you don't know how far. Telling it you don't know how many items is even uglier: Downloading: 1, 22.00 MiB | 10.97 MiB/s Instead, this patch will omit the count entirely if you are on the zero-th item of an unknown number of items. It looks like: Downloading: 22.00 MiB | 10.97 MiB/s Signed-off-by: Jeff King --- progress.c | 17 +++++++++++------ t/t0500-progress-display.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/progress.c b/progress.c index e254877d2c..89abb231ae 100644 --- a/progress.c +++ b/progress.c @@ -135,7 +135,11 @@ static void display(struct progress *progress, uint64_t n, const char *done) } } else if (progress_update) { strbuf_reset(counters_sb); - strbuf_addf(counters_sb, "%"PRIuMAX"%s", (uintmax_t)n, tp); + if (n > 0) + strbuf_addf(counters_sb, "%" PRIuMAX "%s", + (uintmax_t)n, tp); + else + strbuf_addstr(counters_sb, tp); show_update = 1; } @@ -170,11 +174,12 @@ static void display(struct progress *progress, uint64_t n, const char *done) } } -static void throughput_string(struct strbuf *buf, uint64_t total, - unsigned int rate) +static void throughput_string(struct progress *progress, struct strbuf *buf, + uint64_t total, unsigned int rate) { strbuf_reset(buf); - strbuf_addstr(buf, ", "); + if (progress->total || progress->last_value > 0) + strbuf_addstr(buf, ", "); strbuf_humanise_bytes(buf, total); strbuf_addstr(buf, " | "); strbuf_humanise_rate(buf, rate * 1024); @@ -243,7 +248,7 @@ void display_throughput(struct progress *progress, uint64_t total) tp->last_misecs[tp->idx] = misecs; tp->idx = (tp->idx + 1) % TP_IDX_MAX; - throughput_string(&tp->display, total, rate); + throughput_string(progress, &tp->display, total, rate); if (progress->last_value != -1 && progress_update) display(progress, progress->last_value, NULL); } @@ -343,7 +348,7 @@ static void force_last_update(struct progress *progress, const char *msg) unsigned int misecs, rate; misecs = ((now_ns - progress->start_ns) * 4398) >> 32; rate = tp->curr_total / (misecs ? misecs : 1); - throughput_string(&tp->display, tp->curr_total, rate); + throughput_string(progress, &tp->display, tp->curr_total, rate); } progress_update = 1; buf = xstrfmt(", %s.\n", msg); diff --git a/t/t0500-progress-display.sh b/t/t0500-progress-display.sh index b7ed1db3a0..582b9fa899 100755 --- a/t/t0500-progress-display.sh +++ b/t/t0500-progress-display.sh @@ -263,6 +263,37 @@ test_expect_success 'progress display with throughput and total' ' test_cmp expect out ' +test_expect_success 'progress display throughput without total' ' + cat >expect <<-\EOF && + Working hard: + Working hard: 200.00 KiB | 100.00 KiB/s + Working hard: 300.00 KiB | 100.00 KiB/s + Working hard: 400.00 KiB | 100.00 KiB/s + Working hard: 400.00 KiB | 100.00 KiB/s, done. + EOF + + cat >in <<-\EOF && + start 0 + throughput 102400 1000 + update + progress 0 + throughput 204800 2000 + update + progress 0 + throughput 307200 3000 + update + progress 0 + throughput 409600 4000 + update + progress 0 + stop + EOF + test-tool progress stderr && + + show_cr out && + test_cmp expect out +' + test_expect_success 'cover up after throughput shortens' ' cat >expect <<-\EOF && Working hard: 1 From patchwork Wed Feb 19 14:30:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Toon Claes X-Patchwork-Id: 13982367 Received: from out-189.mta1.migadu.com (out-189.mta1.migadu.com [95.215.58.189]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AD23F1F30BE for ; Wed, 19 Feb 2025 14:30:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.189 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975439; cv=none; b=hQm9YJfHOXMShQ2snlHrtDqlCBAf1oIqVvjSN+oqlXJ+xEe6BDALD0oml9geDI0KAmQq46YDmP3whZCmWdhWAcDijvYhd5/1AIIvAj0j6rCgpaIj1vbbWUZv+tUrI1DgkDKV4TWPJQhPXqOHhUJF9TX4w7ECM7O37sti1CDFR6A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975439; c=relaxed/simple; bh=xVvk7vEBiISqGxPLI05npULGqMd+Nx2d52kXQlrJ5AU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=X1suPe/bRfZ3/3k41OUS0/CCc1QseLqBggjHQsbRQUcwKyqdZ8v23B9+MEzBElRn2FBVWMTsQ2LrnLGCOfA7K0TeE8K2oqZopbIJTXTKjIxXSI9mAGZwG5Y0khIWgLCBP5x57Se5AinFiZ4R6H5fJFMD89hQyLWRuWZpxX8x7Gg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com; spf=fail smtp.mailfrom=iotcl.com; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b=4um/7nSp; arc=none smtp.client-ip=95.215.58.189 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=iotcl.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b="4um/7nSp" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iotcl.com; s=key1; t=1739975434; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lO+wAH5Me/7I3gimJ8kxd23x+ZQekL7Kr0gSTFpFJ2g=; b=4um/7nSpoZurnj8Ux3qAmEPSnuBJbT2pIktiNbGFYgsKNqB4cULUazVq1URECTEP1OjV3I MXnAZcwASWYTMlXJoNVd0lMBNloWzb3sDsNiXdBovjvE3NpwPR5Cwu+CLyGgGK4tNLT0m1 oPlvNvXudWwv0ap2tntKMdwGJi9D9fM= From: Toon Claes Date: Wed, 19 Feb 2025 15:30:21 +0100 Subject: [PATCH v2 3/7] http: turn off curl signals Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250219-toon-bundleuri-progress-v2-3-a84e7ffa921a@iotcl.com> References: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> In-Reply-To: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> To: git@vger.kernel.org Cc: Toon Claes , Jeff King X-Migadu-Flow: FLOW_OUT From: Jeff King Curl sets and clears the handler for SIGALRM, which makes it incompatible with git's progress code. However, we can ask curl not to do this. Signed-off-by: Jeff King --- http.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/http.c b/http.c index f4504133e8..38c7c0cd54 100644 --- a/http.c +++ b/http.c @@ -1245,6 +1245,8 @@ static CURL *get_curl_handle(void) set_curl_keepalive(result); + curl_easy_setopt(result, CURLOPT_NOSIGNAL, 1); + return result; } From patchwork Wed Feb 19 14:30:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Toon Claes X-Patchwork-Id: 13982368 Received: from out-184.mta0.migadu.com (out-184.mta0.migadu.com [91.218.175.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 951381F3BBC for ; Wed, 19 Feb 2025 14:30:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.184 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975441; cv=none; b=P6MzowLnmzrhpS4mdwMaPRu3ertHPI1FmijOdn1C1weIDzzlJbdiS2eP0kFa95Xo5f5fKYv8Vt6kxIECxCM6oDd5Uh8zvYZ3STg+mXVl7QqHOAVq+8HJV0jaoSEfqMU7nRzTmitfOfzNbXnE0qUFsDenk32kmkj8bxFe/IYsxTE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975441; c=relaxed/simple; bh=5ukjsvcucFdC0q9d9SUNvqg7U1G51qKwM1DUZ2RpfzQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kS2SJNdTtv/k2qOUqorF/9tpRSaCTbk/jmp6US8VkztuhlUTrXPlwBsS2dCNUxQhqP8frZe8gZhA7OXUMLue0XkMWrvqUddkrmqfu8Beh7WDzDmgynYyvzIu+5okNdZAd/B33adr9MQ4CHc5WL24OvXijCdO2MEkwjzIm9KjiJ0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com; spf=fail smtp.mailfrom=iotcl.com; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b=le1fDC9E; arc=none smtp.client-ip=91.218.175.184 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=iotcl.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b="le1fDC9E" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iotcl.com; s=key1; t=1739975437; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vesGT84jNYl9mSAJzGDDCOzw9+qfAUK8+az7ekNtVYo=; b=le1fDC9E4H91a0/vIU6vm3Lc3HJ//ZQEfXIAPt/zbQLTE0cAi3dvTj4wfDPW/saoeBp3fN W/RW0Iyiu7XzHewViUafrSKx13MFvk8DjAeINuOEdmB4rXRDKRBItBYTXg1GOKJEaP+70a DZKCRaY1OpyYmlRrJMMCifhD2xPxFxc= From: Toon Claes Date: Wed, 19 Feb 2025 15:30:22 +0100 Subject: [PATCH v2 4/7] http: add the ability to log progress Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250219-toon-bundleuri-progress-v2-4-a84e7ffa921a@iotcl.com> References: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> In-Reply-To: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> To: git@vger.kernel.org Cc: Toon Claes X-Migadu-Flow: FLOW_OUT Add an option `progress` to `struct http_get_options` to allow the caller to enable download progress using the progress.c API. Signed-off-by: Toon Claes --- http.c | 34 ++++++++++++++++++++++++++++++++++ http.h | 5 +++++ 2 files changed, 39 insertions(+) diff --git a/http.c b/http.c index 38c7c0cd54..5517863808 100644 --- a/http.c +++ b/http.c @@ -13,6 +13,7 @@ #include "credential.h" #include "version.h" #include "pkt-line.h" +#include "progress.h" #include "gettext.h" #include "trace.h" #include "transport.h" @@ -1504,6 +1505,9 @@ struct active_request_slot *get_active_slot(void) curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1); curl_easy_setopt(slot->curl, CURLOPT_RANGE, NULL); + curl_easy_setopt(slot->curl, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(slot->curl, CURLOPT_XFERINFODATA, NULL); + curl_easy_setopt(slot->curl, CURLOPT_XFERINFOFUNCTION, NULL); /* * Default following to off unless "ALWAYS" is configured; this gives @@ -2068,6 +2072,21 @@ static void http_opt_request_remainder(CURL *curl, off_t pos) #define HTTP_REQUEST_STRBUF 0 #define HTTP_REQUEST_FILE 1 +static int http_progress_callback(void *clientp, curl_off_t dltotal, + curl_off_t dlnow, curl_off_t ultotal UNUSED, + curl_off_t ulnow UNUSED) +{ + struct progress *progress = clientp; + + if (progress) { + progress_set_total(progress, dltotal); + display_progress(progress, dlnow); + display_throughput(progress, dlnow); + } + + return 0; +} + static int http_request(const char *url, void *result, int target, const struct http_get_options *options) @@ -2076,6 +2095,7 @@ static int http_request(const char *url, struct slot_results results; struct curl_slist *headers = http_copy_default_headers(); struct strbuf buf = STRBUF_INIT; + struct progress *progress = NULL; const char *accept_language; int ret; @@ -2112,6 +2132,13 @@ static int http_request(const char *url, if (options && options->initial_request && http_follow_config == HTTP_FOLLOW_INITIAL) curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 1); + if (options && options->progress) { + progress = start_progress(the_repository, _("Downloading via HTTP"), 0); + + curl_easy_setopt(slot->curl, CURLOPT_NOPROGRESS, 0L); + curl_easy_setopt(slot->curl, CURLOPT_XFERINFODATA, progress); + curl_easy_setopt(slot->curl, CURLOPT_XFERINFOFUNCTION, &http_progress_callback); + } headers = curl_slist_append(headers, buf.buf); @@ -2134,6 +2161,13 @@ static int http_request(const char *url, ret = run_one_slot(slot, &results); + if (progress) { + curl_easy_setopt(slot->curl, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(slot->curl, CURLOPT_XFERINFODATA, NULL); + curl_easy_setopt(slot->curl, CURLOPT_XFERINFOFUNCTION, NULL); + stop_progress(&progress); + } + if (options && options->content_type) { struct strbuf raw = STRBUF_INIT; curlinfo_strbuf(slot->curl, CURLINFO_CONTENT_TYPE, &raw); diff --git a/http.h b/http.h index 36202139f4..09ebbdfefe 100644 --- a/http.h +++ b/http.h @@ -146,6 +146,11 @@ struct http_get_options { * request has completed. */ struct string_list *extra_headers; + + /* + * If not zero, display the progress. + */ + int progress; }; /* Return values for http_get_*() */ From patchwork Wed Feb 19 14:30:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Toon Claes X-Patchwork-Id: 13982369 Received: from out-188.mta0.migadu.com (out-188.mta0.migadu.com [91.218.175.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 314AF1F3BBC for ; Wed, 19 Feb 2025 14:30:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975446; cv=none; b=C28esoI32VxkpWVWcgx81dUfKS+LULqGUDM9DRYKnD/O4kn9nJBF2q8CPcniH5YbSyyql6qW6wcnPqdJxdwd9eRWCQy31VAekY2rv4DEpIdZtVZ9reIE7NPZxstP8mLlDAtBN2WXrwmsDRMFMggOxoROWSdtQzDXvxK1TidUP+0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975446; c=relaxed/simple; bh=IZVu+H15wECpIcgG9JuF2Dyl4ag64WDbS0W9QcxqYsU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UKQxlXgSb1BSb0K4Ke1iVzgxYxE+9n3hBIvxqx1neBouxjC5HBe8ssTer4ppscVSrymy5NEYKoigXzKvoaUo7uIPUUjph1B/LDF9rVdBTTDivoPLVQXSeb0M+BCeqQeeSFdFwdD5AR6U46arim8AERScMa9TbIeFpLkx4swmkH0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com; spf=fail smtp.mailfrom=iotcl.com; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b=YfW9Ef1m; arc=none smtp.client-ip=91.218.175.188 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=iotcl.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b="YfW9Ef1m" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iotcl.com; s=key1; t=1739975440; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+fVqSQFfDknsvCxZ8e3E23RsjAZI1DHBzRa3fve39Jc=; b=YfW9Ef1mzPgU9dngjZYZXf0KieZAWvnJTaqz8YBy5mZHnVxX4YW6QoDCb+o2cLmqDm0dwz CCE+NrEYCVkgztVG/WuBZsZiUCfIokQnU2WkumVq7z5dC/J1Q3UR0/AtiH56L+5d925uhk xykh8WFxEBFpIz092l5c5KyHTMa7aBA= From: Toon Claes Date: Wed, 19 Feb 2025 15:30:23 +0100 Subject: [PATCH v2 5/7] remote-curl: optionally show progress for HTTP get Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250219-toon-bundleuri-progress-v2-5-a84e7ffa921a@iotcl.com> References: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> In-Reply-To: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> To: git@vger.kernel.org Cc: Toon Claes X-Migadu-Flow: FLOW_OUT git-remote-curl supports the `option progress` basically since it's inception. But this option had no effect for regular HTTP(S) downloads. Add progress indicator when downloading files through curl HTTP GET. Signed-off-by: Toon Claes --- remote-curl.c | 8 +++++++- t/t5557-http-get.sh | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/remote-curl.c b/remote-curl.c index 1273507a96..f710d6b3cb 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -1317,6 +1317,7 @@ static void parse_get(const char *arg) { struct strbuf url = STRBUF_INIT; struct strbuf path = STRBUF_INIT; + struct http_get_options http_options = {0}; const char *space; space = strchr(arg, ' '); @@ -1327,7 +1328,12 @@ static void parse_get(const char *arg) strbuf_add(&url, arg, space - arg); strbuf_addstr(&path, space + 1); - if (http_get_file(url.buf, path.buf, NULL)) + http_options.initial_request = 1; + + if (options.progress) + http_options.progress = 1; + + if (http_get_file(url.buf, path.buf, &http_options)) die(_("failed to download file at URL '%s'"), url.buf); strbuf_release(&url); diff --git a/t/t5557-http-get.sh b/t/t5557-http-get.sh index 67fcc23f11..41f3d16ef9 100755 --- a/t/t5557-http-get.sh +++ b/t/t5557-http-get.sh @@ -35,4 +35,19 @@ test_expect_success 'get by URL: 200' ' test_cmp "$HTTPD_DOCUMENT_ROOT_PATH/exists.txt" file2 ' +test_expect_success 'get by URL with progress' ' + echo hello >"$HTTPD_DOCUMENT_ROOT_PATH/hello.txt" && + + url="$HTTPD_URL/hello.txt" && + cat >input <<-EOF && + capabilities + option progress true + get $url file3 + + EOF + + git remote-http $url err && + test_grep "^Downloading via HTTP: 100%" err +' + test_done From patchwork Wed Feb 19 14:30:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Toon Claes X-Patchwork-Id: 13982370 Received: from out-188.mta1.migadu.com (out-188.mta1.migadu.com [95.215.58.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AC6D91EFFBA for ; Wed, 19 Feb 2025 14:30:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975447; cv=none; b=Kl8SHVmihINzWBfuSTEfen50MupcZa/BG20xKZoqJIpf9FWIKRbtcjA3Ogr1MSebluDBH+vOlQBTL82czXkI9W7q95648S3qrkj3IVeuiUMP2DeJFWzVPBHXaFU0L8MF0c6U9YYWWcEZju8/KEb6szNYDN56TCIjXv0Wbr9oN2M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975447; c=relaxed/simple; bh=bV2JtYgd58+snXTd6oOUZ6/R2V/BxZ3GK4cbI2KfH/s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qwdc2UgJkq+C+WU9ZGpTFnuoLhvACuQsYZcJAwc9X3UWU63bUtaB81gW2CFZ4iB+6fJhjTfEEBE8/tZhWKB1rAhCvFA4jBOODVrre0gZ1jh2k/nuM7mu9uDdjqy9u8u/ESzREFE5A4s9VO2HzoK3fZsgpM0jLbMLFBcdXQaFkCQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com; spf=fail smtp.mailfrom=iotcl.com; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b=ra+Qd57O; arc=none smtp.client-ip=95.215.58.188 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=iotcl.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b="ra+Qd57O" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iotcl.com; s=key1; t=1739975443; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9je5gL906t30/+gI4ocC72T8uh20JLe7rRStNv7GDaQ=; b=ra+Qd57OeT5MUbuVoPgpvdJ/4W/a82vJuUE1rI8Qgoy4WjetofPNZ8aA1iDSmQZZiYQ8SU vYGXXyj+cPN8wAsA/LvsrjQPVFtkhAQMfxqBeVJBxWZh8yRWaKp3OxV1U6gR3FrUhn4sja Fm/qQA82lqcrwWt9kqn81XuYYDB6NFY= From: Toon Claes Date: Wed, 19 Feb 2025 15:30:24 +0100 Subject: [PATCH v2 6/7] bundle-uri: enable git-remote-https progress Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250219-toon-bundleuri-progress-v2-6-a84e7ffa921a@iotcl.com> References: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> In-Reply-To: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> To: git@vger.kernel.org Cc: Toon Claes X-Migadu-Flow: FLOW_OUT When using bundle URIs large files might get downloaded during clone. During that time, there's no feedback to the user what is happening. Enable HTTP download progress for bundle URIs to inform the user. Signed-off-by: Toon Claes --- bundle-uri.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundle-uri.c b/bundle-uri.c index 744257c49c..0ef96cd00f 100644 --- a/bundle-uri.c +++ b/bundle-uri.c @@ -298,7 +298,6 @@ static int download_https_uri_to_file(const char *file, const char *uri) int found_get = 0; strvec_pushl(&cp.args, "git-remote-https", uri, NULL); - cp.err = -1; cp.in = -1; cp.out = -1; @@ -333,6 +332,7 @@ static int download_https_uri_to_file(const char *file, const char *uri) goto cleanup; } + fprintf(child_in, "option progress true\n"); fprintf(child_in, "get %s %s\n\n", uri, file); cleanup: From patchwork Wed Feb 19 14:30:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Toon Claes X-Patchwork-Id: 13982371 Received: from out-188.mta1.migadu.com (out-188.mta1.migadu.com [95.215.58.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EFC331F2BA7 for ; Wed, 19 Feb 2025 14:30:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975451; cv=none; b=c1dzks4GzGR6jAgQnqUd7XlG8eJXc0mmNIN0VgINIpAQNViDJaPimHFTeL2LnNA+58rUD5wwi6osM5IjbU8ZEp/fXwnFTbkLdgz23KzsmgLi5xVEPGqSMuCvbdh3KdMdzxUkjdQJ/tA/gJfVOIOG4/vMdk3p6kyr8r19M4Qqlbo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739975451; c=relaxed/simple; bh=/4sK7zh25CrrYQR3GvYRTHfdLJGeIsx7Rm+bg7jEQwk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YXIwAAM2r5h2YJltaZzRFppqyoYFOBnBnbH1wcMczZNPgI89WOO1J6kkVS60AjkdfpmdV0dgxn7S9XilQdPIEeymvgv8tLkj/MyUOrrRks8ucOULQzTuPjtMYo/v5UkZjsqcTstWJNd9lsFZleg858JzdL5h9YT406g+qXU/gKA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com; spf=fail smtp.mailfrom=iotcl.com; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b=sIbHkt/C; arc=none smtp.client-ip=95.215.58.188 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=iotcl.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=iotcl.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=iotcl.com header.i=@iotcl.com header.b="sIbHkt/C" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iotcl.com; s=key1; t=1739975448; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=C6poHB484Uy9A9aqVi2HtVMRtKVtYU3qqD1Fgqp6DYQ=; b=sIbHkt/CpM/lHzPP25ticmWB9EGMb2OiryHAOgWYh24zsI0MstRwK11+P4PbdCTQKoB10r +EZC6gNHmdFevMdOJfXQMX7BAkbB1zTjUoy2k0xFIMkHJFGi4XWig+9GPakaar0dCF/bZH huB3/bxrAAPBn0SO8Ec4uYVOPNkGdhs= From: Toon Claes Date: Wed, 19 Feb 2025 15:30:25 +0100 Subject: [PATCH v2 7/7] http: silence stderr when progress is enabled Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250219-toon-bundleuri-progress-v2-7-a84e7ffa921a@iotcl.com> References: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> In-Reply-To: <20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com> To: git@vger.kernel.org Cc: Toon Claes X-Migadu-Flow: FLOW_OUT To download bundle URI bundles over HTTP(s), git-clone(1) spawns a git-remote-http(1) subprocess. Because clone can continue without bundles, all errors sent by the child process over stderr are suppressed. In previous commits, we've added progress output in the child process, and this happens over stderr, so we can no longer silence stderr. But in case a bundle could not be downloaded, the user sees the following messages: fatal: failed to download file at URL 'http://127.0.0.1:5558/bundle-5.bundle' warning: failed to download bundle from URI 'http://127.0.0.1:5558/bundle-5.bundle' Here the child git-remote-http(1) prints a "fatal" error and then the parent git-clone(1) prints a "warning". This is confusing to the user. Instead of suppressing stderr from the parent process, like we did before, modify stderr to write to /dev/null in the child process itself, while keep using the original stderr for progress logging only. Signed-off-by: Toon Claes --- http.c | 5 ++++- progress.c | 17 +++++++++++++---- progress.h | 1 + 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/http.c b/http.c index 5517863808..5c0c6ef204 100644 --- a/http.c +++ b/http.c @@ -2133,7 +2133,10 @@ static int http_request(const char *url, http_follow_config == HTTP_FOLLOW_INITIAL) curl_easy_setopt(slot->curl, CURLOPT_FOLLOWLOCATION, 1); if (options && options->progress) { - progress = start_progress(the_repository, _("Downloading via HTTP"), 0); + progress = start_progress(the_repository, + _("Downloading via HTTP"), 0); + progress_set_fd(progress, fileno(stderr)); + freopen("/dev/null", "w", stderr); curl_easy_setopt(slot->curl, CURLOPT_NOPROGRESS, 0L); curl_easy_setopt(slot->curl, CURLOPT_XFERINFODATA, progress); diff --git a/progress.c b/progress.c index 89abb231ae..1955262000 100644 --- a/progress.c +++ b/progress.c @@ -40,6 +40,7 @@ struct progress { const char *title; uint64_t last_value; uint64_t total; + int fd; unsigned last_percent; unsigned delay; unsigned sparse; @@ -144,7 +145,9 @@ static void display(struct progress *progress, uint64_t n, const char *done) } if (show_update) { - if (is_foreground_fd(fileno(stderr)) || done) { + int fd = progress->fd ? progress->fd : fileno(stderr); + + if (is_foreground_fd(fd) || done) { const char *eol = done ? done : "\r"; size_t clear_len = counters_sb->len < last_count_len ? last_count_len - counters_sb->len + 1 : @@ -155,17 +158,17 @@ static void display(struct progress *progress, uint64_t n, const char *done) int cols = term_columns(); if (progress->split) { - fprintf(stderr, " %s%*s", counters_sb->buf, + dprintf(fd, " %s%*s", counters_sb->buf, (int) clear_len, eol); } else if (!done && cols < progress_line_len) { clear_len = progress->title_len + 1 < cols ? cols - progress->title_len - 1 : 0; - fprintf(stderr, "%s:%*s\n %s%s", + dprintf(fd, "%s:%*s\n %s%s", progress->title, (int) clear_len, "", counters_sb->buf, eol); progress->split = 1; } else { - fprintf(stderr, "%s: %s%*s", progress->title, + dprintf(fd, "%s: %s%*s", progress->title, counters_sb->buf, (int) clear_len, eol); } fflush(stderr); @@ -287,6 +290,12 @@ void progress_set_total(struct progress *progress, uint64_t total) progress->total = total; } +void progress_set_fd(struct progress *progress, int fd) +{ + if (progress) + progress->fd = fd; +} + static int get_default_delay(void) { static int delay_in_secs = -1; diff --git a/progress.h b/progress.h index 2e1bd738c2..f12c82adc4 100644 --- a/progress.h +++ b/progress.h @@ -16,6 +16,7 @@ void progress_test_force_update(void); void display_throughput(struct progress *progress, uint64_t total); void display_progress(struct progress *progress, uint64_t n); void progress_set_total(struct progress *progress, uint64_t total); +void progress_set_fd(struct progress *progress, int fd); struct progress *start_progress(struct repository *r, const char *title, uint64_t total); struct progress *start_sparse_progress(struct repository *r,