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

Re: [RFC PATCH 2/4] Add alias option to git branch

From
KCKenneth Cochran <kenneth.cochran101@gmail.com>
Date
Mar 4, 2019, 15:48 UTC
Message-ID
<D9CFD250-26D4-4D1F-B0CD-01E24E8606D9@gmail.com>
In-Reply-To
<7D21A788-5E38-466F-B3CC-F6A5CBEB2E2E@gmail.com>
From 5aa6f037642df3b358ab659d17b5fb5bc7936f0f Mon Sep 17 00:00:00 2001
From: Kenneth Cochran <kenneth.cochran101@gmail.com>
Date: Sun, 3 Mar 2019 15:05:11 -0600
Subject: [RFC PATCH 2/4] refs: add function to iteratively dereference symref
 chain
Cc: Sahil Dua <sahildua2305@gmail.com>,
    Duy Nguyen <pclouds@gmail.com>,
    Jeff King <peff@peff.net>

As far as I can tell, currently, there's not really any way to run something once per symref in a symref chain. This adds that ability.

This will be useful for instance to improve how `git branch -d` handles a checked out symref.

Signed-off-by: Kenneth Cochran <kenneth.cochran101@gmail.com>
---
 refs.c | 28 ++++++++++++++++++++++++++++
 refs.h | 13 +++++++++++++
 2 files changed, 41 insertions(+)
diff --git a/refs.c b/refs.c
index 142888a40a..18a222d76a 100644
--- a/refs.c
+++ b/refs.c
@@ -1466,6 +1466,34 @@ static int do_for_each_ref(struct ref_store *refs, const char *prefix,
 					do_for_each_ref_helper, &hp);
 }
 
+int refs_for_each_ref_in_chain(struct ref_store *refs, each_ref_fn fn,
+			       void *cb_data, const char *starting_ref)
+{
+	int symref_count;
+	struct object_id oid;
+	int flags;
+	const char *ref_name = xstrdup(starting_ref);
+	int res;
+
+	for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) {
+		res = fn(ref_name, &oid, flags, cb_data);
+		ref_name = refs_resolve_ref_unsafe(refs, ref_name, RESOLVE_REF_NO_RECURSE,
+						   &oid, &flags);
+
+		if (res)
+			return res;
+		if (!(flags & REF_ISSYMREF))
+			break;
+	}
+	return 0;
+}
+
+int for_each_ref_in_chain(each_ref_fn fn, void *cb_data, const char *starting_ref)
+{
+	return refs_for_each_ref_in_chain(get_main_ref_store(the_repository), fn,
+					  cb_data, starting_ref);
+}
+
 int refs_for_each_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
 {
 	return do_for_each_ref(refs, "", fn, 0, 0, cb_data);
diff --git a/refs.h b/refs.h
index 308fa1f03b..66ccb85e8d 100644
--- a/refs.h
+++ b/refs.h
@@ -327,6 +327,19 @@ int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
 int head_ref_namespaced(each_ref_fn fn, void *cb_data);
 int for_each_namespaced_ref(each_ref_fn fn, void *cb_data);
 
+/*
+ * Iteratively calls fn with each reference in a symref chain.
+ * Iteration will continue until one of the following occurs:
+ * - SYMREF_MAXDEPTH is reached
+ * - A non-symbolic ref is reached (fn will be called with this before returning)
+ * - fn returns a non 0 value
+ *
+ * Will always return 0 unless fn returns a non-zero value.
+ */
+int refs_for_each_ref_in_chain(struct ref_store *refs, each_ref_fn fn,
+			       void *cb_data, const char *starting_ref);
+int for_each_ref_in_chain(each_ref_fn fn, void *cb_data, const char *starting_ref);
+
 /* can be used to learn about broken ref and symref */
 int refs_for_each_rawref(struct ref_store *refs, each_ref_fn fn, void *cb_data);
 int for_each_rawref(each_ref_fn fn, void *cb_data);
-- 
2.17.1
Previous: Kenneth CochranNext: Kenneth Cochran
Message 3 of 11 in “Add alias option to git branch”
  1. 0/4 Add alias option to git branchKenneth Cochran, Mar 4, 2019
  2. Kenneth CochranMar 4, 2019
  3. Kenneth CochranMar 4, 2019
  4. Kenneth CochranMar 4, 2019
  5. Kenneth CochranMar 4, 2019
  6. Kenneth CochranMar 4, 2019
  7. Junio C HamanoMar 5, 2019
  8. Kenneth CochranMar 5, 2019
  9. Phil SaintyMar 6, 2019
  10. Phil SaintyMar 4, 2019
  11. Kenneth CochranMar 4, 2019

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.