Skip to content

Git: Support run prepare-commit-msg hooks #27232

@thomasheartman

Description

@thomasheartman

Summary

Zed doesn't run prepare-commit-msg hooks when you start a commit message.

Steps to trigger the problem:

  1. Have an active git repository
  2. Add a prepare-commit-msg hook
  3. Invoke git commit via the git command line, using the $EDITOR variable. Notice that the hook modifies the content of your buffer
  4. Start a commit message via Zed: the message is empty

Actual Behavior:
The prepare-commit-message hook does not affect the commit message editor

Expected Behavior:
The prepare-commit-message hook should be run and allowed to edit the commit buffer.

Context

This isn't a crucial thing to my workflow, but I'm opening the issue for it because @mikayla-maki asked me to when I reported it in the discord.

I've been using the hook for the last couple of years to automatically populate my commit message with the commit type (using conventional commits) and optionally the task number in whatever work tracking system we use.

Typically, I'll name a branch something like chore/do-the-thing or fix(1-26)/doesn't-work. The commit hook then looks at the current branch name, extracts everything before the first slash, and inserts it into the commit message.

As a bonus: I've made it so that if I'm on the main branch of a repo, it'll insert a comment in all caps reminding me that I haven't created a branch yet. I can dismiss this, of course, but often times I've just forgotten to actually create a branch, so it's quite helpful.

If it's helpful, here's the script I use

My current prepare-commit-msg script
#!/usr/bin/env bash
COMMIT_MSG_FILE=$1

CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)

IFS='/'
if read -r _ DEFAULT_BRANCH <<< "$(git rev-parse --verify -q --abbrev-ref origin/HEAD)" && [ "$DEFAULT_BRANCH" = "$CURRENT_BRANCH" ]; then
    MESSAGE="; YOU'RE ON THE DEFAULT BRANCH.\n"

else
    extract_branch_prefix() {
        if [[ $1 == *"/"* ]]; then
            cut -d '/' -f 1 <<< "$1"
        else
            cut -d '-' -f 1-2 <<< "$1"
        fi
    }

    TASK_TYPE="$(extract_branch_prefix "$CURRENT_BRANCH")"
    MESSAGE="${TASK_TYPE}:"
fi

if [ -z "$(head -n 1 "$1")" ]; then
    sed -i "1s/^/${MESSAGE}/" "${COMMIT_MSG_FILE}";
fi

Finally, I'm assuming that the hook is never run, because Zed doesn't invoke git commit and setting itself as the $EDITOR. I'm assuming it just passes the commit message as a string to git commit, thus bypassing prepare-commit-msg (and potentially other hooks related to the msg).

As for the actual implementation: because Zed allows you to toggle the commit window whenever you want, it might be hard to know when to run the hook. I'd think it makes sense to run the first time you open an empty message and have staged hunks? It should probably never clobber anything you have in there already.

Zed Version and System Specs

Zed: v0.179.1 (Zed Preview)
OS: macOS 15.3.1
Memory: 16 GiB
Architecture: aarch64

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    Status

    Post 1.0

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions