[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lmi] Writing a git pre-commit hook
From: |
Greg Chicares |
Subject: |
Re: [lmi] Writing a git pre-commit hook |
Date: |
Wed, 9 Nov 2016 15:33:40 +0000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.3.0 |
On 2016-11-09 09:55, Vadim Zeitlin wrote:
>
> [...] The explanation first: when git runs its hooks, it sets a few
> environment variables for them, such as (for pre-commit hook at least)
> GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL. It also explicitly sets GIT_DIR and,
> for whatever reason, it sets it to a relative path, i.e. typically
> "GIT_DIR=.git". So, in essence, you end up running "GIT_DIR=.git g
> rev-parse --show-toplevel" in a subdirectory and if you run the same
> command from the same location in an interactive shell, you're going to get
> the same output, i.e. "fatal: Not a git repository: '.git'".
There's an additional subtlety: in effect, we end up running
cd $(git rev-parse --show-toplevel); GIT_DIR=.git $GIT_DIR/pre-commit
and it is because of that 'cd' that GIT_DIR=.git works even when a
git command is run elsewhere than in the toplevel directory--e.g., in
$toplevel/aclocal/ . Demonstration:
----8<--------8<--------8<--------8<--------8<--------8<--------8<----
diff --git a/hooks/pre-commit b/hooks/pre-commit
index e08795e..e6538f3 100755
--- a/hooks/pre-commit
+++ b/hooks/pre-commit
@@ -25,6 +25,12 @@
set -e
+ printf "git rev-parse --show-toplevel is $(git rev-parse --show-toplevel)\n"
+ printf "PWD is $PWD\n"
+ printf "GIT_DIR is $GIT_DIR\n"
+ printf "dollar-zero is $0\n"
+ exit 3
+
check_concinnity()
{
output=$( \
---->8-------->8-------->8-------->8-------->8-------->8-------->8----
/opt/lmi/src/lmi[0]$echo $PS1
%d[%?]%(!.#.$)
/opt/lmi/src/lmi[0]$git commit
git rev-parse --show-toplevel is /opt/lmi/src/lmi
PWD is /opt/lmi/src/lmi
GIT_DIR is .git
dollar-zero is .git/hooks/pre-commit
/opt/lmi/src/lmi[1]$cd aclocal
/opt/lmi/src/lmi/aclocal[0]$git commit
git rev-parse --show-toplevel is /opt/lmi/src/lmi
PWD is /opt/lmi/src/lmi
GIT_DIR is .git
dollar-zero is .git/hooks/pre-commit
> GC> + toplevel=$(git rev-parse --show-toplevel)
> GC> - cd $(git rev-parse --show-toplevel)/src && check_concinnity
> GC> + cd $toplevel/src && check_concinnity
> GC> - cd $(git rev-parse --show-toplevel)/data && check_concinnity
> GC> - cd $(git rev-parse --show-toplevel)/test && check_concinnity
> GC> + [...similarly]
>
> As now you run "git rev-parse --show-toplevel" from the top level
> directory, where GIT_DIR=.git is correct, it's not surprising it works. I
> still don't really like it though, it seems like it's going to be too
> simple to break it again accidentally and I think it's more complicated
> than necessary. I'd just do:
>
> (cd src && check_concinnity)
> (cd data && check_concinnity)
> (cd test && check_concinnity)
I'm not sure which is better. If a future version of git replaces the
current implicit behavior:
cd $(git rev-parse --show-toplevel); GIT_DIR=.git $GIT_DIR/pre-commit
e.g. with this behavior:
GIT_DIR=$(git rev-parse --show-toplevel)/.git $GIT_DIR/pre-commit
then explicitly ascertaining the toplevel directory will be more robust.