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

Fwd: Git clone fails during pre-commit hook due to GIT_WORK_TREE=. (regression 2.5 -> 2.6)

From
Anthony Sottile <asottile@umich.edu>
Date
Nov 24, 2015, 02:22 UTC
Message-ID
<CA+dzEB=XiGVFg+AhuJM-jUCPmgZKCJHTp3sinrFt8yzXeC_63Q@mail.gmail.com>
In-Reply-To
<CA+dzEB=2LJXiLSTqyLw8AeHNwdQicwvEiMg=hVEX0-_s1bySpA@mail.gmail.com>
* Short description of the problem *

It seems GIT_WORK_DIR is now exported invariantly when calling git hooks such as pre-commit. If these hooks involve cloning repositories they will not fail due to this exported environment variable. This was not the case in prior versions (such as v2.5.0).

* Simple reproduction *

``` $ cat test.sh #!/usr/bin/env bash set -ex

rm -rf test

# Exit non {0, 1} to abort git bisect make -j 8 > /dev/null || exit 2

# Put our new git on the path PATH="$(pwd):$PATH"

git init test

pushd test mkdir -p .git/hooks echo 'git clone git://github.com/asottile/css-explore css-explore' > .git/hooks/pre-commit chmod 755 .git/hooks/pre-commit

git commit -m foo --allow-empty || exit 1 ```

* Under 2.6.3 *

``` $ ./test.sh

...
+ git init test
warning: templates not found /home/anthony/share/git-core/templates
Initialized empty Git repository in /home/anthony/workspace/git/test/.git/
+ pushd test
~/workspace/git/test ~/workspace/git
+ mkdir -p .git/hooks
+ echo 'git clone git://github.com/asottile/css-explore css-explore'
+ chmod 755 .git/hooks/pre-commit
+ git commit -m foo --allow-empty
fatal: working tree '.' already exists.
+ exit 1
```
* Under 2.5 *

``` $ ./test.sh

...
+ git init test
warning: templates not found /home/anthony/share/git-core/templates
Initialized empty Git repository in /home/anthony/workspace/git/test/.git/
+ pushd test
~/workspace/git/test ~/workspace/git
+ mkdir -p .git/hooks
+ echo 'git clone git://github.com/asottile/css-explore css-explore'
+ chmod 755 .git/hooks/pre-commit
+ git commit -m foo --allow-empty
Cloning into 'css-explore'...
warning: templates not found /home/anthony/share/git-core/templates
remote: Counting objects: 214, done.
remote: Total 214 (delta 0), reused 0 (delta 0), pack-reused 214
Receiving objects: 100% (214/214), 25.89 KiB | 0 bytes/s, done.
Resolving deltas: 100% (129/129), done.
Checking connectivity... done.
[master (root-commit) 5eb999d] foo
```
* Bisect *

``` $ git bisect good v2.5.0 $ git bisect bad origin/master $ git bisect run ./test.sh

...
d95138e695d99d32dcad528a2a7974f434c51e79 is the first bad commit
commit d95138e695d99d32dcad528a2a7974f434c51e79
Author: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date:   Fri Jun 26 17:37:35 2015 +0700
    setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR
    In the test case, we run setup_git_dir_gently() the first time to read
    $GIT_DIR/config so that we can resolve aliases. We'll enter
    setup_discovered_git_dir() and may or may not call set_git_dir() near
    the end of the function, depending on whether the detected git dir is
    ".git" or not. This set_git_dir() will set env var $GIT_DIR.
    For normal repo, git dir detected via setup_discovered_git_dir() will be
    ".git", and set_git_dir() is not called. If .git file is used however,
    the git dir can't be ".git" and set_git_dir() is called and $GIT_DIR
    set. This is the key of this problem.
    If we expand an alias (or autocorrect command names), then
    setup_git_dir_gently() is run the second time. If $GIT_DIR is not set in
    the first run, we run the same setup_discovered_git_dir() as before.
    Nothing to see. If it is, however, we'll enter setup_explicit_git_dir()
    this time.
    This is where the "fun" is.  If $GIT_WORK_TREE is not set but
    $GIT_DIR is, you are supposed to be at the root level of the
    worktree.  But if you are in a subdir "foo/bar" (real worktree's top
    is "foo"), this rule bites you: your detected worktree is now
    "foo/bar", even though the first run correctly detected worktree as
    "foo". You get "internal error: work tree has already been set" as a
    result.
    Bottom line is, when $GIT_DIR is set, $GIT_WORK_TREE should be set too
    unless there's no work tree. But setting $GIT_WORK_TREE inside
    set_git_dir() may backfire. We don't know at that point if work tree is
    already configured by the caller. So set it when work tree is
    detected. It does not harm if $GIT_WORK_TREE is set while $GIT_DIR is
    not.
    Reported-by: Bjørnar Snoksrud <snoksrud@gmail.com>
    Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>

:100644 100644 9daa0ba4a36ced9f63541203e7bcc2ab9e1eae56 36fbba57fc83afd36d99bf5d4f3a1fc3feefba09 M environment.c :040000 040000 1d7c4bf77e0fd49ca315271993cb69a8b055c3aa 145d85895cb6cb0810597e1854a7721ccfc8f457 M t bisect run success ```

