git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] git branch: fix performance problem
@ 2009-07-23 19:18 Linus Torvalds
  2009-07-23 19:18 ` [PATCH 2/3] git branch: avoid unnecessary object lookups Linus Torvalds
  0 siblings, 1 reply; 3+ messages in thread
From: Linus Torvalds @ 2009-07-23 19:18 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List


From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Thu, 23 Jul 2009 10:17:04 -0700

'git branch' looks at _all_ the refs, and verifies them.  Which means that 
during cold-cache situations with a slow disk (and lots of tags, for 
example) it can take several very annoying seconds (7.5s according to a 
report by Carlos R.  Mafra).

This avoids most of it by simply doing the filtering before looking up
the commits, by using the "raw" version of for_each_ref.

Reported-by: Carlos R. Mafra <crmafra2@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---

Ok, this is just a resend of the patches I've sent out, as a proper patch 
series, with sign-offs etc.

 builtin-branch.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/builtin-branch.c b/builtin-branch.c
index 5687d60..54a89ff 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -240,6 +240,10 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
 	if (ARRAY_SIZE(ref_kind) <= i)
 		return 0;
 
+	/* Don't add types the caller doesn't want */
+	if ((kind & ref_list->kinds) == 0)
+		return 0;
+
 	commit = lookup_commit_reference_gently(sha1, 1);
 	if (!commit)
 		return error("branch '%s' does not point at a commit", refname);
@@ -248,10 +252,6 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
 	if (!is_descendant_of(commit, ref_list->with_commit))
 		return 0;
 
-	/* Don't add types the caller doesn't want */
-	if ((kind & ref_list->kinds) == 0)
-		return 0;
-
 	if (merge_filter != NO_FILTER)
 		add_pending_object(&ref_list->revs,
 				   (struct object *)commit, refname);
@@ -426,7 +426,7 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str
 	ref_list.with_commit = with_commit;
 	if (merge_filter != NO_FILTER)
 		init_revisions(&ref_list.revs, NULL);
-	for_each_ref(append_ref, &ref_list);
+	for_each_rawref(append_ref, &ref_list);
 	if (merge_filter != NO_FILTER) {
 		struct commit *filter;
 		filter = lookup_commit_reference_gently(merge_filter_ref, 0);
-- 
1.6.4.rc1.2.gdf1f0

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

* [PATCH 2/3] git branch: avoid unnecessary object lookups
  2009-07-23 19:18 [PATCH 1/3] git branch: fix performance problem Linus Torvalds
@ 2009-07-23 19:18 ` Linus Torvalds
  2009-07-23 19:20   ` [PATCH 3/3] git branch: clean up detached branch handling Linus Torvalds
  0 siblings, 1 reply; 3+ messages in thread
From: Linus Torvalds @ 2009-07-23 19:18 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List


From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Thu, 23 Jul 2009 12:05:34 -0700

They can be expensive in the cold-cache case, so don't bother looking up
the commits for all branches unless we really need them for some reason.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 builtin-branch.c |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/builtin-branch.c b/builtin-branch.c
index 54a89ff..82c2cf0 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -191,7 +191,7 @@ struct ref_item {
 
 struct ref_list {
 	struct rev_info revs;
-	int index, alloc, maxwidth;
+	int index, alloc, maxwidth, verbose;
 	struct ref_item *list;
 	struct commit_list *with_commit;
 	int kinds;
@@ -244,17 +244,20 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
 	if ((kind & ref_list->kinds) == 0)
 		return 0;
 
-	commit = lookup_commit_reference_gently(sha1, 1);
-	if (!commit)
-		return error("branch '%s' does not point at a commit", refname);
+	commit = NULL;
+	if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {
+		commit = lookup_commit_reference_gently(sha1, 1);
+		if (!commit)
+			return error("branch '%s' does not point at a commit", refname);
 
-	/* Filter with with_commit if specified */
-	if (!is_descendant_of(commit, ref_list->with_commit))
-		return 0;
+		/* Filter with with_commit if specified */
+		if (!is_descendant_of(commit, ref_list->with_commit))
+			return 0;
 
-	if (merge_filter != NO_FILTER)
-		add_pending_object(&ref_list->revs,
-				   (struct object *)commit, refname);
+		if (merge_filter != NO_FILTER)
+			add_pending_object(&ref_list->revs,
+					   (struct object *)commit, refname);
+	}
 
 	/* Resize buffer */
 	if (ref_list->index >= ref_list->alloc) {
@@ -423,6 +426,7 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str
 
 	memset(&ref_list, 0, sizeof(ref_list));
 	ref_list.kinds = kinds;
+	ref_list.verbose = verbose;
 	ref_list.with_commit = with_commit;
 	if (merge_filter != NO_FILTER)
 		init_revisions(&ref_list.revs, NULL);
-- 
1.6.4.rc1.2.gdf1f0

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

* [PATCH 3/3] git branch: clean up detached branch handling
  2009-07-23 19:18 ` [PATCH 2/3] git branch: avoid unnecessary object lookups Linus Torvalds
