Skip to content

feat: support configuration via git config#21

Merged
takai merged 3 commits intomainfrom
feat/repo-specific-settings
Mar 7, 2026
Merged

feat: support configuration via git config#21
takai merged 3 commits intomainfrom
feat/repo-specific-settings

Conversation

@takai
Copy link
Copy Markdown
Owner

@takai takai commented Mar 7, 2026

Closes #17

Summary

Adds git config as a configuration source alongside the existing TOML files. Users can now set repository-specific behavior (engine, prompt, filters) via git config --local without touching any tracked files — making it practical for third-party repositories.

Precedence order (lowest → highest)

  1. System git config
  2. Global git config
  3. User TOML (~/.config/git-ai-commit/config.toml)
  4. Repo TOML (.git-ai-commit.toml)
  5. Local git config (.git/config)
  6. Worktree git config
  7. CLI flags

Supported git config keys

Key Equivalent TOML
ai-commit.engine engine
ai-commit.prompt prompt
ai-commit.promptFile prompt_file
ai-commit.maxFileLines filter.max_file_lines
ai-commit.excludePatterns filter.exclude_patterns (multi-value)
ai-commit.defaultExcludePatterns filter.default_exclude_patterns (multi-value)

engines.<name>.args is not supported — there is no natural mapping for nested TOML tables in git config's flat key-value model.

Implementation

  • internal/config/gitconfig.go — reads all ai-commit.* entries in a single git config --list --show-scope call, parses them into per-scope structs, and merges them into Config. Relative promptFile paths resolve from repo root (local/worktree) or $HOME (global). No path containment restriction applies since .git/config cannot be set by a third-party maintainer via push.
  • internal/config/config.go — updated Load() to apply git config scopes at the correct priority positions.

Tests

15 unit tests in internal/config/gitconfig_test.go covering all fields, multi-value patterns, precedence ordering, promptFile path resolution, and error cases (prompt exclusivity, invalid maxFileLines).

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0583843d90

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/config/config.go
Comment thread internal/config/config.go
Comment on lines 112 to +114
if cfg.PromptFile != "" {
promptSource = "user"
promptFilePath = userPath
if _, err := loadPromptFile(cfg.PromptFile, promptFilePath, ""); err != nil {
return cfg, err
}
promptFileRepoRoot = ""
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate user prompt_file before higher layers overwrite it

After loading user TOML, this branch only records promptFilePath and defers file loading until the final merged config. If the user config has an invalid prompt_file and a higher-priority layer later sets prompt/promptFile, the invalid file is never validated and Load() now succeeds, silently masking a broken user config that previously produced an error.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 05df902903

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +38 to +40
if err := cmd.Run(); err != nil {
// Not in a git repo or git not available; no git config to read.
return gitConfigScopes{}, nil
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Propagate git config read errors

When git config --list --show-scope exits non-zero, this branch always returns an empty scope set with no error. That hides real failures such as malformed git config files or Git builds that do not support --show-scope, so all ai-commit.* settings are silently dropped and Load() falls back to other layers with incorrect configuration and no actionable signal.

Useful? React with 👍 / 👎.

Comment on lines +148 to +149
if promptFile == "" || baseDir == "" || filepath.IsAbs(promptFile) {
return promptFile
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject relative promptFile when no base is provided

System scope is passed an empty promptFileBase (intended to disallow relative paths), but this helper returns relative values unchanged when baseDir is empty. Those paths are later resolved from the process working directory, so ai-commit.promptFile in system config becomes CWD-dependent and may fail or load different files depending on where the command is run.

Useful? React with 👍 / 👎.

@takai takai merged commit 8294264 into main Mar 7, 2026
1 check passed
@takai takai deleted the feat/repo-specific-settings branch March 7, 2026 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support configuration via git config for repository-specific settings

1 participant