Causing me a few headaches in https://github.com/pre-commit/pre-commit/issues/300 I'm working around it in https://github.com/pre-commit/pre-commit/pull/301

Thanks,
Anthony
Next: Stefan Beller
Message 1 of 39 in “Fwd: Git clone fails during pre-commit hook due to GIT_WORK_TREE=. (regression 2.5 -> 2.6)”
  1. Anthony SottileNov 24, 2015
  2. Stefan BellerNov 24, 2015
  3. Duy NguyenNov 25, 2015
  4. Duy NguyenNov 30, 2015
  5. Junio C HamanoNov 30, 2015
  6. Duy NguyenDec 1, 2015
  7. Junio C HamanoDec 2, 2015
  8. 1/2 git.c: make it clear save_env() is for alias handling onlyNguyễn Thái Ngọc Duy, Dec 3, 2015
  9. 2/2 setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when ..Nguyễn Thái Ngọc Duy, Dec 3, 2015
  10. Junio C HamanoDec 4, 2015
  11. Duy NguyenDec 5, 2015
  12. 3/2 git.c: make sure we do not leak GIT_* to alias scriptsNguyễn Thái Ngọc Duy, Dec 5, 2015
  13. Junio C HamanoDec 7, 2015
  14. Duy NguyenDec 8, 2015
  15. Jeff KingDec 8, 2015
  16. Junio C HamanoDec 8, 2015
  17. Duy NguyenDec 5, 2015
  18. Junio C HamanoDec 7, 2015
  19. 0/3 nd/clear-gitenv-upon-use-of-aliasNguyễn Thái Ngọc Duy, Dec 20, 2015
  20. 1/3 git.c: make it clear save_env() is for alias handling onlyNguyễn Thái Ngọc Duy, Dec 20, 2015
  21. 2/3 setup.c: re-fix d95138e (setup: set env $GIT_WORK_TREE when ..Nguyễn Thái Ngọc Duy, Dec 20, 2015
  22. 3/3 git.c: make sure we do not leak GIT_* to alias scriptsNguyễn Thái Ngọc Duy, Dec 20, 2015
  23. Junio C HamanoDec 21, 2015
  24. Duy NguyenDec 22, 2015
  25. Duy NguyenDec 22, 2015
  26. Junio C HamanoDec 22, 2015
  27. Jeff KingDec 23, 2015
  28. Duy NguyenDec 23, 2015
  29. Eric SunshineDec 23, 2015
  30. Johannes SixtDec 23, 2015
  31. Jeff KingDec 23, 2015
  32. Duy NguyenDec 24, 2015
  33. Jeff KingDec 29, 2015
  34. Junio C HamanoDec 29, 2015
  35. Revert "setup: set env $GIT_WORK_TREE when work tree is set, like $GIT_DIR"Nguyễn Thái Ngọc Duy, Dec 21, 2015
  36. Junio C HamanoDec 21, 2015
  37. Junio C HamanoDec 21, 2015
  38. Duy NguyenDec 22, 2015
  39. Junio C HamanoDec 22, 2015

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.