Skip to content

Commit e16e402

Browse files
committed
feat: add support for including example commit messages in context
- Introduced a `--examples` flag in the CLI to include recent commit messages as context for commit message generation. - Updated `cmd/commitmsg/main.go`: - Added `flagExamples` to handle the new `--examples` flag. - Integrated logic to fetch the last 3 commit messages using the `internal/git` package. - Passed the fetched examples to the LLM client for enhanced context. - Enhanced `internal/git` package: - Added `GetCommitMessages` function to retrieve recent commit messages from the repository. - Updated `internal/llm` package: - Modified `GenerateCommitMessage` to accept an additional `examples` parameter. - Added logic to include examples in the prompt configuration if provided. - Introduced `createExamplesString` helper function to format examples for the prompt. - Updated `commitmsg.prompt.yml` to include placeholders for example commit messages. - Improved user feedback with additional console messages for better clarity.
1 parent da48cdb commit e16e402

File tree

4 files changed

+55
-4
lines changed

4 files changed

+55
-4
lines changed

cmd/commitmsg/main.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const extensionName = "standup"
1414

1515
var (
1616
flagLanguage string
17+
flagExamples bool
1718
)
1819
var rootCmd = &cobra.Command{
1920
Use: extensionName,
@@ -24,6 +25,7 @@ var rootCmd = &cobra.Command{
2425

2526
func init() {
2627
rootCmd.Flags().StringVarP(&flagLanguage, "language", "l", "english", "Language to generate commit message in")
28+
rootCmd.Flags().BoolVarP(&flagExamples, "examples", "e", false, "Add examples of commit messages to context")
2729
}
2830

2931
func main() {
@@ -38,23 +40,33 @@ func runCommitMsg(_ *cobra.Command, _ []string) error {
3840
if err != nil {
3941
return fmt.Errorf("failed to get staged changes: %w", err)
4042
}
41-
43+
4244
if stagedChanges == "" {
4345
fmt.Println("No staged changes in the repository.")
4446
return nil
4547
}
4648

49+
latestCommitMessages := ""
50+
if flagExamples{
51+
latestCommitMessages, err = git.GetCommitMessages(3)
52+
if err != nil {
53+
return fmt.Errorf("failed to get latest commit messages: %w", err)
54+
}
55+
fmt.Println(" Adding examples of previous commit messages to context")
56+
}
57+
4758
llmClient, err := llm.NewClient()
4859
if err != nil {
4960
return fmt.Errorf("failed to create LLM client: %w", err)
5061
}
5162

52-
commitMsg, err := llmClient.GenerateCommitMessage(stagedChanges, flagLanguage)
63+
fmt.Println(" Language for commit message:", flagLanguage)
64+
commitMsg, err := llmClient.GenerateCommitMessage(stagedChanges, flagLanguage, latestCommitMessages)
5365
if err != nil {
5466
return fmt.Errorf("failed to generate commit message: %w", err)
5567
}
5668

57-
fmt.Println("Generated commit message:")
69+
fmt.Println("💬 Generated commit message:")
5870
fmt.Println(commitMsg)
5971
return nil
6072
}

internal/git/git.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,23 @@ func GetStagedChanges() (string, error) {
2323
return string(output), nil
2424
}
2525

26+
// GetCommitMessages retrieves the last <count> commit messages from the git repository
27+
func GetCommitMessages(count int) (string, error) {
28+
// Check if we are in a git repository
29+
if !isGitRepository() {
30+
return "", fmt.Errorf("current directory is not a git repository")
31+
}
32+
33+
// Execute the command git log -n <count>
34+
cmd := exec.Command("git", "log", "-n", fmt.Sprintf("%d", count))
35+
output, err := cmd.Output()
36+
if err != nil {
37+
return "", fmt.Errorf("error executing git log: %v", err)
38+
}
39+
40+
return string(output), nil
41+
}
42+
2643
// isGitRepository checks if the current directory is a git repository
2744
func isGitRepository() bool {
2845
cmd := exec.Command("git", "rev-parse", "--is-inside-work-tree")

internal/llm/client.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,11 @@ func NewClient() (*Client, error) {
8888
}
8989

9090
// GenerateCommitMessage generates a commit message based on the provided changes summary
91-
func (c *Client) GenerateCommitMessage(changesSummary string, language string) (string, error) {
91+
func (c *Client) GenerateCommitMessage(
92+
changesSummary string,
93+
language string,
94+
examples string,
95+
) (string, error) {
9296
fmt.Print(" Loading prompt configuration... ")
9397
promptConfig, err := loadPromptConfig()
9498
if err != nil {
@@ -111,6 +115,14 @@ func (c *Client) GenerateCommitMessage(changesSummary string, language string) (
111115
content = strings.ReplaceAll(content, "{{changes}}", changesSummary)
112116
content = strings.ReplaceAll(content, "{{language}}", selectedLanguage)
113117

118+
if examples != "" && strings.Contains(content, "{{examples}}") {
119+
// If examples are provided, replace the {{examples}} placeholder
120+
content = strings.ReplaceAll(content, "{{examples}}", createExamplesString(examples))
121+
} else {
122+
// If no examples are provided, remove the {{examples}} placeholder
123+
content = strings.ReplaceAll(content, "{{examples}}", "")
124+
}
125+
114126
messages[i] = Message{
115127
Role: msg.Role,
116128
Content: content,
@@ -188,3 +200,11 @@ func (c *Client) callGitHubModels(request Request) (*Response, error) {
188200

189201
return &response, nil
190202
}
203+
204+
func createExamplesString(examples string) string {
205+
if examples == "" {
206+
return ""
207+
}
208+
209+
return fmt.Sprintf("Here are some examples of good commit messages used previously in project:\n%s", examples)
210+
}

internal/llm/commitmsg.prompt.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ messages:
2626
- Be concise but informative
2727
2828
- Use bullet points for clarity
29+
30+
{{examples}}
2931
- role: user
3032
content: |
3133
Based on the following changes, generate a conventional commit message:

0 commit comments

Comments
 (0)