Subject: worktree_git_path() should not use file relocation git_path is a convenience function that usually produces a string $GIT_DIR/<path>. Since v2.5.0-rc0~143^2~35 (git_path(): be aware of file relocation in $GIT_DIR, 2014-11-30), as a side benefit callers get support for path relocation variables like $GIT_OBJECT_DIRECTORY: - git_path("index") is $GIT_INDEX_FILE when set - git_path("info/grafts") is $GIT_GRAFTS_FILE when set - git_path("objects/<foo>") is $GIT_OBJECT_DIRECTORY/<foo> when set - git_path("hooks/<foo>") is <foo> under core.hookspath when set - git_path("refs/<foo>") etc (see path.c::common_list) is relative to $GIT_COMMON_DIR instead of $GIT_DIR worktree_git_path, by comparison, is designed to resolve files in a specific worktree's git dir. Unfortunately, it shares code with git_path and performs the same relocation. The result is that paths that are meant to be relative to the specified worktree's git dir end up replaced by paths from environment variables within the current git dir. Luckily, no current callers pass such arguments. The relocation was noticed when testing the result of merging two patches under review, one of which introduces a caller: * The first patch made git prune check the index file in each worktree's git dir (using worktree_git_path(wt, "index")) for objects not to prune. This would trigger the unwanted relocation when GIT_INDEX_FILE is set, causing objects reachable from the index to be pruned. * The second patch simplified the relocation logic for index, info/grafts, objects, and hooks to happen unconditionally instead of based on whether environment or configuration variables are set. This caused the relocation to trigger even when GIT_INDEX_FILE is not set. [jn: rewrote commit message; skipping all relocation instead of just GIT_INDEX_FILE] Signed-off-by: Brandon Williams <bmwill@xxxxxxxxxx> Signed-off-by: Jonathan Nieder <jrnieder@xxxxxxxxx> --- Jonathan Nieder wrote: > How about the following? I found it a little easier to understand. > > -- >8 -- > From: Brandon Williams <bmwill@xxxxxxxxxx> > Subject: worktree_git_path: do not let GIT_INDEX_FILE override path to index [...] > Change-Id: I2ba0a48a48b7e9a9c2e3ef97648cf53cb913bdd9 Gah, sorry about the stray Change-Id line. While we're fixing that, here's a version with a slightly clearer commit message. path.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/path.c b/path.c index c1cb1cf62..4c3a27a8e 100644 --- a/path.c +++ b/path.c @@ -397,7 +397,8 @@ static void do_git_path(const struct worktree *wt, struct strbuf *buf, strbuf_addch(buf, '/'); gitdir_len = buf->len; strbuf_vaddf(buf, fmt, args); - adjust_git_path(buf, gitdir_len); + if (!wt) + adjust_git_path(buf, gitdir_len); strbuf_cleanup_path(buf); } -- 2.13.1.611.g7e3b11ae1-goog