Small Commits and PRs
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
Small, focused commits and pull requests reduce the amount of unrelated context a reviewer or maintainer must hold at once.
A coherent change is easier to understand, test, locate with git bisect, and revert without removing unrelated work.
For example, separating a tax-rounding fix from an unrelated payment-client refactor lets a team review and, if necessary, revert only the tax behavior. I do not use a fixed line count: a generated rename may be large and low risk, while a one-line authorization change may need careful review.
I keep the behavior and its tests together, separate cleanup that is not required, and make review-ready commits leave a deliberate testable state. Local work-in-progress commits can be reorganized before sharing, but I coordinate before rewriting history that other people may already use.
Small Commits and PRs
Direct Answer
Small, focused commits and pull requests can be easier to review, diagnose, revert, and merge because each has a clear purpose. The useful boundary is a coherent change, not an arbitrary line count or one file. Shared or review-ready commits should avoid unrelated work and should leave the branch in a testable, understandable state; local work-in-progress history can be cleaned up before sharing.
Code Example
// Bad: one large mixed commit -> "Update order processing"
// 15 files, 800 lines: validation + tax fix + gateway refactor + logging + inventory
// Good: small focused commits
// Commit 1: "Fix tax calculation rounding for Canadian orders"
@Service
public class TaxCalculator {
public BigDecimal calculateTax(BigDecimal amount, String province) {
var rate = TAX_RATES.get(province);
// Fixed: use RoundingMode.HALF_UP for consistent rounding
return amount.multiply(rate).setScale(2, RoundingMode.HALF_UP);
}
}
// Commit 2: "Add order quantity validation before payment"
public void processOrder(OrderRequest request) {
if (request.quantity() <= 0) {
throw new InvalidOrderException("Quantity must be positive");
}
// ... rest of processing
}
// Commit 3: "Extract payment gateway retry logic to a utility"
public class PaymentRetryUtil {
public static <T> T retryOnFailure(Supplier<T> operation, int maxAttempts) {
// Refactored retry logic, isolated in its own reviewable commit
return operation.get();
}
}
Each commit message names one change, so the history reads like a changelog.
Common Mistakes & Pitfalls
- Batching unrelated changes: Freshers fix a bug, add a feature, and update documentation in one commit because they happened to work on them in the same session. This makes the commit impossible to understand and difficult to revert selectively. Each logical change should be its own commit.
- Waiting until work is complete: Freshers work on a feature for a week, then create one massive commit with all the changes. By then, dozens of files are modified and the commit is too large to review effectively. Commit incrementally as you complete logical steps.
- Committing broken code: Freshers commit code that doesn't compile or fails tests, planning to fix it in the next commit. Every commit should leave the codebase in a working state. If you need to save work-in-progress, use git stash or a draft PR, not commits to the main history.
- Vague commit messages: Commits like fix bug or update code don't explain what changed or why. Messages should be specific: Fix null pointer exception in order validation when product is out of stock.
Check your understanding
Answer these without looking back at the article.
- How would you split a large feature into multiple small pull requests?
- What is git bisect and when would you use it?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.