[PATCH v3 09/12] worktree: don't store main worktree twice

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

 



In `get_worktree_ref_store()` we either return the repository's main ref
store, or we look up the ref store via the map of worktree ref stores.
Which of these worktrees gets picked depends on the `is_current` bit of
the worktree, which indicates whether the worktree is the one that
corresponds to `the_repository`.

The bit is getting set in `get_worktrees()`, but only after we have
computed the list of all worktrees. This is too late though, because at
that time we have already called `get_worktree_ref_store()` on each of
the worktrees via `add_head_info()`. The consequence is that the current
worktree will not have been marked accordingly, which means that we did
not use the main ref store, but instead created a new ref store. We thus
have two separate ref stores now that map to the same ref database.

Fix this by setting `is_current` before we call `add_head_info()`.

Signed-off-by: Patrick Steinhardt <ps@xxxxxx>
---
 worktree.c | 29 +++++++++++------------------
 1 file changed, 11 insertions(+), 18 deletions(-)

diff --git a/worktree.c b/worktree.c
index 12eadacc61..70844d023a 100644
--- a/worktree.c
+++ b/worktree.c
@@ -53,6 +53,15 @@ static void add_head_info(struct worktree *wt)
 		wt->is_detached = 1;
 }
 
+static int is_current_worktree(struct worktree *wt)
+{
+	char *git_dir = absolute_pathdup(get_git_dir());
+	const char *wt_git_dir = get_worktree_git_dir(wt);
+	int is_current = !fspathcmp(git_dir, absolute_path(wt_git_dir));
+	free(git_dir);
+	return is_current;
+}
+
 /**
  * get the main worktree
  */
@@ -76,6 +85,7 @@ static struct worktree *get_main_worktree(int skip_reading_head)
 	 */
 	worktree->is_bare = (is_bare_repository_cfg == 1) ||
 		is_bare_repository();
+	worktree->is_current = is_current_worktree(worktree);
 	if (!skip_reading_head)
 		add_head_info(worktree);
 	return worktree;
@@ -102,6 +112,7 @@ struct worktree *get_linked_worktree(const char *id,
 	worktree->repo = the_repository;
 	worktree->path = strbuf_detach(&worktree_path, NULL);
 	worktree->id = xstrdup(id);
+	worktree->is_current = is_current_worktree(worktree);
 	if (!skip_reading_head)
 		add_head_info(worktree);
 
@@ -111,23 +122,6 @@ struct worktree *get_linked_worktree(const char *id,
 	return worktree;
 }
 
-static void mark_current_worktree(struct worktree **worktrees)
-{
-	char *git_dir = absolute_pathdup(get_git_dir());
-	int i;
-
-	for (i = 0; worktrees[i]; i++) {
-		struct worktree *wt = worktrees[i];
-		const char *wt_git_dir = get_worktree_git_dir(wt);
-
-		if (!fspathcmp(git_dir, absolute_path(wt_git_dir))) {
-			wt->is_current = 1;
-			break;
-		}
-	}
-	free(git_dir);
-}
-
 /*
  * NEEDSWORK: This function exists so that we can look up metadata of a
  * worktree without trying to access any of its internals like the refdb. It
@@ -164,7 +158,6 @@ static struct worktree **get_worktrees_internal(int skip_reading_head)
 	ALLOC_GROW(list, counter + 1, alloc);
 	list[counter] = NULL;
 
-	mark_current_worktree(list);
 	return list;
 }
 
-- 
2.45.1.246.gb9cfe4845c.dirty

Attachment: signature.asc
Description: PGP signature


[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]

  Powered by Linux