fetch: skip computing output width when not printing anything

When updating references via git-fetch(1), then by default we report to the user which references have been changed. This output is formatted in a nice table such that the different columns are aligned. Because the first column contains abbreviated object IDs we thus need to iterate over all refs which have changed and compute the minimum length for their respective abbreviated hashes. While this effort makes sense in most cases, it is wasteful when the user passes the `--quiet` flag: we don't print the summary, but still compute the length. Skip computing the summary width when the user asked for us to be quiet. This gives us a speedup of nearly 10% when doing a mirror-fetch in a repository with thousands of references being updated: Benchmark 1: git fetch --quiet +refs/*:refs/* (HEAD~) Time (mean ± σ): 96.078 s ± 0.508 s [User: 91.378 s, System: 10.870 s] Range (min … max): 95.449 s … 96.760 s 5 runs Benchmark 2: git fetch --quiet +refs/*:refs/* (HEAD) Time (mean ± σ): 88.214 s ± 0.192 s [User: 83.274 s, System: 10.978 s] Range (min … max): 87.998 s … 88.446 s 5 runs Summary 'git fetch --quiet +refs/*:refs/* (HEAD)' ran 1.09 ± 0.01 times faster than 'git fetch --quiet +refs/*:refs/* (HEAD~)' Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Feb 10, 2022 at 13:28 UTC b18aaaa5e931d79d057f68ac0d7c3dd0377e5f03
1 file changed +6 -2
builtin/fetch.c
+6 -2
@@ -1094,12 +1094,15 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
1094 struct ref *rm;
1095 char *url;
1096 int want_status;
1097 - int summary_width = transport_summary_width(ref_map);
1097 + int summary_width = 0;
1098
1099 rc = open_fetch_head(&fetch_head);
1100 if (rc)
1101 return -1;
1102
1103 + if (verbosity >= 0)
1104 + summary_width = transport_summary_width(ref_map);
1105 +
1106 if (raw_url)
1107 url = transport_anonymize_url(raw_url);
1108 else
@@ -1345,7 +1348,6 @@ static int prune_refs(struct refspec *rs, struct ref *ref_map,
1348 int url_len, i, result = 0;
1349 struct ref *ref, *stale_refs = get_stale_heads(rs, ref_map);
1350 char *url;
1348 - int summary_width = transport_summary_width(stale_refs);
1351 const char *dangling_msg = dry_run
1352 ? _(" (%s will become dangling)")
1353 : _(" (%s has become dangling)");
@@ -1374,6 +1376,8 @@ static int prune_refs(struct refspec *rs, struct ref *ref_map,
1376 }
1377
1378 if (verbosity >= 0) {
1379 + int summary_width = transport_summary_width(stale_refs);
1380 +
1381 for (ref = stale_refs; ref; ref = ref->next) {
1382 struct strbuf sb = STRBUF_INIT;
1383 if (!shown_url) {