feat: add co-authored-by commit attribution

This commit is contained in:
Andrew Grigorev (aider) 2025-04-12 16:52:45 +03:00
parent 028257480b
commit 67bb4f9552
3 changed files with 70 additions and 16 deletions

View file

@ -448,6 +448,12 @@ def get_parser(default_config_files, git_root):
default=False,
help="Prefix all commit messages with 'aider: ' (default: False)",
)
group.add_argument(
"--attribute-co-authored-by",
action=argparse.BooleanOptionalAction,
default=False,
help="Attribute aider edits using the Co-authored-by trailer in the commit message (default: False).",
)
group.add_argument(
"--git-commit-verify",
action=argparse.BooleanOptionalAction,

View file

@ -2248,7 +2248,7 @@ class Coder:
context = self.get_context_from_history(self.cur_messages)
try:
res = self.repo.commit(fnames=edited, context=context, aider_edits=True)
res = self.repo.commit(fnames=edited, context=context, aider_edits=True, coder=self)
if res:
self.show_auto_commit_outcome(res)
commit_hash, commit_message = res
@ -2284,7 +2284,7 @@ class Coder:
if not self.repo:
return
self.repo.commit(fnames=self.need_commit_before_edits)
self.repo.commit(fnames=self.need_commit_before_edits, coder=self)
# files changed, move cur messages back behind the files messages
# self.move_back_cur_messages(self.gpt_prompts.files_content_local_edits)

View file

@ -111,7 +111,7 @@ class GitRepo:
if aider_ignore_file:
self.aider_ignore_file = Path(aider_ignore_file)
def commit(self, fnames=None, context=None, message=None, aider_edits=False):
def commit(self, fnames=None, context=None, message=None, aider_edits=False, coder=None):
if not fnames and not self.repo.is_dirty():
return
@ -124,15 +124,52 @@ class GitRepo:
else:
commit_message = self.get_commit_message(diffs, context)
if aider_edits and self.attribute_commit_message_author:
commit_message = "aider: " + commit_message
elif self.attribute_commit_message_committer:
commit_message = "aider: " + commit_message
commit_message_trailer = ""
if aider_edits:
# Use coder.args if available, otherwise default to config/defaults
attribute_author = (
coder.args.attribute_author
if coder and hasattr(coder, "args")
else self.attribute_author
)
attribute_committer = (
coder.args.attribute_committer
if coder and hasattr(coder, "args")
else self.attribute_committer
)
attribute_commit_message_author = (
coder.args.attribute_commit_message_author
if coder and hasattr(coder, "args")
else self.attribute_commit_message_author
)
attribute_commit_message_committer = (
coder.args.attribute_commit_message_committer
if coder and hasattr(coder, "args")
else self.attribute_commit_message_committer
)
attribute_co_authored_by = (
coder.args.attribute_co_authored_by
if coder and hasattr(coder, "args")
else False # Default to False if not found
)
# Add Co-authored-by trailer if configured
if attribute_co_authored_by:
model_name = "unknown-model"
if coder and hasattr(coder, "main_model") and coder.main_model.name:
model_name = coder.main_model.name
commit_message_trailer = (
f"\n\nCo-authored-by: aider ({model_name}) <noreply@aider.dev>"
)
# Prefix commit message if configured
if attribute_commit_message_author or attribute_commit_message_committer:
commit_message = "aider: " + commit_message
if not commit_message:
commit_message = "(no commit message provided)"
full_commit_message = commit_message
full_commit_message = commit_message + commit_message_trailer
# if context:
# full_commit_message += "\n\n# Aider chat conversation:\n\n" + context
@ -152,13 +189,25 @@ class GitRepo:
original_user_name = self.repo.git.config("--get", "user.name")
original_committer_name_env = os.environ.get("GIT_COMMITTER_NAME")
original_author_name_env = os.environ.get("GIT_AUTHOR_NAME")
committer_name = f"{original_user_name} (aider)"
if self.attribute_committer:
# Use coder.args if available, otherwise default to config/defaults
use_attribute_committer = (
coder.args.attribute_committer
if coder and hasattr(coder, "args")
else self.attribute_committer
)
use_attribute_author = (
coder.args.attribute_author
if coder and hasattr(coder, "args")
else self.attribute_author
)
if use_attribute_committer:
os.environ["GIT_COMMITTER_NAME"] = committer_name
if aider_edits and self.attribute_author:
original_author_name_env = os.environ.get("GIT_AUTHOR_NAME")
if aider_edits and use_attribute_author:
os.environ["GIT_AUTHOR_NAME"] = committer_name
try:
@ -170,17 +219,16 @@ class GitRepo:
self.io.tool_error(f"Unable to commit: {err}")
finally:
# Restore the env
if self.attribute_committer:
if use_attribute_committer:
if original_committer_name_env is not None:
os.environ["GIT_COMMITTER_NAME"] = original_committer_name_env
else:
elif "GIT_COMMITTER_NAME" in os.environ:
del os.environ["GIT_COMMITTER_NAME"]
if aider_edits and self.attribute_author:
if aider_edits and use_attribute_author:
if original_author_name_env is not None:
os.environ["GIT_AUTHOR_NAME"] = original_author_name_env
else:
elif "GIT_AUTHOR_NAME" in os.environ:
del os.environ["GIT_AUTHOR_NAME"]
def get_rel_repo_dir(self):