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

[PATCH] git-branch: only traverse the requested refs

From
LHLars Hjemli <hjemli@gmail.com>
Date
Oct 10, 2007, 21:54 UTC
Message-ID
<1192053283-2351-1-git-send-email-hjemli@gmail.com>
In-Reply-To
<f329bf540710101424q22309489sada99907e94b2cd0@mail.gmail.com>

This avoids looking at every single file below .git/refs when git-branch is fetching the list of refs to display.

Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---

This patch should make git-branch much more efficient when there exists many files below .git/refs, but it does require two passes through .git/packed-refs when -a is specified.

No benchmarking performed...
 builtin-branch.c |   28 +++++++++-------------------
 1 files changed, 9 insertions(+), 19 deletions(-)
diff --git a/builtin-branch.c b/builtin-branch.c
index 3da8b55..466e1e0 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -185,25 +185,8 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
 {
 	struct ref_list *ref_list = (struct ref_list*)(cb_data);
 	struct ref_item *newitem;
-	int kind = REF_UNKNOWN_TYPE;
 	int len;
 
-	/* Detect kind */
-	if (!prefixcmp(refname, "refs/heads/")) {
-		kind = REF_LOCAL_BRANCH;
-		refname += 11;
-	} else if (!prefixcmp(refname, "refs/remotes/")) {
-		kind = REF_REMOTE_BRANCH;
-		refname += 13;
-	} else if (!prefixcmp(refname, "refs/tags/")) {
-		kind = REF_TAG;
-		refname += 10;
-	}
-
-	/* Don't add types the caller doesn't want */
-	if ((kind & ref_list->kinds) == 0)
-		return 0;
-
 	/* Resize buffer */
 	if (ref_list->index >= ref_list->alloc) {
 		ref_list->alloc = alloc_nr(ref_list->alloc);
@@ -214,7 +197,7 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
 	/* Record the new item */
 	newitem = &(ref_list->list[ref_list->index++]);
 	newitem->name = xstrdup(refname);
-	newitem->kind = kind;
+	newitem->kind = ref_list->kinds;
 	hashcpy(newitem->sha1, sha1);
 	len = strlen(newitem->name);
 	if (len > ref_list->maxwidth)
@@ -296,8 +279,15 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev)
 	struct ref_list ref_list;
 
 	memset(&ref_list, 0, sizeof(ref_list));
+	if (kinds & REF_LOCAL_BRANCH) {
+		ref_list.kinds = REF_LOCAL_BRANCH;
+		for_each_branch_ref(append_ref, &ref_list);
+	}
+	if (kinds & REF_REMOTE_BRANCH) {
+		ref_list.kinds = REF_REMOTE_BRANCH;
+		for_each_remote_ref(append_ref, &ref_list);
+	}
 	ref_list.kinds = kinds;
-	for_each_ref(append_ref, &ref_list);
 
 	qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
 
-- 
1.5.3.4.206.g58ba4
Previous: Lars HjemliNext: Johannes Schindelin
Message 23 of 25 in “git branch performance problem?”
  1. Han-Wen NienhuysOct 10, 2007
  2. Lars HjemliOct 10, 2007
  3. Han-Wen NienhuysOct 10, 2007
  4. Han-Wen NienhuysOct 10, 2007
  5. Han-Wen NienhuysOct 10, 2007
  6. J. Bruce FieldsOct 10, 2007
  7. Lars HjemliOct 10, 2007
  8. Han-Wen NienhuysOct 10, 2007
  9. J. Bruce FieldsOct 10, 2007
  10. Han-Wen NienhuysOct 10, 2007
  11. Johannes SchindelinOct 10, 2007
  12. Brandon CaseyOct 10, 2007
  13. Mike RalphsonOct 11, 2007
  14. Johannes SchindelinOct 11, 2007
  15. Linus TorvaldsOct 10, 2007
  16. Han-Wen NienhuysOct 11, 2007
  17. Alex RiesenOct 11, 2007
  18. Johannes SchindelinOct 11, 2007
  19. Han-Wen NienhuysOct 11, 2007
  20. Linus TorvaldsOct 11, 2007
  21. Salikh ZakirovOct 12, 2007
  22. Lars HjemliOct 10, 2007
  23. git-branch: only traverse the requested refsLars Hjemli, Oct 10, 2007
  24. Johannes SchindelinOct 10, 2007
  25. Lars HjemliOct 10, 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.