From ae8d04a95f55cea28db098a93b83b8b3c7450d14 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 18 Aug 2023 13:20:27 -0700 Subject: [PATCH] Handle diff of file not yet part of repo --- HISTORY.md | 2 +- aider/coders/base_coder.py | 3 ++- aider/repo.py | 10 ++++++-- tests/test_coder.py | 47 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 8f8750dc8..59f727c4d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,7 +2,7 @@ ### main branch -- [Only git commit dirty files that GPT tries to edit](https://aider.chat/docs/faq.html#how-does-aider-use-git) +- [Only git commit dirty files that GPT tries to edit](https://github.com/paul-gauthier/aider/issues/200#issuecomment-1682750798) - Send chat history as prompt/context for Whisper voice transcription - Added `--voice-language` switch to constrain `/voice` to transcribe to a specific language diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 06c1a518e..a2ccde829 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -721,7 +721,6 @@ class Coder: self.io.tool_output(f"Committing {path} before applying edits.") self.need_commit_before_edits.add(path) - return def allowed_to_edit(self, path): full_path = self.abs_root_path(path) @@ -763,6 +762,7 @@ class Coder: self.abs_fnames.add(full_path) self.check_for_dirty_commit(path) + return True apply_update_errors = 0 @@ -891,6 +891,7 @@ class Coder: return if not self.repo: return + self.repo.commit(fnames=self.need_commit_before_edits) # files changed, move cur messages back behind the files messages diff --git a/aider/repo.py b/aider/repo.py index 92cfb1cb2..6b0c0b089 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -135,14 +135,20 @@ class GitRepo: if not fnames: fnames = [] + diffs = "" + for fname in fnames: + if not self.path_in_repo(fname): + diffs += f"Added {fname}\n" + if current_branch_has_commits: args = ["HEAD", "--"] + list(fnames) - return self.repo.git.diff(*args) + diffs += self.repo.git.diff(*args) + return diffs wd_args = ["--"] + list(fnames) index_args = ["--cached"] + wd_args - diffs = self.repo.git.diff(*index_args) + diffs += self.repo.git.diff(*index_args) diffs += self.repo.git.diff(*wd_args) return diffs diff --git a/tests/test_coder.py b/tests/test_coder.py index 3faf42bc7..f0592ea94 100644 --- a/tests/test_coder.py +++ b/tests/test_coder.py @@ -548,6 +548,53 @@ three self.assertEqual(len(saved_diffs), 2) + def test_gpt_edit_to_existing_file_not_in_repo(self): + with GitTemporaryDirectory(): + repo = git.Repo() + + fname = Path("file.txt") + fname.write_text("one\n") + + fname2 = Path("other.txt") + fname2.write_text("other\n") + repo.git.add(str(fname2)) + + repo.git.commit("-m", "initial") + + io = InputOutput(yes=True) + coder = Coder.create(models.GPT4, "diff", io=io, fnames=[str(fname)]) + + def mock_send(*args, **kwargs): + coder.partial_response_content = f""" +Do this: + +{str(fname)} +<<<<<<< HEAD +one +======= +two +>>>>>>> updated + +""" + coder.partial_response_function_call = dict() + + saved_diffs = [] + + def mock_get_commit_message(diffs, context): + saved_diffs.append(diffs) + return "commit message" + + coder.repo.get_commit_message = MagicMock(side_effect=mock_get_commit_message) + coder.send = MagicMock(side_effect=mock_send) + + coder.run(with_message="hi") + + content = fname.read_text() + self.assertEqual(content, "two\n") + + diff = saved_diffs[0] + self.assertIn("file.txt", diff) + if __name__ == "__main__": unittest.main()