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

[PATCH] git-name-rev: accept list of refs from user

From
Jeff King <peff@peff.net>
Date
Feb 17, 2007, 23:13 UTC
Message-ID
<20070217231327.GA5382@coredump.intra.peff.net>
In-Reply-To
<7vmz3ctzer.fsf@assigned-by-dhcp.cox.net>
This lets you do things like
  git show-ref | grep /v1 | git name-rev --refs-from=- $commit
or even
  git show-ref | ./some_complex_ref_filter >refs
  git name-rev --refs-from=refs --stdin <list_of_commits
Signed-off-by: Jeff King <peff@peff.net>
---
On Sat, Feb 17, 2007 at 10:25:00AM -0800, Junio C Hamano wrote:
>> git show-ref | grep tags/v1.4 | git name-rev --stdin-refs 33db5f4d
> FWIW, I like that.

Here it is (I chose --refs-from= so you could use it with the existing --stdin flag). We might want to do the same for git-describe, I would think (they can probably share the for_each_ref_from_file code).

The input format is "sha1 ref"; clearly it could also accept just "ref", and look up the sha1, but I expect most people will just be piping from git-show-ref anyway.

 Documentation/git-name-rev.txt |   16 +++++++++++-
 builtin-name-rev.c             |   54 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt
index 37fbf66..d2fb3bb 100644
--- a/Documentation/git-name-rev.txt
+++ b/Documentation/git-name-rev.txt
@@ -8,7 +8,7 @@ git-name-rev - Find symbolic names for given revs
 
 SYNOPSIS
 --------
-'git-name-rev' [--tags] ( --all | --stdin | <committish>... )
+'git-name-rev' [--tags] [--refs-from=<file>] ( --all | --stdin | <committish>... )
 
 DESCRIPTION
 -----------
@@ -22,6 +22,13 @@ OPTIONS
 --tags::
 	Do not use branch names, but only tags to name the commits
 
+--refs-from=<file>::
+	Instead of choosing a name based on all refs, read refs from <file>,
+	one per line, in the form "sha1 ref". This is the same as the
+	default output generated by "git show-ref". If <file> is "-",
+	read from stdin. The --tags option is still respected when using
+	--refs-from.
+
 --all::
 	List all commits reachable from all refs
 
@@ -52,6 +59,13 @@ Another nice thing you can do is:
 % git log | git name-rev --stdin
 ------------
 
+You can filter the commits used to describe a commit using the --refs-from
+option:
+
+------------
+% git show-ref | grep tags/v1 | git name-rev --refs-from=- 26cfcfbf
+------------
+
 
 Author
 ------
diff --git a/builtin-name-rev.c b/builtin-name-rev.c
index b4f15cc..c8480d2 100644
--- a/builtin-name-rev.c
+++ b/builtin-name-rev.c
@@ -5,7 +5,7 @@
 #include "refs.h"
 
 static const char name_rev_usage[] =
-	"git-name-rev [--tags] ( --all | --stdin | committish [committish...] )\n";
+"git-name-rev [--tags] [--refs-from=<file>] ( --all | --stdin | committish ... )";
 
 typedef struct rev_name {
 	const char *tip_name;
@@ -14,6 +14,7 @@ typedef struct rev_name {
 } rev_name;
 
 static long cutoff = LONG_MAX;
+static const char *refs_from = NULL;
 
 static void name_rev(struct commit *commit,
 		const char *tip_name, int merge_traversals, int generation,
@@ -103,6 +104,46 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void
 	return 0;
 }
 
+static void trim_trailing_whitespace(char *buf)
+{
+	int i = strlen(buf) - 1;
+	while(i >= 0 && isspace(buf[i]))
+		buf[i--] = '\0';
+}
+
+static void for_each_ref_from_file(const char *filename, each_ref_fn fn, void *data)
+{
+	FILE *fh;
+	char buf[PATH_MAX + 40 + 3]; /* "PATH SHA1\n\0" */
+	unsigned char sha1[20];
+
+	if (!strcmp(filename, "-"))
+		fh = stdin;
+	else {
+		fh = fopen(filename, "r");
+		if (!fh)
+			die("unable to open %s: %s", filename, strerror(errno));
+	}
+
+	while (fgets(buf, sizeof buf, fh)) {
+		char *name;
+
+		trim_trailing_whitespace(buf);
+
+		name = strchr(buf, ' ');
+		if (!name)
+			die("invalid input ref format: %s\n", buf);
+		*name++ = '\0';
+
+		if (get_sha1_hex(buf, sha1) < 0)
+			die("invalid sha1: %s\n", buf);
+
+		name_ref(name, sha1, 0, data);
+	}
+
+	fclose(fh);
+}
+
 /* returns a static buffer */
 static const char* get_rev_name(struct object *o)
 {
@@ -160,6 +201,9 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 				transform_stdin = 1;
 				cutoff = 0;
 				continue;
+			} else if (!strncmp(*argv, "--refs-from=", 12)) {
+				refs_from = (*argv)+12;
+				continue;
 			}
 			usage(name_rev_usage);
 		}
@@ -185,7 +229,13 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 		add_object_array((struct object *)commit, *argv, &revs);
 	}
 
-	for_each_ref(name_ref, &tags_only);
+	if (refs_from && !strcmp(refs_from, "-") && transform_stdin)
+		die("--refs-from=- and --stdin are incompatible!");
+
+	if (refs_from)
+		for_each_ref_from_file(refs_from, name_ref, &tags_only);
+	else
+		for_each_ref(name_ref, &tags_only);
 
 	if (transform_stdin) {
 		char buffer[2048];
-- 
1.5.0.552.ge1b1c-dirty
Previous: Junio C HamanoNext: Jeff King
Message 12 of 22 in “finding earliest tags descended from a given commit”
  1. J. Bruce FieldsJan 27, 2007
  2. Shawn O. PearceJan 27, 2007
  3. Linus TorvaldsJan 27, 2007
  4. J. Bruce FieldsJan 27, 2007
  5. Shawn O. PearceJan 27, 2007
  6. Junio C HamanoJan 27, 2007
  7. name-rev: introduce the --ref-filter=<regex> optionJohannes Schindelin, Jan 27, 2007
  8. Johannes SchindelinFeb 17, 2007
  9. Jeff KingFeb 17, 2007
  10. Johannes SchindelinFeb 17, 2007
  11. Junio C HamanoFeb 17, 2007
  12. git-name-rev: accept list of refs from userJeff King, Feb 17, 2007
  13. Jeff KingFeb 17, 2007
  14. Junio C HamanoFeb 17, 2007
  15. Jeff KingFeb 17, 2007
  16. Johannes SchindelinFeb 18, 2007
  17. Junio C HamanoFeb 17, 2007
  18. Johannes SchindelinFeb 17, 2007
  19. name-rev: introduce the --ref-filter=<pattern> optionJohannes Schindelin, Feb 17, 2007
  20. Junio C HamanoFeb 17, 2007
  21. Johannes SchindelinFeb 17, 2007
  22. Junio C HamanoFeb 17, 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.