git:如何忽略所有当前未跟踪的文件?

169

有没有一种方便的方法可以忽略Git存储库中所有未跟踪的文件和文件夹?
(我知道 .gitignore 的存在。)

这样,git status 命令就会再次提供干净的结果。


可能是重复的问题:有没有办法让Git不显示未跟踪的文件? - random
或者你可以在你的.gitignore文件中添加一个星号*。 :) - vilicvane
2
仅使用 * 很可能不是您想要的。 - sjas
对于这么多错误的答案感到惊讶。-u no 是错误的。-uno 是正确的。-u no 尝试对名为 no 的文件执行状态操作!no 不是 -u 的参数。要强制将 no 解释为 -u 的参数,就不能有空格。要测试这一点,请执行 touch Invalid 并比较 git status -uInvalidgit status -u Invalid - Aaron McDaid
由于 -unono 应该是 -u 的参数,因此认为 Git 的选项解析存在问题是合理的。从历史上看,通常带有参数的选项允许它们之间有空格。 - Mr. Lance E Sloan
12个回答

297

正如已经提到的,要从状态中排除,只需使用:

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

如果您希望永久忽略当前未跟踪的文件,则可以从项目根目录启动以下命令:

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

每次调用git status时,都会明确忽略那些文件。

更新:上述命令有一个小缺陷:如果您还没有.gitignore文件,则gitignore将会忽略它自己!这是因为文件.gitignore在执行git status --porcelain之前就被创建了。因此,如果您还没有.gitignore文件,我建议使用:

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

这将创建一个子shell,在创建.gitignore文件之前完成。 命令说明:由于我得到了很多投票(谢谢!),我认为我最好解释一下命令:
  • 使用git status --porcelain而不是git status --short,因为manual指出“以易于解析的脚本格式提供输出。这类似于短输出,但将在git版本和用户配置无关的情况下保持稳定。” 因此我们既有可解析性又有稳定性;
  • grep '^??' 过滤只包含以??开头的行,这根据 git status manual 对应于未跟踪的文件;
  • cut -c4-删除每行的前3个字符,仅给出未跟踪文件的相对路径;
  • |符号是pipes,该符号将前一个命令的输出传递到下一个命令的输入中;
  • >>>符号是redirect operators,它们将前一个命令的输出追加到一个文件中或覆盖/创建新文件。

另一种变体,适用于那些更喜欢使用sed而不是grepcut的人,这里有另一种方法:

git status --porcelain | sed -n -e 's/^?? //p' >> .gitignore

3
cut -c4-命令会删除每一行的前四个字符,这样我们就只得到了未被跟踪文件的相对路径。其中-c标记表示要裁剪的列数,而4-则选择从第四列到末尾的所有内容,因此将删除第1到3列。因此,您的cut命令实际上会删除每行的前三个字符。如果您从git状态行中删除4个字符,例如这个文件的状态行: ?? app/views/static_pages/contact.html.erb,您将删除app的第一个字母。因此,该命令是正确的,但解释有误。 - 7stud
2
我非常感谢这个命令的解释。知道从互联网上复制的随机命令在做什么很好,这有助于我们更好地学习如何使用命令行和Git。 - Eric Fitting
1
“-u no” 对我不起作用。但是“-uno”可以。我已经相应地更新了答案。这对于 Git 来说是奇怪的设计。我使用的是 Git 1.7.1。 - Aaron McDaid
2
@AaronMcDaid:谢谢。更改已被记录在这里,并在这里进行了讨论。 - Diego
1
@AndreasAbel 这个应该可以工作: git status --porcelain | sed -n -e 's,^?? ,/,p' >> .gitignore - Diego
显示剩余4条评论

65

如果您想永久忽略这些文件,添加到 .gitignore 的简单方法是:

  1. 切换到 git 根目录。
  2. git ls-files --others --exclude-standard >> .gitignore

这将枚举所有未跟踪目录中的文件,可能符合或不符合您的要求。


