731

How can I clear my working directory in Git?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Hans Sjunnesson
  • 20,322
  • 17
  • 51
  • 63
  • User interactive approach: git clean -i -fd – bit_cracker007 Jun 14 '17 at 04:16
  • 9
    I don't understand why this question has been **flagged duplicate**. That [other question](https://stackoverflow.com/questions/61212/how-to-remove-local-untracked-files-from-the-current-git-working-tree) clearly deals with removing only `untracked` files from `working directory` and not `modified` files – y2k-shubham Mar 16 '18 at 10:33
  • @y2k-shubham Sure, but *this* question is vague and doesn't explicitly refer to modified files. – danodonovan Aug 02 '19 at 10:50

6 Answers6

1109

To reset a specific file to the last-committed state (to discard uncommitted changes in a specific file):

git checkout thefiletoreset.txt

This is mentioned in the git status output:

(use "git checkout -- <file>..." to discard changes in working directory)

To reset the entire repository to the last committed state:

git reset --hard

To remove untracked files, I usually just delete all files in the working copy (but not the .git/ folder!), then do git reset --hard which leaves it with only committed files.

A better way is to use git clean (warning: using the -x flag as below will cause Git to delete ignored files):

git clean -d -x -f

will remove untracked files, including directories (-d) and files ignored by git (-x). Replace the -f argument with -n to perform a dry-run or -i for interactive mode, and it will tell you what will be removed.

Relevant links:

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
dbr
  • 153,498
  • 65
  • 266
  • 333
  • 23
    Note that by default, 'git clean -d' is insufficient. You need to also add the -f (force) flag. Also, if you want to additionally delete the files that are ignored by .gitignore, then you need to add the -x option. Here's what it all looks like: git clean -xdf – Matt Ball Apr 06 '11 at 15:05
  • 12
    However be sure to NOTE that command will also blow away your local sqlite database -- not undo recent changes, but actually delete it. Sp the "-x" option might NOT ne a good idea depending on what you are trying to do. – jpw Apr 02 '12 at 00:54
  • I am 100% sure I run git clean -d -f ( without -x ) and it also deleted ignored files. – Pawel Dubiel Sep 06 '13 at 12:07
  • 9
    Please note: the suggestion to delete all the files except the `.git/` folder and then restore by running `git reset --hard` will probably take a long time if your repo has been around for any time at all. Please don't do this. Use `git clean`. – Jen Sep 12 '13 at 17:34
  • One thing I found in trying to use this command, is knowing if that was in fact the problem. Turns out one of my colleagues had the dropdown in 'Working Copy' at the top of the page set to 'All Files' when it should be 'Pending'. This gave the appearance that a load of files were being changed, when in fact, it was just showing all the files in the project, as it should do. So the fix for this issue was just to select 'Pending Files' from the dropdown in 'Working Copy' screen. Let me know if this helps anyone. – redfox05 Jan 22 '15 at 11:05
  • 2
    Note also that `git clean -d -x -f` will blow away symlinks to outside directories. – Eric Walker Jul 16 '15 at 15:04
  • The `git clean -fdx` option is very useful. It helped me delete some untracked files that were hidden and that I did not know that were affecting my compilation. – Santiago Villafuerte Sep 29 '15 at 12:47
  • 3
    **Warning** don't forget `-n` for a dry-run ! – Benj Sep 06 '16 at 09:45
  • Quick addition: you could reset the entire subdirectory using wildcards like this. Notice the quotes around the pattern. ```git checkout master 'subdir/*' ``` – nikhilweee Feb 09 '18 at 04:37
  • `git restore ` was required in my case, after the clean -dxf . – pdem Apr 28 '20 at 07:56
145

Use:

git clean -df

It's not well advertised, but git clean is really handy. Git Ready has a nice introduction to git clean.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Marko
  • 28,383
  • 17
  • 70
  • 107
  • 29
    I suggest to not use the `-x` parameter as it will remove all gitignored content. Say you have a folder named '`gitignored`' added to `.gitignore`, and you store there your files that have to be secure, you're also deleting them using `-x` parameter – Highmastdon Dec 21 '12 at 12:39
  • 3
    Oops. `git clean -xdf` also removed `.gitignore`, and I did not notice before the next commit. I won't ignore `.gitignore` anymore. :) – Grastveit Sep 12 '13 at 08:43
  • 4
    @Grastveit `git clean -xdf` will remove `.gitignore` if and only if it has not been added to, thus working as intended. – Marko Sep 13 '13 at 06:58
  • 8
    let's highlight this: - – Mehdi Nov 19 '14 at 14:40
  • @mef I use `git clean -xdf` all the time instead of make clean, ant clean, mvn clean or whatever else. There's no general rule, and everyone is free to use `-x` or not. – Marko Dec 03 '14 at 11:03
  • 8
    @Marko sure, everyone is free to use `-x` or not. But some people may read this github answer, copy-paste the command, and without realizing it loose all their gitignored files they wanted to keep. Then come back here and only notice @Highmastdon's comment, about the consequence of using `-x`. – Mehdi Dec 03 '14 at 15:01
