evilmartians / lefthook

Fast and powerful Git hooks manager for any type of projects.
MIT License
4.77k stars 210 forks source link

Remote sync failures #680

Closed createchange closed 5 months ago

createchange commented 6 months ago

:wrench: Summary

Testing this for implementation with our Engineering team, but have run into a bug (twice) where I can no longer pull from the remote, via remotes config:

$ cat lefthook.yml
remotes:
- git_url: git@gitlab.com:<redacted>/gitlab-security-policies/lefthook.git
  configs:
    - lefthook.yml

The first time, I was getting an error about having unstaged files. While I had some unstaged files, I then staged them, but the same error continued to pop.

│ Searching config in:/Users/<me>/lefthook_test
│ Merging remote config: git@gitlab.com:<redacted>/gitlab-security-policies/lefthook.git: .git/info/lefthook-remotes/lefthook/lefthook.yml
│ Updating remote config repository: .git/info/lefthook-remotes/lefthook
│ [lefthook] cmd: [git -C .git/info/lefthook-remotes/lefthook pull --quiet]
│ [lefthook] dir: /Users/<me>/lefthook_test
│ [lefthook] err: exit status 128
│ [lefthook] out: error: cannot pull with rebase: You have unstaged changes.
error: Please commit or stash them.

Couldn't sync remotes. Will continue without them: exit status 128