4
为什么这个没有得到很多投票?不需要经过其他两个程序的筛选! - JoelFan
8
@JoelFan提供了两个原因: 1)这个方法只在git的根目录下起作用,而被接受的方法可以在任何子目录中起作用,你只需要调整目标.gitignore文件的路径。 2)如果你有一个未跟踪的目录,这个方法会列出其中每个文件,但不包括未跟踪的目录本身(所以你不会忽略目录,因此在未来文件被报告为未跟踪时,你仍然会得到它们的通知)。被接受的方法只列出目录,而不是其中未跟踪的文件。这是一个视情况而定的问题,但通常你只想忽略整个目录。 - Diego
1
谢谢你,Poolie,我很欣赏你的建议之处。因为Diego提到的几点,我开始使用文件和文件夹库进行工作,并且我不想跟踪/推送原始文件。我只想跟踪我添加或重新构建的库文件。添加父文件夹将忽略一切。这个/你的解决方案可以在瞬间添加所有1696个文件。xD - Chaos7703
这也可以通过使用 git config status.showUntrackedFiles no 来实现。 - larsch
1
@Diego,它只在根git目录中工作是不准确的。它可以在任何子目录中工作,但它会添加到该子目录的.gitignore中,在许多用例中是有效的。 - CervEd
1
这是更优雅的解决方案,适用于许多常见情况。问题在于文件列表缺少前导“/”,因此需要插入一步操作,将“/”添加到每个文件的开头。 - Andreas Abel

25

手册中找到了它。

mode参数用于指定如何处理未跟踪的文件。它是可选的:默认值为all,如果指定,则必须与选项结合使用(例如,-uno,但不能是-u no)。

git status -uno


59
如果每个人在发帖前都好好看一下使用手册,那么我们就永远得不到任何声望了 :-) - Jenny D

12

我认为比起已接受的答案,以下方法更好:

git config --local status.showUntrackedFiles no

已接受的答案无法处理未在 .gitignore 中列出的新增文件。


2
问题标题提到了“展示未跟踪的文件”,因此没有提到忽略未来的文件。此外,我会说忽略所有未来的未跟踪文件相当罕见。 - Diego
1
谢谢!这正是我要找的!(即使这似乎不是此处OP要找的...)@Diego,任何在StackOverflow上搜索此类问题的人都可能有罕见的用例哈哈。 - Matt

9

以上答案都对我没用。

在我的情况下,我想永久地忽略一个个人配置文件(git status -uno只在一次使用中有效)。

由于我是团队的一员,所以不能将其添加到.gitignore中,因为它会被检查进去。

我的解决方案是将其添加到:

.git/info/exclude

这就像是你自己的个人.gitignore文件。


非常感谢!这正是我所需要的!谢谢。 - undefined

6

两种方法:

  • 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.


2
一个方便的编辑 .gitignore 的方法是 git status | cat >> temp && vim temp。然后编辑文件,删除前几行和最后一行,以及尾随的 # 和其后的空格。然后执行 cat temp >> .gitignore && rm temp。如果之前没有 .gitignore,则可以使用 mv temp .gitignore。虽然不太美观,但比手动更新 .gitignore 要好得多。 - sjas
1
这个答案是不正确的。正确的答案是-uno。如果你使用-u no,它等同于no -u - 它将对一个名为no的文件执行状态(该文件可能不存在),并使用默认的-u模式。也就是说,它相当于git status no - Aaron McDaid

5

-u no 也不显示未暂存的文件。使用 -uno 可以如愿以偿地显示未暂存的文件,但隐藏未跟踪的文件。


1
即使这样也不完全正确。git status -u X 等同于 git status X -u (X 不是 -u 的参数)。这又等同于 git status X(因为没有参数的 -u 是默认的 -u)。因此,它仅仅是在文件 X 上执行了一次 git-status。因此,如果 Xno,它只是试图在一个名为 no 的文件上执行 git status,而您可能没有这个文件。 - Aaron McDaid

2

如果您的操作系统不是类Unix操作系统,那么可以使用PowerShell在Windows上运行此命令:

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

然而,.gitignore文件必须有一个新的空行,否则它会将文本追加到最后一行,而不管它是否有内容。

这可能是更好的选择:

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


这是做什么的? - Unknow0059

1
如果您有很多未跟踪的文件,并且不想“gitignore”它们全部,注意自git 1.8.3 (April, 22d 2013)以来,即使您没有添加该选项,git status也会提到--untracked-files=no
"git status"建议用户在执行时间过长时考虑使用--untracked=no选项。

1
git reset --hard HEAD
git clean -fxd

将会删除所有未被跟踪的文件,并使您的本地分支与远程分支保持最新状态。如果您不想保留已经进行的任何本地更改,这是一个好的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接