From 389bf9310cf7065cbb9a4b92cfc6d8d106de92f5 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Fri, 18 Aug 2023 07:05:48 -0700 Subject: [PATCH] commit just the edited files, treat named files outside git as dirty --- aider/coders/base_coder.py | 31 ++++++++++++++++--------------- aider/repo.py | 28 +++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 9095c1179..e8771118e 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -479,7 +479,7 @@ class Coder: if edited: if self.repo and self.auto_commits and not self.dry_run: - saved_message = self.auto_commit() + saved_message = self.auto_commit(fnames=edited) elif hasattr(self.gpt_prompts, "files_content_gpt_edits_no_repo"): saved_message = self.gpt_prompts.files_content_gpt_edits_no_repo else: @@ -709,27 +709,28 @@ class Coder: def check_for_dirty_commit(self, path): if not self.repo: - return True + return if not self.dirty_commits: - return True + return if not self.repo.is_dirty(path): - return True + return + + fullp = self.repo.full_path(path) + if not fullp.stat().st_size: + return self.io.tool_output(f"Committing {path} before applying edits.") self.repo.repo.git.add(path) self.need_commit_before_edits = True - return True + return def allowed_to_edit(self, path): full_path = self.abs_root_path(path) - if self.repo: - tracked_files = set(self.repo.get_tracked_files()) - is_in_repo = path in tracked_files + is_in_repo = self.repo.path_in_repo(path) if full_path in self.abs_fnames: - if self.check_for_dirty_commit(path): - return full_path - return + self.check_for_dirty_commit(path) + return full_path if not Path(full_path).exists(): if not self.io.confirm_ask(f"Allow creation of new file {path}?"): @@ -756,8 +757,8 @@ class Coder: self.repo.repo.git.add(full_path) self.abs_fnames.add(full_path) - if self.check_for_dirty_commit(path): - return full_path + self.check_for_dirty_commit(path) + return full_path apply_update_errors = 0 @@ -864,9 +865,9 @@ class Coder: context += "\n" + msg["role"].upper() + ": " + msg["content"] + "\n" return context - def auto_commit(self): + def auto_commit(self, edited): context = self.get_context_from_history(self.cur_messages) - res = self.repo.commit(context=context, prefix="aider: ") + res = self.repo.commit(fnames=edited, context=context, prefix="aider: ") if res: commit_hash, commit_message = res self.last_aider_commit_hash = commit_hash diff --git a/aider/repo.py b/aider/repo.py index deb14fa51..ed25f462f 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -49,8 +49,8 @@ class GitRepo: self.repo = git.Repo(repo_paths.pop(), odbt=git.GitDB) self.root = utils.safe_abs_path(self.repo.working_tree_dir) - def commit(self, context=None, prefix=None, message=None): - if not self.repo.is_dirty(): + def commit(self, fnames=None, context=None, prefix=None, message=None): + if not fnames and not self.repo.is_dirty(): return if message: @@ -69,7 +69,16 @@ class GitRepo: if context: full_commit_message += "\n\n# Aider chat conversation:\n\n" + context - self.repo.git.commit("-a", "-m", full_commit_message, "--no-verify") + cmd = ["-m", full_commit_message, "--no-verify"] + if fnames: + fnames = [str(self.full_path(fn)) for fn in fnames] + for fname in fnames: + self.repo.git.add(fname) + cmd += ["--"] + fnames + else: + cmd += ["-a"] + + self.repo.git.commit(cmd) commit_hash = self.repo.head.commit.hexsha[:7] self.io.tool_output(f"Commit {commit_hash} {commit_message}") @@ -180,5 +189,18 @@ class GitRepo: return res + def path_in_repo(self, path): + if not self.repo: + return + + tracked_files = set(self.get_tracked_files()) + return path in tracked_files + + def full_path(self, path): + return (Path(self.root) / path).resolve() + def is_dirty(self, path=None): + if path and not self.path_in_repo(path): + return True + return self.repo.is_dirty(path=path)