Skip to content
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
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,23 @@ aider --model sonnet --api-key anthropic=<key>
aider --model o3-mini --api-key openai=<key>
```

### Configuration

Create a `.aider.conf.yml` file to configure model aliases and other settings:

```yaml
# Use a list to define multiple aliases
alias:
- "fast:gpt-4o-mini"
- "smart:o3-mini"
- "hacker:claude-3-sonnet-20240229"

# Default model
model: "gpt-4o-mini"
```

> **Note:** YAML does not support repeated keys. Always use a list format for multiple aliases.

See the [installation instructions](https://aider.chat/docs/install.html) and [usage documentation](https://aider.chat/docs/usage.html) for more details.

## More Information
Expand Down
27 changes: 19 additions & 8 deletions aider/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,25 @@ def setup_git(git_root, io):

if user_name and user_email:
return repo.working_tree_dir

with repo.config_writer() as git_config:
if not user_name:
git_config.set_value("user", "name", "Your Name")
io.tool_warning('Update git name with: git config user.name "Your Name"')
if not user_email:
git_config.set_value("user", "email", "[email protected]")
io.tool_warning('Update git email with: git config user.email "[email protected]"')

try:
with repo.config_writer() as git_config:
if not user_name:
git_config.set_value("user", "name", "Your Name")
io.tool_warning('Update git name with: git config user.name "Your Name"')
if not user_email:
git_config.set_value("user", "email", "[email protected]")
io.tool_warning('Update git email with: git config user.email "[email protected]"')
except (OSError, PermissionError) as e:
io.tool_warning(
f"Warning: Could not write to git config: {e}\n"
f"This may be due to network drive permissions or file locking issues.\n"
f"You may need to manually set git config values using:\n"
f"git config user.name \"Your Name\"\n"
f"git config user.email \"[email protected]\""
)
# Continue without modifying config, in read-only mode
pass

return repo.working_tree_dir

Expand Down
46 changes: 46 additions & 0 deletions tests/basic/test_git_config_network.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import os
from pathlib import Path
from unittest import TestCase
from unittest.mock import patch, MagicMock

import git

from aider.io import InputOutput
from aider.main import setup_git
from aider.utils import GitTemporaryDirectory


class TestGitConfigNetworkDrive(TestCase):
def setUp(self):
self.tempdir = GitTemporaryDirectory()
self.old_cwd = os.getcwd()
os.chdir(self.tempdir.name)

def tearDown(self):
os.chdir(self.old_cwd)
self.tempdir.cleanup()

def test_setup_git_with_permission_error(self):
"""Test that setup_git handles permission errors gracefully"""
io = InputOutput(pretty=False, yes=True)

# Create a mock repo that raises PermissionError on config_writer
mock_repo = MagicMock(spec=git.Repo)
mock_config_writer = MagicMock()
mock_config_writer.__enter__ = MagicMock(side_effect=PermissionError("Permission denied"))
mock_repo.config_writer.return_value = mock_config_writer

# Create a test working directory to return
test_dir = str(Path(self.tempdir.name).resolve())
mock_repo.working_tree_dir = test_dir

# Mock git.Repo to return our mock
with patch('git.Repo', return_value=mock_repo):
result = setup_git(test_dir, io)

# Verify setup_git completes and returns working directory despite error
self.assertEqual(result, test_dir)

# Verify warning was shown
warnings = [call[0][0] for call in io.tool_warning.call_args_list]
self.assertTrue(any("Could not write to git config" in warning for warning in warnings))