So, I find this behaviour a little strange; I can't determine if it's
a subtle bug, or intentionally undefined/‘fuzzy’ behaviour:
$ cd a-repo/.git/
$ pwd
/path/to/a-repo/.git
$ git rev-parse --is-inside-work-tree
false
$ export GIT_WORK_TREE=/path/to/a-repo
$ git rev-parse --is-inside-work-tree
true
i.e. when within the repository (the `.git` directory), and when that
directory is a sub-directory of the working-tree, `rev-parse
--is-inside-work-tree` reports *false* (reasonable enough, I suppose);
but then if `$GIT_WORK_TREE` is set to precisely the directory that
git was *already* assuming was the working-directory, then the same
command, in the same location, reports *true*.
This should probably be made consistent: either `rev-parse
--is-inside-work-tree` should report “true”, even inside the `.git`
dir, as long as that directory is a sub-directory of the working-tree
… or repository-directories / `$GIT_DIR` / `.git` directories should
be excluded from truthy responses to `rev-parse
--is-inside-work-tree`.
⁓ ELLIOTTCABLE — fly safe.
http://ell.io/tt
On Tue, Mar 29, 2016 at 6:42 AM, Elliott Cable [off-list ref] wrote:
So, I find this behaviour a little strange; I can't determine if it's
a subtle bug, or intentionally undefined/‘fuzzy’ behaviour ...
Oh lord, it gets worse ...
$ cd a-repo
$ git rev-parse --is-inside-work-tree; git rev-parse --is-inside-git-dir
true
false
$ cd .git
$ git rev-parse --is-inside-work-tree; git rev-parse --is-inside-git-dir
false
true
$ export GIT_WORK_TREE="$(git rev-parse --show-toplevel)" # !!!
$ git rev-parse --is-inside-work-tree; git rev-parse --is-inside-git-dir
true
false
$ # !!?!?
So, basically, if `$GIT_WORK_TREE` is set at all, it appears that the
`rev-parse --is-inside...` flags don't function reliably at all.
⁓ ELLIOTTCABLE — fly safe.
http://ell.io/tt
Did you check the value of GIT_WORK_TREE here? When I try it's the
empty string.
If I set the core.worktree config variable to ".." then rev-parse does
find the working tree correctly. I recall some previous discussion
about this but I can't find it in the list archives from a quick search.
$ git rev-parse --is-inside-work-tree; git rev-parse --is-inside-git-dir
true
false
$ # !!?!?
So, basically, if `$GIT_WORK_TREE` is set at all, it appears that the
`rev-parse --is-inside...` flags don't function reliably at all.
If you set GIT_WORK_TREE you're telling Git to override all of the
normal detection logic. What version of Git are you using? When I try
this it says:
fatal: The empty string is not a valid path
If I set GIT_WORK_TREE to the correct value for this repository then it
behaves the same as with the auto-detection logic.
From: Jeff King <hidden> Date: 2016-06-15 23:09:06
On Tue, Mar 29, 2016 at 06:42:44AM -0500, Elliott Cable wrote:
So, I find this behaviour a little strange; I can't determine if it's
a subtle bug, or intentionally undefined/‘fuzzy’ behaviour:
$ cd a-repo/.git/
$ pwd
/path/to/a-repo/.git
$ git rev-parse --is-inside-work-tree
false
$ export GIT_WORK_TREE=/path/to/a-repo
$ git rev-parse --is-inside-work-tree
true
i.e. when within the repository (the `.git` directory), and when that
directory is a sub-directory of the working-tree, `rev-parse
--is-inside-work-tree` reports *false* (reasonable enough, I suppose);
but then if `$GIT_WORK_TREE` is set to precisely the directory that
git was *already* assuming was the working-directory, then the same
command, in the same location, reports *true*.
This should probably be made consistent: either `rev-parse
--is-inside-work-tree` should report “true”, even inside the `.git`
dir, as long as that directory is a sub-directory of the working-tree
… or repository-directories / `$GIT_DIR` / `.git` directories should
be excluded from truthy responses to `rev-parse
--is-inside-work-tree`.
Yeah, I think this is a bug. Presumably what is happening is that we are
too eager to "cd $GIT_WORK_TREE" inside git-rev-parse, and by the time
we ask "are we in a work tree", the answer has become yes. But the
caller really wants to know "am _I_ inside the work tree".
Unfortunately, I think the fix is likely to be rather tricky, as the
work-tree stuff is happening deep inside setup_git_directory().
-Peff
From: John Keeping <hidden> Date: 2016-06-15 23:09:06
On Tue, Mar 29, 2016 at 04:34:25PM -0400, Jeff King wrote:
On Tue, Mar 29, 2016 at 06:42:44AM -0500, Elliott Cable wrote:
quoted
So, I find this behaviour a little strange; I can't determine if it's
a subtle bug, or intentionally undefined/‘fuzzy’ behaviour:
$ cd a-repo/.git/
$ pwd
/path/to/a-repo/.git
$ git rev-parse --is-inside-work-tree
false
$ export GIT_WORK_TREE=/path/to/a-repo
$ git rev-parse --is-inside-work-tree
true
i.e. when within the repository (the `.git` directory), and when that
directory is a sub-directory of the working-tree, `rev-parse
--is-inside-work-tree` reports *false* (reasonable enough, I suppose);
but then if `$GIT_WORK_TREE` is set to precisely the directory that
git was *already* assuming was the working-directory, then the same
command, in the same location, reports *true*.
This should probably be made consistent: either `rev-parse
--is-inside-work-tree` should report “true”, even inside the `.git`
dir, as long as that directory is a sub-directory of the working-tree
… or repository-directories / `$GIT_DIR` / `.git` directories should
be excluded from truthy responses to `rev-parse
--is-inside-work-tree`.
Yeah, I think this is a bug. Presumably what is happening is that we are
too eager to "cd $GIT_WORK_TREE" inside git-rev-parse, and by the time
we ask "are we in a work tree", the answer has become yes. But the
caller really wants to know "am _I_ inside the work tree".
I don't think that's what's happening. Try:
$ cd .git/
$ GIT_WORK_TREE=.. git rev-parse --is-inside-work-tree
true
so I think it's that we refuse to assume that the directory above a Git
directory is a working tree (something similar happens when the
"core.worktree" config variable is set). I'm not convinced that's
unreasonable.
However, the case above also gives:
$ GIT_WORK_TREE=.. git rev-parse --is-inside-git-dir
false
$ test $(pwd) = $(GIT_WORK_TREE=.. git rev-parse --git-dir); echo $?
0
so even though $PWD *is* the Git directory, we're not in the Git
directory! Setting GIT_DIR=$(pwd) makes no different to that.
From: Jeff King <hidden> Date: 2016-06-15 23:09:06
On Tue, Mar 29, 2016 at 09:52:08PM +0100, John Keeping wrote:
quoted
Yeah, I think this is a bug. Presumably what is happening is that we are
too eager to "cd $GIT_WORK_TREE" inside git-rev-parse, and by the time
we ask "are we in a work tree", the answer has become yes. But the
caller really wants to know "am _I_ inside the work tree".
I don't think that's what's happening. Try:
$ cd .git/
$ GIT_WORK_TREE=.. git rev-parse --is-inside-work-tree
true
so I think it's that we refuse to assume that the directory above a Git
directory is a working tree (something similar happens when the
"core.worktree" config variable is set). I'm not convinced that's
unreasonable.
Yeah, you're right, but I'm not sure how your example shows that, (isn't
it basically the same as Elliott's original, except using a relative
path?). A more compelling counter-example to my hypothesis is:
$ cd .git
$ GIT_WORK_TREE=/tmp git rev-parse --is-inside-work-tree
false
So it is not that we chdir too early, but just that we blindly check "is
$(pwd) inside $GIT_WORK_TREE". And it does not create a problem for the
normal discovered-path cases, because either:
- we discovered .git by walking up the directory tree, which means we
must be in a work-tree
- we discovered that we are inside a .git directory, and therefore
take it to be bare (and thus there is no work tree, and we cannot be
inside it). This is what happens in Elliott's original example that
behaves differently than the $GIT_WORK_TREE case.
I'd be tempted to say that "inside the work tree" is further clarified
to "not inside the $GIT_DIR". But as you note:
However, the case above also gives:
$ GIT_WORK_TREE=.. git rev-parse --is-inside-git-dir
false
$ test $(pwd) = $(GIT_WORK_TREE=.. git rev-parse --git-dir); echo $?
0
so even though $PWD *is* the Git directory, we're not in the Git
directory! Setting GIT_DIR=$(pwd) makes no different to that.
We seem to get that wrong. I'm also not sure if it would make sense if
you explicitly set the two to be equal, like:
# checking in your own refs?
GIT_WORK_TREE=$(pwd) GIT_DIR=$(pwd) git add refs packed-refs
So the current behavior may just be weird-but-true.
-Peff
From: John Keeping <hidden> Date: 2016-06-15 23:09:06
On Tue, Mar 29, 2016 at 05:21:43PM -0400, Jeff King wrote:
On Tue, Mar 29, 2016 at 09:52:08PM +0100, John Keeping wrote:
quoted
quoted
Yeah, I think this is a bug. Presumably what is happening is that we are
too eager to "cd $GIT_WORK_TREE" inside git-rev-parse, and by the time
we ask "are we in a work tree", the answer has become yes. But the
caller really wants to know "am _I_ inside the work tree".
I don't think that's what's happening. Try:
$ cd .git/
$ GIT_WORK_TREE=.. git rev-parse --is-inside-work-tree
true
so I think it's that we refuse to assume that the directory above a Git
directory is a working tree (something similar happens when the
"core.worktree" config variable is set). I'm not convinced that's
unreasonable.
Yeah, you're right, but I'm not sure how your example shows that, (isn't
it basically the same as Elliott's original, except using a relative
path?). A more compelling counter-example to my hypothesis is:
$ cd .git
$ GIT_WORK_TREE=/tmp git rev-parse --is-inside-work-tree
false
So it is not that we chdir too early, but just that we blindly check "is
$(pwd) inside $GIT_WORK_TREE". And it does not create a problem for the
normal discovered-path cases, because either:
- we discovered .git by walking up the directory tree, which means we
must be in a work-tree
- we discovered that we are inside a .git directory, and therefore
take it to be bare (and thus there is no work tree, and we cannot be
inside it). This is what happens in Elliott's original example that
behaves differently than the $GIT_WORK_TREE case.
I'd be tempted to say that "inside the work tree" is further clarified
to "not inside the $GIT_DIR".
Yes, I think that's reasonable. But...
quoted
However, the case above also gives:
$ GIT_WORK_TREE=.. git rev-parse --is-inside-git-dir
false
$ test $(pwd) = $(GIT_WORK_TREE=.. git rev-parse --git-dir); echo $?
0
so even though $PWD *is* the Git directory, we're not in the Git
directory! Setting GIT_DIR=$(pwd) makes no different to that.
We seem to get that wrong. I'm also not sure if it would make sense if
you explicitly set the two to be equal, like:
# checking in your own refs?
GIT_WORK_TREE=$(pwd) GIT_DIR=$(pwd) git add refs packed-refs
So the current behavior may just be weird-but-true.
This case definitely feels wrong:
$ GIT_WORK_TREE=$(cd ..; pwd) GIT_DIR=$(pwd) git rev-parse --is-inside-git-dir
false
Shouldn't that be the same as if GIT_WORK_TREE and GIT_DIR aren't set?
(It's also potentially surprising since "git rev-parse --git-dir" does
give the right answer in this case.)
If GIT_WORK_TREE points somewhere unrelated then it is correct:
$ GIT_WORK_TREE=/tmp GIT_DIR=$(pwd) git rev-parse --is-inside-git-dir
true
From: John Keeping <hidden> Date: 2016-06-15 23:09:06
On Tue, Mar 29, 2016 at 11:00:03PM +0100, John Keeping wrote:
On Tue, Mar 29, 2016 at 05:21:43PM -0400, Jeff King wrote:
quoted
On Tue, Mar 29, 2016 at 09:52:08PM +0100, John Keeping wrote:
quoted
quoted
Yeah, I think this is a bug. Presumably what is happening is that we are
too eager to "cd $GIT_WORK_TREE" inside git-rev-parse, and by the time
we ask "are we in a work tree", the answer has become yes. But the
caller really wants to know "am _I_ inside the work tree".
I don't think that's what's happening. Try:
$ cd .git/
$ GIT_WORK_TREE=.. git rev-parse --is-inside-work-tree
true
so I think it's that we refuse to assume that the directory above a Git
directory is a working tree (something similar happens when the
"core.worktree" config variable is set). I'm not convinced that's
unreasonable.
Yeah, you're right, but I'm not sure how your example shows that, (isn't
it basically the same as Elliott's original, except using a relative
path?). A more compelling counter-example to my hypothesis is:
$ cd .git
$ GIT_WORK_TREE=/tmp git rev-parse --is-inside-work-tree
false
So it is not that we chdir too early, but just that we blindly check "is
$(pwd) inside $GIT_WORK_TREE". And it does not create a problem for the
normal discovered-path cases, because either:
- we discovered .git by walking up the directory tree, which means we
must be in a work-tree
- we discovered that we are inside a .git directory, and therefore
take it to be bare (and thus there is no work tree, and we cannot be
inside it). This is what happens in Elliott's original example that
behaves differently than the $GIT_WORK_TREE case.
I'd be tempted to say that "inside the work tree" is further clarified
to "not inside the $GIT_DIR".
Yes, I think that's reasonable. But...
quoted
quoted
However, the case above also gives:
$ GIT_WORK_TREE=.. git rev-parse --is-inside-git-dir
false
$ test $(pwd) = $(GIT_WORK_TREE=.. git rev-parse --git-dir); echo $?
0
so even though $PWD *is* the Git directory, we're not in the Git
directory! Setting GIT_DIR=$(pwd) makes no different to that.
We seem to get that wrong. I'm also not sure if it would make sense if
you explicitly set the two to be equal, like:
# checking in your own refs?
GIT_WORK_TREE=$(pwd) GIT_DIR=$(pwd) git add refs packed-refs
So the current behavior may just be weird-but-true.
This case definitely feels wrong:
$ GIT_WORK_TREE=$(cd ..; pwd) GIT_DIR=$(pwd) git rev-parse --is-inside-git-dir
false
Shouldn't that be the same as if GIT_WORK_TREE and GIT_DIR aren't set?
(It's also potentially surprising since "git rev-parse --git-dir" does
give the right answer in this case.)
If GIT_WORK_TREE points somewhere unrelated then it is correct:
$ GIT_WORK_TREE=/tmp GIT_DIR=$(pwd) git rev-parse --is-inside-git-dir
true
It seems that this is a result of changing the working directory to the
root of the working tree if we're inside it. is_inside_dir() doesn't
take account of startup_info->prefix and changing to:
real_path(startup_info->prefix)
instead of xgetcwd() means that these tests are less surprising.
But I haven't run the test suite or thought about what else this could
break.
From: Jeff King <hidden> Date: 2016-06-15 23:09:06
On Tue, Mar 29, 2016 at 11:00:03PM +0100, John Keeping wrote:
quoted
We seem to get that wrong. I'm also not sure if it would make sense if
you explicitly set the two to be equal, like:
# checking in your own refs?
GIT_WORK_TREE=$(pwd) GIT_DIR=$(pwd) git add refs packed-refs
So the current behavior may just be weird-but-true.
This case definitely feels wrong:
$ GIT_WORK_TREE=$(cd ..; pwd) GIT_DIR=$(pwd) git rev-parse --is-inside-git-dir
false
Yeah, and not just the is-inside-git-dir test:
$ echo content >../file
$ GIT_WORK_TREE=$(cd ..; pwd) GIT_DIR=$(pwd) git add file
fatal: pathspec 'file' did not match any files
I'd expect that to work, and it doesn't, because we pass ".git/" as the
"prefix" to cmd_add(). Which I guess is true, but it feels kind of weird
(I think most people who set both variables like that would generally
point to some other directory entirely, and we would have a NULL
prefix).
The --is-inside-git-dir thing is related, but a different problem. I
just got your follow-up mentioning that it doesn't take the prefix into
account, which I agree it probably should.
-Peff
On Wed, Mar 30, 2016 at 3:34 AM, Jeff King [off-list ref] wrote:
On Tue, Mar 29, 2016 at 06:42:44AM -0500, Elliott Cable wrote:
quoted
So, I find this behaviour a little strange; I can't determine if it's
a subtle bug, or intentionally undefined/‘fuzzy’ behaviour:
$ cd a-repo/.git/
$ pwd
/path/to/a-repo/.git
$ git rev-parse --is-inside-work-tree
false
$ export GIT_WORK_TREE=/path/to/a-repo
$ git rev-parse --is-inside-work-tree
true
i.e. when within the repository (the `.git` directory), and when that
directory is a sub-directory of the working-tree, `rev-parse
--is-inside-work-tree` reports *false* (reasonable enough, I suppose);
but then if `$GIT_WORK_TREE` is set to precisely the directory that
git was *already* assuming was the working-directory, then the same
command, in the same location, reports *true*.
This should probably be made consistent: either `rev-parse
--is-inside-work-tree` should report “true”, even inside the `.git`
dir, as long as that directory is a sub-directory of the working-tree
… or repository-directories / `$GIT_DIR` / `.git` directories should
be excluded from truthy responses to `rev-parse
--is-inside-work-tree`.
No. Once you set GIT_WORK_TREE you tell git that worktree exists. That
overrides the "bare repo" attribute (i.e. no worktree) that's
automatically set when we try to find .git directory.
Yeah, I think this is a bug. Presumably what is happening is that we are
too eager to "cd $GIT_WORK_TREE" inside git-rev-parse, and by the time
we ask "are we in a work tree", the answer has become yes. But the
caller really wants to know "am _I_ inside the work tree".
On relative GIT_WORK_TREE some mail down this thread, there's this
note in t1510 that you might find interesting
5. GIT_WORK_TREE/core.worktree was originally meant to work only if
GIT_DIR is set, but earlier git didn't enforce it, and some scripts
depend on the implementation that happened to first discover .git by
going up from the users $cwd and then using the specified working tree
that may or may not have any relation to where .git was found in. This
historical behaviour must be kept.
Basically if you set GIT_WORK_TREE you better set GIT_DIR too to keep
things sane.
--
Duy
oh, wow, this got over my head *real* fast. Okay,
1. Yeah, my `$GIT_WORK_TREE` was def. an absolute path; I typed that
example code without running it *precisely* that way (entirely my
mistake! I'm so sorry for the confusion it caused, and all that typing
you did!); if I remember correctly (not at the machine right now), I
had run `git rev-parse --show-toplevel` from a different directory,
with `$GIT_DIR` set, while trying to narrow down this bug, so it gave
me an absolute path … and then copy-pasted that path, and then
replaced my copy-paste with the original command to make the
bug-report example as concise as possible? oops. But, yeah, it fails
in the manner described above with an absolute path. (Which it looks
like you two figured out above.)
2. Re: intentions, again, it seems like you've changed your mind, but …
> So it is a misconfiguration if you only set GIT_WORK_TREE
without setting GIT_DIR.
I really, really hope not! Half the usefulness of `$GIT_WORK_TREE`
existing is in that mode. In fact, that's how I found `$GIT_WORK_TREE`
documented and explained, in [this blog
post](https://git-scm.com/blog/2010/04/11/environment.html) on the Git
site. That usage seems pretty damn useful, so I do hope it's
eventually explicitly supported … (and if that's *not* going to be the
case, it should be explicitly documented in the `GIT(1)` manpage,
alongside the other documentation of the environment-variables, that
the behaviour is undefined is `$GIT_DIR` isn't set first. =)
⁓ ELLIOTTCABLE — fly safe.
http://ell.io/tt