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

[PATCH v7 2/3] worktree: move/refactor find_shared_symref from branch.c

From
Michael Rappazzo <rappazzo@gmail.com>
Date
Sep 4, 2015, 21:39 UTC
Message-ID
<1441402769-35897-3-git-send-email-rappazzo@gmail.com>
In-Reply-To
<1441402769-35897-1-git-send-email-rappazzo@gmail.com>

The code formerly in branch.c was largely the basis of the get_worktree_list implementation is now moved to worktree.c, and the find_shared_symref implementation has been refactored to use get_worktree_list

Signed-off-by: Michael Rappazzo <rappazzo@gmail.com>
---
 branch.c        | 79 +--------------------------------------------------------
 branch.h        |  8 ------
 builtin/notes.c |  1 +
 worktree.c      | 40 +++++++++++++++++++++++++++++
 worktree.h      |  7 +++++
 5 files changed, 49 insertions(+), 86 deletions(-)
diff --git a/branch.c b/branch.c
index d013374..77d7f2a 100644
--- a/branch.c
+++ b/branch.c
@@ -4,6 +4,7 @@
 #include "refs.h"
 #include "remote.h"
 #include "commit.h"
+#include "worktree.h"
 
 struct tracking {
 	struct refspec spec;
@@ -311,84 +312,6 @@ void remove_branch_state(void)
 	unlink(git_path_squash_msg());
 }
 
