Back to Articles
Git Oct 08, 2026 7 min read

How to Switch Git Branches Without Losing Your Uncommitted Changes

Learn how to use git stash effectively to temporarily save uncommitted changes when you need to switch branches without losing your work.

How to Switch Git Branches Without Losing Your Uncommitted Changes

When working with Git, there are times when you're in the middle of a task and have several changes in your working directory, but the task isn't finished yet.

You don't want to commit those changes because the work is incomplete. But suddenly, you need to switch to another branch and work on a different task.

So what do you do?

You can use Git Stash.

The Problem

Suppose you're currently working on:

task-X

You've already written some code:

task-X
 ├── UserService.cs       modified
 ├── UserController.cs    modified
 └── UserDto.cs           new file

But Task X isn't finished yet.

You don't want to create a commit like:

WIP
Temporary changes
Not completed

At the same time, you need to switch to another branch:

task-Y

If you simply run:

git switch task-Y

Git may prevent you from switching, especially if your uncommitted changes would conflict with the target branch.

More importantly, you don't want your unfinished Task X changes to accidentally become part of Task Y.

This is where git stash becomes useful.


What is Git Stash?

git stash temporarily stores your uncommitted changes and gives you a clean working directory.

Think of it as:

"Put my current unfinished work somewhere safe. I'll come back to it later."

Your changes aren't committed to the branch, but Git remembers them so you can restore them later.


The Workflow

Here's the complete workflow:

git switch task-X

git stash push -u -m "WIP: Task X"

git switch task-Y

# Complete the task at Y

git switch task-X

git stash pop

Let's understand each step.


1. Start Working on Task X

First, switch to your task branch:

git switch task-X

Then work normally.

For example:

task-X
 ├── UserService.cs       modified
 ├── UserController.cs    modified
 └── UserDto.cs           new file

Check your changes:

git status

You might see:

Changes not staged for commit:
  modified: UserService.cs
  modified: UserController.cs

Untracked files:
  UserDto.cs

But Task X isn't finished yet.

So you don't want to commit.


2. Stash Your Changes

Run:

git stash push -u -m "WIP: Task X"

The important parts are:

git stash

Tells Git to temporarily store your changes.

-u

Includes untracked files.

This is useful when you've created new files that haven't been added to Git yet.

For example:

UserDto.cs

Without -u, untracked files may not be included in the stash.

-m "WIP: Task X"

Adds a meaningful description to your stash.

Instead of seeing:

stash@{0}: WIP on task-X

you'll have something more descriptive:

stash@{0}: On task-X: WIP: Task X

3. Your Working Directory Is Now Clean

After stashing:

git status

You should see something like:

On branch task-X
nothing to commit, working tree clean

Your changes haven't disappeared.

They are safely stored in Git's stash.

You can verify them with:

git stash list

Example:

stash@{0}: On task-X: WIP: Task X

4. Switch to Task Y

Now you can safely switch:

git switch task-Y

Your unfinished Task X changes won't be carried into Task Y.

You can now work on Task Y normally:

# Work on Task Y

git add .

git commit -m "Complete Task Y"

5. Return to Task X

After finishing Task Y, switch back:

git switch task-X

Your previous Task X changes are still stored in the stash.

Check:

git stash list

You'll see:

stash@{0}: On task-X: WIP: Task X

6. Restore Your Task X Changes

Now run:

git stash pop

Git will restore the changes you previously stashed.

Your working directory should now look like it did before you switched to Task Y.

For example:

task-X
 ├── UserService.cs       modified
 ├── UserController.cs    modified
 └── UserDto.cs           new file

You can now continue working on Task X.


Complete Example

Here's the complete workflow in one place:

# Start working on Task X
git switch task-X

# Work on Task X...
# Some changes are still unfinished

# Temporarily save unfinished changes
git stash push -u -m "WIP: Task X"

# Switch to another task
git switch task-Y

# Work on Task Y...
# Complete Task Y

git add .
git commit -m "Complete Task Y"

# Return to Task X
git switch task-X

# Restore unfinished Task X work
git stash pop

# Continue working on Task X

What Happens Behind the Scenes?

Before stashing:

task-X
   │
   ├── modified files
   ├── new files
   └── unfinished work

After:

git stash push -u -m "WIP: Task X"

Git temporarily stores the changes:

Git Stash
   │
   └── WIP: Task X

Your working directory becomes clean:

task-X
   │
   └── clean working directory

Then you can switch:

task-X ────────────────┐
                       │
                       ▼
                    task-Y
                       │
                  complete work
                       │
                       ▼
                    task-X
                       │
                       ▼
                  git stash pop
                       │
                       ▼
              unfinished work restored

What If I Have Multiple Stashes?

You can have multiple stash entries.

For example:

git stash list

might show:

stash@{0}: On task-Z: WIP: Task Z
stash@{1}: On task-X: WIP: Task X
stash@{2}: On task-A: WIP: Task A

You can inspect a stash with:

git stash show stash@{0}

Or with more details:

git stash show -p stash@{0}

If you specifically want to restore Task X:

git stash pop stash@{1}

So don't always assume that stash@{0} is the stash you want.


git stash pop vs git stash apply

There are two commonly used commands:

git stash pop

and:

git stash apply

The difference is important.

git stash pop

Restores the changes and removes the stash if the operation succeeds.

git stash pop

git stash apply

Restores the changes but keeps the stash.

git stash apply

For normal temporary work, I usually use:

git stash pop

because once I've successfully restored the changes, I don't need the stash anymore.

If you're being cautious or want to keep a backup, use:

git stash apply

A Practical Branching Strategy

If your team uses a structure like:

development
    │
    └── feature/dabananda
            │
            ├── task-X
            ├── task-Y
            └── task-Z

You can work like this:

development
      │
      ▼
feature/dabananda
      │
      ├── task-X
      │      │
      │      ├── work
      │      ├── stash
      │      └── temporarily leave
      │
      ├── task-Y
      │      │
      │      ├── work
      │      └── complete
      │
      └── task-X
             │
             ├── stash pop
             ├── continue work
             └── complete

This allows you to switch between tasks without creating meaningless commits just to save unfinished work.


One Important Tip

Before switching branches, make sure you know what you're stashing.

Run:

git status

Then:

git stash push -u -m "WIP: Task X"

And verify:

git stash list

This makes it much easier to understand what Git has stored.


Final Cheat Sheet

When you need to leave an unfinished task:

git stash push -u -m "WIP: Task X"

Switch to another task:

git switch task-Y

Finish Task Y:

git add .
git commit -m "Complete Task Y"

Return to Task X:

git switch task-X

Restore your unfinished work:

git stash pop

That's it.

You don't need to create a temporary commit just because you need to switch branches.

git stash is designed exactly for this kind of situation.

Share this article

Dabananda Mitra

Dabananda Mitra

Software Engineer specializing in scalable backend systems and minimal, effective API design.

Comments

Loading comments...