When working with worktrees the git directory is split into two part,
the per-worktree gitdir and a commondir which contains things which are
shared among all worktrees (like the object store).  With this notion of
having a split git directory, 557bd833b (git_path(): be aware of file
relocation in $GIT_DIR) and c7b3a3d2f ($GIT_COMMON_DIR: a new
environment variable) changed the way that 'git_path()' functioned so
that paths would be adjusted if they referred to files or directories
that are stored in the commondir or have been changed via an environment
variable.

One interesting problem with this is the index file as it is not shared
across worktrees yet when asking for a path to a specific worktree's
index it will be replaced with a path to the current worktree's index.
In order to prevent this, teach 'adjuct_git_path' to replace the
path to the index with the path recorded in a repository (which would be
the current, active worktree) only when not asked to construct a path
for a specific worktree.

Signed-off-by: Brandon Williams <bmw...@google.com>
---
 path.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/path.c b/path.c
index 76a872297..c6832a30e 100644
--- a/path.c
+++ b/path.c
@@ -372,13 +372,20 @@ void report_linked_checkout_garbage(void)
 }
 
 static void adjust_git_path(const struct repository *repo,
+                           const struct worktree *wt,
                            struct strbuf *buf, int git_dir_len)
 {
        const char *base = buf->buf + git_dir_len;
        if (is_dir_file(base, "info", "grafts"))
                strbuf_splice(buf, 0, buf->len,
                              repo->graft_file, strlen(repo->graft_file));
-       else if (!strcmp(base, "index"))
+       /*
+        * Only try to replace the path '$gitdir/index' with the index file
+        * recorded in the repository when not constructing a path for a
+        * worktree.  This way we can retrieve the correct path to a particular
+        * worktree's index file.
+        */
+       else if (!wt && !strcmp(base, "index"))
                strbuf_splice(buf, 0, buf->len,
                              repo->index_file, strlen(repo->index_file));
        else if (dir_prefix(base, "objects"))
@@ -411,7 +418,7 @@ static void do_git_path(const struct repository *repo,
                strbuf_addch(buf, '/');
        gitdir_len = buf->len;
        strbuf_vaddf(buf, fmt, args);
-       adjust_git_path(repo, buf, gitdir_len);
+       adjust_git_path(repo, wt, buf, gitdir_len);
        strbuf_cleanup_path(buf);
 }
 
-- 
2.13.1.611.g7e3b11ae1-goog

Reply via email to