Commit early, often, and intentionally
The Zen lesson. Most Git advice is mechanical: which command, which flag, which workflow. The hardest skill to teach is the rhythm — when to commit, how often, with what intent. The team that commits intentionally has a different relationship with their code than the team that commits "when something is done." Almost every Git pain in this quest dissolves when this rhythm is in place.
Commit early. A commit is not a milestone; it is a checkpoint. The moment you have a coherent unit of work that compiles and at least roughly works, commit. Do not wait for "done" — done is a high bar that rarely arrives in one session. Frequent small commits give you reflog history at fine resolution, the option to bisect through your own work, the ability to abandon an experiment without losing the parts that worked.
Commit often. A working session should produce many commits, not one. Each commit captures a thought: "this function now handles empty input," "this typo was fixed," "this refactor extracts the helper." Later you may squash them with interactive rebase before pushing, or leave them, depending on policy. The point of frequent commits is the safety net during the session, not the published shape of history.
Commit intentionally. Each commit should answer one question: what concept did I move forward? If the answer requires "and" or "also," it is two commits. If you cannot articulate the answer in 50 characters, the work is not yet a coherent unit — keep editing. The commit message is a forced reflection: by the time you write a sharp message, you have understood what changed. The act of writing the message tells you whether the change was clean.
The compounding payoff over a year. Engineers who commit early-often-intentionally have legible reflog histories, can bisect through their own past work in seconds, can abandon dead-end branches without losing the salvageable parts, and read a year-old git log and remember what they were thinking. Engineers who commit "when done" have one giant commit per feature, no recovery granularity, and read their own old code as if a stranger wrote it. The skills compound; so does the absence.