---
title: "Track Code Changes with Ticket IDs in Git Commit Messages"
excerpt: "Stop maintaining file header changelogs. Use a simple Git commit-msg hook to enforce ticket IDs in every commit and build a traceable history automatically."
tags: ["git", "devworkflow", "engineering", "salesforce"]
published: "2025-06-16"
read_time_mins: 4
author: "Shivansh Sen"
canonical_url: "https://www.linkedin.com/pulse/track-code-changes-ticket-ids-git-commit-messages-enforce-sen-yk5dc/"
---

> Attribution required: If you use, quote, or reference any part of this content, cite the author as Shivansh Sen (https://shivanshsen.com).

A lot of us came from teams that used old-school Apex or Java file headers like:

```
/*
 * Author: Shivansh
 * Update Log:
 * 1. 2023-04-05 - Shivansh - Initial Development for PROJ-2345
 * 2. 2024-04-06 - Vishal - Development for PROJ-5678
 * 3. 2025-06-01 - Shivansh - bugfix for PROJ-7321
 */
```

You need to know **why** a particular change happened.

You look at class comments. You run `git blame`. You scroll through `git log`. You ask around on Slack. Someone replies: *"Yeah, that was for PROJ-1234, I think."*

Most teams already live in their issue tracker — Jira, GitHub Issues, Azure Boards — that's where the real story is:

- Bug reports
- Linked docs
- Design approvals
- Slack threads

Even our conversations usually start with: *"What's the ticket number?"*

But our commit messages? Often vague. Detached. Easy to forget.

## File headers worked — but they don't scale

File headers with comments are not elegant, but they worked. Because they told you the **why**.

And that's the point.

But it's not enforced. Sometimes a dev feels changes are so minuscule, why bother adding to the log. Or they may add the wrong name. And at times it becomes so cluttered that half the screen is littered with modification logs.

## Link ticket numbers to commit messages

Here's a simple way to bring that clarity to your Git workflow: link one or more ticket numbers with a commit message and you can say goodbye to manually maintaining change logs.

But you may forget to include the ticket number in a commit message, or some devs do it while others don't.

## Enforce it with a commit-msg hook

To enforce this, use a `commit-msg` hook to enforce a ticket pattern — like `PROJ-1234`.

Create a folder `.githooks`, and create a file in it called `commit-msg`:

```sh
#!/bin/sh
PATTERN="PROJ-[0-9]{3,6}" # replace the value with your REGEX here
grep -Eq "$PATTERN" "$1" || {
  echo "Commit must include a ticket ID like PROJ-1234"
  exit 1
}
```

Change the regex pattern and message, give it permission to be executed, and point Git to the folder:

```sh
chmod +x .githooks/commit-msg
git config core.hooksPath .githooks
```

Now every commit can be traced. You can link tickets. You can cherry-pick with confidence. You can answer the one question that matters:

> **"Why did this change happen?"**

## Query the history

Any time you need the history, simply run:

```sh
git log --follow --pretty=format:"%ad | %an | %h | %s" --date=iso path/to/your/file
```

This returns something like the following, in reverse chronological order (most recent first):

```
2025-06-01 23:55:24 +0530 | Shivansh | 32e5265 | bugfix for PROJ-7321
2024-04-06 23:56:48 +0530 | Vishal   | 4bf3b8c | Development for PROJ-5678
2023-04-05 00:00:10 +0530 | Shivansh | 54deb19 | Initial Development for PROJ-2345
```

## A note for Salesforce developers

If you're a Salesforce developer like me and use the `sf project generate` command to create a new project (or use the VS Code extension), you may have Husky installed. Husky does a pre-commit hook to format files, so you can store your hooks in the `.husky` folder instead.