Chapter 6.5 β€” Stash Untracked & Including Allβ˜• 14 min read

Force Push Safely

--force mat likhna, --force-with-lease likhna. 14 extra characters team ka kaam bacha sakte hain.

01Untracked Files Stash Karna

Normal push works when your local history extends the remote history β€” meaning your commits are built on top of what the remote already has. Git can fast-forward the remote pointer to include your new commits.

But after a git rebase or git commit --amend, your local history diverges from the remote. The commit hashes change. Git sees different histories and rejects the push to protect the remote.

Force push overrides this safety check. It overwrites the remote history with your local history, regardless of what is on the remote.

Force push is necessary when:

  • You rebased your feature branch β€” rebase creates new commit hashes
  • You amended a commit β€” amend creates a new hash replacing the old one
  • You interactive rebased to clean up WIP commits before PR review

After these operations, your local branch has diverged from the remote. Only force push can update it.

git push --force = dangerous bulldozer. Overwrites everything without checking.
git push --force-with-lease = safe bulldozer with brakes. Checks that no one else pushed commits.

# Normal push rejected after rebase
git checkout feature
git rebase main
# Rebase creates new commit hashes
git push origin feature
# ERROR: Updates were rejected (divergent histories)
# Git is protecting the remote from being overwritten

# You MUST force push after rebase
git push --force-with-lease origin feature
# Checks that remote hasn't changed, then overwrites

# When force push is OK:
# - After rebasing your own feature branch
# - After amending your last commit (if not yet pulled by others)
# - After interactive rebase to clean up commits
02–include-untracked (-u) Flag

--force: overwrites the remote unconditionally. If 3 teammates pushed commits while you were rebasing, their commits are all DELETED from the remote.

--force-with-lease: checks if the remote ref is what you expect. If someone else pushed, it FAILS safely.

Here is how --force-with-lease works internally:

  • When you git fetch, Git remembers the remote branch tip
  • When you git push --force-with-lease, Git asks: "Does the remote still have the commit I fetched earlier?"
  • If yes (no one pushed new commits) β†’ overwrite succeeds
  • If no (someone pushed new commits) β†’ REJECT. The push fails.

This one flag prevents the most destructive Git accident: overwriting teammates' work.

ALWAYS use --force-with-lease. Make it a habit. Make it an alias.

# DANGEROUS: --force
git push --force origin feature
# Overwrites everything on remote/feature
# If teammate pushed 5 commits, they're GONE

# SAFE: --force-with-lease
git push --force-with-lease origin feature
# If no one else pushed: works perfectly
# If someone pushed: fails with error
# "cannot lock ref... remote has new commits"

# Set up alias so you never type --force
git config --global alias.fpush "push --force-with-lease"
# Now use: git fpush origin feature

# When --force-with-lease fails:
# 1. Pull the new commits
git pull --rebase origin feature
# 2. Resolve any conflicts
# 3. Push again
git push --force-with-lease origin feature
πŸ’‘ Pro Tip: Make --force-with-lease your muscle memory. Never type git push --force. If you need to force push, type git push --force-with-lease. The 14 extra characters can save your team from disaster. Set up an alias: git config --global alias.fpush "push --force-with-lease" and use git fpush.
03–all (-a) Flag β€” Untracked + Ignored

Force push is a tool, not a crime. But it must be used on the right branches at the right time.

Acceptable:

  • βœ… After rebasing your OWN feature branch (no one else is on it)
  • βœ… After amending your last commit on a branch you alone work on
  • βœ… After interactive rebase to clean up WIP commits before PR review
  • βœ… In fork-based workflows where you push to your own fork

Unacceptable:

  • ❌ NEVER on main, develop, or release branches
  • ❌ NEVER on shared feature branches without coordinating with teammates
  • ❌ NEVER after someone else has pulled your branch

The rule is simple: if someone else has pulled your branch, it is now shared history. Do not rewrite it.

