void icon indicating copy to clipboard operation
void copied to clipboard

Added Generate Commit Message button for git

Open steaks opened this issue 7 months ago • 13 comments

#535 Added Generate Commit Message button for git

Summary

This PR adds a generate commit message button at the right of the commit message input box. It's a WIP. Here are the known oustanding TODOs. They are marked by comments in the code that start with "TODO VoidSCM"

Screenshots/Videos

https://github.com/user-attachments/assets/a9457d05-628b-466b-a68e-d44db46de59e

https://github.com/user-attachments/assets/9e5e1301-5326-42dd-ba43-2d203527b037

^ the videos don't capture my cursor properly. But I think they show the gist of the changes.

LLM Prompts

System Message

You are an expert software engineer AI assistant responsible for writing clear and concise Git commit messages that summarize the **purpose** and **intent** of the change. Try to keep your commit messages to one sentence. If necessary, you can use two sentences.

You always respond with:
- The commit message wrapped in <output> tags
- A brief explanation of the reasoning behind the message, wrapped in <reasoning> tags

Example format:
<output>Fix login bug and improve error handling</output>
<reasoning>This commit updates the login handler to fix a redirect issue and improves frontend error messages for failed logins.</reasoning>

Do not include anything else outside of these tags.
Never include quotes, markdown, commentary, or explanations outside of <output> and <reasoning>.

User Message

Based on the following Git changes, write a clear, concise commit message that accurately summarizes the intent of the code changes.

Section 1 - Summary of Changes (git diff --stat):

src/vs/workbench/contrib/void/browser/voidSCM.ts   | 32 +++---------------
 .../contrib/void/common/prompt/prompts.ts          | 38 +++++++++++++++++++++-
 2 files changed, 41 insertions(+), 29 deletions(-)

Section 2 - Sampled File Diffs (Top changed files):

==== src/vs/workbench/contrib/void/common/prompt/prompts.ts ====
diff --git a/src/vs/workbench/contrib/void/common/prompt/prompts.ts b/src/vs/workbench/contrib/void/common/prompt/prompts.ts
index d9d5e5c7..c922d8dd 100644
--- a/src/vs/workbench/contrib/void/common/prompt/prompts.ts
+++ b/src/vs/workbench/contrib/void/common/prompt/prompts.ts
@@ -979 +979 @@ Store Result: After computing fib(n), the result is stored in memo for future re
-export const commitMessage_systemMessage = `
+export const gitCommitMessage_systemMessage = `
@@ -991,0 +992,36 @@ Never include quotes, markdown, commentary, or explanations outside of <output>
+
+
+/**
+ * Create a user message for the LLM to generate a commit message. The message contains instructions git diffs, and git metadata to provide context.
+ *
+ *
+ * @param stat - Summary of Changes (git diff --stat)
+ * @param sampledDiffs - Sampled File Diffs (Top changed files)
+ * @param branch - Current Git Branch
+ * @param log - Last 5 commits (excluding merges)
+ * @returns
+ */
+export const gitCommitMessage_userMessage = (stat: string, sampledDiffs: string, branch: string, log: string) => {
+	const section1 = `Section 1 - Summary of Changes (git diff --stat):`
+	const section2 = `Section 2 - Sampled File Diffs (Top changed files):`
+	const section3 = `Section 3 - Current Git Branch:`
+	const section4 = `Section 4 - Last 5 Commits (excluding merges):`
+	return `
+Based on the following Git changes, write a clear, concise commit message that accurately summarizes the intent of the code changes.
+
+${section1}
+
+${stat}
+
+${section2}
+
+${sampledDiffs}
+
+${section3}
+
+${branch}
+
+${section4}
+
+${log}`.trim()
+}

