我如何像 rcsclean 一样使用 git 进行清理

How do i do a clean with git like rcsclean

我习惯于 rcs. after checking in, i usually do an rcsclean 删除所有存在的跟踪罚款,因此目录中只有 未跟踪 文件。我有时会执行 rcsclean -u 来撤消对跟踪文件的任何更改。

我如何在 git 中执行此操作?

之后,当前目录及其子目录中应该只有未跟踪的文件(当然除了 .git 存储库本身)。

使用Git状态

Git 和 RCS 有不同的用例。想要清除你的 Git 工作树是非常不寻常的,所以我假设这是一个 X/Y 问题,你试图查看当前未跟踪的文件。

为此有一个内置的 Git 命令:git status --untracked-files。此命令的默认模式是 all,与默认为 normalgit status(没有标志)的输出相反。有关详细信息,请参阅 man 1 git-status

例子

mkdir -p foo/bar/baz
touch foo/quux foo/bar/wibble
git status -u
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

  foo/bar/wibble
  foo/quux

nothing added to commit but untracked files present (use "git add" to track)

警告:空目录树

请注意,没有文件的目录树不会显示在此输出中。这是因为 Git 不跟踪目录,除非是树对象的一部分,因此本示例中的 foo/bar/baz 永远不会显示为未跟踪,除非文件(a.k.a. 目录条目)存在于或在目录树中 baz 下面。

换句话说,要使 baz 显示为未跟踪,baz 中必须有文件或 baz 必须包含一个文件。例如,使用 --short 标志以获得更简洁的输出:

$ touch foo/bar/baz/file; git status -s -u
?? foo/bar/baz/file
?? foo/bar/wibble
?? foo/quux

将在输出中包含 foo/bar/baz/file。为此,人们经常使用像 .gitkeep 这样的空隐藏文件。

TL;DR

Git 不是 RCS。你可以做你想做的事,但如果你试图将 Git 存储库视为基于文件的修订控制系统,你将给自己带来长期的痛苦。

可以 删除 Git 正在跟踪的文件,但是具有 larger/deeper 目录树的项目将需要您采取额外的步骤来删除空目录 ( Git 不会作为第一个 class 对象进行跟踪),并且您将失去执行 git commit -a 之类的操作的能力,而不 Git 认为您正在删除所有文件.

删除文件和目录

您可以使用 ls-files 子命令删除 Git 知道的所有文件。您需要将输出通过管道传输到 xargs,因为 rm 命令本身不会处理以 null 结尾的字符串,如果没有它们,"foo bar/baz quux" 之类的路径会导致问题。

要删除提交给 Git 的所有 文件

$ git ls-files -z | xargs -0 -- rm -f

但是,Git 并不真正跟踪目录;它跟踪 。因此,除非您将所有文件都放在项目的根目录中,否则如果您希望它们也消失,则需要将 空目录 作为单独的命令自行删除。例如:

$ find . -type d -empty -not -path '*.git*'

清洁后要避免的命令

完成此操作后,您需要避免使用 git commit -a 之类的命令,这些命令会将所有丢失的文件视为已删除。相反,您必须更加小心地暂存文件。您可能还想调查 man git-update-index 并考虑 --assume-unchanged 标记是对您的情况有所帮助还是使情况变得更糟。

此外,git status 命令将继续显示大量更改,因为您已经从工作树中删除了文件。如果您的工作树中有大量文件 "cleaned",则 git status 等命令的输出可能会变得非常混乱,如果不进行过滤就变得毫无用处。例如,查找真正未被跟踪而不是被删除或修改的文件:

$ git status -su | fgrep '??'
?? bar
?? wibble