Skip to content

Commit 3e51d31

Browse files
Merge pull request #111 from Undertone0809/v1.3.1/optimize-prompt
refactor: improve generate_commit_message function and add feedback h…
2 parents 337929b + d22777d commit 3e51d31

File tree

5 files changed

+1478
-1084
lines changed

5 files changed

+1478
-1084
lines changed

gcop/__main__.py

Lines changed: 101 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import subprocess
33
from enum import Enum
44
from pathlib import Path
5-
from typing import List, Literal, Optional
5+
from typing import Callable, Dict, List, Literal, Optional
66

77
import click
88
import pne
@@ -26,19 +26,13 @@
2626
console = Console()
2727

2828

29-
class Color(str, Enum):
30-
white = "white"
31-
red = "red"
32-
cyan = "cyan"
33-
magenta = "magenta"
34-
yellow = "yellow"
35-
green = "green"
36-
37-
3829
class LLMResponse(BaseModel):
39-
content: List[str] = Field(
30+
thought: str = Field(
31+
..., description="the reasoning of why output these commit messages"
32+
) # noqa
33+
content: str = Field(
4034
...,
41-
description="three of alternative git commit messages, eg: feat: Add type annotation to generate_commit_message function", # noqa
35+
description="git commit messages based on guidelines", # noqa
4236
)
4337

4438

@@ -70,22 +64,76 @@ def generate_commit_message(diff: str, feedback: Optional[str] = None) -> List[s
7064
Returns:
7165
str: git commit message
7266
"""
73-
prompt = f"""You need to generate a git commit message based on the following diff:
74-
## Good git messages examples
75-
- feat: Add type annotation to generate_commit_message function
76-
- fix: Fix bug in generate_commit_message function
77-
- docs: Update README.md
78-
- feat: first commit
79-
- style: Format code using black
80-
- refactor: Refactor generate_commit_message function
81-
- ci: Add GitHub Actions workflow for Python package release
82-
- build: Update setup.py and add tests folder
83-
67+
prompt = f"""
68+
# Git Commit Message Generator
69+
You are a professional software developer tasked with generating standardized git commit messages based on given git diff content. Your job is to analyze the diff, understand the changes made, and produce a concise, informative commit message following the Conventional Commits specification.
70+
71+
## Input
72+
You will receive a git diff output showing the differences between the current working directory and the last commit.
73+
74+
## Guidelines
75+
Generate a conventional git commit message adhering to the following format and guidelines:
76+
77+
1. Start with a type prefix, followed by a colon and space. Common types include:
78+
- feat: A new feature
79+
- fix: A bug fix
80+
- docs: Documentation only changes
81+
- style: Changes that do not affect the meaning of the code
82+
- refactor: A code change that neither fixes a bug nor adds a feature
83+
- perf: A code change that improves performance
84+
- test: Adding missing tests or correcting existing tests
85+
- chore: Changes to the build process or auxiliary tools and libraries
86+
2. After the type, provide a short, imperative summary of the change (not capitalized, no period at the end).
87+
3. The entire first line (type + summary) should be no more than 50 characters.
88+
4. After the first line, leave one blank line.
89+
5. The body of the commit message should provide detailed explanations of the changes, wrapped at 72 characters.
90+
6. Use markdown lists to organize multiple points if necessary.
91+
7. Include any of the following information when applicable:
92+
- Motivation for the change
93+
- Contrast with previous behavior
94+
- Side effects or other unintuitive consequences of the change
95+
96+
## Analysis Steps
97+
1. Carefully read the git diff output, identifying changed files and specific code modifications.
98+
2. Determine the primary purpose of the changes (e.g., adding a feature, fixing a bug, refactoring code, updating dependencies).
99+
3. Analyze the scope and impact of the changes, determining if they affect multiple components or functionalities.
100+
4. Consider how these changes impact the overall project or system functionality and performance.
101+
102+
## Notes
103+
- Maintain a professional and objective tone, avoiding emotional or unnecessary descriptions.
104+
- Ensure the commit message clearly communicates the purpose and impact of the changes.
105+
- If the diff contains multiple unrelated changes, suggest splitting them into separate commits.
106+
107+
## Examples
108+
- Good Example
109+
110+
```
111+
feat: implement user registration
112+
113+
- Add registration form component
114+
- Create API endpoint for user creation
115+
- Implement email verification process
116+
117+
This feature allows new users to create accounts and verifies
118+
their email addresses before activation. It includes proper
119+
input validation and error handling.
120+
```
121+
reason: contain relevant detail of the changes, no just one line
122+
123+
- Bad Example
124+
125+
```
126+
feat: add user registration
127+
```
128+
reason: only one line, need more detail based on guidelines
129+
130+
Please generate a conventional commit message based on the provided git diff, following the above guidelines.
131+
132+
## Provided Git Diff
84133
\n{diff}
85134
""" # noqa
86135

87-
if not feedback:
88-
# TODO optimize feedback logic
136+
if feedback is not None:
89137
prompt += f"""
90138
This is original git commit message, it's not good enough, please reflect the
91139
feedback and generate the better git messages.
@@ -99,9 +147,11 @@ def generate_commit_message(diff: str, feedback: Optional[str] = None) -> List[s
99147
model_config={
100148
"api_key": model_config.api_key,
101149
"api_base": model_config.api_base,
150+
"temperature": 0.0,
102151
},
103152
output_schema=LLMResponse,
104153
)
154+
console.print(f"[green][Thought] {response.thought}[/]")
105155
return response.content
106156

107157

@@ -181,30 +231,42 @@ def init_command():
181231
@app.command(name="commit")
182232
def commit_command(feedback: Optional[str] = None):
183233
"""Generate a git commit message based on the staged changes and commit the
184-
changes."""
185-
diff: str = get_git_diff("--staged")
234+
changes.
186235
236+
If you want to commit the changes with the generated commit message, please
237+
select "yes". If you want to retry the commit message generation, please
238+
select "retry". If you want to retry the commit message generation with new
239+
feedback, please select "retry by feedback". If you want to exit the commit
240+
process, please select "exit".
241+
"""
242+
diff: str = get_git_diff("--staged")
187243
if not diff:
188244
console.print("[yellow]No staged changes[/]")
189245
return
190246

191-
console.print(f"[yellow]Staged: {diff}[/]")
247+
console.print(f"[yellow][Code diff] \n{diff}[/]")
192248

193-
commit_messages: List[str] = generate_commit_message(diff, feedback)
249+
commit_messages: str = generate_commit_message(diff, feedback)
250+
console.print(f"[green][Generated commit message]\n{commit_messages}[/]")
194251

195252
response = questionary.select(
196-
"Select a commit message to commit", choices=[*commit_messages, "retry"]
253+
"Do you want to commit the changes with this message?",
254+
choices=["yes", "retry", "retry by feedback", "exit"],
197255
).ask()
198256

199-
if response == "retry":
200-
commit_command(feedback=str(commit_messages))
201-
return
202-
203-
if response:
204-
console.print(f"[green]Command: git commit -m '{response}'[/]")
205-
subprocess.run(["git", "commit", "-m", f"{response}"])
206-
else:
207-
console.print("[red]Canceled[/]")
257+
if response == "yes":
258+
console.print(f"[green]Committing with message: {commit_messages}[/]")
259+
subprocess.run(["git", "commit", "-m", commit_messages])
260+
elif response == "retry":
261+
commit_command(feedback=None)
262+
elif response == "retry by feedback":
263+
new_feedback = questionary.text("Please enter your feedback:").ask()
264+
if new_feedback:
265+
commit_command(feedback=new_feedback)
266+
else:
267+
console.print("[yellow]No feedback provided. Exiting...[/]")
268+
else: # exit
269+
console.print("[yellow]Exiting commit process.[/]")
208270

209271
# # request pypi to get the latest version
210272
# # TODO optimize logic, everyday check the latest version one time

gcop/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ class ModelConfig:
1212
model_name: str
1313
api_key: str
1414
api_base: Optional[str] = None
15+
include_git_history: bool = False # 是否将过去的 git commit 信息作为参考的一部分
16+
enable_data_improvement: bool = False # 是否愿意将数据用于改进 gcop 模型
1517

1618

1719
class GcopConfig(metaclass=Singleton):

0 commit comments

Comments
 (0)