feat: new command scommit - staged commit

This commit is contained in:
easyrider 2025-01-03 14:30:57 +01:00
parent 03a9a94c83
commit 80d18171d4
2 changed files with 99 additions and 0 deletions

View file

@ -291,6 +291,34 @@ class Commands:
commit_message = args.strip() if args else None
self.coder.repo.commit(message=commit_message)
def cmd_scommit(self, args=None):
"Commit edits to the repo made outside the chat (commit message optional)"
try:
self.raw_cmd_scommit(args)
except ANY_GIT_ERROR as err:
self.io.tool_error(f"Unable to complete commit: {err}")
def raw_cmd_scommit(self, args=None):
if not self.coder.repo:
self.io.tool_error("No git repository found.")
return
commit_message = args.strip() if args else None
# Show the diff of the staged changes
self.io.tool_output("Staged changes diff:")
diff = self.coder.repo.repo.git.diff("--cached") # Access git attribute of self.repo.repo
self.io.print(diff)
# Check if the repository is dirty (optional warning)
if self.coder.repo.is_dirty():
self.io.tool_warning("The repository has uncommitted changes in the working tree. Proceeding with the commit of staged changes.")
# staged ONLY:
self.coder.repo.repo.git.commit("-m", commit_message or "Staged changes commit") # test1.txt should be clean after commit
self.io.tool_output("Staged changes committed successfully.")
def cmd_lint(self, args="", fnames=None):
"Lint and fix in-chat files or all dirty files if none in chat"

View file

@ -491,6 +491,77 @@ class TestCommands(TestCase):
commands.cmd_commit(commit_message)
self.assertFalse(repo.is_dirty())
def test_cmd_scommit(self):
with GitTemporaryDirectory() as repo_dir:
repo = git.Repo()
fname1 = "ignoreme1.txt"
fname2 = "ignoreme2.txt"
fname3 = "file3.txt"
file_path = Path(repo_dir) / fname3
file_path.write_text("Initial content\n")
Path(fname2).touch()
repo.git.add(str(fname2))
repo.git.commit("-m", "initial")
repo.git.add(fname3)
aignore = Path(".aiderignore")
aignore.write_text(f"{fname1}\n{fname2}\ndir\n")
io = InputOutput(yes=True)
fnames = [fname1, fname2]
repo = GitRepo(
io,
fnames,
None,
aider_ignore_file=str(aignore),
)
coder = Coder.create(
self.GPT35,
None,
io,
fnames=fnames,
repo=repo,
)
commands = Commands(io, coder)
commands.cmd_scommit("")
self.assertFalse(coder.repo.is_dirty(path=fname3))
def test_cmd_scommit_mock(self):
with GitTemporaryDirectory() as repo_dir:
io = InputOutput(pretty=False, fancy_input=False, yes=True)
coder = Coder.create(self.GPT35, None, io)
commands = Commands(io, coder)
# Create and stage file
(Path(repo_dir) / "test1.txt").write_text("Initial content 1")
# Add and commit files using the git command
coder.repo.repo.git.add("test1.txt")
coder.repo.repo.git.commit("-m", "Initial commit")
# Modify files to make the repository dirty
(Path(repo_dir) / "test1.txt").write_text("Modified content 1")
# Stage one of the modified files
coder.repo.repo.git.add("test1.txt")
self.assertTrue(coder.repo.repo.is_dirty(path="test1.txt"))
# Mock the commit method on the Repo object
with mock.patch.object(coder.repo.repo, 'git', create=True) as mock_git:
mock_git.commit.return_value = None
# Run cmd_scommit
commands.cmd_scommit("")
# Check if the commit method was called with the correct message
mock_git.commit.assert_called_once_with("-m", "Staged changes commit")
def test_cmd_add_from_outside_root(self):
with ChdirTemporaryDirectory() as tmp_dname:
root = Path("root")