169

Is there a handy way to ignore all untracked files and folders in a git repository?
(I know about the .gitignore.)

So git status would provide a clean result again.

Brian Webster
  • 30,033
  • 48
  • 152
  • 225
sjas
  • 18,644
  • 14
  • 87
  • 92
  • possible duplicate of [is there a way to get git not to show the untracked files?](http://stackoverflow.com/questions/2774416/is-there-a-way-to-get-git-not-to-show-the-untracked-files) – random Jul 28 '12 at 04:48
  • Or you may want to add a single * to your .gitignore file. :) – vilicvane Aug 07 '13 at 07:38
  • 2
    Just a `*` will very likely not be what you want. – sjas Oct 23 '13 at 18:44
  • 1
    possible duplicate of [how to add all currently untracked files/folders to git ignore?](http://stackoverflow.com/questions/15862598/how-to-add-all-currently-untracked-files-folders-to-git-ignore) – RedX Nov 05 '13 at 12:55
  • Surprised at so many incorrect answers. `-u no` is wrong. `-uno` is correct. `-u no` tries to do a status on a file called `no`! The `no` is *not* an argument to `-u`. To force `no` to be interpreted as an argument to `-u`, there must be no space. To test this, do `touch Invalid` and compare `git status -uInvalid` to `git status -u Invalid`. – Aaron McDaid Mar 01 '16 at 10:55
  • Since the `no` of `-uno` is supposed to be an argument to `-u`, it's reasonable to consider git's option parsing to be broken. Historically, options that take arguments usually allow spaces between them. – Mr. Lance E Sloan Oct 27 '16 at 13:59

12 Answers12

295

As already been said, to exclude from status just use:

git status -uno  # must be "-uno" , not "-u no"

If you instead want to permanently ignore currently untracked files you can, from the root of your project, launch:

git status --porcelain | grep '^??' | cut -c4- >> .gitignore

Every subsequent call to git status will explicitly ignore those files.

UPDATE: the above command has a minor drawback: if you don't have a .gitignore file yet your gitignore will ignore itself! This happens because the file .gitignore gets created before the git status --porcelain is executed. So if you don't have a .gitignore file yet I recommend using:

echo "$(git status --porcelain | grep '^??' | cut -c4-)" > .gitignore

This creates a subshell which completes before the .gitignore file is created.

COMMAND EXPLANATION as I'm getting a lot of votes (thank you!) I think I'd better explain the command a bit:

  • git status --porcelain is used instead of git status --short because manual states "Give the output in an easy-to-parse format for scripts. This is similar to the short output, but will remain stable across git versions and regardless of user configuration." So we have both the parseability and stability;
  • grep '^??' filters only the lines starting with ??, which, according to the git status manual, correspond to the untracked files;
  • cut -c4- removes the first 3 characters of every line, which gives us just the relative path to the untracked file;
  • the | symbols are pipes, which pass the output of the previous command to the input of the following command;
  • the >> and > symbols are redirect operators, which append the output of the previous command to a file or overwrites/creates a new file, respectively.

ANOTHER VARIANT for those who prefer using sed instead of grep and cut, here's another way:

git status --porcelain | sed -n -e 's/^?? //p' >> .gitignore
Diego
  • 5,326
  • 1
  • 35
  • 32
  • 3
    `cut -c4- ` **removes the first 4 characters of every line, which gives us just the relative path to the untracked file;** No. `-c` marks the beginning of a list of column numbers to cut. And `4-` *selects* the line from column 4 to the end, which cuts columns 1-3. So your cut command actually removes the first 3 characters of each line. If you removed 4 characters from a git status line such as the one for this file here: `?? app/views/static_pages/contact.html.erb`, you would remove the first letter of `app`. So the command is correct, but the explanation is faulty. – 7stud Sep 10 '14 at 21:03
  • @7stud: thank you, you are right, I've wrote 4 by mistake. I've fixed the answer. – Diego Sep 11 '14 at 10:17
  • Slight correction for my comment above: *-c marks the beginning of a list of columns to select*. Any column not selected is cut. – 7stud Sep 11 '14 at 17:58
  • 2
    I really appreciate the command explanation. Its nice to know what the random commands I copied from the internet are doing, and helps us all learn how to use the command line and git better. – Eric Fitting Mar 19 '15 at 13:36
  • 1
    `-u no` doesn't work for me. But `-uno` does. I've updated the answer accordingly. This is strange design for git. I'm on git 1.7.1 – Aaron McDaid Mar 01 '16 at 10:48
  • 2
    @AaronMcDaid: thanks. The change is documented [here](http://www.spinics.net/lists/git/msg260063.html), and discussed [here](http://www.spinics.net/lists/git/msg259971.html) – Diego Mar 02 '16 at 10:45
  • Many times when I have output from a command I want to send to a file but I don't want the presence of the file included, I pipe the output through `sort -o filename`. Obviously sometimes that's going to corrupt the output if order is important. – pedz Oct 24 '22 at 14:33
  • This solution is slightly incorrect. The files listed miss a leading `/`, so there should be a step inserted that prepends `/` to every file. – Andreas Abel Jan 26 '23 at 07:33
  • 1
    @AndreasAbel this should work: `git status --porcelain | sed -n -e 's,^?? ,/,p' >> .gitignore` – Diego Jan 27 '23 at 13:50
64

If you want to permanently ignore these files, a simple way to add them to .gitignore is:

  1. Change to the root of the git tree.
  2. git ls-files --others --exclude-standard >> .gitignore

This will enumerate all files inside untracked directories, which may or may not be what you want.

poolie
  • 9,289
  • 1
  • 47
  • 74
  • 4
    Why doesn't this get as many votes? No need to pipe through 2 other programs! – JoelFan Jan 04 '17 at 21:56
  • 8
    @JoelFan: two reasons: 1) **this one works only from the root of the git**, while the accepted one works from every subdirectory, you just need to tweak the destination `.gitignore` path 2) if you have an untracked directory, **this one list each and every single file in it, but not the untracked directory itself** (so you won't ignore the directory, and thus still get reported future files in the directory as untracked, while the accepted one lists only the directory, and not the untracked files inside. This is a matter of what you want to do, but often you just want to ignore the whole dir – Diego Jun 30 '17 at 13:50
  • 1
    Thank you Poolie I appreciate the difference *of* your suggestion *because* of the points mentioned by @Diego I started working with a library of files & folders and I don't want to track/push the original files. I only want to track files I add or rebuild in the library. Adding the parent folders would ignore everything. This/your solution added all 1696 files in a snap. xD – Chaos7703 Jul 30 '17 at 02:58
  • This can also be achieved using `git config status.showUntrackedFiles no`. – larsch Dec 26 '19 at 19:47
  • 1
    @Diego, it's inaccurate that it only works in the root git directory. It works in any subdirectory but it adds to that subdirectories `.gitignore`, which is valid in many use-cases – CervEd Mar 30 '21 at 08:01
  • 1
    This is the more elegant solution, which works for many common cases. Minor flaw in the ointment: The files listed miss a leading `/`, so there should be a step inserted that prepends `/` to every file. – Andreas Abel Jan 26 '23 at 07:31
24

Found it in the manual

The mode parameter is used to specify the handling of untracked files. It is optional: it defaults to all, and if specified, it must be stuck to the option (e.g. -uno, but not -u no).

git status -uno

sjas
  • 18,644
  • 14
  • 87
  • 92
12

IMHO better than the accepted answer is to use the following:

git config --local status.showUntrackedFiles no

The accepted answer does not work for when new files are added that are not in .gitignore

Martin
  • 659
  • 7
  • 14
  • 2
    The question title mentions "present untracked files", so there's no mention of ignoring future files. Also ignoring all future untracked files is quite a rare use case, I would say. – Diego Jul 21 '21 at 07:32
  • 1
    Thanks! Exactly what I was looking for! (Even though it doesn't seem to be what the OP here was looking for...) @Diego, anyone searching StackOverflow for things like this already likely has a rare usecase lol. – Matt Sep 10 '21 at 17:13
6

None of the above answers worked for me.

In my case, I want a personal config file to be ignored permanently (git status -uno only works for one use).

I'm part of a team so can't add it to .gitignore as that's checked in.

Mu solution was to add it to:

.git/info/exclude

which is like your own personal .gitignore file.

Snowcrash
  • 80,579
  • 89
  • 266
  • 376
5

Two ways:

  • use the argument -uno to git-status. Here's an example:

    [jenny@jenny_vmware:ft]$ git status
    # On branch ft
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #       foo
    nothing added to commit but untracked files present (use "git add" to track)
    [jenny@jenny_vmware:ft]$ git status -uno
    # On branch ft
    nothing to commit (working directory clean)
    
  • Or you can add the files and directories to .gitignore, in which case they will never show up.

guntbert
  • 536
  • 6
  • 19
Jenny D
  • 1,225
  • 9
  • 20
  • 2
    A handy way of editing the `.gitignore` being `git status | cat >> temp && vim temp`. Then editing the file so the first few lines and last line is deleted, as well as trailing `#` and the whitespace after it. Then `cat temp >> .gitignore && rm temp`. In case no `.gitignore` was present before, `mv temp .gitignore` will do. Ugly stuff but better than updating the `.gitignore` manually. – sjas Jul 18 '12 at 13:53
  • 1
    This answer is incorrect. The correct answer is `-uno`. If you use `-u no`, it is equivalent to `no -u` - it will do a status on a file called `no` (which probably doesn't exist) and use the default `-u` mode. i.e. it is equivalent to `git status no` – Aaron McDaid Mar 01 '16 at 10:50
4

-u no doesn't show unstaged files either. -uno works as desired and shows unstaged, but hides untracked.

football
  • 300
  • 3
  • 8
  • 1
    Even this isn't quite correct. `git status -u X` is equivalent to `git status X -u` (`X` is not an argument to `-u`). This, in turn, is equivalent to `git status X` (because `-u` without an argument is the default `-u`). Therefore, it is simply a git-status on file `X`. So, if `X` is `no` it simply tries to do a git status on a file called `no`, which you probably don't have – Aaron McDaid Mar 01 '16 at 10:53
2

In case you are not on Unix like OS, this would work on Windows using PowerShell

git status --porcelain | ?{ $_ -match "^\?\? " }| %{$_ -replace "^\?\? ",""} | Add-Content .\.gitignore

However, .gitignore file has to have a new empty line, otherwise it will append text to the last line no matter if it has content.

This might be a better alternative:

$gi=gc .\.gitignore;$res=git status --porcelain|?{ $_ -match "^\?\? " }|%{ $_ -replace "^\?\? ", "" }; $res=$gi+$res; $res | Out-File .\.gitignore

vhanla
  • 750
  • 5
  • 15
1

If you have a lot of untracked files, and don't want to "gitignore" all of them, note that, since git 1.8.3 (April, 22d 2013), git status will mention the --untracked-files=no even if you didn't add that option in the first place!

"git status" suggests users to look into using --untracked=no option when it takes too long.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
1
git reset --hard HEAD
git clean -fxd

will remove any untracked files, and make your local branch up to date with the remote branch. this is good option if you don't want to preserve any local changes you already made.

0

I came here trying to solve a slightly different problem. Maybe this will be useful to someone else:

I create a new branch feature-a. as part of this branch I create new directories and need to modify .gitignore to suppress some of them. This happens a lot when adding new tools to a project that create various cache folders. .serverless, .terraform, etc.

Before I'm ready to merge that back to master I have something else come up, so I checkout master again, but now git status picks up those suppressed folders again, since the .gitignore hasn't been merged yet.

The answer here is actually simple, though I had to find this blog to figure it out:

Just checkout the .gitignore file from feature-a branch

git checkout feature-a -- feature-a/.gitignore
git add .
git commit -m "update .gitignore from feature-a branch"
0

To add to @Diego's answer above, I think the mentioned solutions will fail for files with spaces (and possibly other special characters, like " itself, although I haven't checked) in their names. This line:

echo "$(git status --porcelain | grep '^??' | cut -c4- | sed 's/^\"//;s/\"$//')" >> .gitignore

removes starting and trailing double quotes where present which fixes it.

I'm not very good with sed though, there may be a better way to do this, or edge cases.

hex
  • 1