Hi Federico, On Tue, 2 Nov 2021, Federico Kircheis wrote: > On Tue, Nov 02, 2021 at 03:26:05PM +0100, Johannes Schindelin wrote: > > > >On Thu, 28 Oct 2021, Federico Kircheis wrote: > > > > > today I reported what I believed to be a bug on > > > > > > https://github.com/git-for-windows/git/issues/3496 > > > > > > and learned about GIT_DIR when working with aliases and git worktree. > > > > > > It's annoying that GIT_DIR it is defined only if (as far as I've > > > understood) > > > working from a worktrees or submodule, as it does not seem to be related > > > to > > > those type of repositories. > > > >To clarify: `GIT_DIR` is set when executing an alias in a worktree other > >than the primary one (and probably also in submodules), but not when > >executing in a primary worktree. > > > > > This is also irritating because apparently working aliases breaks when > > > being > > > executed from those repositories. > > > >To clarify: an alias that wants to switch to a different repository and > >execute Git commands there works well in a primary worktree. But when you > >switch to a different repository while executing an alias from a secondary > >worktree, it will fail because of `GIT_DIR` having been set. > > > > > I believe it would be better if GIT_DIR it's either always set or never > > > (could someone enlighten me why the variable is needed in first place?). > > Yes, sorry if I was not clear, your clarification are what I meant to say. > > >The fact that `GIT_DIR` is not set when calling an alias in a primary > >worktree suggests that the behavior in secondary worktrees is not by > >design. We should therefore be able to stop setting it there. > > > >The question is: what code is responsible for setting it only in some > >circumstances but not others? > > > >Federico, do you have any experience in debugging C code? If so, it would > >be good if you could take a crack at investigating this. > > > >Ciao, > >Johannes > > Yes, I have some experience, but never looked at the git codebase. > > On GitHub (https://github.com/git-for-windows/git/issues/3496) there is > already an hint where those variables are set: > > https://github.com/git/git/blob/v2.33.1/git.c#L354 Well, that's a call to `setup_git_directory_gently()`, and obviously we already know a couple of scenarios where the `GIT_DIR` environment variable is _not_ set in this function. Unfortunately, this function is a bit long and calls other functions, too: https://github.com/git/git/blob/v2.33.1/setup.c#L1206-L1339 I actually believe that the `GIT_DIR` is set (_when_ it is set) in `set_git_dir_1()`: https://github.com/git/git/blob/v2.33.1/environment.c#L332. This function is called, unconditionally, in `set_git_dir()`, so my best bet is that the `set_git_dir()` function calls in `setup_git_directory_gently()` are the reason why `GIT_DIR` is set sometimes, but not always. And it is further my suspicion that calls to `set_git_dir()` are used to potentially turn a relative path into an absolute one, by passing a non-zero value for `make_realpath`. And this might be the reason for the calls in the first place, not the `GIT_DIR` variable. So the first step would probably be to write a test case (see the scripts in t/) that creates a secondary worktree, then calls an alias that verifies that `GIT_DIR` is not set when run in that worktree. This test case would be marked with `test_expect_failure`. Then, you need to debug that test case (e.g. by using the `debug` function to run a given Git command through `gdb` and then setting a breakpoint on `setenv()`). Once you have the call path of the offending `setenv()`, you might find an elegant way to avoid setting the environment variable. On the other hand, you could also simply unset `GIT_DIR` and friends explicitly, by adding something like this after https://github.com/git/git/blob/v2.33.1/git.c#L364: strvec_push(&child.env, "GIT_DIR"); But then, you might actually break things. The `GIT_PREFIX` variable is required to let aliases know in which subdirectory (if any) they were started. For example, if you run this command in Git's `Documentation/` directory, it will actually print the path of the top-level directory: git -c alias.pwd='!pwd' pwd This is long-established behavior, and the only way to go back to the directory from where the alias was started is to call `cd "$GIT_PREFIX"`. That's behavior, therefore, that you cannot change. And if `GIT_PREFIX` needs to be set, maybe there are scenarios where `GIT_DIR` actually _does_ need to be set? Hopefully these explanations make some sense to you. Ciao, Johannes