Commit history is project documentation – other developers read it, git bisect searches it for bugs, and git blame explains decisions. Good commit messages, the ability to tidy history before a merge, and knowing cherry-pick and bisect are tools that separate someone who “uses Git” from someone who “manages” it.
Anatomy of a good commit message
Conventional Commits is the de facto standard in open source projects and well-managed repositories:
type(scope): short summary in imperative mood (max 72 chars) Optional longer description explaining WHAT and WHY (not HOW). Wrap lines at 72 characters. Refs: #123 BREAKING CHANGE: description if API changes
Types: feat, fix, refactor, docs, test, chore, perf. Scope is optional but helpful: fix(checkout), feat(catalog).
# Bad commit messages git commit -m "fix" git commit -m "changes" git commit -m "WIP" git commit -m "Magento stuff" # Good commit messages git commit -m "fix(cart): correct tax calculation for virtual products" git commit -m "feat(catalog): add bulk price update via CSV import" git commit -m "refactor(di): replace ObjectManager with constructor injection in OrderService"
rebase -i – cleaning history before merge
Interactive rebase lets you rewrite local commit history before pushing to remote. Available operations: pick (keep), squash (merge with previous), reword (change message), edit (stop to edit), drop (delete).
# Edit the last 3 commits git rebase -i HEAD~3 # Editor opens with the list: # pick a1b2c3d WIP: fix typo # pick e4f5a6b WIP: more changes # pick 7c8d9e0 WIP: almost done # Change to: # pick a1b2c3d WIP: fix typo # squash e4f5a6b WIP: more changes # squash 7c8d9e0 WIP: almost done # Git merges 3 commits into 1 and opens the message editor # Change message to: # feat(export): add product export service with CSV support
Important rule: never rebase commits that have already been pushed to a shared branch (main, develop). Rebase rewrites SHAs – other people will have history conflicts.
cherry-pick – move individual commits
# Move a specific commit to the current branch git cherry-pick a3d5e2f # Move a range of commits git cherry-pick a3d5e2f..f1a2b3c # Cherry-pick without auto-commit (for editing) git cherry-pick -n a3d5e2f # Typical use case: hotfix on main, then cherry-pick to develop git checkout main git cherry-pick hotfix-sha git checkout develop git cherry-pick hotfix-sha
bisect – binary search through history
Bisect is a binary search through commit history. Ideal when you know “it worked before, now it doesn’t” and you have hundreds of commits between those points.
# Start bisect git bisect start # Mark the current commit as bad git bisect bad # Mark the last known good commit git bisect good v2.4.6 # Git picks a commit to test (bisection) # Test, then mark the result: git bisect good # or git bisect bad # Git narrows the range by half with each step # With 100 commits you need at most 7 steps (log2(100)) # Automated bisect with a test script git bisect run php bin/magento catalog:reindex 2>&1 | grep -q "error" && exit 1 || exit 0 # End bisect git bisect reset
Useful git log options
# Graphical history view git log --oneline --graph --all # Commits touching a specific file git log --follow -p -- src/Model/OrderService.php # Search commit messages git log --grep="fix(cart)" # Commits by author in date range git log --author="Henryk" --after="2026-01-01" --oneline # Show what changed in a commit git show --stat HEAD
Summary
Good commit history is an investment – in debugging, code review and documentation. Conventional Commits provide a readable structure. Rebase -i lets you clean up “WIP” before merge. Cherry-pick moves individual changes between branches. Bisect turns hours of regression hunting into a minutes-long process. Next post: branching and merge – strategies, when fast-forward, when merge commit, when rebase.