# ACCEPTABLE: Rebase your own feature
git checkout my-feature  # only you work on this
git rebase origin/main
git push --force-with-lease origin my-feature

# ACCEPTABLE: Amend your last commit (you alone on branch)
git commit --amend -m "better message"
git push --force-with-lease origin my-feature

# UNACCEPTABLE: Force push main
git push --force origin main
# DESTROYS shared history for the entire team

# UNACCEPTABLE: Force push shared feature
git push --force origin feature/auth
# 3 other people are working on this branch
# Their local repos are now broken
04Stash Specific Files

Scenario: someone accidentally ran git push --force origin main. The team's shared history is overwritten. Commits are missing. People are panicking.

Step 1: Find the correct history. The person who force pushed can use git reflog to find the old main tip before the disaster.

Step 2: Reset and force push back. Reset to the correct commit and force push it back to restore the remote.

Step 3: Tell the entire team to re-sync. Everyone must update their local repos to match the restored remote.

Teammate recovery: git fetch origin then git reset --hard origin/main. Any local commits must be cherry-picked onto the reset branch.

Prevention: enable branch protection rules that disallow force pushes to main.

# Person who force pushed: FIX IT
git reflog
# Find: def5678 HEAD@{5}: the last good main commit
git checkout main
git reset --hard def5678
git push --force-with-lease origin main

# All teammates: re-sync
# Option 1: Reset to fixed main (discard local changes)
git fetch origin
git reset --hard origin/main

# Option 2: Save local work first
git branch backup  # save current state
git fetch origin
git reset --hard origin/main
# Cherry-pick local commits from backup
git cherry-pick abc123 def456

# Prevention: GitHub branch protection
# Settings β†’ Branches β†’ main β†’
# βœ… Do not allow force pushes
05Advanced Stash Scenarios

The BEST solution is PREVENTION. Configure GitHub to block force pushes on important branches so that even if someone makes a mistake, the server rejects it.

GitHub Settings: Repository β†’ Settings β†’ Branches β†’ Branch protection rules β†’ Add rule for "main".

Recommended settings:

  • Do not allow force pushes β€” blocks git push --force origin main
  • Do not allow deletions β€” prevents accidental branch deletion
  • Require pull request before merging β€” no direct pushes to main
  • Require status checks to pass β€” CI must pass before merge

With branch protection, even if someone types git push --force origin main, GitHub REJECTS it. The operation is impossible, not just discouraged.

# Set branch protection via GitHub CLI
gh api repos/:owner/:repo/branches/main/protection \
  --method PUT \
  --field enforce_admins=true \
  --field allow_force_pushes=false

# Now force pushes to main are BLOCKED by GitHub
git push --force origin main
# remote: error: GH006: Protected branch update failed for main
# remote: error: Cannot force-push to a protected branch

# This is the ultimate safety net
# Even if someone makes a mistake, GitHub prevents it
Force push is a tool, not a sin. The problem is not force push β€” it is force push on the WRONG branch. Use --force-with-lease on your own feature branches to clean up history. Use branch protection on main to make accidents impossible. With these two habits, force push becomes safe and professional.

Lo kar liya β€” Key Points:

  • βœ… Force push overwrites remote history; necessary after rebase or amend which change commit hashes
  • βœ… git push --force is dangerous β€” it unconditionally overwrites others' work without checking
  • βœ… git push --force-with-lease checks that no one else pushed commits; fails safely if they did
  • βœ… Force push is acceptable on your own feature branch after rebase or amend
  • βœ… NEVER force push to shared branches (main, develop, release) or branches others have pulled
  • βœ… Branch protection rules on GitHub prevent force pushes to main, making accidents impossible
  • βœ… If someone force pushes main: use reflog to find correct history, force push back, and coordinate team recovery
Course Search
Search across all chapters & stages
πŸ“–

Search the course

Type any topic β€” branching, stash, rebase, hooks β€” and jump straight to that chapter.

merge branchesgit stashundo commitrebase