Skip to content

Commit

Permalink
Add blog post and update samples with GenAI commit message automation.
Browse files Browse the repository at this point in the history
  • Loading branch information
pelikhan committed Sep 19, 2024
1 parent 00f9288 commit c0b1ff9
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
title: "Automate Git Commit Messages with GenAI"
date: 2024-09-19
draft: true
tags: ["genai", "git", "automation", "typescript"]
authors: genaiscript
canonical_url: https://microsoft.github.io/genaiscript/blog/automate-git-commit-messages-with-genai
---

## Simplifying Your Git Workflow with GenAI

Coding can be a lot of fun, but let's be honest, sometimes the administrative parts of the process, like crafting the perfect commit message, can be a bit of a drag. 😓 But what if I told you that you could automate that with GenAI? That's right, with a little bit of setup, GenAI can generate commit messages for you, based on your staged changes. 🎉

The script we're discussing can be found [right here on GitHub](https://github.com/microsoft/genaiscript/blob/main/packages/vscode/genaisrc/gcm.genai.mts), and it's called `git commit message`. Its purpose is to help you swiftly create commit messages without the mental overhead of crafting them manually every single time.

Let's break down this script, shall we?

### The Script Explained

First off, we define the `script` function, which sets up our GenAI script by providing a title and a description, and specifying the model we'll be using:

```ts
script({
title: "git commit message",
description: "Generate a commit message for all staged changes",
model: "openai:gpt-4o",
})
```

Next up, we check for any staged changes in your Git repository using `git diff --cached`. If there's nothing staged, GenAI kindly offers to stage all changes for you:

```ts
let diff = await host.exec("git diff --cached")
if (!diff.stdout) {
const stage = await host.confirm("No staged changes. Stage all changes?", {
default: true,
})
if (stage) {
await host.exec("git add .")
diff = await host.exec("git diff --cached -- . :!**/genaiscript.d.ts")
}
if (!diff.stdout) cancel("no staged changes")
}
```

We then log the diff to the console so you can review what changes are about to be committed:

```ts
console.log(diff.stdout)
```

Here comes the interesting part. We enter a loop where GenAI will generate a commit message for you based on the diff. If you're not satisfied with the message, you can choose to edit it, accept it, or regenerate it:

```ts
let choice
let message
do {
const res = await runPrompt(
(_) => {
_.def("GIT_DIFF", diff, { maxTokens: 20000 })
_.$`GIT_DIFF is a diff of all staged changes, coming from the command:
\`\`\`
git diff --cached
\`\`\`
Please generate a concise, one-line commit message for these changes.
- do NOT add quotes
`
},
{ cache: false, temperature: 0.8 }
)
// ... handle response and user choices
} while (choice !== "commit")
```

If you choose to commit, GenAI runs the `git commit` command with your message, and if you're feeling super confident, it can even push the changes to your repository right after:

```ts
if (choice === "commit" && message) {
console.log(
(await host.exec("git", ["commit", "-m", message, "-n"])).stdout
)
if (await host.confirm("Push changes?", { default: true }))
console.log((await host.exec("git push")).stdout)
}
```

### Running the Script with GenAIScript CLI

Getting this script up and running is a cinch. If you've already installed the [GenAIScript CLI](https://microsoft.github.io/genaiscript/getting-started/installation), you can simply run it with:

```shell
genaiscript run gcm
```

Remember, you'll need to have your changes staged in Git for the script to work its magic. 🧙

So there you have it, a complete breakdown of a script that might just become your new best friend in the Git world. Give it a try and say goodbye to commit message woes! 👋
91 changes: 89 additions & 2 deletions docs/src/content/docs/reference/vscode/samples/gcm.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,96 @@ title: Git Commit Message
description: Generate a commit message for all staged changes
---

import { Code } from '@astrojs/starlight/components';
import { Code } from "@astrojs/starlight/components"
import source from "../../../../../../../packages/vscode/genaisrc/gcm.genai.mts?raw"

## gcm
The `gcm` script provides a guided flow to create commit with generated messages.

## Configuration

First off, we define the `script` function, which sets up our GenAI script by providing a title and a description, and specifying the model we'll be using:

```ts
script({
title: "git commit message",
description: "Generate a commit message for all staged changes",
model: "openai:gpt-4o",
})
```

## Look for changes

Next up, we check for any staged changes in your Git repository using `git diff --cached`. If there's nothing staged, GenAI kindly offers to stage all changes for you:

```ts
let diff = await host.exec("git diff --cached")
if (!diff.stdout) {
const stage = await host.confirm("No staged changes. Stage all changes?", {
default: true,
})
if (stage) {
await host.exec("git add .")
diff = await host.exec("git diff --cached -- . :!**/genaiscript.d.ts")
}
if (!diff.stdout) cancel("no staged changes")
}
```

We then log the diff to the console so you can review what changes are about to be committed:

```ts
console.log(diff.stdout)
```

## Generate and refine commit message

Here comes the interesting part. We enter a loop where GenAI will generate a commit message for you based on the diff. If you're not satisfied with the message, you can choose to edit it, accept it, or regenerate it:

```ts
let choice
let message
do {
const res = await runPrompt(
(_) => {
_.def("GIT_DIFF", diff, { maxTokens: 20000 })
_.$`GIT_DIFF is a diff of all staged changes, coming from the command:
\`\`\`
git diff --cached
\`\`\`
Please generate a concise, one-line commit message for these changes.
- do NOT add quotes
`
},
{ cache: false, temperature: 0.8 }
)
// ... handle response and user choices
} while (choice !== "commit")
```

## Commit and push

If you choose to commit, GenAI runs the `git commit` command with your message, and if you're feeling super confident, it can even push the changes to your repository right after:

```ts
if (choice === "commit" && message) {
console.log(
(await host.exec("git", ["commit", "-m", message, "-n"])).stdout
)
if (await host.confirm("Push changes?", { default: true }))
console.log((await host.exec("git push")).stdout)
}
```

## Running the Script with GenAIScript CLI

Getting this script up and running is a cinch. If you've already installed the [GenAIScript CLI](https://microsoft.github.io/genaiscript/getting-started/installation), you can simply run it with:

```shell
genaiscript run gcm
```

Remember, you'll need to have your changes staged in Git for the script to work its magic. 🧙

## Full source ([GitHub](https://github.com/microsoft/genaiscript/blob/main/packages/vscode/genaisrc/gcm.genai.mts))

<Code code={source} wrap={true} lang="ts" title="gcm.genai.mts" />
2 changes: 1 addition & 1 deletion docs/src/content/docs/reference/vscode/samples/rv.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,6 @@ genaiscript run rv
This will execute the script and provide you with the AI's feedback directly in your terminal or command prompt.
It's like having a virtual code reviewer at your disposal whenever you need it!

## Full source ([GitHub](https://github.com/microsoft/genaiscript/blob/main/packages/vscode/genaisrc/rv.genai.mts)
## Full source ([GitHub](https://github.com/microsoft/genaiscript/blob/main/packages/vscode/genaisrc/rv.genai.mts))

<Code code={source} wrap={true} lang="ts" title="rv.genai.mts" />

0 comments on commit c0b1ff9

Please sign in to comment.