Comments (8)
I've updated the prompting to use the imperative tense. Thanks for calling that out (again).
Aider doesn't share the entire repo context with the weak model when forming a commit message. So unfortunately there's no way for it to see any conventions file you may be using.
from aider.
Aider now falls back to using the main model if the weak model is unable to produce a commit message. This should pretty much stop the "Failed to generate commit message" errors.
from aider.
These would be the steps needed - as provided by aider - the codeblocks dont render in the correct way. Dunno how to fix it.
Here are the steps we'll take:
- Update the
get_commit_message
method to generate a commit message following the semantic versioning format. - Modify the
commit
method to use the new commit message format.
Let's start with the changes to the get_commit_message
method:
aider/repo.py
diffs = "# Diffs:\n" + diffs
content = ""
if context:
content += context + "\n"
content += diffs
messages = [
dict(role="system", content=prompts.commit_system),
dict(role="user", content=content),
]
for model in self.models:
commit_message = simple_send_with_retries(model.name, messages)
if commit_message:
break
if not commit_message:
self.io.tool_error("Failed to generate commit message!")
return
commit_message = commit_message.strip()
if commit_message and commit_message[0] == '"' and commit_message[-1] == '"':
commit_message = commit_message[1:-1].strip()
return commit_message
=======
def get_commit_message(self, diffs, context):
if len(diffs) >= 4 * 1024 * 4:
self.io.tool_error("Diff is too large to generate a commit message.")
return
diffs = "# Diffs:\n" + diffs
content = """
Generate a commit message following this format:
Title: <type>(<scope>): <subject>
Message:
<body>
<footer>
Type: feat, fix, docs, style, refactor, test, chore
Scope: Affected feature/component (optional)
Subject: Concise change description
Body: Detailed description (if necessary)
Footer: Issue references or breaking changes (optional)
Use the following context and diffs to generate the commit message:
"""
if context:
content += context + "\n"
content += diffs
messages = [
dict(role="system", content=prompts.commit_system),
dict(role="user", content=content),
]
for model in self.models:
commit_message = simple_send_with_retries(model.name, messages)
if commit_message:
break
if not commit_message:
self.io.tool_error("Failed to generate commit message!")
return
commit_message = commit_message.strip()
if commit_message and commit_message[0] == '"' and commit_message[-1] == '"':
commit_message = commit_message[1:-1].strip()
return commit_message
>>>>>>> REPLACE
</source>
Now, let's modify the `commit` method to use the new commit message format:
aider/repo.py
<source>python
<<<<<<< SEARCH
def commit(self, fnames=None, context=None, message=None, aider_edits=False):
if not fnames and not self.repo.is_dirty():
return
diffs = self.get_diffs(fnames)
if not diffs:
return
if message:
commit_message = message
else:
commit_message = self.get_commit_message(diffs, context)
if not commit_message:
commit_message = "(no commit message provided)"
full_commit_message = commit_message
if context:
full_commit_message += "\n\n# Aider chat conversation:\n\n" + context
cmd = ["-m", full_commit_message, "--no-verify"]
if fnames:
fnames = [str(self.abs_root_path(fn)) for fn in fnames]
for fname in fnames:
self.repo.git.add(fname)
cmd += ["--"] + fnames
else:
cmd += ["-a"]
original_user_name = self.repo.config_reader().get_value("user", "name")
original_committer_name_env = os.environ.get("GIT_COMMITTER_NAME")
committer_name = f"{original_user_name} (aider)"
if self.attribute_committer:
os.environ["GIT_COMMITTER_NAME"] = committer_name
if aider_edits and self.attribute_author:
original_auther_name_env = os.environ.get("GIT_AUTHOR_NAME")
os.environ["GIT_AUTHOR_NAME"] = committer_name
self.repo.git.commit(cmd)
commit_hash = self.repo.head.commit.hexsha[:7]
self.io.tool_output(f"Commit {commit_hash} {commit_message}")
# Restore the env
if self.attribute_committer:
if original_committer_name_env is not None:
os.environ["GIT_COMMITTER_NAME"] = original_committer_name_env
else:
del os.environ["GIT_COMMITTER_NAME"]
if aider_edits and self.attribute_author:
if original_auther_name_env is not None:
os.environ["GIT_AUTHOR_NAME"] = original_auther_name_env
else:
del os.environ["GIT_AUTHOR_NAME"]
return commit_hash, commit_message
=======
def commit(self, fnames=None, context=None, message=None, aider_edits=False):
if not fnames and not self.repo.is_dirty():
return
diffs = self.get_diffs(fnames)
if not diffs:
return
if message:
commit_message = message
else:
commit_message = self.get_commit_message(diffs, context)
if not commit_message:
commit_message = "(no commit message provided)"
# Split the commit message into title and body
commit_lines = commit_message.split('\n', 1)
commit_title = commit_lines[0]
commit_body = commit_lines[1] if len(commit_lines) > 1 else ""
full_commit_message = f"{commit_title}\n\n{commit_body}"
if context:
full_commit_message += "\n\n# Aider chat conversation:\n\n" + context
cmd = ["-m", full_commit_message, "--no-verify"]
if fnames:
fnames = [str(self.abs_root_path(fn)) for fn in fnames]
for fname in fnames:
self.repo.git.add(fname)
cmd += ["--"] + fnames
else:
cmd += ["-a"]
original_user_name = self.repo.config_reader().get_value("user", "name")
original_committer_name_env = os.environ.get("GIT_COMMITTER_NAME")
committer_name = f"{original_user_name} (aider)"
if self.attribute_committer:
os.environ["GIT_COMMITTER_NAME"] = committer_name
if aider_edits and self.attribute_author:
original_auther_name_env = os.environ.get("GIT_AUTHOR_NAME")
os.environ["GIT_AUTHOR_NAME"] = committer_name
self.repo.git.commit(cmd)
commit_hash = self.repo.head.commit.hexsha[:7]
self.io.tool_output(f"Commit {commit_hash} {commit_title}")
# Restore the env
if self.attribute_committer:
if original_committer_name_env is not None:
os.environ["GIT_COMMITTER_NAME"] = original_committer_name_env
else:
del os.environ["GIT_COMMITTER_NAME"]
if aider_edits and self.attribute_author:
if original_auther_name_env is not None:
os.environ["GIT_AUTHOR_NAME"] = original_auther_name_env
else:
del os.environ["GIT_AUTHOR_NAME"]
return commit_hash, commit_title
>>>>>>> REPLACE
</source>
These changes will implement semantic versioning for git commits in aider according to the conventions outlined in conventions.md. The `get_commit_message` method now instructs the AI model to generate a commit message following the specified format, and the `commit` method has been updated to handle the new commit message structure.
from aider.
I was going to open a similar issue as well. While trying Aider I noticed it uses past tense for generating commit messages (see #602, no idea why that was closed). I'm used to this being an anti-pattern and imperative present tense being a recommended approach for commit messages.
I think it would be a great feature in general to have the ability to override the commit message prompt, since this is a very subjective topic anyway.
As far as I can see this is currently only possible by changing the code of Aider itself (specifically aider/prompts.py
) – I agree that maybe a quick solution would be to give the users the ability to configure this prompt in the Aider configuration file.
Ref:
https://www.gitkraken.com/learn/git/best-practices/git-commit-message#using-imperative-verb-form
https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project (search for imperative)
https://ec.europa.eu/component-library/v1.15.0/eu/docs/conventions/git/ (search for imperative)
from aider.
See #398 for an open enhancement request for configurable commit prompting.
from aider.
I've updated the prompting to use the imperative tense. Thanks for calling that out (again).
Aider doesn't share the entire repo context with the weak model when forming a commit message. So unfortunately there's no way for it to see any conventions file you may be using.
Why not create the commit message for the weak model automatically at the end for the week model?
That way I wouldn't get the change too large, no commit message. Text
from aider.
I'm going to close this issue for now, but feel free to add a comment here and I will re-open or file a new issue any time.
from aider.
Works for me ATM. would still be cool to get a git commit message more similar how professional software developers should work.
Like this:
Generate a commit message following this format:
Title:
<type>(<scope>): <subject>
Message:
<body>
<footer>
Type: feat, fix, docs, style, refactor, test, chore
Scope: Affected feature/component (optional)
Subject: Concise change description
Body: Detailed description (if necessary)
Footer: Issue references or breaking changes (optional)
Use the following context and diffs to generate the commit message:
as shown here: #933 (comment)
from aider.
Related Issues (20)
- Proposal: Compact code modification format
- Is the repo-map possible for Ollama/Deepseekcoder V2? HOT 2
- Alternative Benchmarks
- Invalid command: /add-clipboard-image HOT 1
- Output limit bug HOT 2
- Reverting to a Previous Commit Point HOT 1
- wrong path resolved
- Clear default for "Add the output to the chat?" HOT 1
- Bug GUI HOT 1
- Add /document <filename> as another quick option
- Adding default git config user.name, user.email is too aggressive
- Claude Prompt Caching! HOT 2
- just upgraded and everything seemed messed up.
- TypeError when adding a .jpg file to the chat HOT 1
- Support for Dart/Flutter?
- If aider is unable to fix lint error, it will loop forever without adding or changing code. HOT 2
- What is the syntax to add multiple lint-cmd for different languages?
- How do I map to local folder structure rather than github?
- Deepseek doesn't want to use search and replace blocks?
- openai compatible apis not workign for nvidia since it has meta/model_name so openai/meta/model_name and openai/model_name both doent work
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from aider.