sds/overcommit · error · Overcommit::Exceptions::GitConfigError

Unable to write to local repo git config: #{result.stderr}

Error message

Unable to write to local repo git config: #{result.stderr}

What it means

Overcommit stores each hook's signature under a local git config key (overcommit.<HookType>.<HookName>.signature) by running 'git config --local'. HookSigner#update_signature! raises GitConfigError with git's stderr when that write exits non-zero - git refused to modify .git/config.

Source

Thrown at lib/overcommit/hook_signer.rb:76

        file.start_with?(Overcommit::Utils.repo_root)
    end

    # Return whether the signature for this hook has changed since it was last
    # calculated.
    #
    # @return [true,false]
    def signature_changed?
      signature != stored_signature
    end

    # Update the current stored signature for this hook.
    def update_signature!
      result = Overcommit::Utils.execute(
        %w[git config --local] + [signature_config_key, signature]
      )

      unless result.success?
        raise Overcommit::Exceptions::GitConfigError,
              "Unable to write to local repo git config: #{result.stderr}"
      end
    end

    private

    # Calculates a hash of a hook using a combination of its configuration and
    # file contents.
    #
    # This way, if either the plugin code changes or its configuration changes,
    # the hash will change and we can alert the user to this change.
    def signature
      hook_config = @config.for_hook(@hook_name, @context.hook_class_name).
                            dup.
                            tap { |config| IGNORED_CONFIG_KEYS.each { |k| config.delete(k) } }

      content_to_sign =
        if signable_file?(hook_path) && Overcommit::GitRepo.tracked?(hook_path)

View on GitHub (pinned to fee0cd74b2)

Solutions

  1. Confirm no git process is running, then remove the stale lock: 'rm -f .git/config.lock' and re-run 'overcommit --sign <hook-type>'
  2. Inspect .git/config for conflict markers or malformed lines ('git config --local --list' reproduces the parse error) and fix them
  3. Fix ownership/permissions of the .git directory (e.g. 'chown -R $(id -u):$(id -g) .git') if the write is denied
  4. Re-run the failed overcommit command once the underlying cause is cleared

Example fix

# before
$ overcommit --sign pre-commit
Overcommit::Exceptions::GitConfigError: Unable to write to local repo git config: fatal: Unable to create '/repo/.git/config.lock': File exists.

# after
$ rm -f .git/config.lock
$ overcommit --sign pre-commit
Defensive patterns

Strategy: retry

Validate before calling

def git_config_writable?
  git_dir = `git rev-parse --git-dir`.strip
  !File.exist?(File.join(git_dir, 'config.lock')) && File.writable?(File.join(git_dir, 'config'))
end

raise 'git config locked or unwritable' unless git_config_writable?

Try / catch

begin
  signer.update_signature!
rescue Overcommit::Exceptions::GitConfigError => e
  raise unless e.message.include?('config.lock') && File.exist?('.git/config.lock')
  File.delete('.git/config.lock')
  retry
end

Prevention

When it happens

Trigger: Running 'overcommit --sign <hook-type>' (or the install-time auto-sign) while .git/config.lock exists from a crashed or concurrent git process ('Unable to create .git/config.lock: File exists.'), .git/config is corrupted ('bad config line'), the user lacks write permission on .git, or the environment is not inside a valid work tree.

Common situations: IDE and CLI git tools writing config at the same moment; stale .git/config.lock after a crash; repo restored with different ownership (root-owned .git inside a container); read-only .git in CI artifacts.

Related errors


AI-assisted analysis of sds/overcommit@fee0cd74b2 (2026-08-23). Data as JSON: /api/errors/cba6c2a8d4419bd1. Report an issue: GitHub.