Difference between git reset --hard and git clean
Asked Answered
C

2

32

Hi I am curious about the difference between these two commands. When they introduce here: https://www.atlassian.com/git/tutorials/undoing-changes

Looks like git reset --hard also sets both the staging and the working directory to match the latest commit, but in the end they say that git reset --hard won't change the current working directory. So I am very confused here, can someone clarify it?

Cointon answered 11/6, 2015 at 0:26 Comment(7)
Where does it say 'that git reset --hard won't change the current working directory'? It explicitly says the opposite - "Put another way: this [hard reset] obliterates all uncommitted changes".Wigan
Also, pay attention to "Remember that [hard] resetting only affects tracked files, so a separate [clean] command is required for cleaning up untracked ones. "Wigan
@Wigan right it obliterates all uncommitted changes but if it also resets the working directory to match the last commit, why do we still need the git clean command, since in this case there won't be any untracked files as the working directory and the staging area are the sameCointon
Per the second quote: only. The use of "uncommitted" in refers only to files that git is aware/tracking of (ie. they have been added), but not random "untracked" files floating about in the working directory.Wigan
See git-scm.com/book/en/v2/… : "Remember that each file in your working directory can be in one of two states: tracked or untracked. Tracked files are files that were in the last snapshot; they can be unmodified, modified [representing unstaged/uncomitted changes], or staged [representing uncommitted changes]. Untracked files are everything else – any files in your working directory that were not in your last snapshot and are not in your staging area [are untracked]."Wigan
@Wigan the files that git doesn't recognize, could those be useful ones?Cointon
Perhaps it's some very tedious life changing vital non-reproducible work of art that has been forgotten to be added to git yet. In that case, yes, I'd say it's important/useful - and it would probably be upsetting if it was deleted by running git clean. One of the biggest gripes I've heard about git is new users forgetting to add [and subsequently stage] files. Git doesn't lose changes [without a bit of help] - but some changes never make it into git at all!Wigan
C
23

They do two different things . Let say , you did GIT PULL and then started editing some files and probably have added and commited those changes to the be pushed ... and then for some reason you decided to just discard all the changes that have been made to the given files and go back an earlier state . in the case you will do

$ git reflog
... snip ...
cf42fa2... HEAD@{0}: commit: fixed misc bugs
~
~
cf42fa2... HEAD@{84}: commit: fixed params for .....
73b9363... HEAD@{85}: commit: Don't symlink to themes on deployment.
547cc1b... HEAD@{86}: commit: Deploy to effectif.com web server.
1dc3298... HEAD@{87}: commit: Updated the theme.
18c3f51... HEAD@{88}: commit: Verify with Google webmaster tools.
26fbb9c... HEAD@{89}: checkout: moving to effectif

Choose the commit that you want to roll back to, like so:

git reset --hard 73b9363

after resetting HEAD , all changes/staged files will be gone.

As for git clean . Below is how git-scm.com describes it.

DESCRIPTION
Cleans the working tree by recursively removing files that 
are not under version control, starting from the current directory.

Normally, only files unknown to Git are removed, but if the -x
option is specified, ignored files are also removed. This 
can, for example, be useful to remove all build products.

If any optional <path>... arguments are given, only those paths are affected.

More about reset vs clean and their --options

lnydex99uhc:~  user$ git reset -h
usage: git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]
   or: git reset [-q] <tree-ish> [--] <paths>...
   or: git reset --patch [<tree-ish>] [--] [<paths>...]

    -q, --quiet           be quiet, only report errors
    --mixed               reset HEAD and index
    --soft                reset only HEAD
    --hard                reset HEAD, index and working tree
    --merge               reset HEAD, index and working tree
    --keep                reset HEAD but keep local changes
    -p, --patch           select hunks interactively

VS

 lnydex99uhc:~ user$ git clean -h
    usage: git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>...

        -q, --quiet           do not print names of files removed
        -n, --dry-run         dry run
        -f, --force           force
        -i, --interactive     interactive cleaning
        -d                    remove whole directories
        -e, --exclude <pattern>
                              add <pattern> to ignore rules
        -x                    remove ignored files, too
        -X                    remove only ignored files
Cartilaginous answered 11/6, 2015 at 0:55 Comment(4)
thanks for sharing. does that mean this is a strong command that might affect future coding on the project?Cointon
It will effect recent changes and by resetting to an earlier commit you are telling git to trash all the new changes since the last commit .Cartilaginous
Wrt "all changes/staged files will be gone" - this only affects non-committed changes. Committed changes (as seen with reflog) will always be persisted and can always be recovered as long as they are reachable - eg. via branch, tag, or child. (The only time git 'loses' a commit is when the GC runs and they are not reachable, except by id.) Rewriting commits is a different beast, but git reset is simply not capable of modifying/removing previous commits.Wigan
^- All that is to say is, as long as there are no modified/staged files and all the changes are committed or stashed, git reset doesn't really "affect [existing or] future coding" because it's just as easy to revert. Losing non-committed changes is an immediate concern, not a long-term one.Wigan
E
0

Overview

  • git reset = remove tracked changes.
  • git clean = remove untracked changes.

Example: Reset

Reset the current HEAD (tracked files) to the specified state.

$ git reset
$ git reset --hard
  • git reset = unstage all staged changes.
  • --hard = discard all tracked changes (staged and unstaged), and delete files and directories in the way of writing tracked files.
    • (outcome: reset the index of the working tree).

Example: Clean

Remove files not tracked, skipping ignored files (unless -x).

$ git clean -f -d
$ git clean -f -d -x
  • -f = force (might be required based on other settings).
  • -d = includes untracked directories.
  • -x = skip ignore rules (e.g. will delete files ignored by ".gitignore", like the bin and .vs folders).
Ease answered 5/7 at 11:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.