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

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

From
KCKenneth Cochran <kenneth.cochran101@gmail.com>
Date
Mar 4, 2019, 15:49 UTC
Message-ID
<D4829D84-9192-4C7A-8487-0374DAFC324A@gmail.com>
In-Reply-To
<D9CFD250-26D4-4D1F-B0CD-01E24E8606D9@gmail.com>
From 9f9b9010cb0b8c2874428d2f4bd21f06f747bfee Mon Sep 17 00:00:00 2001
From: Kenneth Cochran <kenneth.cochran101@gmail.com>
Date: Sun, 3 Mar 2019 15:34:20 -0600
Subject: [RFC PATCH 3/4] worktree: symref should be found anywhere in chain
Cc: Sahil Dua <sahildua2305@gmail.com>,
    Duy Nguyen <pclouds@gmail.com>,
    Jeff King <peff@peff.net>

Currently, when searching for a shared symref, a symref chain is fully dereferenced before checking the name. This poses problems for `git branch -d` which will happily delete a checked out symref.

The existing behaviour (recognizing a non-symbolic ref by the same name) still exists, but it will now also find any symref that is in between the starting symref and the first non-symbolic ref.

Concretely, for the following chain HEAD -> symref1 -> symref2 -> master previously the function was only able to find master. With these changes applied, it will be able to find any of the above references.

Signed-off-by: Kenneth Cochran <kenneth.cochran101@gmail.com>
---
 t/t3207-branch-alias.sh | 13 +++++++++++++
 worktree.c              | 18 ++++++++++++------
 2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/t/t3207-branch-alias.sh b/t/t3207-branch-alias.sh
index 9d4c8c2914..c1edeed4eb 100755
--- a/t/t3207-branch-alias.sh
+++ b/t/t3207-branch-alias.sh
@@ -55,4 +55,17 @@ test_expect_success 'git branch --alias refuses to overwrite existing symref' '
 	test_must_fail git branch --alias syme
 '
 
+test_expect_success 'git branch -d refuses to delete a checked out symref' '
+	git branch --alias symd &&
+	git checkout symd &&
+	test_must_fail git branch -d symd
+'
+
+test_expect_success 'git branch -d refuses to delete an indirectly checked out symref' '
+	git symbolic-ref refs/heads/symd2 refs/heads/symd &&
+	git checkout symd2 &&
+	test_must_fail git branch -d symd2 &&
+	test_must_fail git branch -d symd
+'
+
 test_done
diff --git a/worktree.c b/worktree.c
index d6a0ee7f73..b58325c6c1 100644
--- a/worktree.c
+++ b/worktree.c
@@ -387,6 +387,17 @@ int is_worktree_being_bisected(const struct worktree *wt,
 	return found_rebase;
 }
 
+static int find_symref_by_name(const char *ref_name, const struct object_id *oid,
+			       int flags, void *cb_data)
+{
+	const char *target = (const char *)cb_data;
+
+	if ((flags & REF_ISSYMREF) && !strcmp(target, ref_name))
+		return 1;
+	else
+		return 0;
+}
+
 /*
  * note: this function should be able to detect shared symref even if
  * HEAD is temporarily detached (e.g. in the middle of rebase or
@@ -406,9 +417,7 @@ const struct worktree *find_shared_symref(const char *symref,
 
 	for (i = 0; worktrees[i]; i++) {
 		struct worktree *wt = worktrees[i];
-		const char *symref_target;
 		struct ref_store *refs;
-		int flags;
 
 		if (wt->is_bare)
 			continue;
@@ -425,10 +434,7 @@ const struct worktree *find_shared_symref(const char *symref,
 		}
 
 		refs = get_worktree_ref_store(wt);
-		symref_target = refs_resolve_ref_unsafe(refs, symref, 0,
-							NULL, &flags);
-		if ((flags & REF_ISSYMREF) &&
-		    symref_target && !strcmp(symref_target, target)) {
+		if(refs_for_each_ref_in_chain(refs, find_symref_by_name, (void *)target, symref)) {
 			existing = wt;
 			break;
 		}
-- 
2.17.1
Previous: Kenneth CochranNext: Kenneth Cochran
Message 4 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.