-static char *find_linked_symref(const char *symref, const char *branch,
-				const char *id)
-{
-	struct strbuf sb = STRBUF_INIT;
-	struct strbuf path = STRBUF_INIT;
-	struct strbuf gitdir = STRBUF_INIT;
-	char *existing = NULL;
-
-	/*
-	 * $GIT_COMMON_DIR/$symref (e.g. HEAD) is practically outside
-	 * $GIT_DIR so resolve_ref_unsafe() won't work (it uses
-	 * git_path). Parse the ref ourselves.
-	 */
-	if (id)
-		strbuf_addf(&path, "%s/worktrees/%s/%s", get_git_common_dir(), id, symref);
-	else
-		strbuf_addf(&path, "%s/%s", get_git_common_dir(), symref);
-
-	if (!strbuf_readlink(&sb, path.buf, 0)) {
-		if (!starts_with(sb.buf, "refs/") ||
-		    check_refname_format(sb.buf, 0))
-			goto done;
-	} else if (strbuf_read_file(&sb, path.buf, 0) >= 0 &&
-	    starts_with(sb.buf, "ref:")) {
-		strbuf_remove(&sb, 0, strlen("ref:"));
-		strbuf_trim(&sb);
-	} else
-		goto done;
-	if (strcmp(sb.buf, branch))
-		goto done;
-	if (id) {
-		strbuf_reset(&path);
-		strbuf_addf(&path, "%s/worktrees/%s/gitdir", get_git_common_dir(), id);
-		if (strbuf_read_file(&gitdir, path.buf, 0) <= 0)
-			goto done;
-		strbuf_rtrim(&gitdir);
-	} else
-		strbuf_addstr(&gitdir, get_git_common_dir());
-	strbuf_strip_suffix(&gitdir, ".git");
-
-	existing = strbuf_detach(&gitdir, NULL);
-done:
-	strbuf_release(&path);
-	strbuf_release(&sb);
-	strbuf_release(&gitdir);
-
-	return existing;
-}
-
-char *find_shared_symref(const char *symref, const char *target)
-{
-	struct strbuf path = STRBUF_INIT;
-	DIR *dir;
-	struct dirent *d;
-	char *existing;
-
-	if ((existing = find_linked_symref(symref, target, NULL)))
-		return existing;
-
-	strbuf_addf(&path, "%s/worktrees", get_git_common_dir());
-	dir = opendir(path.buf);
-	strbuf_release(&path);
-	if (!dir)
-		return NULL;
-
-	while ((d = readdir(dir)) != NULL) {
-		if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
-			continue;
-		existing = find_linked_symref(symref, target, d->d_name);
-		if (existing)
-			goto done;
-	}
-done:
-	closedir(dir);
-
-	return existing;
-}
-
 void die_if_checked_out(const char *branch)
 {
 	char *existing;
diff --git a/branch.h b/branch.h
index d3446ed..58aa45f 100644
--- a/branch.h
+++ b/branch.h
@@ -59,12 +59,4 @@ extern int read_branch_desc(struct strbuf *, const char *branch_name);
  */
 extern void die_if_checked_out(const char *branch);
 
-/*
- * Check if a per-worktree symref points to a ref in the main worktree
- * or any linked worktree, and return the path to the exising worktree
- * if it is.  Returns NULL if there is no existing ref.  The caller is
- * responsible for freeing the returned path.
- */
-extern char *find_shared_symref(const char *symref, const char *target);
-
 #endif
diff --git a/builtin/notes.c b/builtin/notes.c
index 3608c64..8b30334 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -20,6 +20,7 @@
 #include "notes-merge.h"
 #include "notes-utils.h"
 #include "branch.h"
+#include "worktree.h"
 
 static const char * const git_notes_usage[] = {
 	N_("git notes [--ref <notes-ref>] [list [<object>]]"),
diff --git a/worktree.c b/worktree.c
index 33d2e57..e45b651 100644
--- a/worktree.c
+++ b/worktree.c
@@ -155,3 +155,43 @@ done:
 	return list;
 }
 
+char *find_shared_symref(const char *symref, const char *target)
+{
+	char *existing = NULL;
+	struct strbuf path = STRBUF_INIT;
+	struct strbuf sb = STRBUF_INIT;
+	struct worktree_list *worktree_list = get_worktree_list();
+	struct worktree_list *orig_list = worktree_list;
+	struct worktree *matched = NULL;
+
+	while (!matched && worktree_list) {
+		if (strcmp("HEAD", symref)) {
+			strbuf_reset(&path);
+			strbuf_reset(&sb);
+			strbuf_addf(&path, "%s/%s", worktree_list->worktree->git_dir, symref);
+
+			if (_parse_ref(path.buf, &sb, NULL)) {
+				continue;
+			}
+
+			if (!strcmp(sb.buf, target))
+				matched = worktree_list->worktree;
+		} else {
+			if (worktree_list->worktree->head_ref && !strcmp(worktree_list->worktree->head_ref, target))
+				matched = worktree_list->worktree;
+		}
+		worktree_list = worktree_list->next ? worktree_list->next : NULL;
+	}
+
+	if (matched) {
+		existing = malloc(strlen(matched->path) + 1);
+		strcpy(existing, matched->path);
+	}
+
+done:
+	strbuf_release(&path);
+	strbuf_release(&sb);
+	worktree_list_release(orig_list);
+
+	return existing;
+}
diff --git a/worktree.h b/worktree.h
index 2bc0ab8..320f17e 100644
--- a/worktree.h
+++ b/worktree.h
@@ -45,4 +45,11 @@ struct worktree *get_worktree(const char *id);
 extern void worktree_list_release(struct worktree_list *);
 extern void worktree_release(struct worktree *);
 
+/*
+ * Look for a symref in any worktree, and return the path to the first
+ * worktree found or NULL if not found.  The caller is responsible for
+ * freeing the returned path.
+ */
+extern char *find_shared_symref(const char *symref, const char *target);
+
 #endif
-- 
2.5.0
Previous: Junio C HamanoNext: Junio C Hamano
Message 14 of 27 in “worktree: worktree.c functions and list builtin command”
  1. 0/3 worktree: worktree.c functions and list builtin commandMichael Rappazzo, Sep 4, 2015
  2. 1/3 worktree: add top-level worktree.cMichael Rappazzo, Sep 4, 2015
  3. Junio C HamanoSep 10, 2015
  4. Mike RappazzoSep 11, 2015
  5. Eric SunshineSep 13, 2015
  6. Eric SunshineSep 13, 2015
  7. Mike RappazzoSep 14, 2015
  8. Junio C HamanoSep 14, 2015
  9. Eric SunshineSep 16, 2015
  10. Eric SunshineSep 16, 2015
  11. Mike RappazzoSep 16, 2015
  12. Eric SunshineSep 22, 2015
  13. Junio C HamanoSep 22, 2015
  14. 2/3 worktree: move/refactor find_shared_symref from branch.cMichael Rappazzo, Sep 4, 2015
  15. Junio C HamanoSep 11, 2015
  16. Mike RappazzoSep 11, 2015
  17. Junio C HamanoSep 11, 2015
  18. Eric SunshineSep 11, 2015
  19. Mike RappazzoSep 12, 2015
  20. Eric SunshineSep 13, 2015
  21. Mike RappazzoSep 14, 2015
  22. Eric SunshineSep 16, 2015
  23. Mike RappazzoSep 16, 2015
  24. Eric SunshineSep 22, 2015
  25. 3/3 worktree: add 'list' commandMichael Rappazzo, Sep 4, 2015
  26. Junio C HamanoSep 11, 2015
  27. Eric SunshineSep 13, 2015

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.