@ 2009-07-23 19:20   ` Linus Torvalds
  0 siblings, 0 replies; 3+ messages in thread
From: Linus Torvalds @ 2009-07-23 19:20 UTC (permalink / raw)
  To: Junio C Hamano, Git Mailing List


From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Thu, 23 Jul 2009 12:13:48 -0700

Make the 'show detached branch info' a routine of its own.  And in the
process, avoid the object lookup that is unnecessary if the current
branch isn't detached.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---

With this series of three, 'git branch' now makes no object lookups at all 
for the normal case of an attached branch and no fancy flags. 

 builtin-branch.c |   38 +++++++++++++++++++++++---------------
 1 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/builtin-branch.c b/builtin-branch.c
index 82c2cf0..1a03d5f 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -191,7 +191,7 @@ struct ref_item {
 
 struct ref_list {
 	struct rev_info revs;
-	int index, alloc, maxwidth, verbose;
+	int index, alloc, maxwidth, verbose, abbrev;
 	struct ref_item *list;
 	struct commit_list *with_commit;
 	int kinds;
@@ -418,15 +418,34 @@ static int calc_maxwidth(struct ref_list *refs)
 	return w;
 }
 
+
+static void show_detached(struct ref_list *ref_list)
+{
+	struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1);
+
+	if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) {
+		struct ref_item item;
+		item.name = xstrdup("(no branch)");
+		item.len = strlen(item.name);
+		item.kind = REF_LOCAL_BRANCH;
+		item.dest = NULL;
+		item.commit = head_commit;
+		if (item.len > ref_list->maxwidth)
+			ref_list->maxwidth = item.len;
+		print_ref_item(&item, ref_list->maxwidth, ref_list->verbose, ref_list->abbrev, 1, "");
+		free(item.name);
+	}
+}
+
 static void print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit)
 {
 	int i;
 	struct ref_list ref_list;
-	struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1);
 
 	memset(&ref_list, 0, sizeof(ref_list));
 	ref_list.kinds = kinds;
 	ref_list.verbose = verbose;
+	ref_list.abbrev = abbrev;
 	ref_list.with_commit = with_commit;
 	if (merge_filter != NO_FILTER)
 		init_revisions(&ref_list.revs, NULL);
@@ -446,19 +465,8 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str
 	qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
 
 	detached = (detached && (kinds & REF_LOCAL_BRANCH));
-	if (detached && head_commit &&
-	    is_descendant_of(head_commit, with_commit)) {
-		struct ref_item item;
-		item.name = xstrdup("(no branch)");
-		item.len = strlen(item.name);
-		item.kind = REF_LOCAL_BRANCH;
-		item.dest = NULL;
-		item.commit = head_commit;
-		if (item.len > ref_list.maxwidth)
-			ref_list.maxwidth = item.len;
-		print_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1, "");
-		free(item.name);
-	}
+	if (detached)
+		show_detached(&ref_list);
 
 	for (i = 0; i < ref_list.index; i++) {
 		int current = !detached &&
-- 
1.6.4.rc1.2.gdf1f0

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

end of thread, other threads:[~2009-07-23 19:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-23 19:18 [PATCH 1/3] git branch: fix performance problem Linus Torvalds
2009-07-23 19:18 ` [PATCH 2/3] git branch: avoid unnecessary object lookups Linus Torvalds
2009-07-23 19:20   ` [PATCH 3/3] git branch: clean up detached branch handling Linus Torvalds

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).