The second issue manifested the same - unable to install the hooks - but because of a different reason. To test the first issue, I created a new repo and copied over my lefthook.yml file. The hooks installed fine. I continued on my way, until I did something illegal (I tried to pass {staged_files} through to a script via environment variable.

│ Searching config in:/Users/<me>/lefthook_test_2
│ Merging remote config: git@gitlab.com:<redacted>/gitlab-security-policies/lefthook.git: .git/info/lefthook-remotes/lefthook/lefthook.yml
Error: 1 error(s) decoding:

* 'env[staged_files]' expected type 'string', got unconvertible type 'map[string]interface {}', value: 'map[staged_files:<nil>]'

Removing this offending config, I expected the lefthook install -f -v command to successfully pulled down the fixed copy. Unfortunately, this did not occur.

I created a third repo, and was able to copy the lefthook.yml config to that directory, which pulled without issue.

It seems as though one failed merge of lefthook configs results in persistent errors.

Lefthook version

1.6.1

Steps to reproduce

  1. Have remote config
  2. Have staged files or illegal configuration options
  3. lefthook install -f -v
  4. Fix staged files or illegal configuration options
  5. lefthook install -f -v

Expected results

Remote configuration is successfully merged.

Actual results

Errors that cannot be fixed short of by migrating to a new directory.

Possible Solution

I imagine there is a local state being managed by lefthook that could be cleaned?

Logs / Screenshots

See above.

createchange commented 6 months ago

A bit more testing led me to a more conclusive example. Repo 3 ran into the same error, so I moved to repo 4.

In repo 4, I am using a script to synthesize our custom secrets rules into a gitleaks config. I simply created a new repo, copied over my existing lefthook.yml' config, git init'ed, and then installed the hooks. The first time worked great (other than my script having an error in it). After this, I had a bare repo, except for a.gitleaks.tomlconfig and thelefthook.yml` config:

[nix-shell:~/lefthook_test_4]$ ls -la
total 80
drwxr-xr-x   5 jweaver staff   160 Mar 20 15:00 .
drwx------+ 93 jweaver staff  2976 Mar 20 14:53 ..
drwxr-xr-x  13 jweaver staff   416 Mar 20 14:57 .git
-rw-r--r--   1 jweaver staff 77388 Mar 20 14:57 .gitleaks.toml
-rw-r--r--   1 jweaver staff   582 Mar 20 14:53 lefthook.yml

I remove the .gitleaks.toml config, which leaves me at the barest of repositories. However, the error persists:

[nix-shell:~/lefthook_test_4]$ ls -la
total 80
drwxr-xr-x   5 jweaver staff   160 Mar 20 15:00 .
drwx------+ 93 jweaver staff  2976 Mar 20 14:53 ..
drwxr-xr-x  13 jweaver staff   416 Mar 20 14:57 .git
-rw-r--r--   1 jweaver staff 77388 Mar 20 14:57 .gitleaks.toml
-rw-r--r--   1 jweaver staff   582 Mar 20 14:53 lefthook.yml

[nix-shell:~/lefthook_test_4]$ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    .gitleaks.toml

nothing added to commit but untracked files present (use "git add" to track)

[nix-shell:~/lefthook_test_4]$ rm .gitleaks.toml

[nix-shell:~/lefthook_test_4]$ lefthook install -f -v
│ [lefthook] cmd: [git rev-parse --show-toplevel]
│ [lefthook] dir:
│ [lefthook] err: <nil>
│ [lefthook] out: /Users/jweaver/lefthook_test_4

│ [lefthook] cmd: [git rev-parse --git-path hooks]
│ [lefthook] dir:
│ [lefthook] err: <nil>
│ [lefthook] out: .git/hooks

│ [lefthook] cmd: [git rev-parse --git-path info]
│ [lefthook] dir:
│ [lefthook] err: <nil>
│ [lefthook] out: .git/info

│ [lefthook] cmd: [git rev-parse --git-dir]
│ [lefthook] dir:
│ [lefthook] err: <nil>
│ [lefthook] out: .git

│ Searching config in:/Users/<me>/lefthook_test_4
│ Merging remote config: git@gitlab.com:<redacted>/gitlab-security-policies/lefthook.git: .git/info/lefthook-remotes/lefthook/lefthook.yml
│ Updating remote config repository: .git/info/lefthook-remotes/lefthook
│ [lefthook] cmd: [git -C .git/info/lefthook-remotes/lefthook pull --quiet]
│ [lefthook] dir: /Users/<me>/lefthook_test_4
│ [lefthook] err: exit status 128
│ [lefthook] out: error: cannot pull with rebase: You have unstaged changes.
error: Please commit or stash them.

Couldn't sync remotes. Will continue without them: exit status 128
sync hooks: ✔️ (pre-commit)

It looks like the issue is here:

[nix-shell:~/lefthook_test_4/.git/info/lefthook-remotes/lefthook]$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   .lefthook/pre-commit/gitleaks.sh
mrexox commented 6 months ago

Thank you for submitting the issue. I will take a closer look a bit later. But indeed it seems like lefthook doesn't handle such conflicts. I will try to fix this ASAP.

createchange commented 6 months ago

Thanks! I found that I could delete this directory (rm -rf .git/info/lefthook-remotes/lefthook/), and things were operational once again. Like the other issue that I submitted, this is not a blocker for me, but may prevent adoption among our engineering team.

One small suggestion would be to include the error text if a remote pull fails. For users that are just consumers of lefthook (my engineers, e.g.), this is all they get returned:

$ lefthook install
Couldn't sync remotes. Will continue without them: exit status 128
sync hooks: ✔️ (pre-commit)

When we know that more useful information is included in the output:

│ [lefthook] cmd: [git -C .git/info/lefthook-remotes/lefthook pull --quiet]
│ [lefthook] dir: /Users/<me>/lefthook_test_4
│ [lefthook] err: exit status 128
│ [lefthook] out: error: cannot pull with rebase: You have unstaged changes.
error: Please commit or stash them.

So it looks like it failed, but then maybe like it still somehow succeeded. I foresee troubleshooting Slack messages, from the Engineering team, directed at me in the future. 😅

I appreciate your responses to all my questions, by the way. Thanks again!

mrexox commented 5 months ago

Hey, I've prepared a change that will trigger redownload of the remotes when lefthook install -f is called. I hope this is the desired behavior. Please, feel free to disagree :)

mrexox commented 5 months ago

Hey, with 1.6.9 release lefthook install -f must re-download the remotes. Please, write back if it does not work.