Git should work regardless where the working directory is located,
even at root. This patch fixes two places where it assumes working
directory always have parent directory.
In setup_git_directory_gently(), when Git goes up to root and finds
.git there, it happily sets worktree to "".
In prefix_path(), loosen the outside repo check a little bit. Usually
when a path XXX is inside worktree /foo, it must be either "/foo", or
"/foo/...". When worktree is simply "/", we can safely ignore the
check: we have a slash at the beginning already.
Not related to worktree, but also set gitdir correctly if a bare repo
is placed (insanely?) at root.
Thanks João Carlos Mendes Luís for pointing out this problem.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
Tell me if this patch is rejected, I'll send another one that makes
setup_git_* die() if worktree/gitdir is to be set empty. I don't think we
expect gitdir or worktree to be empty anywhere.
setup.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
From: Junio C Hamano <hidden> Date: 2016-06-15 22:48:12
Nguyễn Thái Ngọc Duy [off-list ref] writes:
Git should work regardless where the working directory is located,
even at root. This patch fixes two places where it assumes working
directory always have parent directory.
In setup_git_directory_gently(), when Git goes up to root and finds
.git there, it happily sets worktree to "".
If you mean "instead set it to "/" and things will work much better."
I agree with the reasoning (not suggesting to reword---just trying to
make sure I understood what you meant).
In prefix_path(), loosen the outside repo check a little bit. Usually
when a path XXX is inside worktree /foo, it must be either "/foo", or
"/foo/...". When worktree is simply "/", we can safely ignore the
check: we have a slash at the beginning already.
The logic for the "are we inside?" check above sounds correct. When
work_tree is at root, have "/" in it, and len inside the "if orig is
absolute" block is 1, so memmove() strips out the leading '/' and makes
the result relative to the root level. Am I reading the code right?
Not related to worktree, but also set gitdir correctly if a bare repo
is placed (insanely?) at root.
@@ -427,6 +427,8 @@ const char *setup_git_directory_gently(int *nongit_ok) inside_git_dir = 0; if (!work_tree_env) inside_work_tree = 1;+ if (offset == 0) /* reached root, set worktree to '/' */+ offset = 1; git_work_tree_cfg = xstrndup(cwd, offset); if (check_repository_format_gently(nongit_ok)) return NULL;
Does not work:
etc@master:1028> ~/Src/git/git/git add resolv.conf
fatal: pathspec 'tc/resolv.conf' did not match any files
I wonder how this works on Windows where we do not want to strip the slash
from C:/ either.
-- Hannes
Git should work regardless where the working directory is located,
even at root. This patch fixes two places where it assumes working
directory always have parent directory.
In setup_git_directory_gently(), when Git goes up to root and finds
.git there, it happily sets worktree to "".
If you mean "instead set it to "/" and things will work much better."
I agree with the reasoning (not suggesting to reword---just trying to
make sure I understood what you meant).
Yes.
quoted
In prefix_path(), loosen the outside repo check a little bit. Usually
when a path XXX is inside worktree /foo, it must be either "/foo", or
"/foo/...". When worktree is simply "/", we can safely ignore the
check: we have a slash at the beginning already.
The logic for the "are we inside?" check above sounds correct. When
work_tree is at root, have "/" in it, and len inside the "if orig is
absolute" block is 1, so memmove() strips out the leading '/' and makes
the result relative to the root level. Am I reading the code right?
You are. But I suspect my change in this code is not enough and caused
the problem (on msys?) for Hannes. If the worktree somehow is '//' and
sanitized is '/etc/resolv.conf', then we could end up eating two
chars, leading to "'tc/resolv.conf' not match" error.
Hannes, can you put a "printf("%s\n", work_tree);" in prefix_path() to
see if it's the case?
--
Duy
But I suspect my change in this code is not enough and caused
the problem (on msys?) for Hannes. If the worktree somehow is '//' and
sanitized is '/etc/resolv.conf', then we could end up eating two
chars, leading to "'tc/resolv.conf' not match" error.
Hannes, can you put a "printf("%s\n", work_tree);" in prefix_path() to
see if it's the case?
Silly me. You used relative path, so that code path was untouched.
--
Duy