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

[RFC/PATCH] git-fetch: mega-terse fetch output

From
Jeff King <peff@peff.net>
Date
Oct 19, 2007, 06:22 UTC
Message-ID
<20071019062219.GA28499@coredump.intra.peff.net>

This makes the fetch output much more terse. It is likely to be very controversial. Here's an example of the new output:

Indexing objects: 100% (1061/1061), done.
Resolving deltas: 100% (638/638), done.
==> git://repo.or.cz/git/spearce.git
 * branch gitk -> origin/gitk
 * branch maint -> origin/maint (fast forward)
 * branch master -> origin/master (fast forward)
 * branch next -> origin/next (fast forward)
 - branch pu -> origin/pu (non-fast forward, refused)
 * branch todo -> origin/todo (fast forward)
==> git://repo.or.cz/git/spearce.git
 * tag v1.5.3.2 -> v1.5.3.2
Particular changes include:
  - rather than each updated ref stating the remote url, the
    url is printed once before any refs
  - refs which did not update get a '-' rather than a '*'
  - the order is changed from "$to: storing $from" to
    "$from -> $to"
  - we abbreviate the local refs (chopping refs/heads,
    refs/tags, refs/remotes). This means we're losing
    information, but hopefully it is obvious when storing
    "origin/master" that it is in refs/remotes.
  - fast forward information goes at the end
  - cut out "Auto-following ..." text
What do people think? Some changes? All?
Other questions:
  - Is the "==>" too ugly? It needs to be short (many urls
    are almost 80 characters already), and it needs to stand
    out from the "resolving deltas" line, so I think some
    symbol is reasonable.
  - Should we omit "(fast forward)" since it is the usual
    case?
  - Should refs/remotes/* keep the "remotes/" part?
  - If you read the patch, there are a few cases covered
    that I don't show in the example. Are they ugly or
    better? I can't even figure out how to
    get the '==' case to show up.
  - Should tags always just say "tag $foo". Do we ever
    actually map the tags when following?
  - How annoying is the doubled '==> $url' line? It comes
    from the fact that we fetch the tags separately.

Somebody mentioned colorization on irc. I think that is reasonable but should definitely wait for another patch.

---
 builtin-fetch.c |   73 +++++++++++++++++++++++++------------------------------
 1 files changed, 33 insertions(+), 40 deletions(-)
It drops more lines than it adds, so it _must_ be good!
diff --git a/builtin-fetch.c b/builtin-fetch.c
index 3442f3d..4440521 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -123,12 +123,6 @@ static struct ref *get_ref_map(struct transport *transport,
 	return ref_map;
 }
 
-static void show_new(enum object_type type, unsigned char *sha1_new)
-{
-	fprintf(stderr, "  %s: %s\n", typename(type),
-		find_unique_abbrev(sha1_new, DEFAULT_ABBREV));
-}
-
 static int s_update_ref(const char *action,
 			struct ref *ref,
 			int check_old)
@@ -157,6 +151,11 @@ static int update_local_ref(struct ref *ref,
 	struct commit *current = NULL, *updated;
 	enum object_type type;
 	struct branch *current_branch = branch_get(NULL);
+	const char *pretty_ref = ref->name + (
+		!prefixcmp(ref->name, "refs/heads/") ? 11 :
+		!prefixcmp(ref->name, "refs/tags/") ? 10 :
+		!prefixcmp(ref->name, "refs/remotes/") ? 13 :
+		0);
 
 	type = sha1_object_info(ref->new_sha1, NULL);
 	if (type < 0)
@@ -164,19 +163,15 @@ static int update_local_ref(struct ref *ref,
 
 	if (!*ref->name) {
 		/* Not storing */
-		if (verbose) {
-			fprintf(stderr, "* fetched %s\n", note);
-			show_new(type, ref->new_sha1);
-		}
+		if (verbose)
+			fprintf(stderr, " * branch %s -> FETCH_HEAD\n", note);
 		return 0;
 	}
 
 	if (!hashcmp(ref->old_sha1, ref->new_sha1)) {
-		if (verbose) {
-			fprintf(stderr, "* %s: same as %s\n",
-				ref->name, note);
-			show_new(type, ref->new_sha1);
-		}
+		if (verbose)
+			fprintf(stderr, " - %s == %s\n",
+				note, pretty_ref);
 		return 0;
 	}
 
@@ -189,30 +184,33 @@ static int update_local_ref(struct ref *ref,
 		 * the head, and the old value of the head isn't empty...
 		 */
 		fprintf(stderr,
-			" * %s: Cannot fetch into the current branch.\n",
-			ref->name);
+			" - %s: Cannot fetch into the current branch.\n",
+			pretty_ref);
 		return 1;
 	}
 
 	if (!is_null_sha1(ref->old_sha1) &&
 	    !prefixcmp(ref->name, "refs/tags/")) {
-		fprintf(stderr, "* %s: updating with %s\n",
-			ref->name, note);
-		show_new(type, ref->new_sha1);
+		fprintf(stderr, " * tag %s -> %s\n",
+			note, pretty_ref);
 		return s_update_ref("updating tag", ref, 0);
 	}
 
 	current = lookup_commit_reference(ref->old_sha1);
 	updated = lookup_commit_reference(ref->new_sha1);
 	if (!current || !updated) {
-		char *msg;
-		if (!strncmp(ref->name, "refs/tags/", 10))
+		const char *msg;
+		const char *what;
+		if (!strncmp(ref->name, "refs/tags/", 10)) {
 			msg = "storing tag";
-		else
+			what = "tag";
+		}
+		else {
 			msg = "storing head";
-		fprintf(stderr, "* %s: storing %s\n",
-			ref->name, note);
-		show_new(type, ref->new_sha1);
+			what = "branch";
+		}
+		fprintf(stderr, " * %s %s -> %s\n",
+			what, note, pretty_ref);
 		return s_update_ref(msg, ref, 0);
 	}
 
