git-clean - Remove untracked files from the working tree
Synopsis
git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>…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
-xoption 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.
Step 1 is to show what will be deleted by using the -n option:
# Print out the list of files and directories which will be removed (dry run)
git clean -n -d
Clean Step - beware: this will delete files:
# Delete the files from the repository
git clean -f
- To remove directories, run
git clean -f -dorgit clean -fd - To remove ignored files, run
git clean -f -Xorgit clean -fX - To remove ignored and non-ignored files, run
git clean -f -xorgit clean -fx
Note the case difference on the X for the two latter commands.
If clean.requireForce is set to "true" (the default) in your configuration, one needs to specify -f otherwise nothing will actually happen.
Again see the git-clean docs for more information.
Options
-f,--forceIf the Git configuration variable clean.requireForce is not set to false, git clean will refuse to run unless given
-f,-nor-i.
-xDon’t use the standard ignore rules read from .gitignore (per directory) and
$GIT_DIR/info/exclude, but do still use the ignore rules given with-eoptions. This allows removing all untracked files, including build products. This can be used (possibly in conjunction with git reset) to create a pristine working directory to test a clean build.
-XRemove only files ignored by Git. This may be useful to rebuild everything from scratch, but keep manually created files.
-n,--dry-runDon’t actually remove anything, just show what would be done.
-dRemove untracked directories in addition to untracked files. If an untracked directory is managed by a different Git repository, it is not removed by default. Use
-foption twice if you really want to remove such a directory.
git-clean - Remove untracked files from the working tree
Synopsis
git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>…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
-xoption 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.
Step 1 is to show what will be deleted by using the -n option:
# Print out the list of files and directories which will be removed (dry run)
git clean -n -d
Clean Step - beware: this will delete files:
# Delete the files from the repository
git clean -f
- To remove directories, run
git clean -f -dorgit clean -fd - To remove ignored files, run
git clean -f -Xorgit clean -fX - To remove ignored and non-ignored files, run
git clean -f -xorgit clean -fx
Note the case difference on the X for the two latter commands.
If clean.requireForce is set to "true" (the default) in your configuration, one needs to specify -f otherwise nothing will actually happen.
Again see the git-clean docs for more information.
Options
-f,--forceIf the Git configuration variable clean.requireForce is not set to false, git clean will refuse to run unless given
-f,-nor-i.
-xDon’t use the standard ignore rules read from .gitignore (per directory) and
$GIT_DIR/info/exclude, but do still use the ignore rules given with-eoptions. This allows removing all untracked files, including build products. This can be used (possibly in conjunction with git reset) to create a pristine working directory to test a clean build.
-XRemove only files ignored by Git. This may be useful to rebuild everything from scratch, but keep manually created files.
-n,--dry-runDon’t actually remove anything, just show what would be done.
-dRemove untracked directories in addition to untracked files. If an untracked directory is managed by a different Git repository, it is not removed by default. Use
-foption twice if you really want to remove such a directory.
Use git clean -f -d to make sure that directories are also removed.
Don’t actually remove anything, just show what would be done.
git clean -nor
git clean --dry-runRemove untracked directories in addition to untracked files. If an untracked directory is managed by a different Git repository, it is not removed by default. Use the
-foption twice if you really want to remove such a directory.git clean -fd
You can then check if your files are really gone with git status.
git checkout -- * and skip untracked files - Stack Overflow
How can I checkout an untracked file in a git stash? - Stack Overflow
version control - Why does git checkout not delete new files? - Stack Overflow
Checkout removes untracked files
git stash internally creates special black magic merge commits to store different parts of your changes. The merge commit has the original base commit (what you had at the top of the branch when you stashed) as its first parent, a throwaway commit representing the index contents at time of stashing as its second parent, and (only if you used --include-untracked) a throwaway commit containing the untracked files as its third parent.
So, the merge commit references the untracked files (as one of its parents)... but it doesn't actually include those files in its own tree (if that doesn't make any sense, either you've got a few things to learn yet about Git's internals... or you know too much about merge commits and this whole construct just seems too horrible to think about ;)).
In short... to access the untracked parts of your stash, access its third parent: git checkout stash@{0}^3 -- filename
I've got a scratch branch that I experiment with but don't generally commit to. I want to pull over a few select changes into my real topic branch.
In that case, don't bother with stashing the changes to move them from one branch to another. Do directly a git commit, and move the changes from the branch you committed on to the other one using git cherry-pick: git cherry-pick #hash_of_the_commit.
git checkout doesn't overwrite your working copy by-design.
It works in the same way as git reset --hard but with the important difference - git checkout is working-directory safe, so it doesn't overwrite existing changes in your working directory. Actually, it’s a bit smarter — it tries to do a trivial merge in the working directory.
So, if you want to discard all of your changes and just get the snapshot from HEAD use git reset --hard HEAD or just git reset --hard instead.
But even git reset --hard doesn't remove your untracked files. To remove untracked files:
- Run
git clean --dry-run. It just tells you what will be removed. Do it because cleaning is a dangerous command. - Run
git clean --forceto eventually remove your untracked files.
You can find more details about git checkout and git reset here and about cleaning here.
file.txt, being untracked, is "invisible" to Git. If there is another file named file.txt in the commit you check out, it can be overwritten as a side effect of the check out, but Git won't go out of its way to removed untracked files.
I don't understand this message. What it's saying seems to indicate to me that the files being listed should show up when I do git status, but nothing does. Why is that? I must have a fundamental misunderstanding here.
Context of the problem:
I created a new feature branch (breaking change feature) and created bunch of files in it (not ready for commit yet).
Now I have need to go back to my main and do some not related hotfix.
But when I checkout to my main branch all new files from feature branch are still there, and because its a breaking change I can't run npm run dev without tons of errors.
I want to see my main branch as it is in my github repo without bringing any changes from.
Commands I've used:git stash // on feature branchgit checkout main // on feature branchnpm run dev // results in errors, due to breaking changes in new files
Research I have completed prior to requesting assistance:
Googled the title of this post.
Looked at stack overflow solutions telling to use git stash / git switch, but that didn't help.
----------
Solved.
Changed branches via GitHub Desktop app leaving all changes on feature branch.Why terminal git commands didn't work for me - I have no idea.
When you switch to a branch, Git makes sure that your working tree matches the content of the commit you're switching. Quoting an extract of Basic Branching of the Git Pro book:
when you switch branches, Git resets your working directory to look like it did the last time you committed on that branch. It adds, removes, and modifies files automatically to make sure your working copy is what the branch looked like on your last commit to it.
This means that:
Every tracked file in your working directory that is not present in the selected commit will be removed.
Every tracked file in the selected commit that is not present in your working directory will be added.
Every tracked file that is present in both your working directory and the selected commit will be updated to the version contained in the commit.
In your case, even though master had a .gitignore for some of the files on gitignoreless, once you switched to master those files had to be removed in order to match the content of master's head commit. This is because the files were already tracked on gitignoreless, and every tracked file in the working directory that is not contained in the selected commit is removed.
As already explained by @matt, .gitignore affects only files that are not already in the index. Therefore, you might want to consider having your .gitignore on all your branches, and build it in such a way to not show undesired files during the staging process. However, since some of the undesired files have already been tracked, you can "untrack" them with the --cached option of git rm. In your case, you could run:
# untrack the undesired files
git rm --cached <file1> <file2> ... <fileN>
# add the previous files as entries in your gitignore
echo <file1> >> .gitgnore
echo <file2> >> .gitgnore
...
echo <fileN> >> .gitgnore
The entire approach here (indeed, the very question title itself) seems to be based on a misapprehension, or a cascade of misapprehensions, about gitignore (and perhaps Git itself):
gitignore is not branch-based.
gitignore does not affect what happens during checkout.
gitignore has no effect on files that already exist in the repo (i.e. in the current HEAD); it affects only files that are not already in the index, and it affects only what happens when you say things like
git statusorgit add.
So, if the goal is simply to develop a gitignore, then just develop it, i.e. change it incrementally, over time, as experience suggests.
How? Well, as I said, this is all about what git status means (and what git add . means). So think about your gitignore as you are making a commit by assembling files in the index. Every time you are about to make a commit, say git status to see what Git "knows" about the working tree in relation to the index (and the index in relation to the HEAD).
If you see a file being tracked in a way you don't like (e.g. it is listed as untracked and you want it to be both untracked and not mentioned any longer), list it in gitignore.
If you see a file has already been made part of the index and it shouldn't be, remove it from the index and list it in gitignore.
If files that you don't think should be checked in have already been checked in (i.e. not just in the index but in the HEAD), gitignore will have no effect on that. It would then be incumbent on you to delete such a file from the index and check that in as a commit, so that the file doesn't reappear in the index every time you switch to this branch.
Ultimately, though, don't expect gitignore to work some kind of magic. It is merely a time-saver, to help keep files from being checked into the repo that you do not want shared between developers (or with the public, if it's a public repo). Use it for what it's intended for and you'll be fine.