Hi Elijah, > Le 14 oct. 2020 à 18:02, Elijah Newren <newren@xxxxxxxxx> a écrit : > > On Wed, Oct 14, 2020 at 8:27 AM Philippe Blain > <levraiphilippeblain@xxxxxxxxx> wrote: >> >> Hello all, >> >> Up to recently I had an alias 'st' for `git status`, i.e. `git config alias.st status`. >> This works well in the main working tree as well as secondary worktrees (`git worktree add ...`), >> and also shows paths relative to the current directory if I'm not at the root of the repo, >> just like `git status`. >> >> Now I wanted to change my alias so that it ran `git status` and then an additional command, i.e. >> `git config alias.st '!git status && date'` (for demonstration purposes). >> This works correctly in the main worktree and secondary worktrees, but since aliases >> run from the root of the repo, the paths in the output of 'git st' are not relative >> to the current directory. >> >> So my next attempt was `git config alias.st '!git -C "${GIT_PREFIX}" status && date'`, >> so that paths would be relative in the output. However, this works in the main worktree >> but fails badly in the secondary worktree: >> >> ``` >> rm -rf test && >> rm -rf test2 && >> git init test && >> cd test && >> mkdir folder && >> date>>folder/file && >> git add folder/file && >> git ci -m "commit" && >> git config alias.st '!git -C "${GIT_PREFIX}" status && date' && >> date >>folder/file && >> echo '=== `git st` in main worktree at root ===' && >> git st && >> cd folder && >> echo '=== `git st` in main worktree in folder ===' && >> git st && >> git worktree add ../test2 && >> cd ../test2 && >> date >>folder/file && >> echo '=== `git st` in secondary worktree at root ===' && >> git st && >> cd folder && >> echo '=== `git st` in secondary worktree in folder ===' && >> git st >> ``` >> >> The last commands ouputs: >> >> ``` >> === `git st` in secondary worktree in folder === >> On branch test2 >> Changes not staged for commit: >> (use "git add/rm <file>..." to update what will be committed) >> (use "git restore <file>..." to discard changes in working directory) >> deleted: folder/file >> >> Untracked files: >> (use "git add <file>..." to include in what will be committed) >> file >> >> no changes added to commit (use "git add" and/or "git commit -a") >> ``` >> >> So something is wrong in the automatic worktree path detection... >> If I replace the alias with >> >> git config alias.st '!git -C "${GIT_PREFIX}" --work-tree=$PWD status && date' >> >> then it works correctly, but I have a feeling this should not be necessary... >> >> I've CC-ed Eric (because of his work on `git worktree`) and Elijah (because >> I remember he worked on `dir.c` so maybe this is related to that code, but I'm >> not sure). >> >> Cheers, >> Philippe > > I don't think there's anything dir.c-specific here (thank > goodness...). I extended your aliases slightly to echo the command > they would run (so I could see the value of $GIT_PREFIX) as well as to > print all the GIT_* environment variables, and found that GIT_DIR was > set as well as GIT_PREFIX, so you can duplicate the funny results with > > GIT_DIR=$WHEREVER git -C folder status > > or even > > git --git-dir=$WHEREVER -C folder status > > In fact, you don't need any special worktrees setup; using these > commands will trigger the funny status output. Looking at the > documentation for core.worktree, I see > > "If --git-dir or GIT_DIR is specified but none of --work-tree, > GIT_WORK_TREE and core.worktree is specified, the current working > directory is regarded as the top level of your working tree." Yes, this is in line with git(1) [1] : "Specifying the location of the ".git" directory using this option (or GIT_DIR environment variable) turns off the repository discovery that tries to find a directory with ".git" subdirectory (which is how the repository and the top-level of the working tree are discovered), and tells Git that you are at the top level of the working tree. If you are not at the top-level directory of the working tree, you should tell Git where the top-level of the working tree is, with the --work-tree=<path> option (or GIT_WORK_TREE environment variable)" > and indeed, I find that if I run from the toplevel: > > git --work-tree=folder/ status > > then I see the same output that you are complaining about. So, it > seems that "the current working directory is regarded as the top level > of your working tree" is implemented to take effect AFTER the "-C > folder" first changes the current working directory. > > I haven't tracked down where in the code this happens, but I suspect > that this is what is happening and is the culprit behind the behavior > you are seeing. If I am right, it doesn't answer whether this is a > bug, of course -- it could be that this ordering is intentional and > desired, or it could be that this ordering is not wanted. Anyway, > does this help you track it down? I found two threads [2] and [3] which are manifestations of similar (or the same ?) problems... Maybe git-config(1) could document which variables will be set in aliases that shell out, but even that might be tricky because it seems the answer is "it depends" (according to [2])... I also found 57ea7123c8 (git.c: make sure we do not leak GIT_* to alias scripts, 2015-12-20), in topic 'nd/clear-gitenv-upon-use-of-alias', which tries to clear out GIT_* variables from aliases environment, which I guess is defeated by the fact that I run `git -C` in my alias... Anyway thanks for your answer. [1] https://git-scm.com/docs/git#Documentation/git.txt---git-dirltpathgt [2] https://lore.kernel.org/git/20200130102933.GE840531@xxxxxxxxxxxxxxxxxxxxxxx/ [3] https://lore.kernel.org/git/20200228190218.GC1408759@xxxxxxxxxxxxxxxxxxxxxxx/ Philippe.