46

All the answers so far retain local commits. If you're really serious, you can discard all local commits and all local edits by doing:

git reset --hard origin/branchname

For example:

git reset --hard origin/master

This makes your local repository exactly match the state of the origin (other than untracked files).

If you accidentally did this after just reading the command, and not what it does :), use git reflog to find your old commits.

dbn
  • 10,463
  • 2
  • 50
  • 83
  • Is branch name really required? For me `git reset --hard` simply works for current working branch without branch name. – RBT Dec 20 '16 at 12:48
  • Without the branch, it does not clear local commits. – dbn Dec 20 '16 at 19:20
  • ohh. ok. My observation was only regarding the local modified and newly added untracked files. So if I got you correctly, if any file is staged or has already been committed in local branch (not pushed as yet) will not get cleaned if I do not use the branch name explicitly. Correct? – RBT Dec 21 '16 at 03:50
  • 3
    Super. I verified your observation. You were correct buddy. `git reset --hard` doesn't clear local commits until you specify the branch name explicitly. +1. – RBT Dec 21 '16 at 04:00
13

You could create a commit which contains an empty working copy.

This is a generally safe, non-destructive approach because it does not involve the use of any brute-force reset mechanisms. First you hide all managed content with git checkout empty, then you are free to manually review and remove whatever unmanaged content remains.

## create a stand-alone, tagged, empty commit
true | git mktree | xargs git commit-tree | xargs git tag empty

## clear the working copy
git checkout empty

Your working copy should now be clear of any managed content. All that remains are unmanaged files and the .git folder itself.

To re-populate your working copy...

git checkout master ## or whatever branch you will be using

If you're a forward thinking individual, you might start your repository off on the right foot by basing everything on an initial empty commit...

git init
git commit --allow-empty --allow-empty-message -m ""
git tag empty
...

There are various uses for a tagged empty worktree. My favorite at the moment is to depopulate the root under a set of git worktree subfolders.

Brent Bradburn
  • 40,766
  • 12
  • 126
  • 136
  • This can also be a nice way to save some disk-space in a pinch. – Brent Bradburn Jan 25 '13 at 05:24
  • 5
    A much faster way to create the empty checkout: `true | git mktree | xargs git commit-tree | xargs git tag empty` – jthill Mar 21 '13 at 18:15
  • 2
    Note: There seems to be some value in using an empty commit as the base for projects. This makes it easier to perform full-project rebase operations in case your initial commit needs to be fixed -- and may simplify things when [pushing an existing git repository to svn](http://stackoverflow.com/questions/661018/pushing-an-existing-git-repository-to-svn). – Brent Bradburn Aug 16 '13 at 15:57
  • 2
    Like most other workflows, this gets messy if you are using Git submodules. – Brent Bradburn May 16 '15 at 02:23
  • 1
    'git init && git commit --allow-empty "EMPTY COMMIT && git tag empty' would do the job of the first block too. – Bodo Thiesen Jan 18 '18 at 09:58
  • You may have better luck if you do a `make clean` or equivalent before checking out `empty`. :) – Brent Bradburn Aug 15 '18 at 01:09
9

To switch to another branch, discarding all uncommitted changes (e.g. resulting from Git's strange handling of line endings):

git checkout -f <branchname>

I had a working copy with hundreds of changed files (but empty git diff --ignore-space-at-eol) which I couldn't get rid off with any of the commands I read here, and git checkout <branchname> won't work, either - unless given the -f (or --force) option.

Tobias
  • 2,249
  • 3
  • 21
  • 37
2

To reset a specific file as git status suggests:

git checkout <filename>

To reset a folder

git checkout <foldername>/*
anshuman
  • 3,288
  • 1
  • 17
  • 13