如何通过保留Git中的文件夹结构来导出被忽略的文件?

How to export the ignored files by retaining the folders structure in Git?

我有一个项目,我想将(未版本化/.gitignored)文件(其中大部分是配置文件)与实际源代码分开。我想将它们复制到与项目目录结构相同的目录结构中。例如:

/foo
/bar/config/env.xml <-- ignored
/bar/config/env.xml.dist
/buz/keys <-- ignored
/buz/logs <-- ignored
/buz/source

$ git extract-ignored-files --exclude-from-extracting=/buz/logs (pseudocode)
Aimed result:

/bar/config/env.xml <-- ignored
/buz/keys <-- ignored

其背后的具体要求是能够将设置从一个系统传输到另一个系统(并通过仅调整几个设置来快速设置另一个系统)。

如何导出 .gitignored 个文件? 在最好的情况下,我还希望 (1) 保持文件夹结构与原始文件相同结构和(2)能够从提取结果中排除一些路径。

cp 的 --parents 标志将保持目录结构。

mkdir ignored_files
  for x in `git status --ignored .`; do
  cp -va --parents $x ignored_files/$x
done

rsync -R 保留相对路径名:

rsync -aR `git ls-files --others` ignored_files/

1.定义要传输的路径。它将是被忽略文件集的子集。

这可以通过多种方式完成,例如通过查看 .gitignore 并将其规则转换为路径或使用 git status --ignoredgit check-ignore *。我更喜欢这样:

一个。获取所有 .gitignored 个文件 (git ls-files --others > ./transfer-excludes.txt)(在我的例子中,我得到了一个包含大约 22k 行的文件)。

b。从结果文件的条目中手动定义您不想 (!) 传输的模式。例如,它可以是您的 IDE 设置、包含外部库的文件夹、日志等——您绝对不需要复制到另一个项目实例的所有内容。

2。获取要传输的路径

$ git ls-files --others --exclude-from=./transfer-excludes.txt > ./transfer-files.txt

该方法可能需要更多努力。但是随后所有可能的忽略路径(包括被子目录排除的那些 .gitignores)变得可见并且可以被检查。

3。复制文件。

这只是一个简单的 bash 脚本,扫描路径,创建所需的目录结构(通过使用 mkdir -p),并复制文件:

#!/bin/bash
INFILE="./transfer-files.txt"
TARGETROOT="./transfer"
while read line
do
    TARGETDIR=`dirname $line`
    TARGETPATH="${TARGETROOT}/${TARGETDIR}"
    if [ ! -d "${TARGETPATH}" ]
    then
        mkdir -p "${TARGETPATH}"
    fi
    # echo ${TARGETPATH}
    cp "$line" "${TARGETPATH}"
done < ${INFILE}

cp --parents 而不是 mkdir -pcp 的组合在这种情况下不起作用,因为它不能递归地创建完整路径,如果它还不存在的话。

$ ./transfer.sh

就是这样。


一点检查:

$ find ./transfer/ -type f -exec du -a {} +

输出应等于 transfer-files.txt.

中的文件列表

可能的改进:

  • 步骤23可以合并到脚本中。 (但有时你不想,为了有机会先检查文件列表。)
  • 另一个改进想法:可以创建 Git 挂钩,检查提交是否影响 .gigitnore 文件——在这种情况下,应该更新 transfer-excludes.txt .