J4N
J4N

Reputation: 20761

"Hook already exists: pre-push" after adding new git hook

In a git repository, where we already have a .Net solution, we recently added an angular part.

For this angular part, we did add some hooks with husky. Since the frontend, that contains the package.json is in a subfolder, we did the following:

  1. npm install husky --save-dev
  2. Ran cd .. && husky install ./Frontend/.husky
  3. Added a "prepare" script: "prepare": "cd .. && husky install ./Frontend/.husky"
  4. ran npx husky add .husky/pre-commit "cd ./Frontend && npm run lint"
  5. We also added a hook to do the automatic npm install after getting the code: npx husky add .husky/post-merge "cd ./Frontend && npx git-pull-run --pattern 'package-lock.json' --command 'npm install'"

This seems to work fine locally, but when the repository is checked out by our CI agent(azure devop), we get an error:

Syncing repository: XXX (Git)
Prepending Path environment variable with directory containing 'git.exe'.
git version
git version 2.30.2.windows.1
git lfs version
git-lfs/2.13.3 (GitHub; windows amd64; go 1.16.2; git a5e65851)
git config --get remote.origin.url
git clean -ffdx
git reset --hard HEAD
git config gc.auto 0
git config --get-all http.https://[email protected]/yyy/zzz/_git/aaa.extraheader
git config --get-all http.extraheader
git config --get-regexp .*extraheader
git config --get-all http.proxy
git config http.version HTTP/1.1
git lfs install --local
Hook already exists: post-merge

    #!/usr/bin/env sh
    . "$(dirname -- "$0")/_/husky.sh"
    
    cd ./Frontend && npx git-pull-run --pattern 'package-lock.json' --command 'npm install'

To resolve this, either:
  1: run `git lfs update --manual` for instructions on how to merge hooks.
  2: run `git lfs update --force` to overwrite your hook.
##[error]Git-lfs installation failed with exit code: 2

This error doesn't happen when azure devop has a clean repository, but on the second run only.

I tried to run the git lfs update --manual/--force commands, without any changes.

How to properly integrate git-lfs with git hooks?

Upvotes: 1

Views: 5359

Answers (2)

I just searched for a solution and landed here. Checked the referenced article etc.

In the current version of git lfs install I get the following output:

╰─ git lfs install
Hook already exists: pre-push

        #!/usr/bin/env sh
        . "$(dirname "$0")/h"

To resolve this, either:
  1: run `git lfs update --manual` for instructions on how to merge hooks.
  2: run `git lfs update --force` to overwrite your hook.

With the hint to use git lfs update --force, the manual is shown as follows:

╰─ git lfs update --manual
Add the following to '.husky/_/pre-push':

        #!/bin/sh
        command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'pre-push' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks').\n"; exit 2; }
        git lfs pre-push "$@"

Add the following to '.husky/_/post-checkout':

        #!/bin/sh
        command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'post-checkout' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks').\n"; exit 2; }
        git lfs post-checkout "$@"

Add the following to '.husky/_/post-commit':

        #!/bin/sh
        command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'post-commit' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks').\n"; exit 2; }
        git lfs post-commit "$@"

Add the following to '.husky/_/post-merge':

        #!/bin/sh
        command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'post-merge' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks').\n"; exit 2; }
        git lfs post-merge "$@"

For me, this seems a more viable solution as is added the printed files as husky hook in the respective .husky/* folder instead of the shown .husky/_/*.

Upvotes: 1

Gavimoss
Gavimoss

Reputation: 375

Husky and LFS use some of the same hooks and the error message you're seeing here is due to LFS failing to install a hook that Husky has already 'reserved' so to speak.

There is a great solution documented here: https://dev.to/mbelsky/pair-husky-with-git-lfs-in-your-javascript-project-2kh0

In a nutshell, you need to install the LFS hooks first, move them to a separate directory and then install the Husky hooks.

$ rm -rf .git/hooks
$ git lfs install
$ mv .git/hooks ./lfs-hooks
$ rm -rf node_modules/husky
$ npm install

Then you need to update your Husky configuration to ensure that LFS still runs when you need it (as it no longer has it's hooks in the .git/hooks folder).

  "husky": {
    "hooks": {
      "post-checkout": "echo $HUSKY_GIT_STDIN | lfs-hooks/post-checkout $HUSKY_GIT_PARAMS",
      "post-commit": "echo $HUSKY_GIT_STDIN | lfs-hooks/post-commit $HUSKY_GIT_PARAMS",
      "post-merge": "echo $HUSKY_GIT_STDIN | lfs-hooks/post-merge $HUSKY_GIT_PARAMS",
      "pre-push": "echo $HUSKY_GIT_STDIN | lfs-hooks/pre-push $HUSKY_GIT_PARAMS"
    }
  },

Alternatively, git-hooks apparently offers a better integration with LFS for those happy to try another tool.

Note that this issue only affects some earlier versions of Husky so it sounds like you may be using a newer version locally but an older version in your pipeline.

Upvotes: 1

Related Questions