git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: $GIT_DIR is no longer set when pre-commit hooks are called

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Aug 28, 2018, 12:50 UTC
Message-ID
<nycvar.QRO.7.76.6.1808281442190.73@tvgsbejvaqbjf.bet>
In-Reply-To
<20180827233706.GA11663@sigill.intra.peff.net>
Hi Peff,
On Mon, 27 Aug 2018, Jeff King wrote:
Show 27 quoted lines
> On Mon, Aug 27, 2018 at 06:25:26PM +0200, Johannes Schindelin wrote:
> 
> > On Sat, 25 Aug 2018, Jeff King wrote:
> > 
> > > On Wed, Aug 22, 2018 at 04:16:00PM -0700, Gregory Oschwald wrote:
> > > 
> > > diff --git a/builtin/commit.c b/builtin/commit.c
> > > index 3bfeabc463..3670024a25 100644
> > > --- a/builtin/commit.c
> > > +++ b/builtin/commit.c
> > > @@ -1440,6 +1440,7 @@ int run_commit_hook(int editor_is_used, const char *index_file, const char *name
> > >  	int ret;
> > >  
> > >  	argv_array_pushf(&hook_env, "GIT_INDEX_FILE=%s", index_file);
> > > +	argv_array_pushf(&hook_env, "GIT_DIR=%s", get_git_dir());
> > 
> > We did something similar in sequencer.c, and it required setting
> > `GIT_WORK_TREE`, too, to avoid problems in worktrees. Do you need the same
> > here, too?
> 
> Hmm, good point. Maybe. If we're just trying to restore the original
> behavior (i.e., fix a regression), then this would behave as the
> original.
> 
> I'm not at all opposed to going beyond that and actually fixing more
> cases. But I am a little nervous of introducing a new regression, given
> the subtlety around some of our startup code.

I concur about the subtlety around the startup code. Quite a bit of that mess is now a bit easier to grok, thanks to my work to discover the GIT_DIR gently, but there are still monsters lurking in that code.

Having said that, I don't think that we can get away with setting GIT_DIR without GIT_WORK_TREE here. That would *definitely* introduce a bug, as far as I can tell.

> My current understanding is:
> 
>   - If we're setting GIT_DIR, it's probably always save to set
With s/save/safe/, I agree.
Show 17 quoted lines
>     GIT_WORK_TREE (or GIT_IMPLICIT_WORK_TREE=0 if there isn't a
>     worktree). I.e., there is no case I know that would be broken by
>     this.
> 
>   - Passing GIT_DIR to any sub-process operating in the context of our
>     repo (i.e., excluding cases where we're clearing local_repo_env) can
>     break a script that expects to do:
> 
>       cd /another/repo
>       git ...
> 
>     and operate in /another/repo. But such a script is already broken at
>     least in some cases, because running the initial command as:
> 
>       git --git-dir=/some/repo
> 
>     will mean that GIT_DIR is set.

Since this mailing list often indulges in tangent fest, I'll allow myself this one: `git --git-dir=...` should probably handle the case where GIT_DIR/GIT_WORK_TREE were set differently when the command was started, and if so, unset them.

>     already broken, though it may be small consolation to somebody whose
>     hook happened to work most of the time, because they do not pass in
>     GIT_DIR.

I seem to remember two reports about such funny way to do things. So they exist, I agree.

Show 13 quoted lines
>   - Any command that uses setup_work_tree() (which includes things with
>     NEED_WORK_TREE in git.c) would have always been setting GIT_DIR up
>     through v2.17.x. So any hooks they run would have seen it
>     consistently, and therefore are exempt from being regressed in the
>     case above.
> 
> So I _think_ it would be safe to:
> 
>   1. Set GIT_DIR again anytime we call setup_work_tree(), because that's
>      what has always happened.
> 
>   2. Start setting GIT_WORK_TREE at the same time. This didn't happen
>      before, but it can't break anybody, and might help.
With s/might help/will help in some edge cases/, I agree.
> That makes the rules for when GIT_DIR is set confusing, but at least it
> shouldn't regress. A more consistent rule of "hooks always see GIT_DIR"
> (or even "any sub-process always sees...") is easier to explain, but
> might break people in practice.
Indeed.
Show 6 quoted lines
> I notice also that sequencer.c sets an absolute path, since 09d7b6c6fa
> (sequencer: pass absolute GIT_DIR to exec commands, 2017-10-31). That
> does seem friendlier, though I wonder if could break any scripts. I
> cannot think of a case, unless the intermediate paths were no accessible
> to the uid running the process (but then, how would Git have generated
> the absolute path in the first place?).

Please note that (IIRC) this commit just reinstated the handling in git-sh-setup, which always set GIT_DIR to an absolute path. Scripts used in conjunction with `git rebase -i` would therefore have had to expect this.

Ciao, Dscho

Previous: Jeff King
Message 5 of 5 in “$GIT_DIR is no longer set when pre-commit hooks are called”
  1. Gregory OschwaldAug 22, 2018
  2. Jeff KingAug 26, 2018
  3. Johannes SchindelinAug 27, 2018
  4. Jeff KingAug 27, 2018
  5. Johannes SchindelinAug 28, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.