[PATCH/RFC] avoid accessing _all_ loose refs in git-show-ref

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If you want to verify a ref, it is overkill to first read all loose refs
into a linked list, and then check if the desired ref is there.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@xxxxxx>

---

	This is kind of quick and dirty.

	An alternative would be to pack the tags _per default_. I once
	argued for that, but it appears nobody liked that idea. I even
	proposed to pack _all_ refs, and I still think this would be
	a good idea.

	However, HTTP/FTP transport would have to learn about that long
	before, and/or a config option would be needed to allow public
	repos to cater for older clients.

	Isn't it a bug that --verify succeeds, if only _one_ ref passed to 
	the command exists?

 builtin-show-ref.c |   14 +++++++++++++-
 refs.c             |   17 +++++++++++------
 refs.h             |    1 +
 3 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/builtin-show-ref.c b/builtin-show-ref.c
index 0739798..b57b074 100644
--- a/builtin-show-ref.c
+++ b/builtin-show-ref.c
@@ -157,7 +157,19 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix)
 	}
 	if (show_head)
 		head_ref(show_ref, NULL);
-	for_each_ref(show_ref, NULL);
+	if (verify) {
+		for (i = 0; pattern[i]; i++)
+			if (!access(git_path(pattern[i]), R_OK)) {
+				unsigned char sha1[20];
+				if (resolve_ref(pattern[i], sha1, 1, NULL)) {
+					found_match++;
+					printf("%s %s\n", sha1_to_hex(sha1),
+							pattern[i]);
+				}
+			}
+		for_each_packed_ref(show_ref, NULL);
+	} else
+		for_each_ref(show_ref, NULL);
 	if (!found_match) {
 		if (verify && !quiet)
 			die("No match");
diff --git a/refs.c b/refs.c
index a02957c..7e6a459 100644
--- a/refs.c
+++ b/refs.c
@@ -413,11 +413,11 @@ int peel_ref(const char *ref, unsigned char *sha1)
 }
 
 static int do_for_each_ref(const char *base, each_ref_fn fn, int trim,
-			   void *cb_data)
+			   void *cb_data, int packed_only)
 {
 	int retval;
 	struct ref_list *packed = get_packed_refs();
-	struct ref_list *loose = get_loose_refs();
+	struct ref_list *loose = packed_only ? NULL : get_loose_refs();
 
 	while (packed && loose) {
 		struct ref_list *entry;
@@ -456,24 +456,29 @@ int head_ref(each_ref_fn fn, void *cb_data)
 	return 0;
 }
 
+int for_each_packed_ref(each_ref_fn fn, void *cb_data)
+{
+	return do_for_each_ref("refs/", fn, 0, cb_data, 1);
+}
+
 int for_each_ref(each_ref_fn fn, void *cb_data)
 {
-	return do_for_each_ref("refs/", fn, 0, cb_data);
+	return do_for_each_ref("refs/", fn, 0, cb_data, 0);
 }
 
 int for_each_tag_ref(each_ref_fn fn, void *cb_data)
 {
-	return do_for_each_ref("refs/tags/", fn, 10, cb_data);
+	return do_for_each_ref("refs/tags/", fn, 10, cb_data, 0);
 }
 
 int for_each_branch_ref(each_ref_fn fn, void *cb_data)
 {
-	return do_for_each_ref("refs/heads/", fn, 11, cb_data);
+	return do_for_each_ref("refs/heads/", fn, 11, cb_data, 0);
 }
 
 int for_each_remote_ref(each_ref_fn fn, void *cb_data)
 {
-	return do_for_each_ref("refs/remotes/", fn, 13, cb_data);
+	return do_for_each_ref("refs/remotes/", fn, 13, cb_data, 0);
 }
 
 /* NEEDSWORK: This is only used by ssh-upload and it should go; the
diff --git a/refs.h b/refs.h
index 51aab1e..0cfe7b5 100644
--- a/refs.h
+++ b/refs.h
@@ -19,6 +19,7 @@ struct ref_lock {
  */
 typedef int each_ref_fn(const char *refname, const unsigned char *sha1, int flags, void *cb_data);
 extern int head_ref(each_ref_fn, void *);
+extern int for_each_packed_ref(each_ref_fn, void *);
 extern int for_each_ref(each_ref_fn, void *);
 extern int for_each_tag_ref(each_ref_fn, void *);
 extern int for_each_branch_ref(each_ref_fn, void *);
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]