2024-11-08
5 min read

How to Move Uncommitted Work to a New Branch in Git

How to Move Uncommitted Work to a New Branch in Git

You started making changes and then realized you're on the wrong branch. Maybe you're on main when you should be on a feature branch. Git makes it easy to move uncommitted work to a new branch without losing anything.

TLDR: To move uncommitted changes to a new branch, use git checkout -b new-branch-name before committing. Git automatically brings your changes with you. If you have both staged and unstaged changes, they all move together to the new branch.

In this guide, you'll learn different ways to move uncommitted work between branches.

Prerequisites

You'll need Git installed on your system and a repository with uncommitted changes. Basic familiarity with Git branches and the staging area will help you follow along.

Understanding Uncommitted Changes

Git handles changes in three states:

Working Directory → Staging Area → Committed
(modified files)    (git add)      (git commit)

Uncommitted changes exist in either your working directory or staging area. These changes are not tied to a specific branch until you commit them, making them easy to move.

Moving Changes to a New Branch

The simplest way to move uncommitted work is to create a new branch before committing:

# You're on main with uncommitted changes
git status
# On branch main
# Changes not staged for commit:
#   modified: app.js
#   modified: styles.css

# Create new branch and switch to it
git checkout -b feature-new-ui

# Your changes come with you
git status
# On branch feature-new-ui
# Changes not staged for commit:
#   modified: app.js
#   modified: styles.css

Now you can commit your changes on the new branch:

# Stage and commit on the new branch
git add .
git commit -m "Add new UI components"

The main branch remains unchanged, and your new branch contains all your work.

Moving Staged and Unstaged Changes

Git moves both staged and unstaged changes when you switch branches:

# Mixed staged and unstaged changes
git status
# On branch main
# Changes to be committed:
#   modified: app.js
# Changes not staged for commit:
#   modified: styles.css

# Create new branch - both types of changes move
git checkout -b feature-styling

# Verify everything moved
git status
# On branch feature-styling
# Changes to be committed:
#   modified: app.js
# Changes not staged for commit:
#   modified: styles.css

Your staging area state is preserved when creating the new branch.

Using git switch for Modern Git

Git 2.23 and later provide the switch command as a clearer alternative:

# Create new branch and switch to it
git switch -c feature-authentication

# Or the long form
git switch --create feature-authentication

The switch command works identically to checkout -b but has a more intuitive name focused on branch switching.

Moving Changes to an Existing Branch

If you want to move changes to an existing branch instead of creating a new one:

# You're on main with uncommitted changes
git status

# Switch to existing branch
git checkout feature-dashboard

# Changes move if there are no conflicts

Git allows this only if switching would not overwrite your local changes. If there are conflicts, you'll see:

error: Your local changes to the following files would be overwritten by checkout:
  app.js
Please commit your changes or stash them before you switch branches.

In this case, use stash or commit first.

Using Stash When Switching is Blocked

When Git prevents switching due to conflicts, use stash:

# Stash your changes
git stash push -m "Work in progress"

# Switch to the target branch
git checkout feature-dashboard

# Apply the stashed changes
git stash pop

The stash temporarily saves your changes, letting you switch branches freely. Then you reapply them on the new branch.

Moving Specific Files Only

To move only some changes to a new branch:

# You have multiple changed files
git status
# modified: app.js
# modified: styles.css
# modified: README.md

# Stash everything
git stash

# Create new branch
git checkout -b feature-ui-only

# Apply only specific files from stash
git checkout stash@{0} -- app.js styles.css

# The other files remain stashed
git stash list

This gives you fine-grained control over which changes go to the new branch.

Handling Untracked Files

Untracked files (new files not yet added to Git) automatically move with you:

# New files in working directory
git status
# Untracked files:
#   new-component.js
#   new-styles.css

# Create new branch
git checkout -b feature-new-component

# Untracked files come along
git status
# On branch feature-new-component
# Untracked files:
#   new-component.js
#   new-styles.css

Since untracked files are not tied to any branch, they remain in your working directory when switching.

Common Workflow Pattern

Here's a typical workflow when you realize you're on the wrong branch:

# 1. Check what you've changed
git status
git diff

# 2. Create a new branch from current position
git checkout -b fix-authentication-bug

# 3. Stage and commit your work
git add .
git commit -m "Fix authentication token validation"

# 4. Switch back to main
git checkout main

# 5. Verify main is clean
git status
# On branch main
# nothing to commit, working tree clean

The main branch is never affected because you committed the changes on the new branch.

Moving Changes While Keeping Main Up to Date

If you want your new branch to start from the latest main:

# You're on main with changes
git stash

# Update main
git pull origin main

# Create new branch from updated main
git checkout -b feature-new-endpoint

# Restore your changes
git stash pop

This makes sure your feature branch is based on the latest code.

What If You Already Committed?

If you committed to the wrong branch, use a different approach:

# You committed to main by mistake
git log --oneline -1
# abc1234 Add new feature

# Create new branch from current position
git branch feature-new-branch

# Reset main to before your commit
git reset --hard HEAD~1

# Switch to the new branch
git checkout feature-new-branch

# Your commit is now on the new branch
git log --oneline -1
# abc1234 Add new feature

This moves the commit itself to a new branch, not just uncommitted changes.

Handling Merge Conflicts After Moving

When you apply stashed changes to a new branch, conflicts can occur:

# Apply stash causes conflicts
git stash pop
# CONFLICT (content): Merge conflict in app.js

# Resolve the conflicts in your editor
nano app.js

# Stage the resolved files
git add app.js

# Drop the stash (it's been applied)
git stash drop

Conflicts happen when the branch you switched to has different code in the same areas you modified.

Moving Changes Between Remote Branches

If both branches are tracking remote branches:

# On local main with changes
git checkout -b feature-api-update

# Commit the changes
git add .
git commit -m "Update API endpoints"

# Push to remote
git push -u origin feature-api-update

# Main branch is unaffected locally and remotely
git checkout main
git status
# On branch main
# Your branch is up to date with 'origin/main'

Your changes are now on the remote feature branch without affecting main.

Quick Reference

Here's a quick decision tree for moving uncommitted work:

Have uncommitted changes?
  ├─ Want to create NEW branch?
  │  └─ git checkout -b new-branch-name
  │
  ├─ Want to switch to EXISTING branch?
  │  ├─ No conflicts expected?
  │  │  └─ git checkout existing-branch
  │  │
  │  └─ Conflicts possible?
  │     └─ git stash → git checkout existing-branch → git stash pop
  │
  └─ Already committed?
     └─ git branch new-branch → git reset --hard HEAD~1 → git checkout new-branch

Best Practices

Always check your branch before starting work:

# Before making changes
git branch
# * main
#   feature-authentication

# Oops, I'm on main
git checkout feature-authentication
# Now start working

Create topic branches for new work:

# Good practice: Always work on feature branches
git checkout main
git pull origin main
git checkout -b feature-user-profile
# Now make changes

Use descriptive branch names:

# Good branch names
git checkout -b fix-login-redirect
git checkout -b feature-payment-gateway
git checkout -b refactor-api-handlers

# Less helpful names
git checkout -b temp
git checkout -b fix
git checkout -b updates

Now you know how to move uncommitted work to a new branch in Git. The key is understanding that uncommitted changes are not bound to a specific branch until you commit them, making them easy to move with git checkout -b or git switch -c.

Published: 2024-11-08|Last updated: 2024-11-08T10:30:00Z

Found an issue?