Thank you for this wonderful remedy, Eric! I really appreciate the background context and how you framed the problem that I ran into. I have two questions: 1. Documentation is a great first step in addressing this, but I'm wondering if this should be automatic? If this is a best practice for hook authors, could `git` do this for them automatically when running hooks? 2. Should we add something in the `git-worktree` documentation? In `Documentation/git-worktree.txt`, it mentions: > BUGS > ---- > Multiple checkout in general is still experimental, and the support > for submodules is incomplete. ... Would it be helpful to plant a flag in the above documentation to point to this potential issue? Thank you, Preston On Sun, Jan 8, 2023 at 3:58 AM Eric Sunshine via GitGitGadget <gitgitgadget@xxxxxxxxx> wrote: > > From: Eric Sunshine <sunshine@xxxxxxxxxxxxxx> > > Hook authors are periodically caught off-guard by difficult-to-diagnose > errors when their hook invokes Git commands in a repository other than > the local one. In particular, Git environment variables, such as GIT_DIR > and GIT_WORK_TREE, which reference the local repository cause the Git > commands to operate on the local repository rather than on the > repository which the author intended. This is true whether the > environment variables have been set manually by the user or > automatically by Git itself. The same problem crops up when a hook > invokes Git commands in a different worktree of the same repository, as > well. > > Recommended best-practice[1,2,3,4,5,6] for avoiding this problem is for > the hook to ensure that Git variables are unset before invoking Git > commands in foreign repositories or other worktrees: > > unset $(git rev-parse --local-env-vars) > > However, this advice is not documented anywhere. Rectify this > shortcoming by mentioning it in githooks.txt documentation. > > [1]: https://lore.kernel.org/git/YFuHd1MMlJAvtdzb@xxxxxxxxxxxxxxxxxxxxxxx/ > [2]: https://lore.kernel.org/git/20200228190218.GC1408759@xxxxxxxxxxxxxxxxxxxxxxx/ > [3]: https://lore.kernel.org/git/20190516221702.GA11784@xxxxxxxxxxxxxxxxxxxxx/ > [4]: https://lore.kernel.org/git/20190422162127.GC9680@xxxxxxxxxxxxxxxxxxxxx/ > [5]: https://lore.kernel.org/git/20180716183942.GB22298@xxxxxxxxxxxxxxxxxxxxx/ > [6]: https://lore.kernel.org/git/20150203163235.GA9325@xxxxxxxx/ > > Signed-off-by: Eric Sunshine <sunshine@xxxxxxxxxxxxxx> > --- > githooks: discuss Git operations in foreign repositories > > Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1457%2Fsunshineco%2Fhookenv-v1 > Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1457/sunshineco/hookenv-v1 > Pull-Request: https://github.com/gitgitgadget/git/pull/1457 > > Documentation/githooks.txt | 11 +++++++++++ > 1 file changed, 11 insertions(+) > > diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt > index a16e62bc8c8..6e9a5420b7c 100644 > --- a/Documentation/githooks.txt > +++ b/Documentation/githooks.txt > @@ -31,6 +31,17 @@ Hooks can get their arguments via the environment, command-line > arguments, and stdin. See the documentation for each hook below for > details. > > +If your hook needs to invoke Git commands in a foreign repository or in a > +different working tree of the same repository, then it should clear local Git > +environment variables, such as `GIT_DIR`, `GIT_WORK_TREE`, etc., which could > +interfere with Git operations in the foreign repository since those variables > +will be referencing the local repository and working tree. For example: > + > +------------ > +local_desc=$(git describe) > +foreign_desc=$(unset $(git rev-parse --local-env-vars); git -C ../foreign-repo describe) > +------------ > + > `git init` may copy hooks to the new repository, depending on its > configuration. See the "TEMPLATE DIRECTORY" section in > linkgit:git-init[1] for details. When the rest of this document refers > > base-commit: a38d39a4c50d1275833aba54c4dbdfce9e2e9ca1 > -- > gitgitgadget