* Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails @ 2024-09-20 10:07 Gabriel Nützi 2024-09-20 10:42 ` Gabriel Nützi 2024-10-07 8:03 ` Patrick Steinhardt 0 siblings, 2 replies; 14+ messages in thread From: Gabriel Nützi @ 2024-09-20 10:07 UTC (permalink / raw) To: git [-- Attachment #1: Type: text/plain, Size: 2101 bytes --] Thank you for filling out a Git bug report! Please answer the following questions to help us understand your issue. What did you do before the bug happened? (Steps to reproduce your issue) I set `git config --global core.hooksPath ~/myhooks` and placed a `reference-transaction` hook in `~/myhooks/reference-transaction` with the content: ```shell #!/usr/bin/env bash set -e echo "$GIT_DIR" git rev-parse --absolute-git-dir ``` then I ran ```shell mkdir ~/test && cd test git init ``` What did you expect to happen? (Expected behavior) The Git repo `~/test` should have been initialized (and the hook `reference-transaction` would have passed successfully.) What happened instead? (Actual behavior) The hook `reference-transaction` crashes since `git rev-parse -- absolute-git-dir` with ``` failed: not a git repository: ... ``` What's different between what you expected and what actually happened? The documentation says that `git rev-parse --absolute-git-dir` inside the `reference-transaction` hooks read "$GIT_DIR" if defined (which is defined!) so the `reference-transaction` should have passed. I assume that hooks should be executed on properly initialized repositories, right? Therefore I do not understand why `git rev-parse --absolute-git- dir` fails -> Bug? Anything else you want to add: This came up with `Githooks` hooks manager https://github.com/gabyx/Githooks where we use this command to locate the current Git dir... Please review the rest of the bug report below. You can delete any lines you don't wish to share. [System Info] git version: git version 2.46.0 cpu: x86_64 no commit associated with this build sizeof-long: 8 sizeof-size_t: 8 shell-path: /nix/store/izpf49b74i15pcr9708s3xdwyqs4jxwl-bash- 5.2p32/bin/bash libcurl: 8.9.1 OpenSSL: OpenSSL 3.0.14 4 Jun 2024 zlib: 1.3.1 uname: Linux 6.6.45 #1-NixOS SMP PREEMPT_DYNAMIC Sun Aug 11 10:47:28 UTC 2024 x86_64 compiler info: gnuc: 13.3 libc info: glibc: 2.39 $SHELL (typically, interactive shell): /run/current-system/sw/bin/zsh [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails 2024-09-20 10:07 Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails Gabriel Nützi @ 2024-09-20 10:42 ` Gabriel Nützi 2024-10-07 8:03 ` Patrick Steinhardt 1 sibling, 0 replies; 14+ messages in thread From: Gabriel Nützi @ 2024-09-20 10:42 UTC (permalink / raw) To: git [-- Attachment #1.1: Type: text/plain, Size: 2594 bytes --] The same happens with `git rev-parse --git-comon-dir` and `git config a.a "hello"` (which might be ok, since the config file is not yet setup at this point...) On Fri, 2024-09-20 at 12:07 +0200, Gabriel Nützi wrote: > Thank you for filling out a Git bug report! > Please answer the following questions to help us understand your issue. > > What did you do before the bug happened? (Steps to reproduce your > issue) > > I set `git config --global core.hooksPath ~/myhooks` and placed a > `reference-transaction` hook in `~/myhooks/reference-transaction` > with the content: > > ```shell > #!/usr/bin/env bash > > set -e > echo "$GIT_DIR" > git rev-parse --absolute-git-dir > ``` > > then I ran > > ```shell > mkdir ~/test && cd test > git init > ``` > > What did you expect to happen? (Expected behavior) > > The Git repo `~/test` should have been initialized (and the hook > `reference-transaction` would have passed successfully.) > > > What happened instead? (Actual behavior) > > The hook `reference-transaction` crashes since `git rev-parse -- > absolute-git-dir` with > ``` > failed: not a git repository: ... > ``` > > What's different between what you expected and what actually happened? > > The documentation says that `git rev-parse --absolute-git-dir` inside > the `reference-transaction` hooks read "$GIT_DIR" if defined (which is > defined!) so the `reference-transaction` should have passed. I assume > that hooks should be executed on properly initialized repositories, > right? Therefore I do not understand why `git rev-parse --absolute-git- > dir` fails -> Bug? > > Anything else you want to add: > > This came up with `Githooks` hooks manager > [https://github.com/gabyx/Githooks](https://github.com/gabyx/Githooks) where we use this command > to locate the current Git dir... > > Please review the rest of the bug report below. > You can delete any lines you don't wish to share. > > > [System Info] > git version: > git version 2.46.0 > cpu: x86_64 > no commit associated with this build > sizeof-long: 8 > sizeof-size_t: 8 > shell-path: /nix/store/izpf49b74i15pcr9708s3xdwyqs4jxwl-bash- > 5.2p32/bin/bash > libcurl: 8.9.1 > OpenSSL: OpenSSL 3.0.14 4 Jun 2024 > zlib: 1.3.1 > uname: Linux 6.6.45 #1-NixOS SMP PREEMPT_DYNAMIC Sun Aug 11 10:47:28 > UTC 2024 x86_64 > compiler info: gnuc: 13.3 > libc info: glibc: 2.39 > $SHELL (typically, interactive shell): /run/current-system/sw/bin/zsh > [-- Attachment #1.2: Type: text/html, Size: 2948 bytes --] [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails 2024-09-20 10:07 Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails Gabriel Nützi 2024-09-20 10:42 ` Gabriel Nützi @ 2024-10-07 8:03 ` Patrick Steinhardt 2024-10-07 10:54 ` Gabriel Nützi 1 sibling, 1 reply; 14+ messages in thread From: Patrick Steinhardt @ 2024-10-07 8:03 UTC (permalink / raw) To: Gabriel Nützi; +Cc: git, Karthik Nayak On Fri, Sep 20, 2024 at 12:07:53PM +0200, Gabriel Nützi wrote: > Thank you for filling out a Git bug report! > Please answer the following questions to help us understand your issue. > > What did you do before the bug happened? (Steps to reproduce your > issue) > > I set `git config --global core.hooksPath ~/myhooks` and placed a > `reference-transaction` hook in `~/myhooks/reference-transaction` > with the content: > > ```shell > #!/usr/bin/env bash > > set -e > echo "$GIT_DIR" > git rev-parse --absolute-git-dir > ``` > > then I ran > > ```shell > mkdir ~/test && cd test > git init > ``` > > What did you expect to happen? (Expected behavior) > > The Git repo `~/test` should have been initialized (and the hook > `reference-transaction` would have passed successfully.) > > > What happened instead? (Actual behavior) > > The hook `reference-transaction` crashes since `git rev-parse -- > absolute-git-dir` with > ``` > failed: not a git repository: ... > ``` > > What's different between what you expected and what actually happened? > > The documentation says that `git rev-parse --absolute-git-dir` inside > the `reference-transaction` hooks read "$GIT_DIR" if defined (which is > defined!) so the `reference-transaction` should have passed. I assume > that hooks should be executed on properly initialized repositories, > right? Therefore I do not understand why `git rev-parse --absolute-git- > dir` fails -> Bug? > > Anything else you want to add: > > This came up with `Githooks` hooks manager > https://github.com/gabyx/Githooks where we use this command > to locate the current Git dir... > > Please review the rest of the bug report below. > You can delete any lines you don't wish to share. Thanks for your bug report, and sorry for taking so long to respond. Reproducing the observed behaviour is quite simple: test_expect_success 'git-init with global hook' ' test_when_finished "rm -rf hooks repo" && mkdir hooks && write_script hooks/reference-transaction <<-EOF && git rev-parse --absolute-git-dir >>"$(pwd)/reftx-logs" EOF test_config --global core.hooksPath "$(pwd)/hooks" && git init repo ' This breakage is new in Git v2.46 and comes from the patch series that introduces support for symbolic refs in the reftx hook via a8ae923f85 (refs: support symrefs in 'reference-transaction' hook, 2024-05-07) . Before that change we didn't execute the hook for "HEAD" in the first place, now we do. Now the question is whether this is a bug or not. When the reftx hook executes the first time it is when we are creating the "HEAD" ref in the repo. Consequently, that file did not yet exist beforehand. And as Git only considers something a repository when the "HEAD" file exists it rightfully complains that this is not a valid Git repository when you ask it to resolve the repo paths. So conceptually, the behaviour here is correct. There are two ways we could fix this that I can think of: - We can create a dummy "HEAD" file with invalid contents such that we do have a proper Git repository when creating "HEAD". It feels like a bit of a hack though, but we play similar games in git-clone(1). - We can skip execution of the "reference-transaction" hook during initialization of the repository. But this would make us miss some ref updates, which feels conceptually wrong. I'd rule out (2), but (1) could be feasible if we label this a bug. I'm not a 100% sure whether we should, as you could also argue that this is reflecting the actual state of the repo. I'd be happy to hear arguments in either direction. Also Cc'd Karthik, the author of the menitoned change. Patrick ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails 2024-10-07 8:03 ` Patrick Steinhardt @ 2024-10-07 10:54 ` Gabriel Nützi 2024-10-07 10:57 ` Patrick Steinhardt 0 siblings, 1 reply; 14+ messages in thread From: Gabriel Nützi @ 2024-10-07 10:54 UTC (permalink / raw) To: Patrick Steinhardt; +Cc: git, Karthik Nayak [-- Attachment #1.1: Type: text/plain, Size: 4966 bytes --] Hi Patrick, Thanks for clarifications! Could it work if for (2) -> call the reference-transaction hook after the HEAD has been initialized, meaning that Git would internally cache the different reference transactions and then call the hooks in one go at once after the creation of the repo, such that it is initialized properly? This might be probably a more elaborate change which introduces too many technicalities? Gabriel -----Original Message----- **From**: Patrick Steinhardt <[ps@pks.im](mailto:Patrick%20Steinhardt%20%3cps@pks.im%3e)> **To**: Gabriel Nützi <[gnuetzi@gmail.com](mailto:Gabriel%20%3d%3fISO-8859-1%3fQ%3fN%3dFCtzi%3f%3d%20%3cgnuetzi@gmail.com%3e)> **Cc**: [git@vger.kernel.org](mailto:git@vger.kernel.org), Karthik Nayak <[karthik.188@gmail.com](mailto:Karthik%20Nayak%20%3ckarthik.188@gmail.com%3e)> **Subject**: Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails **Date**: 10/07/2024 10:03:30 AM On Fri, Sep 20, 2024 at 12:07:53PM +0200, Gabriel Nützi wrote: > Thank you for filling out a Git bug report! > Please answer the following questions to help us understand your issue. > > What did you do before the bug happened? (Steps to reproduce your > issue) > > I set `git config --global core.hooksPath ~/myhooks` and placed a > `reference-transaction` hook in `~/myhooks/reference-transaction` > with the content: > > ```shell > #!/usr/bin/env bash > > set -e > echo "$GIT_DIR" > git rev-parse --absolute-git-dir > ``` > > then I ran > > ```shell > mkdir ~/test && cd test > git init > ``` > > What did you expect to happen? (Expected behavior) > > The Git repo `~/test` should have been initialized (and the hook > `reference-transaction` would have passed successfully.) > > > What happened instead? (Actual behavior) > > The hook `reference-transaction` crashes since `git rev-parse -- > absolute-git-dir` with > ``` > failed: not a git repository: ... > ``` > > What's different between what you expected and what actually happened? > > The documentation says that `git rev-parse --absolute-git-dir` inside > the `reference-transaction` hooks read "$GIT_DIR" if defined (which is > defined!) so the `reference-transaction` should have passed. I assume > that hooks should be executed on properly initialized repositories, > right? Therefore I do not understand why `git rev-parse --absolute-git- > dir` fails -> Bug? > > Anything else you want to add: > > This came up with `Githooks` hooks manager > [https://github.com/gabyx/Githooks](https://github.com/gabyx/Githooks) where we use this command > to locate the current Git dir... > > Please review the rest of the bug report below. > You can delete any lines you don't wish to share. Thanks for your bug report, and sorry for taking so long to respond. Reproducing the observed behaviour is quite simple: test_expect_success 'git-init with global hook' ' test_when_finished "rm -rf hooks repo" && mkdir hooks && write_script hooks/reference-transaction <<-EOF && git rev-parse --absolute-git-dir >>"$(pwd)/reftx-logs" EOF test_config --global core.hooksPath "$(pwd)/hooks" && git init repo ' This breakage is new in Git v2.46 and comes from the patch series that introduces support for symbolic refs in the reftx hook via a8ae923f85 (refs: support symrefs in 'reference-transaction' hook, 2024-05-07) . Before that change we didn't execute the hook for "HEAD" in the first place, now we do. Now the question is whether this is a bug or not. When the reftx hook executes the first time it is when we are creating the "HEAD" ref in the repo. Consequently, that file did not yet exist beforehand. And as Git only considers something a repository when the "HEAD" file exists it rightfully complains that this is not a valid Git repository when you ask it to resolve the repo paths. So conceptually, the behaviour here is correct. There are two ways we could fix this that I can think of: - We can create a dummy "HEAD" file with invalid contents such that we do have a proper Git repository when creating "HEAD". It feels like a bit of a hack though, but we play similar games in git-clone(1). - We can skip execution of the "reference-transaction" hook during initialization of the repository. But this would make us miss some ref updates, which feels conceptually wrong. I'd rule out (2), but (1) could be feasible if we label this a bug. I'm not a 100% sure whether we should, as you could also argue that this is reflecting the actual state of the repo. I'd be happy to hear arguments in either direction. Also Cc'd Karthik, the author of the menitoned change. Patrick [-- Attachment #1.2: Type: text/html, Size: 5706 bytes --] [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails 2024-10-07 10:54 ` Gabriel Nützi @ 2024-10-07 10:57 ` Patrick Steinhardt 2024-10-07 11:02 ` Gabriel Nützi 0 siblings, 1 reply; 14+ messages in thread From: Patrick Steinhardt @ 2024-10-07 10:57 UTC (permalink / raw) To: Gabriel Nützi; +Cc: git, Karthik Nayak On Mon, Oct 07, 2024 at 12:54:36PM +0200, Gabriel Nützi wrote: > Hi Patrick, > > Thanks for clarifications! > Could it work if for (2) -> call the reference-transaction hook after the HEAD has been initialized, meaning that Git would internally cache the > different reference transactions and then call the hooks in one go at once after the creation of the repo, such that it is initialized properly? > This might be probably a more elaborate change which introduces too many technicalities? That would break basic assumptions of how the hook operates. It is expected that we abort the transaction when the hook returns an error, so if we were to run the hook _after_ `HEAD` has been created that expectation would be broken. So the only viable solution is to create a stub `HEAD`, but as said I'm not a 100% sure whether we want to go there or not. Patrick ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails 2024-10-07 10:57 ` Patrick Steinhardt @ 2024-10-07 11:02 ` Gabriel Nützi 2024-10-07 11:24 ` Patrick Steinhardt 0 siblings, 1 reply; 14+ messages in thread From: Gabriel Nützi @ 2024-10-07 11:02 UTC (permalink / raw) To: Patrick Steinhardt; +Cc: git, Karthik Nayak [-- Attachment #1.1: Type: text/plain, Size: 974 bytes --] Ah, jeah thats true: The command in question which is `git rev-parse --git-dir` to find the actual GIT_DIR is actually the issue here: It relies on having a proper HEAD despite the docs saying it only reports GIT_DIR if set etc... Could we maybe make these commands more agnostic? Making an empty HEAD probably directly also resolves these commands to work correctly. Gabriel -----Original Message----- **From**: Patrick Steinhardt <[ps@pks.im](mailto:Patrick%20Steinhardt%20%3cps@pks.im%3e)> **To**: Gabriel Nützi <[gnuetzi@gmail.com](mailto:Gabriel%20%3d%3fISO-8859-1%3fQ%3fN%3dFCtzi%3f%3d%20%3cgnuetzi@gmail.com%3e)> **Cc**: [git@vger.kernel.org](mailto:git@vger.kernel.org), Karthik Nayak <[karthik.188@gmail.com](mailto:Karthik%20Nayak%20%3ckarthik.188@gmail.com%3e)> **Subject**: Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails **Date**: 10/07/2024 12:57:19 PM git rev-parse --git-dir [-- Attachment #1.2: Type: text/html, Size: 1194 bytes --] [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails 2024-10-07 11:02 ` Gabriel Nützi @ 2024-10-07 11:24 ` Patrick Steinhardt 2024-10-07 21:02 ` Junio C Hamano 0 siblings, 1 reply; 14+ messages in thread From: Patrick Steinhardt @ 2024-10-07 11:24 UTC (permalink / raw) To: Gabriel Nützi; +Cc: git, Karthik Nayak On Mon, Oct 07, 2024 at 01:02:56PM +0200, Gabriel Nützi wrote: > Ah, jeah thats true: > > The command in question which is `git rev-parse --git-dir` to find the actual GIT_DIR is actually the issue here: > It relies on having a proper HEAD despite the docs saying it only reports GIT_DIR if set etc... That's not quite true. The second paragraph for the `--git-dir` option in git-rev-parse(1) has this to say: If $GIT_DIR is not defined and the current directory is not detected to lie in a Git repository or work tree print a message to stderr and exit with nonzero status. But in our case you're correct: `$GIT_DIR` _is_ defined during hook execution. So in theory, if git-rev-parse(1) behaved exactly as documented, it shouldn't even care whether or not it is executing in a repository. > Could we maybe make these commands more agnostic? So this could indeed be a viable fix, but I guess we'd rather play whack-a-mole because other Git commands that one may want to execute in this repository would also be broken. > Making an empty HEAD probably directly also resolves these commands to work correctly. So agreed, creating a stub HEAD is the most sensible option we have. I'd like to wait a bit for more feedback from other contributors before we do so though. Patrick ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails 2024-10-07 11:24 ` Patrick Steinhardt @ 2024-10-07 21:02 ` Junio C Hamano 2024-10-09 9:39 ` Patrick Steinhardt 0 siblings, 1 reply; 14+ messages in thread From: Junio C Hamano @ 2024-10-07 21:02 UTC (permalink / raw) To: Patrick Steinhardt; +Cc: Gabriel Nützi, git, Karthik Nayak Patrick Steinhardt <ps@pks.im> writes: > `$GIT_DIR` _is_ defined during hook > execution. So in theory, if git-rev-parse(1) behaved exactly as > documented, it shouldn't even care whether or not it is executing in a > repository. I've always considered "git rev-parse --git-dir" and friends were to verify the validity of the repository before returning "Your GIT_DIR is here". Otherwise there is no easy way to ask "I have this directory. Is it a valid repository you can work with?". So, I am not sure I agree with the above. For what is worth, I am skeptical to the "solution" that tentively creates a bogus HEAD file while the repository is being initialized. The code today may ignore certain bogosity in such a HEAD (like the ".invalid" magic used during "git clone"), but there is no guarantee that a random third-party add-on a hook script may invoke do the same as we do, and more importantly, what a repository with its initialization complete look like may change over time and it may not be enough to have HEAD pointing at "refs/heads/.invalid" to fool our bootstrap process. If we were to go that route, I would rather see us pick a pointee that is *not* bogus at the mechanical level (i.e., "git symbolic-ref HEAD refs/heads/.invalid" would fail) but is clearly a placeholder value to humans, soon to be updated. Let's say if we were to create a repository with the name of initial branch as 'main', we could create HEAD that points at refs/heads/main bypassing any hook intervention, then call the hook to see if it approves the name. We'd need to make sure that we fail the repository creation when the hook declines, as it is refusing to set a HEAD, one critical element in the repository that has to exist, and probably remove the directory if we are not reinitializing. Or we could use a name that is clearly bogus to humans but is still structurally OK, say "refs/heads/hook-failed-during-initialization", ask the hook if it is OK to repoint HEAD to "refs/heads/main" from that state, and (1) if it approves, HEAD will point at "refs/heads/main" and "hook-failed-during-initialization" will be seen nowhere but the reflog of HEAD, or (2) if it refuses, we stop, and the user will be left on an unborn branch with a long descriptive name that explains the situation. A much simpler alternative would be to simply ignore any hooks, traces, or anything that want to look into the directory we are working to turn into a repository but haven't completed doing so, during repository initialization, I would think, though. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails 2024-10-07 21:02 ` Junio C Hamano @ 2024-10-09 9:39 ` Patrick Steinhardt 2024-10-09 10:09 ` Karthik Nayak ` (2 more replies) 0 siblings, 3 replies; 14+ messages in thread From: Patrick Steinhardt @ 2024-10-09 9:39 UTC (permalink / raw) To: Junio C Hamano; +Cc: Gabriel Nützi, git, Karthik Nayak On Mon, Oct 07, 2024 at 02:02:02PM -0700, Junio C Hamano wrote: > Patrick Steinhardt <ps@pks.im> writes: > > > `$GIT_DIR` _is_ defined during hook > > execution. So in theory, if git-rev-parse(1) behaved exactly as > > documented, it shouldn't even care whether or not it is executing in a > > repository. > > I've always considered "git rev-parse --git-dir" and friends were to > verify the validity of the repository before returning "Your GIT_DIR > is here". Otherwise there is no easy way to ask "I have this directory. > Is it a valid repository you can work with?". > > So, I am not sure I agree with the above. Well, I'm not sure either. I was merely pointing out that the documented behaviour is different than the actual behaviour. Which of both is the more sensible one is a different question. > For what is worth, I am skeptical to the "solution" that tentively > creates a bogus HEAD file while the repository is being initialized. > The code today may ignore certain bogosity in such a HEAD (like the > ".invalid" magic used during "git clone"), but there is no guarantee > that a random third-party add-on a hook script may invoke do the > same as we do, and more importantly, what a repository with its > initialization complete look like may change over time and it may > not be enough to have HEAD pointing at "refs/heads/.invalid" to fool > our bootstrap process. If we were to go that route, I would rather > see us pick a pointee that is *not* bogus at the mechanical level > (i.e., "git symbolic-ref HEAD refs/heads/.invalid" would fail) but > is clearly a placeholder value to humans, soon to be updated. > > Let's say if we were to create a repository with the name of initial > branch as 'main', we could create HEAD that points at refs/heads/main > bypassing any hook intervention, then call the hook to see if it > approves the name. We'd need to make sure that we fail the > repository creation when the hook declines, as it is refusing to set > a HEAD, one critical element in the repository that has to exist, > and probably remove the directory if we are not reinitializing. > > Or we could use a name that is clearly bogus to humans but is still > structurally OK, say "refs/heads/hook-failed-during-initialization", > ask the hook if it is OK to repoint HEAD to "refs/heads/main" from > that state, and (1) if it approves, HEAD will point at "refs/heads/main" > and "hook-failed-during-initialization" will be seen nowhere but the > reflog of HEAD, or (2) if it refuses, we stop, and the user will be > left on an unborn branch with a long descriptive name that explains > the situation. I dunno. It all feels rather complex. > A much simpler alternative would be to simply ignore any hooks, > traces, or anything that want to look into the directory we are > working to turn into a repository but haven't completed doing so, > during repository initialization, I would think, though. That could work, yes, but it would limit the usefulness of the hook. In theory, you can create a full log of all changes in the repository from its inception. If we didn't log the first item, that log would be incomplete. We have another solution that is even simpler: just do nothing. I do not think that the behaviour we exhibit is wrong. Unwieldy? Maybe. But it is merely stating facts: we are executing a transaction in a repository that is not yet fully set up. If you don't want that, either don't set up a global reference-transaction hook, or alternatively handle that edge case in your script. Patrick ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails 2024-10-09 9:39 ` Patrick Steinhardt @ 2024-10-09 10:09 ` Karthik Nayak 2024-10-09 11:53 ` Gabriel Nützi 2024-10-09 17:31 ` Junio C Hamano 2 siblings, 0 replies; 14+ messages in thread From: Karthik Nayak @ 2024-10-09 10:09 UTC (permalink / raw) To: Patrick Steinhardt, Junio C Hamano; +Cc: Gabriel Nützi, git [-- Attachment #1: Type: text/plain, Size: 3841 bytes --] Patrick Steinhardt <ps@pks.im> writes: > On Mon, Oct 07, 2024 at 02:02:02PM -0700, Junio C Hamano wrote: >> Patrick Steinhardt <ps@pks.im> writes: >> >> > `$GIT_DIR` _is_ defined during hook >> > execution. So in theory, if git-rev-parse(1) behaved exactly as >> > documented, it shouldn't even care whether or not it is executing in a >> > repository. >> >> I've always considered "git rev-parse --git-dir" and friends were to >> verify the validity of the repository before returning "Your GIT_DIR >> is here". Otherwise there is no easy way to ask "I have this directory. >> Is it a valid repository you can work with?". >> >> So, I am not sure I agree with the above. > > Well, I'm not sure either. I was merely pointing out that the documented > behaviour is different than the actual behaviour. Which of both is the > more sensible one is a different question. > >> For what is worth, I am skeptical to the "solution" that tentively >> creates a bogus HEAD file while the repository is being initialized. >> The code today may ignore certain bogosity in such a HEAD (like the >> ".invalid" magic used during "git clone"), but there is no guarantee >> that a random third-party add-on a hook script may invoke do the >> same as we do, and more importantly, what a repository with its >> initialization complete look like may change over time and it may >> not be enough to have HEAD pointing at "refs/heads/.invalid" to fool >> our bootstrap process. If we were to go that route, I would rather >> see us pick a pointee that is *not* bogus at the mechanical level >> (i.e., "git symbolic-ref HEAD refs/heads/.invalid" would fail) but >> is clearly a placeholder value to humans, soon to be updated. >> >> Let's say if we were to create a repository with the name of initial >> branch as 'main', we could create HEAD that points at refs/heads/main >> bypassing any hook intervention, then call the hook to see if it >> approves the name. We'd need to make sure that we fail the >> repository creation when the hook declines, as it is refusing to set >> a HEAD, one critical element in the repository that has to exist, >> and probably remove the directory if we are not reinitializing. >> >> Or we could use a name that is clearly bogus to humans but is still >> structurally OK, say "refs/heads/hook-failed-during-initialization", >> ask the hook if it is OK to repoint HEAD to "refs/heads/main" from >> that state, and (1) if it approves, HEAD will point at "refs/heads/main" >> and "hook-failed-during-initialization" will be seen nowhere but the >> reflog of HEAD, or (2) if it refuses, we stop, and the user will be >> left on an unborn branch with a long descriptive name that explains >> the situation. > > I dunno. It all feels rather complex. > >> A much simpler alternative would be to simply ignore any hooks, >> traces, or anything that want to look into the directory we are >> working to turn into a repository but haven't completed doing so, >> during repository initialization, I would think, though. > > That could work, yes, but it would limit the usefulness of the hook. In > theory, you can create a full log of all changes in the repository from > its inception. If we didn't log the first item, that log would be > incomplete. > > We have another solution that is even simpler: just do nothing. I do not > think that the behaviour we exhibit is wrong. Unwieldy? Maybe. But it is > merely stating facts: we are executing a transaction in a repository > that is not yet fully set up. If you don't want that, either don't set > up a global reference-transaction hook, or alternatively handle that > edge case in your script. This does seem like we're putting the onus on the users, but ultimately I agree with this. What the hook is doing is as expected. Thanks Patrick for responding while I was away. Karthik [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 690 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails 2024-10-09 9:39 ` Patrick Steinhardt 2024-10-09 10:09 ` Karthik Nayak @ 2024-10-09 11:53 ` Gabriel Nützi 2024-10-09 12:19 ` Patrick Steinhardt 2024-10-09 17:31 ` Junio C Hamano 2 siblings, 1 reply; 14+ messages in thread From: Gabriel Nützi @ 2024-10-09 11:53 UTC (permalink / raw) To: Patrick Steinhardt, Junio C Hamano; +Cc: git, Karthik Nayak [-- Attachment #1.1: Type: text/plain, Size: 5604 bytes --] > We have another solution that is even simpler: just do nothing. I do not > think that the behaviour we exhibit is wrong. Unwieldy? Maybe. But it is > merely stating facts: we are executing a transaction in a repository > that is not yet fully set up. If you don't want that, either don't set > up a global reference-transaction hook, or alternatively handle that > edge case in your script. But then Git should at least give the hooks maintainers a chance to know what it is doing. Could we have a new env. variable or mechanism stating that the repository is not yet setup or so? The issue here comes from the fact that Githooks is a hooks manager which basically calls `reference-transaction` for you, but before it does it calls `git rev-parse --git-dir` to get the correct Git directory, basically not doing env. lookup on GIT_DIR which this command actually does, but that apparently only works on a "initialized" repo, so currently I do a workaround and looking directly at GIT_DIR. I would be really happy also if I could somehow know when Git is creating a new repository (clone, or init), that would also improve other scenarios I came across. Basically you cannot react on hook `post-checkout` only when a new repo is created... Gabriel -----Original Message----- **From**: Patrick Steinhardt <[ps@pks.im](mailto:Patrick%20Steinhardt%20%3cps@pks.im%3e)> **To**: Junio C Hamano <[gitster@pobox.com](mailto:Junio%20C%20Hamano%20%3cgitster@pobox.com%3e)> **Cc**: Gabriel Nützi <[gnuetzi@gmail.com](mailto:Gabriel%20%3d%3fISO-8859-1%3fQ%3fN%3dFCtzi%3f%3d%20%3cgnuetzi@gmail.com%3e)>, [git@vger.kernel.org](mailto:git@vger.kernel.org), Karthik Nayak <[karthik.188@gmail.com](mailto:Karthik%20Nayak%20%3ckarthik.188@gmail.com%3e)> **Subject**: Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails **Date**: 10/09/2024 11:39:26 AM On Mon, Oct 07, 2024 at 02:02:02PM -0700, Junio C Hamano wrote: > Patrick Steinhardt <[ps@pks.im](mailto:ps@pks.im)> writes: > > > > `$GIT_DIR` _is_ defined during hook > > execution. So in theory, if git-rev-parse(1) behaved exactly as > > documented, it shouldn't even care whether or not it is executing in a > > repository. > > > I've always considered "git rev-parse --git-dir" and friends were to > verify the validity of the repository before returning "Your GIT_DIR > is here". Otherwise there is no easy way to ask "I have this directory. > Is it a valid repository you can work with?". > > So, I am not sure I agree with the above. Well, I'm not sure either. I was merely pointing out that the documented behaviour is different than the actual behaviour. Which of both is the more sensible one is a different question. > For what is worth, I am skeptical to the "solution" that tentively > creates a bogus HEAD file while the repository is being initialized. > The code today may ignore certain bogosity in such a HEAD (like the > ".invalid" magic used during "git clone"), but there is no guarantee > that a random third-party add-on a hook script may invoke do the > same as we do, and more importantly, what a repository with its > initialization complete look like may change over time and it may > not be enough to have HEAD pointing at "refs/heads/.invalid" to fool > our bootstrap process. If we were to go that route, I would rather > see us pick a pointee that is *not* bogus at the mechanical level > (i.e., "git symbolic-ref HEAD refs/heads/.invalid" would fail) but > is clearly a placeholder value to humans, soon to be updated. > > Let's say if we were to create a repository with the name of initial > branch as 'main', we could create HEAD that points at refs/heads/main > bypassing any hook intervention, then call the hook to see if it > approves the name. We'd need to make sure that we fail the > repository creation when the hook declines, as it is refusing to set > a HEAD, one critical element in the repository that has to exist, > and probably remove the directory if we are not reinitializing. > > Or we could use a name that is clearly bogus to humans but is still > structurally OK, say "refs/heads/hook-failed-during-initialization", > ask the hook if it is OK to repoint HEAD to "refs/heads/main" from > that state, and (1) if it approves, HEAD will point at "refs/heads/main" > and "hook-failed-during-initialization" will be seen nowhere but the > reflog of HEAD, or (2) if it refuses, we stop, and the user will be > left on an unborn branch with a long descriptive name that explains > the situation. I dunno. It all feels rather complex. > A much simpler alternative would be to simply ignore any hooks, > traces, or anything that want to look into the directory we are > working to turn into a repository but haven't completed doing so, > during repository initialization, I would think, though. That could work, yes, but it would limit the usefulness of the hook. In theory, you can create a full log of all changes in the repository from its inception. If we didn't log the first item, that log would be incomplete. We have another solution that is even simpler: just do nothing. I do not think that the behaviour we exhibit is wrong. Unwieldy? Maybe. But it is merely stating facts: we are executing a transaction in a repository that is not yet fully set up. If you don't want that, either don't set up a global reference-transaction hook, or alternatively handle that edge case in your script. Patrick [-- Attachment #1.2: Type: text/html, Size: 6229 bytes --] [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails 2024-10-09 11:53 ` Gabriel Nützi @ 2024-10-09 12:19 ` Patrick Steinhardt [not found] ` <B0631C6D-0914-4C25-AAF7-E742129836FC@gmail.com> 0 siblings, 1 reply; 14+ messages in thread From: Patrick Steinhardt @ 2024-10-09 12:19 UTC (permalink / raw) To: Gabriel Nützi; +Cc: Junio C Hamano, git, Karthik Nayak On Wed, Oct 09, 2024 at 01:53:17PM +0200, Gabriel Nützi wrote: > > > We have another solution that is even simpler: just do nothing. I do not > > think that the behaviour we exhibit is wrong. Unwieldy? Maybe. But it is > > merely stating facts: we are executing a transaction in a repository > > that is not yet fully set up. If you don't want that, either don't set > > up a global reference-transaction hook, or alternatively handle that > > edge case in your script. > > But then Git should at least give the hooks maintainers a chance to know what it is doing. > Could we have a new env. variable or mechanism stating that the repository is not yet setup or so? > The issue here comes from the fact that Githooks is a hooks manager which basically calls `reference-transaction` for you, but before > it does it calls `git rev-parse --git-dir` to get the correct Git directory, basically not doing env. lookup on GIT_DIR which this command actually does, but that apparently only works on a "initialized" repo, so currently I do a workaround and looking directly at GIT_DIR. > I would be really happy also if I could somehow know when Git is creating a new repository (clone, or init), that would also improve other scenarios I came across. Basically you cannot react on hook `post-checkout` only when a new repo is created... Yeah, that's fair indeed, thanks for the background. In practice you already have a unique way to identify whether the repo is about to be created or whether you're using "normal" operations, namely by checking whether the HEAD file exists in the Git directory. Is that an acceptable workaround for you? As said, we're currently just exploring options. I'm not yet saying that this is the way we'll go, even though it seems like the most sensible solution to me right now. That picture of course changes when there are valid usecases like what you present here. Patrick ^ permalink raw reply [flat|nested] 14+ messages in thread
[parent not found: <B0631C6D-0914-4C25-AAF7-E742129836FC@gmail.com>]
* Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails [not found] ` <B0631C6D-0914-4C25-AAF7-E742129836FC@gmail.com> @ 2024-10-14 12:25 ` Patrick Steinhardt 0 siblings, 0 replies; 14+ messages in thread From: Patrick Steinhardt @ 2024-10-14 12:25 UTC (permalink / raw) To: Gabriel Nützi; +Cc: Junio C Hamano, git, Karthik Nayak On Fri, Oct 11, 2024 at 12:09:18PM +0200, Gabriel Nützi wrote: > > namely by checking whether the HEAD file exists in the Git directory. > > The problem here is the chicken-egg problem: How do I know inside a > hook where to look for HEAD, so the non. env. way of doing this would > be 'git rev-parse —git-dir' which crahshes… So there should be cleary > some better way of knowing if a Git repo is on the way of beeing > created, and when it is fully initialized. What about > GIT_DIR_INITIALIZING and this variable does not exist once it is done > or whats about making ‚git rev-parse —git-dir‘ not panic if the env. > variables are defined. I guess for a good solution we need both? Our documentation in githooks(5) says that the GIT_DIR environment variable is always set so that the hook can identify the location of the Git repository. So I'd argue that using git-rev-parse(1) is unnecessary in the first place. Or am I missing something? Patrick ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails 2024-10-09 9:39 ` Patrick Steinhardt 2024-10-09 10:09 ` Karthik Nayak 2024-10-09 11:53 ` Gabriel Nützi @ 2024-10-09 17:31 ` Junio C Hamano 2 siblings, 0 replies; 14+ messages in thread From: Junio C Hamano @ 2024-10-09 17:31 UTC (permalink / raw) To: Patrick Steinhardt; +Cc: Gabriel Nützi, git, Karthik Nayak Patrick Steinhardt <ps@pks.im> writes: > We have another solution that is even simpler: just do nothing. I do not > think that the behaviour we exhibit is wrong. Unwieldy? Maybe. But it is > merely stating facts: we are executing a transaction in a repository > that is not yet fully set up. If you don't want that, either don't set > up a global reference-transaction hook, or alternatively handle that > edge case in your script. I like that over all the other choices. My art in leaving out what I really want to see happen and let others say it is improving, it seems ;-). ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2024-10-14 12:25 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-09-20 10:07 Bug: `git init` with hook `reference-transaction` running `git rev-parse --git-dir` fails Gabriel Nützi 2024-09-20 10:42 ` Gabriel Nützi 2024-10-07 8:03 ` Patrick Steinhardt 2024-10-07 10:54 ` Gabriel Nützi 2024-10-07 10:57 ` Patrick Steinhardt 2024-10-07 11:02 ` Gabriel Nützi 2024-10-07 11:24 ` Patrick Steinhardt 2024-10-07 21:02 ` Junio C Hamano 2024-10-09 9:39 ` Patrick Steinhardt 2024-10-09 10:09 ` Karthik Nayak 2024-10-09 11:53 ` Gabriel Nützi 2024-10-09 12:19 ` Patrick Steinhardt [not found] ` <B0631C6D-0914-4C25-AAF7-E742129836FC@gmail.com> 2024-10-14 12:25 ` Patrick Steinhardt 2024-10-09 17:31 ` Junio C Hamano
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).