| created | "2026-01-21T00:00:00.000Z" |
| modified | "2026-05-09T00:00:00.000Z" |
| reviewed | "2026-04-25T00:00:00.000Z" |
| name | git-push |
| description | Push local commits to remote — handles branch tracking, upstream setup, safe push patterns. Use when user says "push", "send to remote", or "update remote". Pushes existing commits — see git-commit for commits and git-pr for PR creation. |
| user-invocable | false |
| allowed-tools | Bash(git status *), Bash(git diff *), Bash(git log *), Bash(git push *), Bash(git branch *), Bash(git remote *), Bash(git rev-list *), Bash(git fetch *), Read, Grep, Glob, TodoWrite |
Git Push
When to Use This Skill
| Use this skill when... | Use the alternative when... |
|---|
| Pushing existing local commits to a remote with branch tracking and upstream setup | Use git-commit first when there are uncommitted changes to push |
| Sending changes to remote without opening a PR yet | Use git-pr afterwards to open a pull request from the pushed branch |
| Migrating commits from local main to a remote feature branch via explicit refspec | Use git-branch-pr-workflow to design the broader main-branch-dev pattern |
| Updating a remote branch with new commits after a rebase or amend | Use git-commit-push-pr for the consolidated commit + push + PR macro |
Push local commits to remote repositories with proper branch tracking.
When to Use
Trigger phrases:
- "push" / "push changes" / "push commits"
- "send to remote" / "update remote"
- "sync with origin"
- "upload changes"
Context signals:
- Local commits exist that aren't on remote
- User has just committed changes
git status shows "Your branch is ahead"
- No mention of "PR" or "pull request"
Workflow
1. Assess Push State
git branch --show-current
git status --porcelain=v2 --branch
git rev-list --count @{upstream}..HEAD 2>/dev/null || echo "no upstream"
git remote -v
2. Determine Push Strategy
Has upstream tracking:
git push
No upstream (new branch, same remote branch name):
git push -u origin $(git branch --show-current)
On main, pushing to a differently-named remote branch:
git push origin main:<remote-branch>
Force push needed (rebased/amended):
git push --force-with-lease
3. Verify Push
git status --porcelain=v2 --branch
Push Patterns
Standard Push (Default)
For regular commits on a tracked branch:
git push
Push to Remote Feature Branch (Main-Branch Development)
When on main with commits to push for a PR, push directly to a remote feature branch without creating a local branch:
git push origin main:<remote-branch-name>
git push origin <start>^..<end>:<remote-branch-name>
This avoids local branch juggling. After the PR merges, a git pull on main syncs cleanly.
First Push (New Branch)
For branches without upstream, when remote branch name matches local:
git push -u origin $(git branch --show-current)
Warning: -u binds the current local branch's upstream to the named remote branch. If you're on main and want to push to a differently-named feature branch, use the refspec form instead — otherwise main will track the feature branch:
git push origin main:feat/foo
Push with Tags
When commits include version tags:
git push --follow-tags
Force Push (With Lease)
For rebased or amended commits (requires confirmation):
git push --force-with-lease
Safety Checks
Before pushing, verify:
- Branch name - Avoid pushing directly to main/master
- Commit count - Reasonable number of commits
- No uncommitted changes - Clean working tree
- Remote reachable - Network connectivity
- Branch is live and in sync - When continuing work on a branch that already
has a PR, invoke
/git:pr-sync-check first. A pr_merged verdict means the
work belongs on a fresh branch off the updated default, not here; a behind
verdict means reconcile (git pull --rebase) before pushing. The
check-branch-sync-on-push.sh hook also nudges automatically. See
.claude/rules/pr-branch-sync.md.
Main Branch Push Behavior
branch=$(git branch --show-current)
if [ "$branch" = "main" ] || [ "$branch" = "master" ]; then
fi
Composability
This skill pushes commits only. For full workflows:
| User Intent | Skills Invoked |
|---|
| "push" | git-push only |
| "commit and push" | git-commit → git-push |
| "push and create PR" | git-push → git-pr |
| "commit, push, and PR" | git-commit → git-push → git-pr |
| "create PR" (on main) | git-pr handles push + PR creation automatically |
Output
On success, report:
Pushed to origin/feature-branch
Commits pushed: 3
Branch is now up to date with remote
Ready for: create PR, continue working, or merge
Error Handling
No upstream configured:
Branch has no upstream. Setting upstream to origin/<branch>
Remote has diverged:
Push rejected: remote contains commits not in local branch.
Options:
1. Pull and merge: git pull
2. Pull and rebase: git pull --rebase
3. Force push (loses remote commits): git push --force-with-lease
Remote unreachable:
Cannot reach remote 'origin'. Check network connection.
Protected branch rejection:
Push rejected: branch 'main' is protected.
Create a feature branch and submit a pull request instead.
Quick Reference
| Scenario | Command |
|---|
| Standard push | git push |
| Main to remote feature branch | git push origin main:<branch-name> |
| Commit range to remote branch | git push origin <start>^..<end>:<branch> |
| New branch (same local/remote name) | git push -u origin $(git branch --show-current) |
| With tags | git push --follow-tags |
| After rebase | git push --force-with-lease |
| Check ahead count | git rev-list --count @{upstream}..HEAD |
| Check tracking | git branch -vv |
Best Practices
- Push frequently - Smaller, incremental pushes are safer
- Never force push shared branches - Coordinate with team first
- Use feature branches - Keep main/master clean
- Verify before force push - Always use
--force-with-lease
- Check CI after push - Ensure tests pass on remote