Stage. Click. Push. Magic Push reads the actual diff, writes a commit message that describes what changed and why, then pushes — no "wip" placeholders, no "fix stuff" entries.
Most engineers know what a good commit message looks like, and most engineers' commit logs are full of bad ones. The reason isn't that good messages are hard to write — they aren't. The reason is that by the time you're ready to commit, you've already done the work, you're tired, the diff is complicated, and writing a short imperative summary of all of it is one more cognitive task you don't want. So you type "fix" or "updates" or worst of all "wip" and move on. Three weeks later, when something is wrong and you're trying to git blame the regression, you find a commit message that tells you nothing.
This problem is asymmetric. Writing the commit message takes thirty seconds; reading a bad one costs minutes every time it gets read. Yet the cost is paid by future-you, and the time is saved by present-you, so the equilibrium drifts toward bad messages. The only sustainable fix is to remove the friction at write-time. If the message takes zero seconds to write, you'll write a good one.
Magic Push closes that gap. The agent reads the staged diff — what files changed, what lines, what shape of change — and drafts a commit message describing it. You review the draft, edit if it's wrong, and push. Total time: about the time it takes to read three lines. The activation energy for "actually write a good message" goes from "thirty seconds of thought" to "five seconds of reading."
Open the git panel in the sidebar. You'll see two sections — "Unstaged" with current edits, "Staged" with what's ready to commit. Click to move files between the two, or click hunks within a file to stage by hunk.
The granularity matters: Magic Push describes what's staged, not what's modified. If you've changed five things and only want to commit one of them, stage just that one. The generated message will be about that one, not the full diff.
Above the commit message text box in the git panel, there's a button (typically a sparkle icon, sometimes labeled "Suggest"). Click it. The agent reads the staged diff and writes a draft message into the box, usually in the form of an imperative one-line summary, optionally with a body paragraph for non-trivial changes.
For example, a diff that adds rate-limit logging to one HTTP handler might produce: "Add rate-limit logging to /api/upload." A diff that refactors three files to use a shared helper might produce: "Extract shared signing logic into AuthHelper." A diff that mixes two unrelated changes might produce: "Add rate-limit logging and rename UserRepo to UserStore." That last one is a flag: when the agent struggles to write one summary, the commit is probably two commits in a trench coat.
The agent's draft is good at describing what changed because it can see the diff. It's less good at describing why, because the why isn't in the diff — it's in your head, in the ticket, in last week's discussion. When the why matters (which is for most non-trivial commits), edit the draft to add it.
Example: "Rename UserRepo to UserStore" is what the diff shows. The why might be "Match the StoreRepo / FooStore naming convention adopted in #1422." The agent doesn't know about #1422 unless you said so. Add it.
For trivial commits (lint fixes, formatting, typo corrections), the draft is usually fine as-is.
With the message in place, click the push button. The git panel commits with your message, then pushes to the tracking remote. The whole flow — stage, generate, edit, push — fits in well under a minute for typical changes.
If you'd rather commit without pushing (you're not ready to share yet), there's a separate "Commit only" option. Push later when you are.
Different teams have different commit message conventions. Conventional Commits (feat: ..., fix: ..., chore: ...). Imperative without a prefix. Short summary only, no body. Reference ticket IDs at the end.
Tell the agent your team's convention once in CLAUDE.md at the project root:
## Commit messages
Use imperative voice, no conventional-commit prefix. End with the
ticket ID if applicable, e.g. "Add rate-limit logging (#1422)".
From then on, generated drafts follow the convention. The whole repo benefits — anyone using LingCode in this project gets the same style.
main if you have a "never push to main" policy. Magic Push respects whatever branch you're on. If your team uses PR-based workflows, push to a feature branch and open the PR. (You can also enforce this with a PreToolUse hook — "refuse any git push targeting main.")