@@ -220,23 +218,19 @@ static int update_local_ref(struct ref *ref,
 	strcpy(newh, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
 
 	if (in_merge_bases(current, &updated, 1)) {
-		fprintf(stderr, "* %s: fast forward to %s\n",
-			ref->name, note);
-		fprintf(stderr, "  old..new: %s..%s\n", oldh, newh);
+		fprintf(stderr, " * branch %s -> %s (fast forward)\n",
+			note, pretty_ref);
 		return s_update_ref("fast forward", ref, 1);
 	}
 	if (!force && !ref->force) {
 		fprintf(stderr,
-			"* %s: not updating to non-fast forward %s\n",
-			ref->name, note);
-		fprintf(stderr,
-			"  old...new: %s...%s\n", oldh, newh);
+			" - branch %s -> %s (non-fast forward, refused)\n",
+			note, pretty_ref);
 		return 1;
 	}
 	fprintf(stderr,
-		"* %s: forcing update to non-fast forward %s\n",
-		ref->name, note);
-	fprintf(stderr, "  old...new: %s...%s\n", oldh, newh);
+		" * branch %s -> %s (non-fast forward)\n",
+		note, pretty_ref);
 	return s_update_ref("forced-update", ref, 1);
 }
 
@@ -249,6 +243,8 @@ static void store_updated_refs(const char *url, struct ref *ref_map)
 	const char *what, *kind;
 	struct ref *rm;
 
+	fprintf(stderr, "==> %s\n", url);
+
 	fp = fopen(git_path("FETCH_HEAD"), "a");
 	for (rm = ref_map; rm; rm = rm->next) {
 		struct ref *ref = NULL;
@@ -308,7 +304,7 @@ static void store_updated_refs(const char *url, struct ref *ref_map)
 			note);
 
 		if (ref)
-			update_local_ref(ref, note, verbose);
+			update_local_ref(ref, what, verbose);
 	}
 	fclose(fp);
 }
@@ -368,9 +364,6 @@ static struct ref *find_non_local_tags(struct transport *transport,
 		if (!path_list_has_path(&existing_refs, ref_name) &&
 		    !path_list_has_path(&new_refs, ref_name) &&
 		    lookup_object(ref->old_sha1)) {
-			fprintf(stderr, "Auto-following %s\n",
-				ref_name);
-
 			path_list_insert(ref_name, &new_refs);
 
 			rm = alloc_ref(strlen(ref_name) + 1);
-- 
1.5.3.4.1252.g21baf-dirty
Next: David Symonds
Message 1 of 40 in “git-fetch: mega-terse fetch output”
  1. git-fetch: mega-terse fetch outputJeff King, Oct 19, 2007
  2. David SymondsOct 19, 2007
  3. Jeff KingOct 19, 2007
  4. Shawn O. PearceOct 19, 2007
  5. Jeff KingOct 19, 2007
  6. Shawn O. PearceOct 19, 2007
  7. Jeff KingOct 19, 2007
  8. Johannes SixtOct 19, 2007
  9. Santi BéjarOct 19, 2007
  10. Theodore TsoOct 19, 2007
  11. Johannes SixtOct 19, 2007
  12. Nicolas PitreOct 19, 2007
  13. Johannes SchindelinOct 19, 2007
  14. Santi BéjarOct 19, 2007
  15. Karl HasselströmOct 19, 2007
  16. Johannes SixtOct 19, 2007
  17. Nicolas PitreOct 19, 2007
  18. Johannes SchindelinOct 19, 2007
  19. Nicolas PitreOct 19, 2007
  20. Nicolas PitreOct 19, 2007
  21. Jeff KingOct 20, 2007
  22. Shawn O. PearceOct 20, 2007
  23. Karl HasselströmOct 19, 2007
  24. Nicolas PitreOct 19, 2007
  25. Theodore TsoOct 19, 2007
  26. Nicolas PitreOct 19, 2007
  27. Theodore TsoOct 19, 2007
  28. Nicolas PitreOct 19, 2007
  29. Miles BaderOct 23, 2007
  30. Andreas EricssonOct 19, 2007
  31. Andreas EricssonOct 19, 2007
  32. Nicolas PitreOct 19, 2007
  33. Steven GrimmOct 19, 2007
  34. Steven GrimmOct 19, 2007
  35. Nicolas PitreOct 19, 2007
  36. Sam RavnborgOct 19, 2007
  37. Nicolas PitreOct 19, 2007
  38. Andreas EricssonOct 19, 2007
  39. David KastrupOct 19, 2007
  40. Jeff KingOct 19, 2007

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.