Skip to main content

Two AI Prompts That Fixed My Git History

·1220 words·6 mins

TL;DR
#

I used to have pull requests with dozens, and sometimes hundreds, of commits. Most of the messages were complete garbage: Cleanup., More tests., fix., some initial notes.

Two small Markdown prompt files removed the friction:

  • commit.md stages the requested changes, reads the staged diff, and creates a short descriptive commit message.
  • create-pull-request.md reads the commit log, generates a PR title and description, pushes the branch, and runs gh pr create.

The useful part is how the quality compounds. Good commit messages become good PR descriptions. Those descriptions give reviewers better context, and the commit history becomes useful to both humans and coding agents later.

The prompt content is agent-agnostic. I usually package these prompts as commands, although skills can work too. For this kind of housekeeping task, I also prefer a fast, cheap model over the most expensive reasoning model available.

Video Walkthrough
#

If you prefer a video walkthrough, here it is:


A Real Pull Request With 209 Bad Commits
#

This was not a hypothetical example. I had a real pull request with 209 commits, and many messages looked like this:

Cleanup.
More tests.
Some initial notes.
More readme.
fix.

Sure, you can squash before merging. But that does not make the branch history useful while the work is in progress, and a vague squashed commit is still vague.

Usually nobody reads commit messages until production is on fire and you’re trying to figure out what changed three months ago. At that point the history becomes a search index, and good history is way easier to search. Sure, an LLM will probably find the answer anyway, but it will take longer, explore more diffs, and likely burn more tokens as well.

I can write a good commit message by hand. The problem is doing it consistently while committing often, switching between branches, or working with several agents that are producing a bunch of code that I need to review and commit. This is a good LLM task: read some text that happens to be code, summarize it, and run a few Git commands, so adding prompts to automate this was a logical next step.

Prompt One: Turn the Diff Into a Commit
#

My current commit.md is intentionally small:

# Follow this instruction to commit changes.

Only use this instruction if the user asks for it.
* All commands should be run from a repo root.
* You will be given a list of files to commit.
* Commit all updated files if not otherwise specified. In this case use `git add .` from a repo root as a first step to stage all updated files.
* If user requested to commit specific files, use `git add <file1> <file2> ...` to stage specific files only.
* When committing, make sure to provide a sensible message. Figure out the message from chat history and/or the actual code changes. Make the message short and descriptive.
* Always run `git diff --staged` before composing the message so you can summarise what was changed.
* If you still lack context after reviewing the diff, consult the chat history; the diff should be your primary source for message content, not just `git status`.
Do NOT do any other verification or actions unrelated to this instruction. You SHOULD just commit the changes as specified here.

The staged diff is the primary source because it is what you are actually committing. Chat history is useful as extra context, but it can be incomplete, stale, or describe changes that never made it into the worktree.

The last line is also important. Without that boundary, a helpful agent may run lint, start fixing unrelated problems, or turn a five-second checkpoint into a much larger task. This prompt has one job. It does not replace the verification you run before calling the actual coding task complete.

If I want the whole worktree committed, git add . is convenient. If I want a specific set of changes, I give the agent the file list instead, but I think I do this less often.

Prompt Two: Turn Commit History Into a Pull Request
#

The companion create-pull-request.md uses the branch history as its input:

# Instruction to create pull request

This is an instruction to follow when user is referencing it. Only use this instruction when explicitly requested by the user.

1. Review the commit history between the base branch (use **main** unless another base is specified) and the current branch:
```bash
# Make sure remote is up to date
git fetch origin

# Get the current branch; use it when pushing and creating the PR
git branch --show-current

# Read commits on this branch that are not on the base branch
git log origin/<base branch>..HEAD --oneline | cat
```

2. Review commit history and come up with a sensible PR title.
3. Review commit history and come up with a sensible PR description:
   ```markdown
   * Short change description 1
   * Short change description 2
   * ...
   ```
4. Prepare the PR title and description.
5. Push pending changes and create a PR. Pass the description through standard input so multiline Markdown and shell characters remain intact:
```bash
git push origin <current branch> --set-upstream
gh pr create \
  --title "<PR title>" \
  --body-file - \
  --base "<base branch>" \
  --head "<current branch>" <<'EOF'
<PR description>
EOF
```
6. Show the PR URL to the user.

git fetch origin needs to happen before the comparison. Otherwise the agent may summarize the wrong range against stale remote state.

Good Summaries Compound
#

The first prompt is useful on its own, but the second prompt is where the workflow starts paying back.

Instead of this:

cleanup
fix
more changes
update tests
final tweaks

I get history closer to this:

Add AccountsStore load/validate/query and tests
Add cmd/bbmd Cobra scaffold and DI smoke tests
Implement bbmd auth sub-commands
Implement bbmd pr sub-commands
bbmd: unify auth/PR execution via exec helpers and tests

Now the PR description is a summary of already-good summaries. A real PR created with this workflow has a specific title, a short explanation of the change, and a useful high-level list for reviewers.

The same history helps later when a teammate reviews the PR, an agent needs to understand why something changed, or you need to generate release notes. The compound effect works in the other direction too: vague commits give the PR prompt vague input.

How Do I Run This?
#

For the commit.md one, I usually do it like this:

  • Run it manually when I want to checkpoint my work, for example with /commit or follow @commit.md. I do this less often these days.
  • Have my agent run it during a long-running orchestration loop, usually as part of a verification step handled by a dedicated sub-agent.

The create-pull-request.md prompt works the same way: I run it myself or let my agent run it when it’s time to submit the PR.

If Something Goes Wrong
#

If you notice a model misbehaving with these prompts, Agent Diagnostics Mode can help you understand why. I use it for prompt problems in general, not just commit and pull request automation.

Is This Lazy?
#

Maybe. But it is the good kind of lazy.

The output is better, the friction is lower, and the history is more useful. I will take that trade-off.

Eugene
Author
Eugene