Git & Workflow — Java-Specific Git Discipline¶
Git is universal; this file covers only the Java-specific bits and the workflow choices that matter in 2026. You already know git commit -m. What you need is the .gitignore that stops you from ever committing target/, the commit convention that makes your PRs credible, and the trunk-based-vs-GitFlow verdict.
The Java .gitignore — Copy This¶
Save as .gitignore in every new Java repo you create. This is the union of what IntelliJ, Eclipse, VS Code, Maven, and Gradle all leak:
# Compiled output
target/
build/
out/
bin/
*.class
*.jar
*.war
*.ear
*.nar
# Maven
.mvn/wrapper/maven-wrapper.jar
!.mvn/wrapper/maven-wrapper.properties
# Gradle
.gradle/
gradle-app.setting
!gradle-wrapper.jar
!gradle-wrapper.properties
# IntelliJ IDEA
.idea/
*.iml
*.iws
*.ipr
# Eclipse
.settings/
.project
.classpath
.factorypath
.apt_generated/
# VS Code
.vscode/
*.code-workspace
# NetBeans
nb-configuration.xml
nbproject/private/
build/
nbbuild/
dist/
nbdist/
.nb-gradle/
# macOS
.DS_Store
# Windows
Thumbs.db
Desktop.ini
# JVM crash logs
hs_err_pid*.log
replay_pid*.log
# Local env
.env
.env.local
application-local.yml
application-local.properties
# Logs
logs/
*.log
# Test output
test-output/
surefire-reports/
allure-results/
# JDK-managed
.sdkmanrc
# OS temp
*~
*.swp
*.swo
One rule: if you commit target/ once, junior devs on your team will copy your repo and think it’s fine. Enforce the .gitignore from Day 1.
Committing IntelliJ config safely¶
Some teams commit .idea/runConfigurations/ and .idea/copyright/ (both useful for team consistency) while ignoring everything else. If you need this:
.idea/*
!.idea/runConfigurations/
!.idea/copyright/
Global ~/.gitignore_global¶
Set up once per machine for personal noise:
git config --global core.excludesfile ~/.gitignore_global
Contents:
.DS_Store
.vscode/
.idea/
*.swp
*.swo
Thumbs.db
Keep repo .gitignore for project-specific noise; use global for OS/editor noise.
Commit Message Convention — Conventional Commits¶
Adopt Conventional Commits. Not because you’ll auto-generate changelogs (you probably won’t), but because it forces you to think about what you actually changed.
Format:
<type>(<optional scope>): <short summary>
<optional body — what / why, not how>
<optional footer — breaking changes, issue refs>
Types:
feat:— new featurefix:— bug fixrefactor:— code change without behavior changeperf:— performance improvementtest:— adding/fixing tests onlydocs:— documentation onlychore:— build config, deps, toolingci:— CI configstyle:— formatting, whitespacebuild:— build system
Examples:
feat(user-api): add pagination to GET /users
Previous endpoint returned unbounded list, causing OOM on production
tenant with 300k users. Adds page + size query params with 100 default.
Closes #142.
fix(auth): reject expired refresh tokens
RefreshTokenService was checking issuedAt instead of expiresAt.
Regression from #98. Added parameterized test.
refactor(order-service): extract PricingCalculator
No behavior change. Separates pricing rules from Order aggregate to
prepare for #201 (tax-per-region).
One line, imperative mood, present tense. “Add feature” not “Added” not “Adds”.
Commit hygiene rules¶
One logical change per commit. If you
git statusand see 12 unrelated files, split.Never commit
WIPorfix stuff. Usegit commit --amendorgit rebase -i.Commit tests with the code they test. Not a separate commit.
Squash before merging PR. History should read like a book of features, not a diary.
Branching Strategy — The 2026 Verdict¶
Trunk-based development won. In 2026, most modern Java shops (including most Indian product companies — Zoho, Freshworks, Razorpay, PhonePe, Swiggy, CRED) use short-lived feature branches merged to main daily or several times a day.
GitFlow (with develop, release/, hotfix/ branches) is now considered overkill for ~90% of projects. It survives in:
Regulated enterprises (banking, healthcare) where release cadence is monthly+
Some Infosys/TCS/Wipro legacy programs
Products with true version-parallel releases (rare)
Trunk-based rules¶
mainis always releasable. Never merge broken code.Feature branches live < 2 days. Longer = merge hell.
Behind feature flags for incomplete work. Ship code, hide feature.
Merge via PR with 1+ reviewer. No direct pushes.
CI runs on every push. Broken CI = highest-priority team incident.
Rebase before merge. Squash-merge preferred over merge-commit for clean history.
PR discipline¶
A good Java PR:
< 400 lines diff
One logical change
All tests pass
Description explains: problem → approach → risks → how tested
Screenshots/logs if UI or observable output changed
Reviewer merges within 24 hrs, author responds to comments within 24 hrs
PR title = the merge commit message. Use Conventional Commits format.
The Zoho / Indian-context note¶
Some Zoho / Freshworks / Infosys teams still use SVN or Perforce for legacy monoliths. Learn Git for personal work regardless — it’s the study standard and the industry standard. If your day job is SVN, keep personal projects in Git for portfolio velocity.
Tools Worth Installing¶
Tool |
Purpose |
How to install |
|---|---|---|
|
Create PRs from terminal |
|
|
TUI Git client |
|
|
Better |
|
|
Git hooks framework |
|
Sourcetree / Fork / Tower |
GUI clients |
Optional; terminal is enough |
~/.gitconfig starter¶
[user]
name = Raghul R
email = your-email@zohomail.com
[core]
editor = code --wait
excludesfile = ~/.gitignore_global
autocrlf = input
[init]
defaultBranch = main
[pull]
rebase = true
[push]
default = current
autoSetupRemote = true
[rebase]
autoStash = true
[fetch]
prune = true
[alias]
st = status -sb
co = checkout
br = branch
ci = commit
cim = commit -m
lg = log --graph --pretty=format:'%C(yellow)%h%C(reset) %C(cyan)%an%C(reset) %s %C(green)(%cr)%C(reset)%C(bold red)%d%C(reset)' --abbrev-commit
unstage = reset HEAD --
Pre-commit Hooks for Java¶
Install pre-commit, then add .pre-commit-config.yaml:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
args: ['--maxkb=1000']
- repo: local
hooks:
- id: mvn-fmt
name: Maven fmt (Spotless)
entry: ./mvnw spotless:apply
language: system
pass_filenames: false
files: \.java$
Enable: pre-commit install.
Signing Commits (Optional but Recommended)¶
GitHub shows “verified” badge if commits are signed with GPG or SSH keys.
Modern path (2026): SSH signing.
# In ~/.gitconfig
[user]
signingkey = ~/.ssh/id_ed25519.pub
[gpg]
format = ssh
[commit]
gpgsign = true
Add SSH key as a signing key on GitHub (Settings → SSH and GPG keys → New SSH key → Key type: signing).
The Anti-Patterns¶
git push --forceto shared branches. Rewrites history for everyone. Only use--force-with-leaseon your own feature branches.Committing secrets. Set up
gitleaksorgit-secretsas a pre-commit hook.Long-lived feature branches. Merge hell 2 weeks later. Break work into small commits/PRs.
git pullon unclean working tree without rebase. Creates merge commits for nothing.Copy-pasting from Stack Overflow into a huge commit. Small commits, one intent each.
Return to README.md · Next: 05_docker_and_containers.md