Skip to content

Commit

Permalink
feat: Remove all unnecessary install modes (#159)
Browse files Browse the repository at this point in the history
**Two modes:**:

- The normal mode  sets **local** `core.hooksPath` on `git hooks install` in a repository and will not do any automatic installation on clone/init.
- The centralized mode sets this globally and will work by default for all clone/init repos.

**More changes**:

- Run-wrappers can still be installed in local repos, **`init.templateDir` is not used and controlled by Githooks anymore**.
- Run-wrapper will use by default `githooks-runner` and as fallback use `git config githooks.runner`. Package manager builds `tag: package_manager_enabled` will not set this.
- The installer has an option `--hooks-dir` which specifies the directory to place the maintained hooks.
- The installer has an option `--hooks-dir-use-template-dir` in non-`--centralized` mode which looks for a set `GIT_TEMPLATE_DIR` or `init.templateDir` or the Git default directory. This option is not encouraged, and will install templates on each init/clone as before. 
- The installer warns if  the chosen hooks dir during install is pointing to a template directory used by Git.

- User wanting to install run-wrappers instead of setting `core.hooksPath` should either use `git hooks install --maintained-hooks` or place a file `<template-dir>/hooks/githooks-contains-run-wrappers` to let Githooks know that this repo maintains run-wrappers (for updates etc, that no `core.hooksPath` is used but run-wrappers installed directly).
- Registering is now done for all repositories (also in centralized mode).
- `git hook uninstall --full` and `git hooks uninstaller --full-uninstall-from-repos` will clean all Git config and cached settings (checksums) in registered repositories, by default `git hooks uninstall` will not remove locally set `githooks.*` Git config variables, this is to make `reinstallation` more easy, e.g. `githooks.maintainedHooks` stays and will be read on reinstall.

**CI**:
- Go 1.22
- Remove `EXTRA_INSTALL_ARGS` sed modifications and pass explicitly.
- Disabled hanging test 064 (build from source) on windows.
- Coverage also runs `--centralized` tests too.
  • Loading branch information
gabyx committed Apr 21, 2024
1 parent ee2ec60 commit 6e0d4b9
Show file tree
Hide file tree
Showing 200 changed files with 2,921 additions and 1,628 deletions.
3 changes: 2 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:
steps:
- checkout
- run:
no_output_timeout: 30m
command: "& 'C:/Program Files/Git/bin/sh.exe' tests/<<parameters.test>>.sh"

workflows:
Expand All @@ -43,7 +44,7 @@ workflows:
"test-alpine",
"test-alpine-nolfs",
"test-alpine-user",
"test-corehookspath",
"test-centralized",
"test-whitespace",
"test-unittests",
"test-unittests-podman",
Expand Down
24 changes: 14 additions & 10 deletions .githooks/pre-commit/golint
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@ fi

cd githooks || exit 1

if CGO_ENABLED=0 golangci-lint run -E godot \
-E gomnd \
-E goconst \
-E gochecknoinits \
-E nlreturn \
-E misspell \
-E lll \
-E exportloopref \
-E gocritic \
--max-same-issues 0 ./...; then
if
CGO_ENABLED=0 golangci-lint run \
--skip-dirs /usr/local/go \
-E godot \
-E gomnd \
-E goconst \
-E gochecknoinits \
-E nlreturn \
-E misspell \
-E lll \
-E exportloopref \
-E gocritic \
--max-same-issues 0 ./...
then
echo "* golangci-lint OK" >&2
else
echo "! golangci-lint problems detected" >&2
Expand Down
5 changes: 2 additions & 3 deletions .githooks/pre-commit/update-templates
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ for hook_name in $hook_names; do
-e "s|echo \"! .*|echo \"! The runner '\$GITHOOKS_RUNNER' is not existing\" \>\&2\n|g" \
-e "s|\(various Git triggers.*\)|\1\n#\n# This file is auto-generated, do not edit!|" \
<githooks/build/embedded/run-wrapper.sh >"hooks/$hook_name" &&
chmod u+x "hooks/$hook_name" &&
git add hooks/* ||
chmod u+x "hooks/$hook_name" ||
{
echo "Failed to update \`hooks/$hook_name\`" >&2
echo "Failed to update 'hooks/$hook_name'" >&2
exit 2
}
done
Expand Down
208 changes: 102 additions & 106 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ following cases:
1. **Trust prompt**: The user is required to trust/untrust a new/changed hook:
**fatal**.
2. **Update prompts**: The user is requested to accept a new update if automatic
updates are enabled (`git hooks update --enable`): **non-fatal**.
updates are enabled (`git hooks update --enable-check`): **non-fatal**.
- Various other prompts when the updater is launched: **non-fatal**.

User prompts during `runner` execution are sometimes not desirable (server
Expand Down Expand Up @@ -979,56 +979,75 @@ The installer will:

1. Verify the checksums and signature of the downloaded binaries.

1. Launch the current (or new if `--update` is given) installer which proceeds
with the next steps.
1. Launch the current installer which proceeds with the next steps. If
`--update` is given the newest Githooks is downloaded and installed directly.

1. Find the install mode relevant directory:
1. Find the install mode relevant hooks directory `<hooksDir>`:

- For `Template Dir` install mode: Use the Git template directory
- Use the directory given with `--hooks-dir <dir>` on the command line.

1. from `--template-dir` if given or
1. from the `$GIT_TEMPLATE_DIR` environment variable or
1. use the `git config --get init.templateDir` or
1. use the Git default `/usr/share/git-core/templates` folder or
1. search on the file system for matching directories or
1. offer to set up a new one.
- Use `git config --get githooks.pathForUseCoreHooksPath` if Githooks is
already installed.

- For `Centralized Hooks` install mode: Use the hooks directory
- Use the following template directory if `--hooks-dir-use-template-dir` is
given:

1. from `--template-dir` if given, or
1. use `git config --get core.hooksPath` command if set or
1. otherwise use `<install-dir>/templates`.
1. use `GIT_TEPMLATE_DIR` if set and add `/hooks`
1. use Git config value `init.templateDir` if set and add `/hooks`
1. use `<install-dir>/templates/hooks`.

- For `Manual` install mode use the directory
**Note:** This will silenty make all new repositories with `git init` or
`git clone` directly use Githooks, this is similar to the
[`centralized`](#install-mode-centralized-hooks) install mode.

1. from `--template-dir` if given or
1. otherwise use `<install-dir>/templates`.
1. Write all Githooks run-wrappers into the hooks directory `<hooksDir>` and

1. Write all Githooks run-wrappers into the hooks directory and set

- either `init.templateDir` for `Normal` install mode or
- `core.hooksPath` for `Centralized Hooks` install mode
(`--use-core-hooks-path`) or
- `githooks.manualTemplateDir` for `Manual` install mode (`--use-manual`)
- set `core.hooksPath` for [`centralized`](#install-mode-centralized-hooks)
install mode (`--use-core-hooks-path`).

1. Offer to enable automatic update checks.

1. Offer to find existing Git repositories on the file system (disable with
`--skip-install-into-existing`)

1. Install run-wrappers into them (`.git/hooks`).
2. Offer to add an intro README in their `.githooks` folder.
1. Make them use Githooks by either setting `core.hooksPath` (or install
run-wrappers if `<repo-git-dir>/hooks/githooks-contains-run-wrappers`
exists).

1. Offer to add an intro README in their `.githooks` folder.

1. Install/update run-wrappers into all registered repositories: Repositories
using Githooks get registered in the install folders `registered.yaml` file
on their first hook invocation.

1. Offer to set up shared hook repositories.

### Install Mode - Template Dir
### Instal Modes

This installer can install Githooks in one of 2 ways:

- **Manual**: To use Githooks in a repo, it must be installed (default behavior)
with `git hooks install`.

- **Centralized**: Using the Git `core.hooksPath` **global** variable (set by
passing the `--centralized` parameter to the install script). All repositories
will use Githooks by default.

Read the details about the differences between these 2 approaches
[below](#global-hooks-or-no-global-hooks).

### Install Mode - Manual

**This is the default installation mode.**

In this mode, you decide yourself when to use Githooks in a repository simply by
doing one of the following with the same effect:

- Run `git hooks install` or `git hooks uninstall` to install run wrappers
explicitly.

This means that Githooks might not run if you forget to install the hooks.

To install Githooks on your system, simply execute `cli installer`. It will
guide you through the installation process. Check the `cli installer --help` for
available options. Some of them are described below:
Expand All @@ -1042,8 +1061,7 @@ curl -sL https://raw.githubusercontent.com/gabyx/githooks/main/scripts/install.s
--maintained-hooks "pre-rebase, post-checkout, post-merge, pre-push"
```

This will only support the mentioned hooks in the template directory (e.g. for
new clones). You can still overwrite selectively for a repository by
You can still overwrite selectively for a repository by
[installing another set of hooks](#installing-or-removing-run-wrappers). Missing
Git LFS hooks will always be placed if necessary.

Expand All @@ -1055,47 +1073,26 @@ curl -sL https://raw.githubusercontent.com/gabyx/githooks/main/scripts/install.s
--dry-run
```

### Install Mode - Centralized Hooks

Lastly, you have the option to install the templates to a centralized location
(`core.hooksPath`). You can read more about the difference between this option
and the default one [below](#templates-or-global-hooks). For this, run the
command below.
Optionally, you can also pass the hooks directory to which you want to install
the Githooks run-wrappers by appending `--hook-dir <path>` to the command above,
for example:

```shell
curl -sL https://raw.githubusercontent.com/gabyx/githooks/main/scripts/install.sh | bash -s -- -- \
--use-core-hookspath
--hooks-dir /home/public/myhooks
```

Optionally, you can also pass the template directory to which you want to
install the centralized hooks by appending `--template-dir <path>` to the
command above, for example:
### Install Mode - Centralized Hooks

You have the option to install Githooks centralized which will use the
run-wrappers globally by setting the global `core.hooksPath` additionally. For
this, run the command below.

```shell
curl -sL https://raw.githubusercontent.com/gabyx/githooks/main/scripts/install.sh | bash -s -- -- \
--use-core-hookspath
--template-dir /home/public/.githooks
--centralized
```

### Install Mode - Manual

You also have the option for none of the two above methods and to use Githooks
in _manual_ mode. This means that hook run wrappers are not injected by the
`init.templateDir` Git config setting into new cloned repositories, nor does it
set `core.hooksPath`. This means, you decide yourself when to use Githooks in a
repository simply by doing one of the following with the same effect:

- Run `git hooks install` or `git hooks uninstall` to install run wrappers
explicitly.
- Set `core.hooksPath` inside the repository you want to use Githooks with to
the template directory Githooks maintains, e.g.

```shell
git config core.hooksPath "$(git config githooks.manualTemplateDir)"
```

This also means that Githooks might not run if you forget to install the hooks.

### Install from different URL and Branch

If you want to install from another Git repository (e.g. from your own or your
Expand Down Expand Up @@ -1384,93 +1381,92 @@ git hooks config trust-all-hooks --accept
# Don't do global automatic updates, since the Githooks updater
# might get invoked in parallel on a server.
git hooks config update --disable
git hooks config update --disable-check
```

Note: A user cannot change bare repository Githooks by pushing changes to a bare
repository on the server. If you use shared hook repositories in you bare
repository, you might consider disabling shared hooks updates by
[`git hooks config disable-shared-hooks-update --set`](docs/cli/git_hooks_config_disable-shared-hooks-update).

### Templates or Global Hooks

This installer command can work in one of 2 ways:

- Using the git template folder `init.templateDir` (default behavior)
- Using the git `core.hooksPath` variable (set by passing the
`--use-core-hookspath` parameter to the install script)

Read about the differences between these 2 approaches below.

In both cases, the installer command will make sure Git will find the Githooks
run-wrappers.

#### Template Folder (`init.templateDir`)
### Global Hooks or No Global Hooks

In this approach, the install script creates hook templates (global Git config
`init.templateDir`) that are installed into the `.git/hooks` folders
automatically on `git init` and `git clone`. For bare repositories, the hooks
are installed into the `./hooks` folder on `git init --bare`. This is the
recommended approach, especially if you want to selectively control which
repositories use Githooks or not.
#### Manual: Use Githooks Selectively

The install script offers to search for repositories to which it will install
the run-wrappers, and any new repositories you clone will have these hooks
configured.
In this approach, the install script installs the hook run-wrapper into a common
location (`~/.githooks/templates/` by default).

You can disable installing Githooks run-wrappers by using:
To make Githooks available inside a repository, you must install it with

```shell
git clone --template= <url> <repoPath>
git lfs install # Important if you use Git LFS!. It never hurts doing this.
cd repo
git hooks install
```

**Note**: It's recommended that you do `git lfs install` again. However, with
the latest `git` version 2.30, and `git lfs` version 2.9.2, `--template=` will
not result in **no** LFS hooks inside `${GIT_DIR}/hooks` if your repository
**contains** LFS objects.
which will simply set the `core.hooksPath` to the common location where Githooks
maintaines its run-wrappers. If you want a partial maintained hooks set with
`git hooks install --maintained-hooks ...`, it will switch to install Githooks
run-wrappers inside this sole repository.

You have the possibility to install the Githooks run-wrappers into a Git
template directory (e.g. `GIT_TEMPLATE_DIR` or `init.templateDir` or the default
Git template directory from the Git install) by specifying
`--hooks-dir-use-template-dir`. This option is discouraged and only available
for backward compatibility and is not really needed and can be covered with the
below `centralized` install mode.

#### Global Hooks Location (`core.hooksPath`)
#### Centralized: Use Githooks For All Repositories

In this approach, the install script installs the hook templates into a
centralized location (`~/.githooks/templates/` by default) and sets the global
In this approach, the install script installs the hook run-wrapper into a common
location (`~/.githooks/templates/` by default) and sets the global
`core.hooksPath` variable to that location. Git will then, for all relevant
actions, check the `core.hooksPath` location, instead of the default
`${GIT_DIR}/hooks` location.

This approach works more like a _blanket_ solution, where **all
repositories**<span id="a2">[<sup>2</sup>](#2)</span> will start using the hook
templates, regardless of their location.
repositories**<span id="a2">[<sup>2</sup>](#2)</span> will start using the
Githooks run-wrappers (thus launching Githooks), regardless of their location.

**<span id="2"><sup>2</sup></span>[⏎](#a2) Note:** It is possible to override
the behavior for a specific repository, by setting a local `core.hooksPath`
variable with value `${GIT_DIR}/hooks`, which will revert Git back to its
default behavior for that specific repository. You don't need to initialize
`git lfs install`, because they presumably be already in `${GIT_DIR}/hooks` from
any `git clone/init`.
any `git clone/init`. **This does NOT work when using this inside a Git
worktree**.

### Updates

You can update the Githooks any time by running one of the install commands
above. It will update itself and simply overwrite the template run-wrappers with
the new ones, and if you opt-in to install into existing or registered local
repositories, those will get overwritten too.
You can update the Githooks any time by running

```shell
git hooks update
```

or one of the install commands above with `--update`.

It then downloads the binaries (GPG signed + checksummed) and dispatches to the
new installer to install the new version. It will update itself and simply
overwrite the template run-wrappers with the new ones, and if you opt-in to
install into existing or registered local repositories, those will get
overwritten too.

#### Automatic Update Checks

You can also enable automatic update checks during the installation, that is
executed **once a day after a successful commit**. It checks for a new version
and asks whether you want to install it. It then downloads the binaries (GPG
signed + checksummed) and dispatches to the new installer to install the new
version.
where you can then call `git hooks update` your-self (\*previous to version `3`
this was automatic which was removed).

Automatic updates can be enabled or disabled at any time by running the command
below.

```shell
# enable with:
$ git hooks update --enable # `Config: githooks.updateCheckEnabled`
$ git hooks update --enable-check # `Config: githooks.updateCheckEnabled`

# disable with:
$ git hooks update --disable
$ git hooks update --disable-check
```

#### Update Mechanics
Expand Down
4 changes: 2 additions & 2 deletions docs/cli/git_hooks_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ git hooks config
Enable/disable skipping active, untrusted hooks.
- [git hooks config trust-all](git_hooks_config_trust-all.md) - Change trust
settings in the current repository.
- [git hooks config update](git_hooks_config_update.md) - Change Githooks update
settings.
- [git hooks config update-check](git_hooks_config_update-check.md) - Change
Githooks update-check settings.
- [git hooks config update-time](git_hooks_config_update-time.md) - Changes the
Githooks update time.

Expand Down
Loading

0 comments on commit 6e0d4b9

Please sign in to comment.