Skip to content

Discard Local Changes and Switch Branch

When you need to abandon local work entirely and move to a different branch, two commands handle the two categories of changes: git restore resets tracked files that have been modified, and git clean removes untracked files and folders that Git has never recorded. Both steps are needed for a fully clean working tree. This case can happen when unwanted local changes made in production such as celery outputs, local data updates etc.

git status will show two kinds of local changes that block a clean branch switch.

  • Tracked modified files: files Git knows about that have been changed since the last commit. Cleared with git restore.
  • Untracked files and folders: new files or generated output that Git has never recorded. Cleared with git clean.

Before deleting anything, do a dry run to see exactly which untracked files and folders git clean would remove. Nothing is deleted at this step.

Terminal window
git clean -fdn

Once you have confirmed what will be removed, run both commands in sequence. This is permanent for untracked files and cannot be recovered.

Terminal window
git restore .
git clean -fd

git restore . resets every tracked modified file back to the last commit. git clean -fd deletes all untracked files (-f forces the delete, -d includes untracked directories).

If the branch already exists locally, fetch any remote updates and switch directly.

Terminal window
git fetch origin
git switch <branch-name>

If the branch exists on the remote but not yet locally, create it and set tracking in one step.

Terminal window
git fetch origin
git switch -c <branch-name> --track origin/<branch-name>

The complete sequence from a unwanted working tree to a clean branch switch, including the dry run preview.

Terminal window
git restore .
git clean -fdn # preview - nothing deleted yet
git clean -fd # actual delete
git fetch origin
# if branch already exists locally:
git switch <branch-name>
# if branch is remote only:
git switch -c <branch-name> --track origin/<branch-name>