Re: git aliases and GIT_PREFIX

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux