git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 2/7] progress: allow pure-throughput progress meters

From
Toon Claes <toon@iotcl.com>
Date
Feb 19, 2025, 14:30 UTC
Message-ID
<20250219-toon-bundleuri-progress-v2-2-a84e7ffa921a@iotcl.com>
In-Reply-To
<20250219-toon-bundleuri-progress-v2-0-a84e7ffa921a@iotcl.com>
From: Jeff King <peff@peff.net>

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 <peff@peff.net>
---
 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: <CR>
+	Working hard: 200.00 KiB | 100.00 KiB/s<CR>
+	Working hard: 300.00 KiB | 100.00 KiB/s<CR>
+	Working hard: 400.00 KiB | 100.00 KiB/s<CR>
+	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 <in 2>stderr &&
+
+	show_cr <stderr >out &&
+	test_cmp expect out
+'
+
 test_expect_success 'cover up after throughput shortens' '
 	cat >expect <<-\EOF &&
 	Working hard: 1<CR>
-- 
2.48.1.658.g4767266eb4
Previous: Jeff KingNext: Toon Claes
Message 19 of 25 in “bundle-uri: show progress when downloading from bundle URIs”
  1. 0/4 bundle-uri: show progress when downloading from bundle URIsToon Claes, May 8, 2024
  2. 1/4 progress: add function to set totalToon Claes, May 8, 2024
  3. 2/4 http: add the ability to log progressToon Claes, May 8, 2024
  4. Eric SunshineMay 8, 2024
  5. Jeff KingMay 9, 2024
  6. Junio C HamanoMay 9, 2024
  7. Jeff KingMay 9, 2024
  8. Jeff KingMay 9, 2024
  9. 3/4 remote-curl: optionally show progress for HTTP getToon Claes, May 8, 2024
  10. Junio C HamanoMay 8, 2024
  11. 4/4 bundle-uri: enable git-remote-https progressToon Claes, May 8, 2024
  12. Jeff KingMay 9, 2024
  13. Toon ClaesFeb 14, 2025
  14. Jeff KingFeb 21, 2025
  15. Junio C HamanoMay 8, 2024
  16. 0/7 Show progress when downloading from bundle URIsToon Claes, Feb 19, 2025
  17. 1/7 progress: add function to set totalToon Claes, Feb 19, 2025
  18. Jeff KingFeb 21, 2025
  19. 2/7 progress: allow pure-throughput progress metersToon Claes, Feb 19, 2025
  20. 3/7 http: turn off curl signalsToon Claes, Feb 19, 2025
  21. 4/7 http: add the ability to log progressToon Claes, Feb 19, 2025
  22. 5/7 remote-curl: optionally show progress for HTTP getToon Claes, Feb 19, 2025
  23. 6/7 bundle-uri: enable git-remote-https progressToon Claes, Feb 19, 2025
  24. 7/7 http: silence stderr when progress is enabledToon Claes, Feb 19, 2025
  25. Jeff KingFeb 21, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.