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

[PATCH v2] sha1_name: reorganize get_sha1_basic()

From
Felipe Contreras <felipe.contreras@gmail.com>
Date
May 2, 2013, 17:48 UTC
Message-ID
<1367516919-4735-1-git-send-email-felipe.contreras@gmail.com>

Through the years the functionality to handle @{-N} and @{u} has moved around the code, and as a result, code that once made sense, doesn't any more.

There is no need to call this function recursively with the branch of @{-N} substituted because dwim_{ref,log} already replaces it.

However, there's one corner-case where @{-N} resolves to a detached HEAD, in which case we wouldn't get any ref back.

So we parse the nth-prior manually, and deal with it depending on weather it's a SHA-1, or a ref.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 sha1_name.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/sha1_name.c b/sha1_name.c
index 3820f28..6428001 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -431,13 +431,14 @@ static inline int upstream_mark(const char *string, int len)
 }
 
 static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned lookup_flags);
+static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf);
 
 static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
 {
 	static const char *warn_msg = "refname '%.*s' is ambiguous.";
 	char *real_ref = NULL;
 	int refs_found = 0;
-	int at, reflog_len;
+	int at, reflog_len, nth_prior = 0;
 
 	if (len == 40 && !get_sha1_hex(str, sha1))
 		return 0;
@@ -447,6 +448,10 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
 	if (len && str[len-1] == '}') {
 		for (at = len-2; at >= 0; at--) {
 			if (str[at] == '@' && str[at+1] == '{') {
+				if (at == 0 && str[2] == '-') {
+					nth_prior = 1;
+					continue;
+				}
 				if (!upstream_mark(str + at, len - at)) {
 					reflog_len = (len-1) - (at+2);
 					len = at;
@@ -460,20 +465,22 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
 	if (len && ambiguous_path(str, len))
 		return -1;
 
-	if (!len && reflog_len) {
+	if (nth_prior) {
 		struct strbuf buf = STRBUF_INIT;
-		int ret;
-		/* try the @{-N} syntax for n-th checkout */
-		ret = interpret_branch_name(str+at, &buf);
-		if (ret > 0) {
-			/* substitute this branch name and restart */
-			return get_sha1_1(buf.buf, buf.len, sha1, 0);
-		} else if (ret == 0) {
-			return -1;
+		int detached;
+
+		if (interpret_nth_prior_checkout(str, &buf) > 0) {
+			detached = (buf.len == 40 && !get_sha1_hex(buf.buf, sha1));
+			strbuf_release(&buf);
+			if (detached)
+				return 0;
 		}
+	}
+
+	if (!len && reflog_len)
 		/* allow "@{...}" to mean the current branch reflog */
 		refs_found = dwim_ref("HEAD", 4, sha1, &real_ref);
-	} else if (reflog_len)
+	else if (reflog_len)
 		refs_found = dwim_log(str, len, sha1, &real_ref);
 	else
 		refs_found = dwim_ref(str, len, sha1, &real_ref);
-- 
1.8.3.rc0.401.g45bba44
Next: Felipe Contreras
Message 1 of 7 in “sha1_name: reorganize get_sha1_basic()”
  1. sha1_name: reorganize get_sha1_basic()Felipe Contreras, May 2, 2013
  2. Felipe ContrerasMay 2, 2013
  3. Ramkumar RamachandraMay 2, 2013
  4. Felipe ContrerasMay 2, 2013
  5. Ramkumar RamachandraMay 2, 2013
  6. Ramkumar RamachandraMay 2, 2013
  7. Felipe ContrerasMay 2, 2013

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.