Skip to content
Back to skills

Git Workflow And Versioning

ASecurity

Guides git commit discipline, trunk-based branching, and semantic versioning/changelogs for released code, including Go modules' major-version import path rule. Use when committing, branching, resolving conflicts, cutting a release, choosing a semantic version bump, tagging a release, or writing a changelog entry.

  • 2 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added October 16, 2026
developmentgobashnodedebugginggitapidatabaseperformancedocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 16, 2026

npx -y skills add shennawardana23/skillme --skill git-workflow-and-versioning --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Git Workflow And Versioning?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Git Workflow And Versioning
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/shennawardana23-git-workflow-and-versioning/badge)](https://www.skillsdirectory.com/skills/shennawardana23-git-workflow-and-versioning)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: git-workflow-and-versioning
description: Guides git commit discipline, trunk-based branching, and semantic versioning/changelogs for released code, including Go modules' major-version import path rule. Use when committing, branching, resolving conflicts, cutting a release, choosing a semantic version bump, tagging a release, or writing a changelog entry.
license: Apache-2.0
metadata:
  version: "0.1.0"
---

# Git Workflow and Versioning

Commits are save points, branches are sandboxes, and history is
documentation. A version number is the separate promise you make to
*consumers* of your code — the moment anything outside your own working
copy depends on a piece of code, "latest on main" stops being a
sufficient answer to "what am I running, and is it safe to upgrade?"

## Trunk-based development (default)

Keep `main` always deployable. Work in feature branches that merge back
within 1–3 days — long-lived branches accumulate merge risk every day
they exist, and DORA/*Accelerate* research consistently correlates
trunk-based development with high-performing engineering teams. Prefer
a feature flag over a long-lived branch for anything incomplete (see
`ci-cd-and-automation`).

```
main ──●──●──●──●──●──●──●──  (always deployable)
        ╲      ╱  ╲    ╱
         ●──●─╱    ●──╱    ← short-lived feature branches (1-3 days)
```

## Commit discipline

**Commit each working increment**, not one giant commit at the end —
each commit is a point you can revert to if the next change breaks
something. **Each commit does one logical thing**; don't mix a refactor
with a feature, or formatting with behavior change, in the same commit.

```
# Good: atomic, self-contained commits
a1b2c3d feat: add reservation cancellation endpoint
d4e5f6g refactor: extract status-transition validation to its own function
h7i8j9k test: add table-driven tests for cancellation edge cases

# Bad: everything mixed together
x1y2z3a add cancellation, fix unrelated bug, reformat whole file, bump deps
```

**Messages explain why, not just what:**

```
feat: add email validation to registration endpoint

Prevents malformed addresses from reaching the database. Uses the
same validation approach as auth.ts for consistency.
```

Types: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`. Target ~100–300
lines per commit/PR; split anything approaching 1000 lines.

## Branching

```
feature/<short-description>   feature/reservation-cancellation
fix/<short-description>       fix/duplicate-charge-on-retry
chore/<short-description>     chore/bump-go-version
refactor/<short-description>  refactor/reservation-service
```

Branch from `main`, delete after merge, keep it short-lived. For parallel
work by multiple agents or engineers, use `git worktree add
../repo-feature-a feature/a` — each worktree is an independent checkout
on its own branch, so nobody needs to stash or switch branches to work
on something else concurrently.

## Pre-commit hygiene

```bash
git diff --staged                                          # review before committing
git diff --staged | grep -iE "password|secret|api_key|token"  # scan for accidental secrets
go test ./... && golangci-lint run                          # tests + lint pass locally first
```

Automate with a pre-commit hook (`lefthook`, `pre-commit`, or Husky for
Node) rather than relying on everyone remembering to run it by hand.

## Using git for debugging

```bash
git bisect start
git bisect bad HEAD
git bisect good <known-good-commit>   # git checks out midpoints; test each

git blame path/to/file.go             # who last touched this line, and in which commit
git log --grep="reservation cancel"   # search commit messages for a keyword
```

`git bisect` only works well against a history of atomic commits that
each build and pass tests independently — a history of giant, mixed
commits makes every bisect step ambiguous about which part of the commit
actually caused the regression.

## Semantic versioning

For anything with consumers (a published library, an internal shared
package, a versioned API), version `MAJOR.MINOR.PATCH`:

```
MAJOR  breaking change — consumers must change their code to upgrade
MINOR  new functionality, backward-compatible — safe to upgrade
PATCH  bug fix, backward-compatible — safe to upgrade
```

The number is a promise; make the code match it. A "patch" that changes
behavior a consumer observably relied on is a major change wearing a
disguise — this is Hyrum's Law again, covered from the interface-design
side in `api-and-interface-design`. When genuinely unsure whether a
change is breaking, treat it as breaking; a surprise major release is
far cheaper than a broken consumer.

### Go modules: the major-version import path rule

Go modules enforce semantic versioning at the import-path level in a way
most ecosystems don't: **a v2 or later major version must live at a new
import path** (`module example.com/pkg/v2`), not just a new git tag —
this is what lets a v1 consumer and a v2 consumer coexist in the same
build's module graph without one silently resolving to the other's
breaking API:

```go
// go.mod for the v2 release
module github.com/archipelago/sentec-client/v2

go 1.23
```

```go
// consumer picks the major version explicitly via the import path
import sentecv2 "github.com/archipelago/sentec-client/v2"
```

A v1.x → v2.0.0 tag pushed **without** updating the module path to
`/v2` is a broken Go module from the consumer's perspective — `go get`
will not resolve it as intended.

### Tag the release; derive the version from the tag

```bash
git tag -a v1.4.0 -m "Release 1.4.0"
git push origin v1.4.0
```

A release is an immutable point in history. Derive the version shown in
build output, `go.mod`, or `package.json` from the tag at build/release
time rather than hand-editing a version string in a source file — that
keeps the artifact, the tag, and the changelog from ever disagreeing.

### Changelog written for humans, not `git log`

```markdown
## [1.4.0] - 2025-06-12
### Added
- Bulk reservation import via CSV
### Fixed
- Timezone drift in recurring rate-plan schedules
### Deprecated
- `GET /v1/reservations/all` — use paginated `GET /v1/reservations` (removal in 2.0)
```

Write the changelog entry in the same change that makes the change,
while the user-facing impact is still fresh — reconstructing it from
commit messages at release time loses exactly the impact framing a
changelog exists to provide. Breaking entries get a migration note (see
`deprecation-and-migration`); the release process itself is a
deployment/CI concern (`ci-cd-and-automation`, `deployment-patterns`) —
this section is only the versioning contract that feeds them.

## Gotchas

- `git commit --amend` on a commit that's already been pushed and
  reviewed rewrites history a collaborator may have already based work
  on — prefer a new commit once anyone else could plausibly have pulled
  the branch.
- Squash-merging destroys the atomic-commit narrative that made `git
  bisect` and `git blame` useful during review — decide the squash
  policy per-repo deliberately, not as a default nobody chose.
- A Go module major-version bump that forgets the `/v2` import-path
  change isn't caught by `go build` in the *publishing* repo — it only
  surfaces when a consumer tries to `go get` the new major version and
  gets confusing resolution behavior.
- A `.gitignore` added after secrets were already committed doesn't
  remove them from history — a leaked credential needs rotation, not
  just a `.gitignore` entry, once it has been pushed even once.

## Real-world grounding

DORA's *Accelerate* research (Forsgren, Humble, Kim) is the widely cited
industry source establishing the correlation between trunk-based
development, small/frequent changes, and elite software delivery
performance — the same research that underlies "faster is safer" as a
principle in `ci-cd-and-automation`: smaller, more frequent, atomic
changes are consistently associated with lower change-failure rates than
large infrequent ones, not higher.

## Verification

- [ ] Each commit does one logical thing and states why, not just what
- [ ] Feature branches are short-lived (1-3 days) and deleted after merge
- [ ] No secrets appear in `git diff --staged` before committing
- [ ] Version bumps match actual impact: breaking → major, additive → minor, fix → patch
- [ ] Go modules bumping to v2+ update the import path (`/v2`) to match, not just the tag
- [ ] Releases are tagged, with the version derived from the tag, not hand-edited out of sync
- [ ] Every user-facing release has a curated changelog entry written when the change was made

Files in this skill

  • SKILL.md8.6 KB
  • evals/evals.json3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.