从工作副本备份所有 gitignored 文件

backup all gitignored files from a working copy

我正在 git 存储库上工作。 我有一个工作副本,其中包含大量文件列表。

我的.gitignore长得像

roo/output*  # ignore set of folders
*.pyc           # ignore a filetype
root/a_folder   # ignore a folder
root/filemame*.txt # ignore a set of files
root/**/.bin # ignore an extension within a folder

现在我想创建一个新的工作副本。为了让它工作,我还需要 git 在原始 wc.

中被忽略的文件

我在这里尝试了一些答案:

Git command to show which specific files are ignored by .gitignore

git check-ignore * # return only folders for me

git status --ignored # takes forever to run
git ls-files --others -i --exclude-standard # returns empty for me

我需要得到这个包含原始路径名的列表,这样我就可以创建一个保留文件夹结构的 zip 文件,这样我就可以在新的工作副本中无缝解压它。

好吧,我们可以看看如何让 git check-ignore 更好地工作,但这似乎有点过度设计。如果您只需要执行一次,只需从您知道的忽略文件中的模式中找出要包含的内容即可。 (我忽略了这个目录,所以我会压缩这个目录。等等)如果你需要经常这样做,你可能想重新审视你是如何使用忽略规则的。

无论如何,check-ignore 命令可能会输出文件 and/or 目录,但有两个注意事项:

首先,你需要告诉它是否要搜索子目录。如果你只是说 git check-ignore * 那么它只会搜索当前目录。相反,你可能想要

git check-ignore * **/*

但即便如此,当您排除目录 a/ 并且该目录包含另一个目录 a/b/ 时,第二个问题就会出现。有坏消息和更坏的消息。

坏消息是,即使使用 **/* 模式,它也不会在 a/b/ 内搜索;一旦它看到 a/b/ 被排除在外,它就会列出并继续。

更糟糕的是,如果 a/b/ 中存在任何未排除的路径(例如,因为它们是在路径被忽略之前添加的,或者因为它们是用 -f 添加的),那么 a/b/ 未列出,它 仍然 不会在 a/b/ 下搜索以查找是否确实排除了更具体的路径。在我看来,这就像一个错误。作为部分解决方法,您可以说

git check-ignore --no-index **/* *

它会列出目录,但仍然不会在目录内搜索 - 这意味着您有一些隐含的误报(因为该目录中的某些内容 而不是 被忽略文件)。

所以...如果您 (a) 知道索引不包含路径中文件的条目,否则将被忽略,或者 (b) 可以通过使用可能拾取一些未忽略的文件来解决--no-index,那么你可以使用 `check-ignore 输出。如果您看到一个目录,您只需将整个目录(及其内容,递归地)包含在 ZIP 中。

如果这会复制一个没有真正被忽略的文件,我想做一些类似的事情

git checkout -- a/b

解压 ZIP 后应该可以解决这个问题。 (您始终可以在解压缩 ZIP 后使用 git status 来验证是否有任何您想要撤消的未忽略的更改。)

以下是适合我的方法。首先,为了检查,我列出了所有忽略的文件,没有忽略目录的内容(所以只是目录本身):

$ git ls-files -o -i --directory --exclude-standard
TODO
some/ignored/dir/

然后我将此列表传递到单行压缩以将所有内容保存到忽略-files.zip:

$ zip ignored-files.zip -r $(git ls-files -o -i --directory --exclude-standard)

另一种(有点被忽视的)方法是在 dry-运行 模式下使用 git clean

git clean -dxn

遍历所有子目录,吐出每个不在 git 上的文件的名称,无论是新的还是忽略的(-x 标志确保忽略的文件包含在输出中).

为了清除显示在 git-clean 输出的每一行上的前缀 Would remove 并将其发送到 zip,可以键入:

git clean -dxn | sed 's/^Would remove \(.*\)//g' | zip -@ backup-file.zip