Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 4 additions & 24 deletions codemcp/git_message.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#!/usr/bin/env python3

import logging
import subprocess

from .git_parse_message import parse_message

Expand All @@ -23,29 +22,10 @@ def append_metadata_to_message(message: str, metadata: dict[str, str]) -> str:
Returns:
The updated commit message with trailers added
"""
# Ensure there's a blank line before trailers if the message doesn't end with one
processed_message = message
if message and not message.endswith("\n\n"):
if message.endswith("\n"):
processed_message = message + "\n"
else:
processed_message = message + "\n\n"

result = subprocess.check_output(
[
"git",
"interpret-trailers",
*[f"--trailer={k}: {v}" for k, v in metadata.items()],
],
input=processed_message.encode("utf-8"),
).decode("utf-8")

# git interpret-trailers adds a trailing newline that we need to handle properly
# Remove one trailing newline if there are multiple
if result.endswith("\n\n"):
result = result[:-1]

return result
from .git_parse_message import interpret_trailers

trailers_to_add = [f"{k}: {v}" for k, v in metadata.items()]
return interpret_trailers(message, trailers_to_add)


def update_commit_message_with_description(
Expand Down
62 changes: 62 additions & 0 deletions codemcp/git_parse_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,65 @@ def is_trailer_block(lines: List[str]) -> bool:
return (trailer_lines > 0 and non_trailer_lines == 0) or (
has_git_generated_trailer and trailer_lines * 3 >= non_trailer_lines
)


def interpret_trailers(message: str, trailers_to_add: List[str]) -> str:
"""
Add trailers to a commit message, mimicking git interpret-trailers.

Args:
message: The commit message to add trailers to
trailers_to_add: List of trailers to add in the format "Key: Value"

Returns:
The commit message with trailers added
"""
subject, body, existing_trailers = parse_message(message)

# Create a new list with all trailers (existing + new)
all_trailers = []
if existing_trailers:
all_trailers.append(existing_trailers)

all_trailers.extend(trailers_to_add)

# Build the new message
new_message = subject

if body:
new_message += "\n\n" + body

if all_trailers:
# Handle empty message case specially
if not message:
new_message += "\n" + "\n".join(all_trailers) + "\n"
else:
# Add proper spacing before trailers for non-empty messages
if body:
new_message += "\n"
elif not body and existing_trailers:
new_message += "\n"
elif not body and not existing_trailers:
new_message += "\n"

new_message += "\n" + "\n".join(all_trailers)

# Handle trailing newlines carefully based on original message
if message and all_trailers:
# Count trailing newlines in original message
original_trailing_newlines = 0
for i in range(len(message) - 1, -1, -1):
if message[i] == "\n":
original_trailing_newlines += 1
else:
break

# Only preserve trailing newlines if the original had some AND we added trailers
# This handles the specific test cases with trailing newlines
if original_trailing_newlines > 0:
new_message += "\n" * original_trailing_newlines
elif original_trailing_newlines == 0:
# For normal messages without trailing newlines, add a single trailing newline
new_message += "\n"

return new_message