@@ -317,14 +317,14 @@ remotes:
317317 t .Run (fmt .Sprintf ("%d: %s" , n , tt .name ), func (t * testing.T ) {
318318 assert := assert .New (t )
319319
320- // Prepend git config commands required by getHooksPathConfig () in install.go .
321- // These commands are always called at the start of Install() to detect core.hooksPath conflicts .
320+ // Append git config commands required by ensureHooksPathUnset () via installHooks() .
321+ // These commands are called after remote syncing, when hooks are about to be created .
322322 gitCmds := tt .git
323323 if len (gitCmds ) == 0 || gitCmds [0 ].Command != "git config --local core.hooksPath" {
324- gitCmds = append ([]cmdtest. Out {
325- {Command : "git config --local core.hooksPath" },
326- {Command : "git config --global core.hooksPath" },
327- }, gitCmds ... )
324+ gitCmds = append (gitCmds ,
325+ cmdtest. Out {Command : "git config --local core.hooksPath" },
326+ cmdtest. Out {Command : "git config --global core.hooksPath" },
327+ )
328328 }
329329
330330 repo := gittest .NewRepositoryBuilder ().
@@ -506,6 +506,52 @@ commit-msg:
506506 hookPath (config .GhostHookName ),
507507 },
508508 },
509+ {
510+ // Reproduces the bug: when core.hooksPath is set globally (e.g. for
511+ // credential leak detection), syncHooks should skip hook creation
512+ // rather than overwriting the user's global hooks directory.
513+ // See: reproduce-bug.sh
514+ name : "unsynchronized with global core.hooksPath set" ,
515+ config : `
516+ pre-commit:
517+ commands:
518+ tests:
519+ run: yarn test
520+ ` ,
521+ checksum : "00000000f706df65f379a9ff5ce0119b 1555894311\n " ,
522+ git : []cmdtest.Out {
523+ {Command : "git config --local core.hooksPath" },
524+ {Command : "git config --global core.hooksPath" , Output : "/home/user/.config/git/hooks" },
525+ },
526+ wantExist : []string {
527+ configPath ,
528+ },
529+ wantNotExist : []string {
530+ hookPath ("pre-commit" ),
531+ hookPath (config .GhostHookName ),
532+ },
533+ },
534+ {
535+ name : "unsynchronized with local core.hooksPath set" ,
536+ config : `
537+ pre-commit:
538+ commands:
539+ tests:
540+ run: yarn test
541+ ` ,
542+ checksum : "00000000f706df65f379a9ff5ce0119b 1555894311\n " ,
543+ git : []cmdtest.Out {
544+ {Command : "git config --local core.hooksPath" , Output : ".custom-hooks" },
545+ {Command : "git config --global core.hooksPath" },
546+ },
547+ wantExist : []string {
548+ configPath ,
549+ },
550+ wantNotExist : []string {
551+ hookPath ("pre-commit" ),
552+ hookPath (config .GhostHookName ),
553+ },
554+ },
509555 {
510556 name : "with unfetched remote" ,
511557 config : `
@@ -566,7 +612,18 @@ remotes:
566612 t .Run (fmt .Sprintf ("%d: %s" , n , tt .name ), func (t * testing.T ) {
567613 assert := assert .New (t )
568614
569- repo := gittest .NewRepositoryBuilder ().Root (root ).Fs (fs ).Cmd (cmdtest .NewOrdered (t , tt .git )).Build ()
615+ // Append git config commands required by ensureHooksPathUnset() via installHooks().
616+ // These commands are called when syncHooks needs to create/update hooks,
617+ // which happens after any remote fetching.
618+ gitCmds := tt .git
619+ if len (gitCmds ) == 0 || gitCmds [0 ].Command != "git config --local core.hooksPath" {
620+ gitCmds = append (gitCmds ,
621+ cmdtest.Out {Command : "git config --local core.hooksPath" },
622+ cmdtest.Out {Command : "git config --global core.hooksPath" },
623+ )
624+ }
625+
626+ repo := gittest .NewRepositoryBuilder ().Root (root ).Fs (fs ).Cmd (cmdtest .NewOrdered (t , gitCmds )).Build ()
570627 lefthook := & Lefthook {
571628 fs : fs ,
572629 repo : repo ,
0 commit comments