==== src/vs/workbench/contrib/void/browser/voidSCM.ts ====
diff --git a/src/vs/workbench/contrib/void/browser/voidSCM.ts b/src/vs/workbench/contrib/void/browser/voidSCM.ts
index ed8f6328..4f757fae 100644
--- a/src/vs/workbench/contrib/void/browser/voidSCM.ts
+++ b/src/vs/workbench/contrib/void/browser/voidSCM.ts
@@ -13 +13 @@ import { ModelSelection, OverridesOfModel, ModelSelectionOptions } from '../comm
-import { commitMessage_systemMessage } from '../common/prompt/prompts.js'
+import { gitCommitMessage_systemMessage, gitCommitMessage_userMessage } from '../common/prompt/prompts.js'
@@ -80 +80,2 @@ class GenerateCommitMessageService extends Disposable implements IGenerateCommit
-				const prompt = this.preparePrompt(stat, sampledDiffs, branch, log)
+				const prompt = gitCommitMessage_userMessage(stat, sampledDiffs, branch, log)
+				console.log(prompt)
@@ -159,25 +159,0 @@ class GenerateCommitMessageService extends Disposable implements IGenerateCommit
-	private preparePrompt(stat: string, sampledDiffs: string, branch: string, log: string) {
-		const section1 = `Section 1 - Summary of Changes (git diff --stat):`
-		const section2 = `Section 2 - Sampled File Diffs (Top changed files):`
-		const section3 = `Section 3 - Current Git Branch:`
-		const section4 = `Section 4 - Last 5 Commits (excluding merges):`
-		return `
-Based on the following Git changes, write a clear, concise commit message that accurately summarizes the intent of the code changes.
-
-${section1}
-
-${stat}
-
-${section2}
-
-${sampledDiffs}
-
-${section3}
-
-${branch}
-
-${section4}
-
-${log}`.trim()
-	}
-
@@ -188 +164 @@ ${log}`.trim()
-			systemMessage: commitMessage_systemMessage,
+			systemMessage: gitCommitMessage_systemMessage,

Section 3 - Current Git Branch:

commit-prompt

Section 4 - Last 5 Commits (excluding merges):

189e2074|Improve system message prompt|2025-05-26
f88dba76|Add git branch and log info to prompt|2025-05-26
5e100fcf|Limit commit message length|2025-05-25
3a395512|Handle loading, aborting, debouncing, and errors|2025-05-25
033a23aa|Update service name|2025-05-25

steaks avatar May 12 '25 17:05 steaks

I'm going on a trip from Mon May 12th - Thurs May 22nd. I'll be out of touch for most or all of that time. Feel free to modify, reject, or merge this PR while I'm away!

steaks avatar May 12 '25 18:05 steaks

Wow, great work with this! Just let me know when you're ready to have it reviewed.

andrewpareles avatar May 26 '25 03:05 andrewpareles

@andrewpareles sounds good. I'll make a few touchups. Then it should be ready for review.

steaks avatar May 26 '25 16:05 steaks

@andrewpareles this is ready for review

steaks avatar May 26 '25 22:05 steaks

Great work @steaks! Can you just add the ability to change the LLM model in Settings for SCM (not seeing it?) but great work syncing it to chat! I'm getting "no changes detected" if I stage all my messages - do the messages need to be unstaged, or maybe there's a small issue we need to fix?

andrewpareles avatar May 30 '25 05:05 andrewpareles

Asked sonnet 4 to add this, can you review the latest commit and add it as a Feature in Settings.tsx @steaks? Should be ready after that!

andrewpareles avatar May 30 '25 05:05 andrewpareles

Added, but getting git errors, can you test a bit?

andrewpareles avatar May 30 '25 10:05 andrewpareles

Oh I missed staged changes!

What do you think about sending only staged changes if any exist and falling back to unstaged changes if there are none rather than sending both in the prompt?

steaks avatar May 31 '25 14:05 steaks

I would like to ask for sticking with staged only or add as setting to setup what you prefer. From my point of view unstaged changes means they should be excluded or temporal or not ready yet. So commit message should be build only on changes that are staged and ready for commit.

waiting a lot for this feature live ^^

HesyRa avatar Jun 02 '25 12:06 HesyRa

I implemented this spec: If any staged changes then send staged diffs to LLM. If no staged changes then send unstaged changed to LLM.

@HesyRa I understand where you're coming from. But I think developers will still want a quick & convenient way to generate a commit message before staging changes (that's how I'd use the tool). And I don't think it'll be too confusing.

@andrewpareles I forked on staged vs. unstaged rather than sending both because it seemed like it'd make more predictable commit messages and cause less confusion. This is ready for a re-review.

steaks avatar Jun 05 '25 14:06 steaks

Great job with this, I like this logic.

Now we just need to add the ability for the user to pick an SCM model in Settings.tsx, the same way we do for Apply. (or if that's complicated to add, we can just use the Chat model to do this; I think that makes intuitive sense)

andrewpareles avatar Jun 05 '25 22:06 andrewpareles

Will try and add this quickly; it's very similar logic to Apply's settings so should be simple

andrewpareles avatar Jun 05 '25 23:06 andrewpareles

I'm ready to merge this; @steaks let me know if there's anything else you'd like to add or give me the go ahead!

andrewpareles avatar Jun 05 '25 23:06 andrewpareles

Nice work!

andrewpareles avatar Jun 06 '25 02:06 andrewpareles

Great work!! (just tried). Can we somehow enforce LLM to use commit message convention (https://www.conventionalcommits.org/en/v1.0.0/) ?

HesyRa avatar Jun 06 '25 14:06 HesyRa