From: Petr Baudis <pasky@suse.cz>
To: Junio C Hamano <junkio@cox.net>
Cc: torvalds@osdl.org, git@vger.kernel.org
Subject: [RFC][PATCH] for_each_ref() returning heads in wrong order
Date: Sat, 23 Sep 2006 18:36:21 +0200 [thread overview]
Message-ID: <20060923160712.5890.73139.stgit@machine.or.cz> (raw)
Using the #next branch I've now hit a problem with git-fetch-pack
master choosing refs/bases/master (I geuss created by StGIT) instead
of refs/heads/master. The old upload-pack returned the refs in the order
heads-tags-everything_else but the new one just goes for whatever order
readdir() returns them in (modulo merging with packed refs). I actually
can't see the difference that caused this right now, though.
This is a _really ugly_ patch to fix that. I wonder if there's a more
elegant solution to this.
If you have your refs already packed, you should somehow unpack them
and then pack them again.
Signed-off-by: Petr Baudis <pasky@suse.cz>
---
I send the patch with the hope that someone will be so irritated by it
that he'll create a nicer one. ;-)
refs.c | 39 ++++++++++++++++++++++++++++++++++++---
1 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/refs.c b/refs.c
index 2cef2b4..9b3986a 100644
--- a/refs.c
+++ b/refs.c
@@ -91,7 +91,8 @@ static struct ref_list *get_packed_refs(
return refs;
}
-static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
+static struct ref_list *get_ref_dir(const char *base, struct ref_list *list,
+ char **except)
{
DIR *dir = opendir(git_path("%s", base));
@@ -121,7 +122,13 @@ static struct ref_list *get_ref_dir(cons
if (stat(git_path("%s", ref), &st) < 0)
continue;
if (S_ISDIR(st.st_mode)) {
- list = get_ref_dir(ref, list);
+ if (except) {
+ char **e;
+ for (e = except; *e; e++)
+ if (!strcmp(*e, ref))
+ goto nextitem;
+ }
+ list = get_ref_dir(ref, list, except);
continue;
}
if (!resolve_ref(ref, sha1, 1, &flag)) {
@@ -129,6 +136,7 @@ static struct ref_list *get_ref_dir(cons
continue;
}
list = add_ref(ref, sha1, flag, list);
+nextitem:;
}
free(ref);
closedir(dir);
@@ -142,7 +150,23 @@ static struct ref_list *get_loose_refs(v
static struct ref_list *refs = NULL;
if (!did_refs) {
- refs = get_ref_dir("refs", NULL);
+ /* We need to make sure refs/heads and refs/tags always
+ * go before everything else. */
+ char *except[] = {"refs/heads", "refs/tags", NULL};
+ struct ref_list *other_refs = NULL, *r;
+
+ refs = get_ref_dir("refs/heads", NULL, NULL);
+ refs = get_ref_dir("refs/tags", refs, NULL);
+
+ other_refs = get_ref_dir("refs", NULL, except);
+ if (refs) {
+ for (r = refs; r->next; r = r->next)
+ ;
+ r->next = other_refs;
+ } else {
+ refs = other_refs;
+ }
+
did_refs = 1;
}
return refs;
@@ -298,10 +322,19 @@ static int do_for_each_ref(const char *b
while (packed && loose) {
struct ref_list *entry;
int cmp = strcmp(packed->name, loose->name);
+ int packed_is_ht, loose_is_ht;
if (!cmp) {
packed = packed->next;
continue;
}
+ /* We need to make sure refs/heads and refs/tags always
+ * go before everything else. */
+ packed_is_ht = !strncmp(packed->name, "refs/heads", 10)
+ || !strncmp(packed->name, "refs/tags", 9);
+ loose_is_ht = !strncmp(loose->name, "refs/heads", 10)
+ || !strncmp(loose->name, "refs/tags", 9);
+ if (packed_is_ht != loose_is_ht)
+ cmp = loose_is_ht - packed_is_ht;
if (cmp > 0) {
entry = loose;
loose = loose->next;
next reply other threads:[~2006-09-23 16:36 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-23 16:36 Petr Baudis [this message]
2006-09-23 16:47 ` [RFC][PATCH] for_each_ref() returning heads in wrong order Petr Baudis
2006-09-23 17:20 ` Johannes Schindelin
2006-09-23 17:42 ` Petr Baudis
2006-09-23 17:12 ` Linus Torvalds
2006-09-23 19:31 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060923160712.5890.73139.stgit@machine.or.cz \
--to=pasky@suse.cz \
--cc=git@vger.kernel.org \
--cc=junkio@cox.net \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).