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

[PATCH 3/5] pretty describe: move library functions to the new file describe.c

From
René Scharfe <rene.scharfe@lsrfire.ath.cx>
Date
Nov 4, 2007, 11:48 UTC
Message-ID
<472DB199.2040305@lsrfire.ath.cx>

load_commit_names(), describe_commit() et. al. are moved out to their own file and properly exported. There are no code changes inside the functions.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 Makefile           |    2 +-
 builtin-describe.c |  202 ---------------------------------------------------
 cache.h            |    5 ++
 describe.c         |  204 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 210 insertions(+), 203 deletions(-)
 create mode 100644 describe.c
diff --git a/Makefile b/Makefile
index 042f79e..afdd847 100644
--- a/Makefile
+++ b/Makefile
@@ -312,7 +312,7 @@ LIB_OBJS = \
 	alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
 	color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
 	convert.o attr.o decorate.o progress.o mailmap.o symlinks.o remote.o \
-	transport.o bundle.o walker.o parse-options.o
+	transport.o bundle.o walker.o parse-options.o describe.o
 
 BUILTIN_OBJS = \
 	builtin-add.o \
diff --git a/builtin-describe.c b/builtin-describe.c
index e68a3d0..fcd93f4 100644
--- a/builtin-describe.c
+++ b/builtin-describe.c
@@ -1,14 +1,9 @@
 #include "cache.h"
 #include "commit.h"
-#include "tag.h"
-#include "refs.h"
 #include "builtin.h"
 #include "exec_cmd.h"
 #include "parse-options.h"
 
