How to Fix: Accidentally Committed to Main Branch Instead of Feature Branch

How to Fix: Accidentally Committed to Main Branch Instead of Feature Branch

· 6 min read

The “Oh Crap” Moment

You push to main and get this:

git push origin main
remote: GitLab: You are not allowed to push code to protected branches on this project.

You never created a feature branch. All your commits went straight to main.

Your commits are safe, and this takes about 2 minutes to fix.

Why This Happens

If you’re seeing this error, it means your team has branch protection enabled on the main branch. This is actually a good thing - it prevents anyone (including you) from accidentally pushing broken code directly to production. The protection is working as intended; you just forgot to follow the workflow.

Learn more about why we use branch protection in our Git branching strategy guide.

What Went Wrong?

Your Git history right now:

Diagram

Local main is ahead of remote main by a few commits. The remote won’t accept the push because main is protected.

The plan:

  1. Move your commits to a new feature branch
  2. Reset local main to match remote
  3. Push the feature branch
  4. Create a merge request

No commits will be lost. We’re just relocating them.

The Fix: Move Commits to Feature Branch

You should be on the main branch with commits that can’t be pushed.

Step 1: Check Your Current Status

git status
git log --oneline -5

This tells you:

  • Which branch you’re on
  • How many commits ahead you are
  • What your recent commits look like

Example output:

On branch main
Your branch is ahead of 'origin/main' by 3 commits.

a1b2c3d (HEAD -> main) Fix: Update user validation logic
e4f5g6h Add: User authentication endpoint
i7j8k9l Refactor: Database connection handling

Those 3 commits need to move.

Step 2: Create Feature Branch From Current Position

This branches right where you are, preserving all commits:

git checkout -b feature/user-authentication

Replace feature/user-authentication with something appropriate. Follow your team’s branch naming convention.

Your new branch now has all your commits, and you’re on it.

Step 3: Verify Feature Branch Has Your Commits

git log --oneline -5

All your commits should be there. They’re safe on the feature branch.

Step 4: Switch Back to Main and Reset It

Reset main to match remote:

# Switch back to main
git checkout main

# Reset main to match remote (THIS IS SAFE - your commits are on feature branch)
git reset --hard origin/main

This makes local main identical to origin/main, discarding commits that now live on your feature branch.

Important: Only Run This on Main

Never run git reset --hard on a branch with work you haven’t saved elsewhere. We’re only doing this on main because we already copied the commits to the feature branch in Step 2.

Step 5: Verify Main Is Reset

git status
git log --oneline -5

Expected output:

On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean

Main is clean again.

Step 6: Push Feature Branch and Create Merge Request

Switch back and push:

# Switch to feature branch
git checkout feature/user-authentication

# Push to remote (creates new branch on GitLab/GitHub)
git push -u origin feature/user-authentication

The -u flag (--set-upstream) creates the remote branch and sets up tracking for future pushes.

Step 7: Create Merge/Pull Request

Create an MR/PR through your platform’s UI or via CLI:

GitLab:

# If you have GitLab CLI installed
glab mr create --title "feat: Add user authentication" --description "Adds JWT-based authentication for API endpoints"

GitHub:

# If you have GitHub CLI installed
gh pr create --title "feat: Add user authentication" --body "Adds JWT-based authentication for API endpoints"

Both platforms also show a direct URL in your terminal after pushing.

Visual: What We Just Did

Diagram
  • main branch: In sync with remote
  • feature branch: Has all your commits, ready for MR
  • Your work: Safe and in the right place

Verification Checklist

Quick sanity check:

  • git status on main shows “up to date with origin/main”
  • git log on main doesn’t show your recent commits
  • git checkout feature/user-authentication switches to feature branch
  • git log on feature branch shows all your commits
  • Feature branch exists on remote (check GitLab/GitHub UI)
  • Merge request is created and shows your changes

Preventing This (Because We All Forget)

1. Git Aliases for Common Workflows

Add these to your ~/.gitconfig:

[alias]
    # Create feature branch and switch to it in one command
    feature = "!f() { git checkout -b feature/$1; }; f"

    # Before starting work, ensure you're on main and up to date
    sync = "!git checkout main && git pull origin main"

    # Start new feature (syncs main, creates feature branch)
    start = "!f() { git checkout main && git pull origin main && git checkout -b feature/$1; }; f"

Usage:

# Old way (easy to forget checkout)
git checkout main
git pull
git checkout -b feature/my-feature

# New way (one command)
git start my-feature

2. Pre-Commit Hook to Warn on Main

Create .git/hooks/pre-commit in your repository:

#!/bin/bash

# Get current branch name
branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')

# Check if on main/master
if [ "$branch" = "main" ] || [ "$branch" = "master" ]; then
    echo "⚠️  WARNING: You're committing directly to $branch!"
    echo "Are you sure you want to do this? (y/n)"
    read -r response
    if [ "$response" != "y" ]; then
        echo "Commit cancelled. Create a feature branch first:"
        echo "  git checkout -b feature/my-feature"
        exit 1
    fi
fi

Make it executable:

chmod +x .git/hooks/pre-commit

This warns you every time you try to commit on main.

Conclusion

This happens to everyone. Branch protection catching it means the system is working.

The fix:

  1. Create feature branch from current position (saves commits)
  2. Reset local main to remote (cleans up main)
  3. Push feature branch (gets work where it belongs)
  4. Create merge request (proper workflow)

Your commits were never in danger. Set up the aliases and hooks above to make this less frequent.

Related reading: