git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] describe: Don’t look up commits with --exact-match
@ 2010-11-17 23:33 Anders Kaseorg
  2010-12-03  8:43 ` Jonathan Nieder
  0 siblings, 1 reply; 28+ messages in thread
From: Anders Kaseorg @ 2010-11-17 23:33 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

This makes ‘git describe --exact-match HEAD’ about 15 times faster on
a cold cache (2.3s instead of 35s) in a linux-2.6 repository with many
packed tags.  That’s a huge win for the interactivity of the __git_ps1
shell prompt helper.

Signed-off-by: Anders Kaseorg <andersk@ksplice.com>
---
 builtin/describe.c |   64 ++++++++++++++++++++++++++-------------------------
 1 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/builtin/describe.c b/builtin/describe.c
index 43caff2..1cdb831 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -22,7 +22,7 @@ static int tags;	/* Allow lightweight tags */
 static int longformat;
 static int abbrev = DEFAULT_ABBREV;
 static int max_candidates = 10;
-static int found_names;
+struct commit_name *names = NULL;
 static const char *pattern;
 static int always;
 static const char *dirty;
@@ -34,6 +34,8 @@ static const char *diff_index_args[] = {
 
 
 struct commit_name {
+	struct commit_name *next;
+	unsigned char peeled[20];
 	struct tag *tag;
 	unsigned prio:2; /* annotated tag = 2, tag = 1, head = 0 */
 	unsigned name_checked:1;
@@ -78,31 +80,26 @@ static int replace_name(struct commit_name *e,
 }
 
 static void add_to_known_names(const char *path,
-			       struct commit *commit,
+			       const unsigned char *peeled,
 			       int prio,
 			       const unsigned char *sha1)
 {
-	struct commit_name *e = commit->util;
 	struct tag *tag = NULL;
-	if (replace_name(e, prio, sha1, &tag)) {
-		size_t len = strlen(path)+1;
-		free(e);
-		e = xmalloc(sizeof(struct commit_name) + len);
-		e->tag = tag;
-		e->prio = prio;
-		e->name_checked = 0;
-		hashcpy(e->sha1, sha1);
-		memcpy(e->path, path, len);
-		commit->util = e;
-	}
-	found_names = 1;
+	size_t len = strlen(path)+1;
+	struct commit_name *e = xmalloc(sizeof(struct commit_name) + len);
+	hashcpy(e->peeled, peeled);
+	e->tag = tag;
+	e->prio = prio;
+	e->name_checked = 0;
+	hashcpy(e->sha1, sha1);
+	memcpy(e->path, path, len);
+	e->next = names;
+	names = e;
 }
 
 static int get_name(const char *path, const unsigned char *sha1, int flag, void *cb_data)
 {
 	int might_be_tag = !prefixcmp(path, "refs/tags/");
-	struct commit *commit;
-	struct object *object;
 	unsigned char peeled[20];
 	int is_tag, prio;
 
@@ -110,16 +107,10 @@ static int get_name(const char *path, const unsigned char *sha1, int flag, void
 		return 0;
 
 	if (!peel_ref(path, peeled) && !is_null_sha1(peeled)) {
-		commit = lookup_commit_reference_gently(peeled, 1);
-		if (!commit)
-			return 0;
-		is_tag = !!hashcmp(sha1, commit->object.sha1);
+		is_tag = !!hashcmp(sha1, peeled);
 	} else {
-		commit = lookup_commit_reference_gently(sha1, 1);
-		object = parse_object(sha1);
-		if (!commit || !object)
-			return 0;
-		is_tag = object->type == OBJ_TAG;
+		hashcpy(peeled, sha1);
+		is_tag = 0;
 	}
 
 	/* If --all, then any refs are used.
@@ -142,7 +133,7 @@ static int get_name(const char *path, const unsigned char *sha1, int flag, void
 		if (!prio)
 			return 0;
 	}
-	add_to_known_names(all ? path + 5 : path + 10, commit, prio, sha1);
+	add_to_known_names(all ? path + 5 : path + 10, peeled, prio, sha1);
 	return 0;
 }
 
@@ -228,7 +219,7 @@ static void describe(const char *arg, int last_one)
 	unsigned char sha1[20];
 	struct commit *cmit, *gave_up_on = NULL;
 	struct commit_list *list;
-	struct commit_name *n;
+	struct commit_name *n, *e;
 	struct possible_tag all_matches[MAX_TAGS];
 	unsigned int match_cnt = 0, annotated_cnt = 0, cur_match;
 	unsigned long seen_commits = 0;
@@ -240,7 +231,12 @@ static void describe(const char *arg, int last_one)
 	if (!cmit)
 		die("%s is not a valid '%s' object", arg, commit_type);
 
-	n = cmit->util;
+	n = NULL;
+	for (e = names; e; e = e->next) {
+		if (hashcmp(e->peeled, cmit->object.sha1) == 0 &&
+		    replace_name(n, e->prio, e->sha1, &e->tag))
+			n = e;
+	}
 	if (n && (tags || all || n->prio == 2)) {
 		/*
 		 * Exact match to an existing ref.
@@ -259,6 +255,12 @@ static void describe(const char *arg, int last_one)
 	if (debug)
 		fprintf(stderr, "searching to describe %s\n", arg);
 
+	for (e = names; e; e = e->next) {
+		struct commit *c = lookup_commit_reference_gently(e->peeled, 1);
+		if (c && replace_name(c->util, e->prio, e->sha1, &e->tag))
+			c->util = e;
+	}
+
 	list = NULL;
 	cmit->object.flags = SEEN;
 	commit_list_insert(cmit, &list);
@@ -418,8 +420,8 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
 		return cmd_name_rev(i + argc, args, prefix);
 	}
 
-	for_each_ref(get_name, NULL);
-	if (!found_names && !always)
+	for_each_rawref(get_name, NULL);
+	if (!names && !always)
 		die("No names found, cannot describe anything.");
 
 	if (argc == 0) {
-- 
1.7.3.2

^ permalink raw reply related	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2010-12-09  6:47 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-17 23:33 [PATCH] describe: Don’t look up commits with --exact-match Anders Kaseorg
2010-12-03  8:43 ` Jonathan Nieder
2010-12-06  7:19   ` Anders Kaseorg
2010-12-06  7:22     ` Anders Kaseorg
2010-12-06  7:32     ` Jonathan Nieder
2010-12-06 10:53       ` Thomas Rast
2010-12-06 17:28       ` Anders Kaseorg
2010-12-06 17:47         ` Jonathan Nieder
2010-12-07  9:58         ` SZEDER Gábor
2010-12-07 18:22           ` [PATCH 1/2] describe: Use for_each_rawref Anders Kaseorg
2010-12-07 18:22             ` [PATCH 2/2] describe: Don’t look up commits with --exact-match Anders Kaseorg
2010-12-07 18:26             ` [PATCH 1/2] describe: Use for_each_rawref Anders Kaseorg
2010-12-07 19:49               ` Junio C Hamano
2010-12-07 21:59                 ` Junio C Hamano
2010-12-07 18:39         ` [PATCH] describe: Don’t look up commits with --exact-match Junio C Hamano
2010-12-08  4:41           ` Anders Kaseorg
2010-12-08  4:42             ` [PATCH v2 1/4] describe: Use for_each_rawref Anders Kaseorg
2010-12-08  4:43               ` [PATCH v2 2/4] describe: Don’t use a flex array in struct commit_name Anders Kaseorg
2010-12-08  4:43               ` [PATCH v2 3/4] describe: Store commit_names in a hash table by commit SHA1 Anders Kaseorg
2010-12-08 18:23                 ` [PATCH v2.1 " Anders Kaseorg
2010-12-08 22:50                   ` Junio C Hamano
2010-12-08  4:46               ` [PATCH v2 4/4] describe: Delay looking up commits until searching for an inexact match Anders Kaseorg
2010-12-08 22:50                 ` Junio C Hamano
2010-12-08 23:47                   ` Anders Kaseorg
2010-12-09  6:42                     ` [PATCH v3 1/4] describe: Use for_each_rawref Anders Kaseorg
2010-12-09  6:43                       ` [PATCH v3 2/4] describe: Don’t use a flex array in struct commit_name Anders Kaseorg
2010-12-09  6:46                       ` [PATCH v3 3/4] describe: Store commit_names in a hash table by commit SHA1 Anders Kaseorg
2010-12-09  6:47                       ` [PATCH v3 4/4] describe: Delay looking up commits until searching for an inexact match Anders Kaseorg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).