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
5 changes: 4 additions & 1 deletion aider/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,10 @@ def path_in_repo(self, path):
return

tracked_files = set(self.get_tracked_files())
normalized = self.normalize_path(path)
try:
normalized = self.normalize_path(path)
except ValueError:
return False
return normalized in tracked_files

def abs_root_path(self, path):
Expand Down
42 changes: 42 additions & 0 deletions tests/basic/test_issue_5620_add_route.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""Regression for Aider-AI/aider#5620, second entry route (/read-only + /add).

An image outside the repo is allowed as read-only from anywhere. Promoting it
with /add reaches GitRepo.path_in_repo() with an out-of-root absolute path,
which must answer "not tracked" rather than raise ValueError.
"""

import os
import tempfile
from pathlib import Path
from unittest import TestCase

from aider.coders import Coder
from aider.commands import Commands
from aider.io import InputOutput
from aider.models import Model
from aider.utils import GitTemporaryDirectory


class TestIssue5620AddRoute(TestCase):
def test_add_promotes_outside_readonly_image_without_crash(self):
with tempfile.TemporaryDirectory() as outside_dir:
outside_image = Path(outside_dir) / "outside.png"
outside_image.write_bytes(b"not really a png")
with GitTemporaryDirectory():
io = InputOutput(pretty=False, fancy_input=False, yes=True)
coder = Coder.create(Model("gpt-4o"), None, io)
commands = Commands(io, coder)

commands.cmd_read_only(str(outside_image))
self.assertEqual(len(coder.abs_read_only_fnames), 1)

# Must not raise; the file is not part of the repository.
commands.cmd_add(str(outside_image))

self.assertEqual(len(coder.abs_fnames), 0)
self.assertTrue(
any(
os.path.samefile(str(outside_image), fname)
for fname in coder.abs_read_only_fnames
)
)
8 changes: 8 additions & 0 deletions tests/basic/test_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,14 @@ def test_get_tracked_files_from_subdir(self):
fnames = git_repo.get_tracked_files()
self.assertIn(str(fname), fnames)

def test_path_outside_repo_is_not_tracked(self):
with GitTemporaryDirectory():
outside_path = Path.cwd().parent / "outside.txt"
git_repo = GitRepo(InputOutput(), None, None)

self.assertFalse(git_repo.path_in_repo(outside_path))
self.assertTrue(git_repo.is_dirty(outside_path))

def test_subtree_only(self):
with GitTemporaryDirectory():
# Create a new repo
Expand Down