git stash -u (git stash --include-untracked) - Best way to discard uncommitted changes?

I found a link (http://stackoverflow.com/questions/22620393/remove-local-git-changes) that indicates that git stash –u will discard all file changes and get me back to the last commit. I’ve tried it. It seems to work. Yet the command doesn’t seem consistent  with Git’s intent for git stash (http://git-scm.com/docs/git-stash) Is git stash –u the best way to accomplish a discard?
jdanaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

tigermattCommented:
indicates that git stash –u will discard all file changes and get me back to the last commit. I’ve tried it. It seems to work. Yet the command doesn’t seem consistent  with Git’s intent for git stash (http://git-scm.com/docs/git-stash) Is git stash –u the best way to accomplish a discard?
Yes and no. Depends on what you are trying to accomplish; your question is somewhat vague by mentioning "discard all file changes". It depends which files you want to discard changes to: files already committed, new files which are untracked (never been committed nor subject to a git add invocation).

There are several commands I will mention below; pick the best one for your usecase.

---

An alternative command is git reset --hard.

The git reset command allows the branch head (the HEAD pointer), the index and/or the working tree to be manipulated. Passing the --hard switch causes the index and working tree to be completely reverted to the state at the last commit -- in other lingo, all changes since the last commit are discarded from the index and the working tree. HOWEVER, note that git reset will not delete untracked files -- git silently skips over them.

It WILL, however, delete a file which has been staged to the index but not yet committed -- i.e. if you run git add <NEWFILE> followed immediately thereafter by git reset --hard, the file goes away at that point because the change has been staged and is now being tracked in the index.

Another command of note is the git clean command. The definition of this command in the man page -- the canonical reference for figuring out what commands do -- is this:

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

Hence, git clean is a more appropriate choice if you are trying to remove untracked files from the repository. There are various switches to pass to the command; of particular note are -n for a dry-run (show changes which would be made, but don't make them) and -i for an interactive interface. Check out the other switches from a Unix-like system by interrogating the man page with man git-clean.

As you rightly point out, the stash command is almost certainly not what you want to do unless you want to keep a copy of changes to files around after resetting the state to the last commit. As I am sure you know, git stash allows you to keep the diff of changes to be manipulated on a stack, and later replayed over the repository at your leisure.

Passing the -u (or, equivalently, --include-untracked) switch to git stash, then untracked files are also saved in the stash and then removed.

The key insight is that stash simply makes use of the other commands to go about "cleaning up" the repository and resetting its state: by default, git stash or git stash save makes the stash entry and then calls git reset --hard to reset the index and working state to the last commit.

Hence, you guessed it: git stash -u, the subject of your question, resets the index and working state, but also takes a copy of untracked files followed by issuing a call to git clean to remove the untracked files from the working tree.

So, it really depends on what you want to do:

if you want to remove all the untracked files in your repository, and you do not desire to keep a copy of them hanging around to be replayed later, then git clean is your friend
if you want to do the above, but keep a copy of those untracked files for later use, then you can stash them using git stash -u and later replay the stash in the usual way
If you want to do some other combination (many more not considered here), then check out the git man-pages. For any git NNN command, the man page can be read using man git-NNN (i.e. replace the space with a hyphen '-').

---
PROTIP:

I should note that git clean's default behavior will not simply walk all over your repository and obliterate all the untracked files you put there for later commit; that is not git's style.

As you will learn when you first issue the command, the default git configuration will cause an error message to be displayed; no changes are made to the repository and you are required to pass a further switch to git clean to override its safety and allow it to permanently destroy untracked files.

I have deliberately not described the switch here, to force you to experiment with this command before using it in anger in a real repository, and to encourage appeal to the man pages or the git help pages to review the syntax. :-)
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jdanaAuthor Commented:
tigermatt -

Wow. What a response. Along with git stash and git reset --hard, git clean is now in my toolkit.

Have a great weekend

J
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Git

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.