-#define SEEN		(1u<<0)
-#define MAX_TAGS	(FLAG_BITS - 1)
-
 static const char * const describe_usage[] = {
 	"git-describe [options] <committish>*",
 	NULL
@@ -20,203 +15,6 @@ static int tags;	/* But allow any tags if --tags is specified */
 static int abbrev = DEFAULT_ABBREV;
 static int max_candidates = 10;
 
-static const char *prio_names[] = {
-	"head", "lightweight", "annotated",
-};
-
-static int get_name(const char *path, const unsigned char *sha1, int flag, void *cb_data)
-{
-	struct commit *commit = lookup_commit_reference_gently(sha1, 1);
-	struct object *object;
-	int min_prio = *((int *)cb_data);
-	int prio;
-
-	if (!commit)
-		return 0;
-	object = parse_object(sha1);
-
-	if (!prefixcmp(path, "refs/tags/")) {
-		if (object->type == OBJ_TAG)
-			prio = 2;
-		else
-			prio = 1;
-	}
-	else
-		prio = 0;
-	if (prio < min_prio)
-		return 0;
-
-	if (commit->name) {
-		if (commit->name_prio >= prio)
-			return 0;
-		free(commit->name);
-	}
-	commit->name = xstrdup(path + 5);
-	commit->name_prio = prio;
-
-	return 0;
-}
-
-void load_commit_names(int min_prio)
-{
-	for_each_ref(get_name, &min_prio);
-}
-
-struct possible_tag {
-	char *name;
-	int prio; /* annotated tag = 2, tag = 1, head = 0 */
-	int depth;
-	int found_order;
-	unsigned flag_within;
-};
-
-static int compare_pt(const void *a_, const void *b_)
-{
-	struct possible_tag *a = (struct possible_tag *)a_;
-	struct possible_tag *b = (struct possible_tag *)b_;
-	if (a->prio != b->prio)
-		return b->prio - a->prio;
-	if (a->depth != b->depth)
-		return a->depth - b->depth;
-	if (a->found_order != b->found_order)
-		return a->found_order - b->found_order;
-	return 0;
-}
-
-static unsigned long finish_depth_computation(
-	struct commit_list **list,
-	struct possible_tag *best)
-{
-	unsigned long seen_commits = 0;
-	while (*list) {
-		struct commit *c = pop_commit(list);
-		struct commit_list *parents = c->parents;
-		seen_commits++;
-		if (c->name_flags & best->flag_within) {
-			struct commit_list *a = *list;
-			while (a) {
-				struct commit *i = a->item;
-				if (!(i->name_flags & best->flag_within))
-					break;
-				a = a->next;
-			}
-			if (!a)
-				break;
-		} else
-			best->depth++;
-		while (parents) {
-			struct commit *p = parents->item;
-			parse_commit(p);
-			if (!(p->name_flags & SEEN))
-				insert_by_date(p, list);
-			p->name_flags |= c->name_flags;
-			parents = parents->next;
-		}
-	}
-	return seen_commits;
-}
-
-char *describe_commit(struct commit *cmit, int max_candidates, int debug, int *depthp)
-{
-	struct commit *gave_up_on = NULL;
-	struct commit_list *list;
-	struct possible_tag all_matches[MAX_TAGS];
-	unsigned int match_cnt = 0, annotated_cnt = 0, cur_match;
-	unsigned long seen_commits = 0;
-
-	if (cmit->name) {
-		*depthp = 0;
-		return cmit->name;
-	}
-
-	if (debug)
-		fprintf(stderr, "searching...\n");
-
-	if (max_candidates < 1)
-		max_candidates = 1;
-	else if (max_candidates > MAX_TAGS)
-		max_candidates = MAX_TAGS;
-
-	list = NULL;
-	cmit->name_flags = SEEN;
-	commit_list_insert(cmit, &list);
-	while (list) {
-		struct commit *c = pop_commit(&list);
-		struct commit_list *parents = c->parents;
-		seen_commits++;
-		if (c->name) {
-			if (match_cnt < max_candidates) {
-				struct possible_tag *t = &all_matches[match_cnt++];
-				t->name = c->name;
-				t->prio = c->name_prio;
-				t->depth = seen_commits - 1;
-				t->flag_within = 1u << match_cnt;
-				t->found_order = match_cnt;
-				c->name_flags |= t->flag_within;
-				if (c->name_prio == 2)
-					annotated_cnt++;
-			}
-			else {
-				gave_up_on = c;
-				break;
-			}
-		}
-		for (cur_match = 0; cur_match < match_cnt; cur_match++) {
-			struct possible_tag *t = &all_matches[cur_match];
-			if (!(c->name_flags & t->flag_within))
-				t->depth++;
-		}
-		if (annotated_cnt && !list) {
-			if (debug)
-				fprintf(stderr, "finished search at %s\n",
-					sha1_to_hex(c->object.sha1));
-			break;
-		}
-		while (parents) {
-			struct commit *p = parents->item;
-			parse_commit(p);
-			if (!(p->name_flags & SEEN))
-				insert_by_date(p, &list);
-			p->name_flags |= c->name_flags;
-			parents = parents->next;
-		}
-	}
-
-	if (!match_cnt) {
-		free_commit_list(list);
-		*depthp = -1;
-		return NULL;
-	}
-
-	qsort(all_matches, match_cnt, sizeof(all_matches[0]), compare_pt);
-
-	if (gave_up_on) {
-		insert_by_date(gave_up_on, &list);
-		seen_commits--;
-	}
-	seen_commits += finish_depth_computation(&list, &all_matches[0]);
-	free_commit_list(list);
-
-	if (debug) {
-		for (cur_match = 0; cur_match < match_cnt; cur_match++) {
-			struct possible_tag *t = &all_matches[cur_match];
-			fprintf(stderr, " %-11s %8d %s\n",
-				prio_names[t->prio], t->depth, t->name);
-		}
-		fprintf(stderr, "traversed %lu commits\n", seen_commits);
-		if (gave_up_on) {
-			fprintf(stderr,
-				"more than %i tags found; listed %i most recent\n"
-				"gave up search at %s\n",
-				max_candidates, max_candidates,
-				sha1_to_hex(gave_up_on->object.sha1));
-		}
-	}
-
-	*depthp = all_matches[0].depth;
-	return all_matches[0].name;
-}
-
 static void describe(const char *arg, int last_one)
 {
 	unsigned char sha1[20];
diff --git a/cache.h b/cache.h
index bfffa05..84423a3 100644
--- a/cache.h
+++ b/cache.h
@@ -602,4 +602,9 @@ extern int diff_auto_refresh_index;
 /* match-trees.c */
 void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int);
 
+/* describe.c */
+struct commit;
+extern void load_commit_names(int min_prio);
+extern char *describe_commit(struct commit *cmit, int max_candidates, int debug, int *depthp);
+
 #endif /* CACHE_H */
diff --git a/describe.c b/describe.c
new file mode 100644
index 0000000..18c7abc
--- /dev/null
+++ b/describe.c
@@ -0,0 +1,204 @@
+#include "cache.h"
+#include "commit.h"
+#include "tag.h"
+#include "refs.h"
+
+#define SEEN		(1u<<0)
+#define MAX_TAGS	(FLAG_BITS - 1)
+
+static const char *prio_names[] = {
+	"head", "lightweight", "annotated",
+};
+
+static int get_name(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+{
+	struct commit *commit = lookup_commit_reference_gently(sha1, 1);
+	struct object *object;
+	int min_prio = *((int *)cb_data);
+	int prio;
+
+	if (!commit)
+		return 0;
+	object = parse_object(sha1);
+
+	if (!prefixcmp(path, "refs/tags/")) {
+		if (object->type == OBJ_TAG)
+			prio = 2;
+		else
+			prio = 1;
+	}
+	else
+		prio = 0;
+	if (prio < min_prio)
+		return 0;
+
+	if (commit->name) {
+		if (commit->name_prio >= prio)
+			return 0;
+		free(commit->name);
+	}
+	commit->name = xstrdup(path + 5);
+	commit->name_prio = prio;
+
+	return 0;
+}
+
+void load_commit_names(int min_prio)
+{
+	for_each_ref(get_name, &min_prio);
+}
+
+struct possible_tag {
+	char *name;
+	int prio; /* annotated tag = 2, tag = 1, head = 0 */
+	int depth;
+	int found_order;
+	unsigned flag_within;
+};
+
+static int compare_pt(const void *a_, const void *b_)
+{
+	struct possible_tag *a = (struct possible_tag *)a_;
+	struct possible_tag *b = (struct possible_tag *)b_;
+	if (a->prio != b->prio)
+		return b->prio - a->prio;
+	if (a->depth != b->depth)
+		return a->depth - b->depth;
+	if (a->found_order != b->found_order)
+		return a->found_order - b->found_order;
+	return 0;
+}
+
+static unsigned long finish_depth_computation(
+	struct commit_list **list,
+	struct possible_tag *best)
+{
+	unsigned long seen_commits = 0;
+	while (*list) {
+		struct commit *c = pop_commit(list);
+		struct commit_list *parents = c->parents;
+		seen_commits++;
+		if (c->name_flags & best->flag_within) {
+			struct commit_list *a = *list;
+			while (a) {
+				struct commit *i = a->item;
+				if (!(i->name_flags & best->flag_within))
+					break;
+				a = a->next;
+			}
+			if (!a)
+				break;
+		} else
+			best->depth++;
+		while (parents) {
+			struct commit *p = parents->item;
+			parse_commit(p);
+			if (!(p->name_flags & SEEN))
+				insert_by_date(p, list);
+			p->name_flags |= c->name_flags;
+			parents = parents->next;
+		}
+	}
+	return seen_commits;
+}
+
+char *describe_commit(struct commit *cmit, int max_candidates, int debug, int *depthp)
+{
+	struct commit *gave_up_on = NULL;
+	struct commit_list *list;
+	struct possible_tag all_matches[MAX_TAGS];
+	unsigned int match_cnt = 0, annotated_cnt = 0, cur_match;
+	unsigned long seen_commits = 0;
+
+	if (cmit->name) {
+		*depthp = 0;
+		return cmit->name;
+	}
+
+	if (debug)
+		fprintf(stderr, "searching...\n");
+
+	if (max_candidates < 1)
+		max_candidates = 1;
+	else if (max_candidates > MAX_TAGS)
+		max_candidates = MAX_TAGS;
+
+	list = NULL;
+	cmit->name_flags = SEEN;
+	commit_list_insert(cmit, &list);
+	while (list) {
+		struct commit *c = pop_commit(&list);
+		struct commit_list *parents = c->parents;
+		seen_commits++;
+		if (c->name) {
+			if (match_cnt < max_candidates) {
+				struct possible_tag *t = &all_matches[match_cnt++];
+				t->name = c->name;
+				t->prio = c->name_prio;
+				t->depth = seen_commits - 1;
+				t->flag_within = 1u << match_cnt;
+				t->found_order = match_cnt;
+				c->name_flags |= t->flag_within;
+				if (c->name_prio == 2)
+					annotated_cnt++;
+			}
+			else {
+				gave_up_on = c;
+				break;
+			}
+		}
+		for (cur_match = 0; cur_match < match_cnt; cur_match++) {
+			struct possible_tag *t = &all_matches[cur_match];
+			if (!(c->name_flags & t->flag_within))
+				t->depth++;
+		}
+		if (annotated_cnt && !list) {
+			if (debug)
+				fprintf(stderr, "finished search at %s\n",
+					sha1_to_hex(c->object.sha1));
+			break;
+		}
+		while (parents) {
+			struct commit *p = parents->item;
+			parse_commit(p);
+			if (!(p->name_flags & SEEN))
+				insert_by_date(p, &list);
+			p->name_flags |= c->name_flags;
+			parents = parents->next;
+		}
+	}
+
+	if (!match_cnt) {
+		free_commit_list(list);
+		*depthp = -1;
+		return NULL;
+	}
+
+	qsort(all_matches, match_cnt, sizeof(all_matches[0]), compare_pt);
+
+	if (gave_up_on) {
+		insert_by_date(gave_up_on, &list);
+		seen_commits--;
+	}
+	seen_commits += finish_depth_computation(&list, &all_matches[0]);
+	free_commit_list(list);
+
+	if (debug) {
+		for (cur_match = 0; cur_match < match_cnt; cur_match++) {
+			struct possible_tag *t = &all_matches[cur_match];
+			fprintf(stderr, " %-11s %8d %s\n",
+				prio_names[t->prio], t->depth, t->name);
+		}
+		fprintf(stderr, "traversed %lu commits\n", seen_commits);
+		if (gave_up_on) {
+			fprintf(stderr,
+				"more than %i tags found; listed %i most recent\n"
+				"gave up search at %s\n",
+				max_candidates, max_candidates,
+				sha1_to_hex(gave_up_on->object.sha1));
+		}
+	}
+
+	*depthp = all_matches[0].depth;
+	return all_matches[0].name;
+}
-- 
1.5.3.5.529.ge3d6d
Next: Johannes Schindelin
Message 1 of 3 in “pretty describe: move library functions to the new file describe.c”
  1. 3/5 pretty describe: move library functions to the new file describe.cRené Scharfe, Nov 4, 2007
  2. Johannes SchindelinNov 4, 2007
  3. René ScharfeNov 4, 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.