[4/5] progress: clear previous progress update dynamically
diff mbox series

Message ID 20190325103844.26749-5-szeder.dev@gmail.com
State New
Headers show
  • Progress display fixes
Related show

Commit Message

SZEDER Gábor March 25, 2019, 10:38 a.m. UTC
When the progress bar includes throughput, its length can shorten as
the unit of display changes from KiB to MiB.  To cover up remnants of
the previous progress bar when such a change of units happens we
always print three spaces at the end of the progress bar.

Alas, covering only three characters is not quite enough: when both
the total and the throughput happen to change units from KiB to MiB in
the same update, then the progress bar's length is shortened by four

  Receiving objects:  25% (2901/11603), 772.01 KiB | 733.00 KiB/s
  Receiving objects:  27% (3133/11603), 1.43 MiB | 1.16 MiB/s   s

and a stray 's' is left behind.

So instead of hard-coding the three characters to cover, let's compare
the length of the current progress bar with the previous one, and
cover up as many characters as needed.

Sure, it would be much simpler to just print four spaces instead of
three at the end of the progress bar, but this approach is more
future-proof, and it won't print extra spaces when none are needed,
notably when the progress bar doesn't show throughput and thus never

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
 progress.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff mbox series

diff --git a/progress.c b/progress.c
index 390d2487ca..b37a5398c5 100644
--- a/progress.c
+++ b/progress.c
@@ -84,6 +84,7 @@  static void display(struct progress *progress, uint64_t n, const char *done)
 	const char *tp;
 	struct strbuf *counters_sb = &progress->counters_sb;
 	int update = 0;
+	int last_count_len = counters_sb->len;
 	if (progress->delay && (!progress_update || --progress->delay))
@@ -115,10 +116,11 @@  static void display(struct progress *progress, uint64_t n, const char *done)
 	if (update) {
-		const char *eol = done ? done : "   \r";
-		fprintf(stderr, "%s: %s%s", progress->title, counters_sb->buf,
-			eol);
+		const char *eol = done ? done : "\r";
+		int clear_len = counters_sb->len < last_count_len ?
+				last_count_len - counters_sb->len : 0;
+		fprintf(stderr, "%s: %s%-*s", progress->title,
+			counters_sb->buf, clear_len, eol);
 		progress_update = 0;