771

When I run git reset --hard HEAD, it's supposed to reset to a pristine version of what you pulled, as I understand it. Unfortunately, it leaves files lying around, as a git status shows a big list of untracked files.

How do you tell git "Just bring it back to EXACTLY what was in the last pull, nothing more, nothing less"?

Karl
  • 14,434
  • 9
  • 44
  • 61
  • 61
    `git reset --hard` resets your index and reverts the tracked files back to state as they are in HEAD. It leaves untracked files alone. – fifigyuri Dec 01 '10 at 18:47
  • 4
    @fifigyuri -- correct. This was stated already in the question. – BrainSlugs83 Mar 11 '22 at 00:18
  • 1
    I noticed that you need have all the unstaged files in your path, not some directories above like `../../file.yaml`. Instead you need to first `cd ../../` then do `git reset --hard` and/or `git clean -fd` to reset everything. When you run `git status` nothing should be any directories above you. An easy way is to just do these commands from the base directory of the repo. – wordsforthewise Sep 23 '22 at 11:18

10 Answers10

1194

You have to use git clean -f -d to get rid of untracked files and directories in your working copy. You can add -x to also remove ignored files, more info on that in this excellent SO answer.

If you need to reset an entire repository with submodules to the state on master, run this script:

git fetch origin master
git checkout --force -B master origin/master
git reset --hard
git clean -fdx
git submodule update --init --recursive --force
git submodule foreach git fetch
git submodule foreach git checkout --force -B master origin/master
git submodule foreach git reset --hard
git submodule foreach git clean -fdx
knittl
  • 246,190
  • 53
  • 318
  • 364
  • 62
    Also `-x` if you want to remove your .gitignored files and get back to a pristine state. – jtdubs Dec 01 '10 at 19:45
  • 49
    Add `-n` to test would be removed first. combine all of them in one argument: `-dfn` – HyBRiD Dec 30 '12 at 11:51
  • 34
    My common command is `git clean -qfdx` here. Remove everything and do it silently. – aragaer May 25 '13 at 17:51
  • 8
    `-d -f` can be decalred twice `-dff` for `-d -f -f`, this will delete ALL untracked directories, including protected untracked directories. – ThorSummoner Oct 09 '15 at 23:08
  • 1
    wait so this deletes files? What if you want the untracked files to be exactly as everything was from before? – BenKoshy Oct 26 '15 at 02:53
  • 3
    @BKSpurgeon: yes, it deletes files. What do you mean with »I want untracked files as they were before«? Git doesn't know anything about untracked files, except that they exist. It doesn't track multiple versions of these files (since they are _untracked_). – knittl Oct 26 '15 at 08:04
  • 2
    @knittl - of course that makes perfect sense! i'm inexperienced with git hence the sillyness of my question. thx for the clarification. +1. – BenKoshy Oct 26 '15 at 12:29
  • 1
    see [How do I remove local (untracked) files from my current Git branch?](http://stackoverflow.com/q/61212) – Michael Freidgeim Apr 26 '16 at 07:03
  • there's a lot of duplication in that script. But instead of listing it, lemme contribute an edit... – xeruf Dec 25 '20 at 17:26
  • doesn't work for me, neither any command, even in comments. files are still in index and its written as "modified"... – nick Jun 01 '23 at 16:55
83
git reset --hard && git clean -df

Optional:

There is also an -x option for the git clean command. Which will also delete 'git ignored' files, so add this option as well if it is what you want. zsh provides a 'gpristine' alias which includes the usage of the -x flag:

alias gpristine='git reset --hard && git clean -dfx'

If working on a forked repo, make sure to fetch and reset from the correct repo/branch, for example:

git fetch upstream && git reset --hard upstream/master && git clean -df
Kuba Jagoda
  • 4,908
  • 2
  • 19
  • 21
jjnevis
  • 2,672
  • 3
  • 22
  • 22
  • 10
    Apologies if this is not a safe command - I was not trying to be safe, I was trying to answer the question. Could you comment on whether this answers the question? – jjnevis Dec 28 '15 at 17:22
  • 3
    This works well and should be built into git IMHO (although I'm not sure I would use -x routinely). So many times I'm working on a local project, not yet synced to github etc, and a messy refactor goes haywire beyond the IDE 'undo' state. My instinct is to revert to last commit but googling for that usually takes to answers for penultimate commit, not last commit. All I want to to is get back to most recent commit. This does that. Should be an easier way though. Thanks Linus! ;-) – Dell Anderson Oct 07 '16 at 17:54
  • 14
    **It's dangerous because it also deletes ignored files** with the `-x` like if you'd have just cloned the repo. If that's what you want, it's perfect. If you just want to delete _untracked_ files, removing the `-x` option works well. – Emile Bergeron Oct 02 '17 at 20:03
  • 2
    Thank god for `gpristine` – Snowcrash Oct 24 '18 at 11:42
  • 4
    and deletes intellij settings ;) – Kalpesh Soni Nov 15 '18 at 21:59
  • 5
    Whoever comes to this answer, DO NOT EXECUTE `git clean -dfx`. This will delete files ignored as well. It's not safe to execute this command, except you know what you're doing – Kasra Jul 23 '20 at 13:47
  • 1
    I updated the answer to NOT include the `-x` option by default. Since this is a place where most people copy/paste. It was VERY dangerous. – Ozan Kurt Dec 02 '21 at 15:50
  • 1
    This answer is wrong and dangerous. The `gpristine` alias is not as listed here - IT ALSO DELETES IGNORED FILES (it includes the x flag) Please update your answer. – UpTheCreek Jul 19 '22 at 12:55
  • today I learn git clean -df – Phạm Huy Phát Oct 03 '22 at 03:00
  • Updated the answer once again, because the update removing the`-x` option from the top script also mistakenly removed it from the `gpristine` alias, however `gpristine` DOES INCLUDE THAT OPTION (and therefore it's unsafe - learned it the hard way) – Kuba Jagoda Jun 22 '23 at 05:58
74

If you have files you still want to keep:

git clean -di will do an interactive clean which allows you to only delete the files/dirs you don't want anymore.

Sogger
  • 15,962
  • 6
  • 43
  • 40
25

You can use git stash. You have to specify --include-untracked, otherwise you'll end up with the original problem.

git stash --include-untracked

Then just drop the last entry in the stash

git stash drop

You can make a handy-dandy alias for that, and call it git discard for example:

git config --global alias.discard "! git stash -q --include-untracked && git stash drop -q"
Nikola Diklich
  • 409
  • 1
  • 7
  • 15
21

User interactive approach:

git clean -i -fd

Remove .classpath [y/N]? N
Remove .gitignore [y/N]? N
Remove .project [y/N]? N
Remove .settings/ [y/N]? N
Remove src/com/amazon/arsdumpgenerator/inspector/ [y/N]? y
Remove src/com/amazon/arsdumpgenerator/manifest/ [y/N]? y
Remove src/com/amazon/arsdumpgenerator/s3/ [y/N]? y
Remove tst/com/amazon/arsdumpgenerator/manifest/ [y/N]? y
Remove tst/com/amazon/arsdumpgenerator/s3/ [y/N]? y

-i for interactive
-f for force
-d for directory
-x for ignored files(add if required)

Note: Add -n or --dry-run to just check what it will do.

bit_cracker007
  • 2,341
  • 1
  • 26
  • 26
5

git-clean Use to remove untracked files in the working tree. Following are some options (in brief) that can use with git clean command.

-d use when no path is specified. So git recurse into untracked directories remove them.

-f/--force To remove nested untracked files.

-i/--interactive Show what would be done and clean files interactively.

-n/--dry-run Show what will happen without removing anything.

-x ignore files

example: git clean -f -d -> Remove all untracked files in current directory any subdirectories.

Yuresh Karunanayake
  • 519
  • 1
  • 4
  • 10
3

The command you are looking for is git clean

Dexter
  • 49
  • 3
  • 5
    Next time please do add a little more description/examples etc. Whatever helps the user to understand what it does, and, in this case, what parameters to use. – rugk Oct 21 '18 at 18:26
1

You can add this useful alias to hard reset all the files (tracked and untracked) and to come back to the previous commit version:

git config --global alias.reset-hard '!f() { git reset --hard; git clean -df ; }; f'

Then you can reset this way:

git reset-hard
Alessandro Argentieri
  • 2,901
  • 3
  • 32
  • 62
1

I had a similar issue on Windows and I had to restart PC and make sure I opened the SourceTree/GitBash etc. as an Administrator and then removing the files from interface worked. I assume git clean -f -d it's also going to work if GitBash is opened as Administrator.

Alin Ciocan
  • 3,082
  • 4
  • 34
  • 47
-15

You might have done a soft reset at some point, you can solve this problem by doing

git add .
git reset --hard HEAD~100
git pull
Avery
  • 2,270
  • 4
  • 33
  • 35