Skip to content

Commit 52d953e

Browse files
authored
Merge pull request #1 from inem/copilot/fix-31f81c49-913a-4f66-8306-4773c2fb150a
Enhance commit message generation with intention-revealing prompts and quality controls
2 parents 113d07a + 46afb3f commit 52d953e

File tree

3 files changed

+57
-14
lines changed

3 files changed

+57
-14
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ module dot-commit
22

33
go 1.24.3
44

5-
require github.com/sashabaranov/go-openai v1.40.3 // indirect
5+
require github.com/sashabaranov/go-openai v1.40.3

main.go

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ func main() {
100100
// 2. For "." - full diff mode
101101
logDebug(logFile, "using full diff mode")
102102

103-
// Exclude static files from diff
104103
excludeArgs := []string{"diff", "--cached", "--binary"}
105104
for _, ext := range staticExt {
106105
excludeArgs = append(excludeArgs, fmt.Sprintf(":(exclude)*.%s", ext))
@@ -113,7 +112,6 @@ func main() {
113112
return
114113
}
115114

116-
// Get static files list
117115
staticCmd := exec.Command("git", "diff", "--cached", "--name-only")
118116
staticOutput, err := staticCmd.Output()
119117
if err != nil {
@@ -123,8 +121,7 @@ func main() {
123121

124122
body = string(diffOutput) + "\nSTATIC FILES CHANGED:\n" + string(staticOutput)
125123

126-
// Trim to 8KB
127-
if len(body) > 8000 {
124+
if len(body) > 8000 { // Trim to 8KB
128125
body = body[:8000]
129126
}
130127
}
@@ -140,9 +137,50 @@ func main() {
140137

141138
var prompt string
142139
if text == ".." {
143-
prompt = fmt.Sprintf("Generate a short (≤70 chars) git commit message based on file list.\nIf only static files changed (css/html/images) - note this.\n%s", body)
140+
prompt = fmt.Sprintf(`You are a senior software engineer crafting high–quality, intention‑revealing Git commit titles.
141+
142+
TASK:
143+
Infer the underlying intent / purpose of the staged changes from ONLY the file list below and output ONE concise commit title (<=70 chars).
144+
145+
GUIDELINES:
146+
- Focus on WHY / intent, not a mechanical list of filenames.
147+
- Use imperative mood (Add, Fix, Refactor, Improve, Optimize, Remove, Adjust, Document, Configure, Harden).
148+
- Infer probable category: feature, fix, refactor, perf, tests, docs, build, chore, style.
149+
- Avoid bland "update" unless nothing else fits.
150+
- Do NOT include quotes, punctuation at end, or code fences.
151+
- Do NOT just say "update X file" unless that is genuinely all.
152+
- If only static/front-end assets (css/html/images) changed: summarize purpose (e.g. "Refine layout spacing", "Update hero images", "Adjust responsive styles").
153+
- If mostly tests added: "Add tests for ..." (or similar).
154+
- If looks like a rename/move: "Rename X to Y" (if clear).
155+
- Prefer describing effect (e.g. "Fix panic on empty config", "Improve cache invalidation logic").
156+
- No trailing period. Single line only.
157+
158+
FILE CHANGES:
159+
%s
160+
161+
Commit message:`, body)
144162
} else {
145-
prompt = fmt.Sprintf("Write a git commit message (max 70 chars) describing these code changes:\n%s\n\nMessage:", body)
163+
prompt = fmt.Sprintf(`You are a senior software engineer writing a single Git commit title.
164+
165+
TASK:
166+
Analyze the following staged diff (and a list of static files at the end) and produce ONE concise, intention‑revealing commit message line (<=70 chars) capturing the primary purpose (WHY) of the change set.
167+
168+
DIFF & CONTEXT:
169+
%s
170+
171+
INSTRUCTIONS:
172+
1. Derive the intent (feature addition, bug fix, refactor, performance improvement, reliability, error handling, security, configuration, cleanup, tests, docs).
173+
2. Prefer the most meaningful unifying theme over listing multiple trivial edits.
174+
3. Use imperative mood (Add, Fix, Refactor, Improve, Optimize, Remove, Harden, Document).
175+
4. Avoid generic "update", "change", "misc", "adjust" if a more specific verb fits.
176+
5. Do not list filenames unless a rename/move is itself the core change.
177+
6. If mainly cleanup (whitespace / formatting): "Format code" or "Apply go fmt" (whichever fits).
178+
7. If adding error handling / validation: describe the protected aspect ("Handle nil X", "Validate Y before Z").
179+
8. If improving performance: state what was optimized ("Optimize query building", etc.).
180+
9. If only static asset/style changes: summarize design intent (e.g. "Refine button spacing", "Update hero images").
181+
10. No trailing period, no quotes, no code fences. Output ONLY the commit title.
182+
183+
Commit message:`, body)
146184
}
147185

148186
logDebug(logFile, "sending request to OpenAI...")
@@ -151,13 +189,11 @@ func main() {
151189
context.Background(),
152190
openai.ChatCompletionRequest{
153191
Model: openai.GPT4oMini,
154-
Messages: []openai.ChatCompletionMessage{
155-
{
156-
Role: openai.ChatMessageRoleUser,
157-
Content: prompt,
158-
},
159-
},
160-
MaxTokens: 20,
192+
Messages: []openai.ChatCompletionMessage{{
193+
Role: openai.ChatMessageRoleUser,
194+
Content: prompt,
195+
}},
196+
MaxTokens: 40,
161197
Temperature: 0.3,
162198
},
163199
)
@@ -173,6 +209,13 @@ func main() {
173209
}
174210

175211
newMsg := strings.TrimSpace(resp.Choices[0].Message.Content)
212+
// Safety: ensure single line & <= 70 chars
213+
if idx := strings.IndexAny(newMsg, "\r\n"); idx >= 0 {
214+
newMsg = strings.TrimSpace(newMsg[:idx])
215+
}
216+
if len(newMsg) > 70 {
217+
newMsg = strings.TrimSpace(newMsg[:70])
218+
}
176219
logDebug(logFile, fmt.Sprintf("got response: '%s'", newMsg))
177220

178221
if newMsg != "" {

release/dot-commit

508 KB
Binary file not shown.

0 commit comments

Comments
 (0)