From: Junio C Hamano <gitster@pobox.com>
To: "Yoichi NAKAYAMA via GitGitGadget" <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org, Yoichi Nakayama <yoichi.nakayama@gmail.com>
Subject: Re: [PATCH v3] worktree repair: detect relative path in .git file correctly
Date: Fri, 21 Aug 2026 15:02:42 -0700 [thread overview]
Message-ID: <xmqq8q5zyvwd.fsf@gitster.g> (raw)
In-Reply-To: <pull.2205.v3.git.1787344586470.gitgitgadget@gmail.com> (Yoichi NAKAYAMA via GitGitGadget's message of "Fri, 21 Aug 2026 20:36:26 +0000")
"Yoichi NAKAYAMA via GitGitGadget" <gitgitgadget@gmail.com> writes:
> From: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com>
>
> Given a state in which the cross-references between the worktree and
> the repository (specifically worktree/id/gitdir in the main repository
> and the .git file in the worktree) are recorded using absolute paths,
> setting 'worktree.useRelativePaths=true' and running 'git worktree
> repair' within the main worktree converts them to relative paths.
>
> Conversely, given a state in which the cross-references are recorded
> using relative paths, one would expect that setting
> 'worktree.useRelativePaths=false' and running 'git worktree repair'
> would convert them to absolute paths. However, they remain as relative
> paths.
>
> This is because we incorrectly use read_gitfile_gently(), which always
> returns an absolute path. To fix this, introduce read_gitfile_raw(),
> which is almost identical to read_gitfile_gently(), but skips checking
> the existence of the referenced repository and returns the path as-is
> from the .git file.
Excellent observation of the problem addressed by the patch. I wish
everybody wrote his or her proposed log message this clearly.
> diff --git a/setup.c b/setup.c
> index 95909e9603..9041827336 100644
> --- a/setup.c
> +++ b/setup.c
> @@ -962,16 +962,48 @@ void read_gitfile_error_die(int error_code, const char *path)
> * cases).
> */
> const char *read_gitfile_gently(const char *path, int *return_error_code)
> +{
> + int error_code = 0;
> + const char *slash;
> + struct strbuf contents = STRBUF_INIT;
> + static struct strbuf realpath = STRBUF_INIT;
> +
> + error_code = read_gitfile_raw(&contents, path);
> + if (error_code)
> + goto cleanup_return;
> +
> + if (!is_absolute_path(contents.buf) && (slash = strrchr(path, '/'))) {
> + size_t pathlen = slash+1 - path;
> + char *dir = xstrfmt("%.*s%s", (int)pathlen, path, contents.buf);
> + strbuf_reset(&contents);
> + strbuf_addstr(&contents, dir);
> + free(dir);
> + }
This massages path = "worktrees/foo/.git" into "worktrees/foo". And
the non-absolute contents.buf "../main/.git/worktrees/foo" that is
relative to gitfile is turned into relative to cwd of our process by
prepending "worktrees/foo" to it.
> + if (!is_git_directory(contents.buf)) {
> + error_code = READ_GITFILE_ERR_NOT_A_REPO;
> + goto cleanup_return;
> + }
This ensures that the thing referenced by .git file (i.e., what
comes after "gitdir:") is a sanely formatted git directory.
> + strbuf_realpath(&realpath, contents.buf, 1);
This turns the thing into an absolute path.
Among these three, the last one obviously belongs here. Leaving the
relative path relative was the reason why we wanted to add
read_gitfile_raw() in the first place.
But moving the other two to here is a bit iffy. The worktree repair
job used to call read_gitfile_gently(), which means it used to
depend on what the first two did for it, namely, to make the
relative path after "gitdir:" from the .git file relative to the
current process to make it usable, and to ensure that the directory
pointed at by .git is indeed a git directory. Is it correct to drop
these from the caller, which now calls read_gitfile_raw() instead?
IOW, I am not sure if the two functions are split correctly. I
expected that the only two things read_gitfile_gently() would do
after read_gitfile_raw() are (1) upon error, jump to cleanup_return,
and (2) otherwise call strbuf_realpath().
Thanks.
next prev parent reply other threads:[~2026-08-21 22:02 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-15 13:11 [PATCH] worktree repair: detect relative path in .git file correctly Yoichi NAKAYAMA via GitGitGadget
2026-08-17 17:21 ` Junio C Hamano
2026-08-17 21:27 ` Yoichi Nakayama
2026-08-20 15:46 ` [PATCH v2] " Yoichi NAKAYAMA via GitGitGadget
2026-08-21 2:09 ` Junio C Hamano
2026-08-21 20:36 ` [PATCH v3] " Yoichi NAKAYAMA via GitGitGadget
2026-08-21 22:02 ` Junio C Hamano [this message]
2026-08-21 22:20 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqq8q5zyvwd.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=gitgitgadget@gmail.com \
--cc=yoichi.nakayama@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.