Git & GitHub Best Practices
Portable Git and GitHub habits for Go module repos.
Search across all documentation pages
Portable Git and GitHub habits for Go module repos.
These rules keep trunk releasable, module graphs tidy, and releases trustworthy for downstream go get.
main always releasable. Every merge should pass go test ./... and module tidy checks in CI.go.sum merge pain.release/vN exists and how patches cherry-pick from trunk.internal/parse: reject empty input.go.mod and go.sum with the code that caused dependency changes. Never split across unnoticed merges.retract and forward-fix tags.--force-with-lease only on personal feature branches. Never on shared or release branches.go.mod diffs.v1.2.3 matching go.mod major line.git tag -a or git tag -s.git push origin v1.2.3 - tags are not default on plain push./v2 module paths for incompatible API changes. Do not break consumers under the v1 import path.go.mod instead of deleting tags. Document migration in changelog.go.mod go directive. Use go-version-file in setup-go.go.sum keys. Include nested sums in monorepos.GOPRIVATE for org modules and scope narrowly. Avoid disabling sumdb for public deps.GOWORK=off tests before tagging monorepo modules. Simulates consumer resolution..gitignore. Binaries, profiles, IDE noise; never ignore go.sum..gitattributes merge strategy for go.sum if needed. union reduces manual conflict lines.replace paths. Use go.work locally or team-committed workspace files.go.mod.-ldflags from git describe or CI env.Never merge to trunk without CI that runs go test ./... and fails on tidy drift.
Everything else supports that gate.
Squash keeps trunk readable for libraries.
Choose rebase-merge if commit-level history is curated and reviewers want granular archaeology.
Libraries: when API or fixes warrant semver.
Services: tag deployable commits; consumers may be internal only.
Signed commits help provenance.
Signed release tags are often higher ROI for module consumers than signing every commit.
Per-module paths for go.mod and exported packages.
Require owner review when public API or dependencies change.
Useful with CI and human review on transitive changes.
Blind merges risk supply-chain surprises.
Maintainers cherry-pick or merge from fork PRs after CI.
Do not grant secrets to untrusted fork workflows.
Air-gapped CI, regulated environments, or pinned disaster recovery.
Document vendor refresh cadence in README.
Enable when many PRs merge hourly and trunk tests are reliable.
Requires consistent CI duration under team SLA.
Use the same semver string where possible.
Build images from tagged SHAs in CI, not floating branch heads.
When the whole team shares the same workspace modules.
Personal supersets stay untracked.
Tagging before /v2 path migration on a breaking change.
Consumers pin broken import graphs.
Stack versions: This page was written for Go 1.26.x (Green Tea GC default, go fix modernizers - verify patch at build), chi (latest - verify at build), gin (latest - verify at build), echo (latest - verify at build), google.golang.org/grpc (latest - verify at build), sigs.k8s.io/controller-runtime (latest - verify at build), kubebuilder (latest - verify at build), tinygo (latest - verify board targets at build), wazero (latest - verify at build), and golangci-lint (latest - verify linter set at build).
Reviewed by Chris St. John·Last updated Jul 18, 2026