Skip to content

feat: add ability to disable signing git commits #4007

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions aider/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,12 @@ def get_parser(default_config_files, git_root):
default=False,
help="Enable/disable git pre-commit hooks with --no-verify (default: False)",
)
group.add_argument(
"--git-commit-no-sign",
action=argparse.BooleanOptionalAction,
default=False,
help="Disable git commit signing with --no-gpg-sign (default: False)",
)
group.add_argument(
"--commit",
action="store_true",
Expand Down
4 changes: 4 additions & 0 deletions aider/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def __init__(
commit_prompt=None,
subtree_only=False,
git_commit_verify=True,
git_commit_no_sign=False,
attribute_co_authored_by=False, # Added parameter
):
self.io = io
Expand All @@ -89,6 +90,7 @@ def __init__(
self.commit_prompt = commit_prompt
self.subtree_only = subtree_only
self.git_commit_verify = git_commit_verify
self.git_commit_no_sign = git_commit_no_sign
self.ignore_file_cache = {}

if git_dname:
Expand Down Expand Up @@ -277,6 +279,8 @@ def commit(self, fnames=None, context=None, message=None, aider_edits=False, cod
cmd = ["-m", full_commit_message]
if not self.git_commit_verify:
cmd.append("--no-verify")
if self.git_commit_no_sign:
cmd.append("--no-gpg-sign")
if fnames:
fnames = [str(self.abs_root_path(fn)) for fn in fnames]
for fname in fnames:
Expand Down
3 changes: 3 additions & 0 deletions aider/website/assets/sample.aider.conf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@
## Enable/disable git pre-commit hooks with --no-verify (default: False)
#git-commit-verify: false

## Disable git commit signing with --no-gpg-sign (default: False)
#git-commit-no-sign: false

## Commit all pending changes with a suitable commit message, then exit
#commit: false

Expand Down
3 changes: 3 additions & 0 deletions aider/website/assets/sample.env
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@
## Enable/disable git pre-commit hooks with --no-verify (default: False)
#AIDER_GIT_COMMIT_VERIFY=false

## Disable git commit signing with --no-gpg-sign (default: False)
#AIDER_GIT_COMMIT_NO_SIGN=false

## Commit all pending changes with a suitable commit message, then exit
#AIDER_COMMIT=false

Expand Down
3 changes: 3 additions & 0 deletions aider/website/docs/config/aider_conf.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,9 @@ cog.outl("```")
## Enable/disable git pre-commit hooks with --no-verify (default: False)
#git-commit-verify: false

## Disable git commit signing with --no-gpg-sign (default: False)
#git-commit-no-sign: false

## Commit all pending changes with a suitable commit message, then exit
#commit: false

Expand Down
3 changes: 3 additions & 0 deletions aider/website/docs/config/dotenv.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ cog.outl("```")
## Enable/disable git pre-commit hooks with --no-verify (default: False)
#AIDER_GIT_COMMIT_VERIFY=false

## Disable git commit signing with --no-gpg-sign (default: False)
#AIDER_GIT_COMMIT_NO_SIGN=false

## Commit all pending changes with a suitable commit message, then exit
#AIDER_COMMIT=false

Expand Down
9 changes: 9 additions & 0 deletions aider/website/docs/config/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ usage: aider [-h] [--model] [--openai-api-key] [--anthropic-api-key]
[--attribute-commit-message-committer | --no-attribute-commit-message-committer]
[--attribute-co-authored-by | --no-attribute-co-authored-by]
[--git-commit-verify | --no-git-commit-verify]
[--git-commit-no-sign | --no-git-commit-no-sign]
[--commit] [--commit-prompt] [--dry-run | --no-dry-run]
[--skip-sanity-check-repo]
[--watch-files | --no-watch-files] [--lint]
Expand Down Expand Up @@ -460,6 +461,14 @@ Aliases:
- `--git-commit-verify`
- `--no-git-commit-verify`

### `--git-commit-no-sign`
Disable git commit signing with --no-gpg-sign (default: False)
Default: False
Environment variable: `AIDER_GIT_COMMIT_NO_SIGN`
Aliases:
- `--git-commit-no-sign`
- `--no-git-commit-no-sign`

### `--commit`
Commit all pending changes with a suitable commit message, then exit
Default: False
Expand Down
52 changes: 52 additions & 0 deletions tests/basic/test_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,58 @@ def test_subtree_only(self):
self.assertNotIn(str(root_file), tracked_files)
self.assertNotIn(str(another_subdir_file), tracked_files)

@patch("aider.repo.GitRepo.get_commit_message")
@patch("git.Repo.git")
def test_git_commit_no_sign(self, mock_git, mock_get_commit_message):
"""Test that git_commit_no_sign controls whether --no-gpg-sign is passed to git commit"""
mock_get_commit_message.return_value = "Test commit message"

with GitTemporaryDirectory():
# Create a new repo
raw_repo = git.Repo()

# Create a file to commit
fname = Path("test_file.txt")
fname.write_text("initial content")
raw_repo.git.add(str(fname))

# Do the initial commit
raw_repo.git.commit("-m", "Initial commit")

# Modify the file
fname.write_text("modified content")
raw_repo.git.add(str(fname)) # Stage the change

# Create GitRepo with no_sign=True
io = InputOutput()
git_repo_no_sign = GitRepo(io, None, None, git_commit_no_sign=True)

# Attempt to commit with no_sign=True
# Mock the actual git.commit call on the Git object returned by mock_git
mock_git.commit = MagicMock()
commit_result = git_repo_no_sign.commit(fnames=[str(fname)], message="Should not sign")

# Verify that commit was called with --no-gpg-sign
mock_git.commit.assert_called_once()
call_args, call_kwargs = mock_git.commit.call_args
self.assertIn("--no-gpg-sign", call_args[0])
self.assertIsNotNone(commit_result) # Should return commit hash/message tuple

# Reset mock for the next test case
mock_git.commit.reset_mock()

# Create GitRepo with no_sign=False
git_repo_sign = GitRepo(io, None, None, git_commit_no_sign=False)

# Attempt to commit with no_sign=False
commit_result = git_repo_sign.commit(fnames=[str(fname)], message="Should sign")

# Verify that commit was called WITHOUT --no-gpg-sign
mock_git.commit.assert_called_once()
call_args, call_kwargs = mock_git.commit.call_args
self.assertNotIn("--no-gpg-sign", call_args[0])
self.assertIsNotNone(commit_result) # Should return commit hash/message tuple

@patch("aider.models.Model.simple_send_with_retries")
def test_noop_commit(self, mock_send):
mock_send.return_value = '"a good commit message"'
Expand Down