Git 使用本地配置分支进行涂抹和清洁

Git smudge and clean using local configuration branch

我正在处理的项目的本地配置涉及以复杂的方式更改多个文件,这些文件无法提交到任何已提交的分支。为了解决这个问题,我已经将这些本地配置更改提交给一个专用的本地分支 config,并且在开始一个新的工作分支后 运行 宁这个 bash 脚本 config.sh :

#!/bin/bash

# put relevant config files in array
mapfile -t files < <(git diff config develop --name-only) 
# overwrite only those files to my working directory
git checkout config -- ${files[@]}
# unstage them so they aren't accidentally committed
git reset HEAD ${files[@]}
echo The following files were successfully overwritten for local configuration:
printf '\t%s\n' "${files[@]}"

与另一个 .deconfig 脚本一起执行相反的操作。 运行 直接从终端,这些脚本运行良好,但我想使用 git 的 cleansmudge 过滤器进一步简化流程。所以我创建了一个 .gitattributes 文件:

 *.* filter=config

然后将其添加到我的 .git/config 文件中:

[filter "config"]
        smudge = ./config.sh
        clean = ./deconfig.sh

但是,它就是行不通。如果我不得不猜测这是因为 git 不希望我 运行 作为过滤器的一部分额外的 checkout,过滤器本身 运行 在 [=21= 之后] 命令针对所有文件。 smudgeclean 的大多数用例似乎都涉及简单的查找和替换操作,但考虑到所需更改的复杂性,这种方法实施起来会很复杂并且难以维护。我可以将配置文件存储在某个静态的外部目录中,但我想基于相同的配置分支进行涂抹和清理,因为本地配置本身经常发展并受益于与项目其余部分一起进行版本控制,理想情况下分支可以用作其他开发人员本地配置的基准。 Git 的 filter-branch 可能更合适,但 git 的 own documentation 建议不要使用它。有没有办法做到这一点?我的 git 配置有问题吗?脚本本身会导致问题吗?还有其他可能的方法吗?

虽然在任何地方都没有记录,但您无法使用涂抹或清洁过滤器来更改工作树的状态。 Git 期望通过将数据传输到每个文件并从标准输出中读取数据来为每个文件调用一次过滤器。换句话说,这些过滤器旨在针对每个文件调用并仅处理该文件,而不是通过修改工作树状态。

解决您问题的最佳方法是避免保留单独的分支。只需将所有文件(包括开发文件和生产文件)保存在某个目录中,然后使用脚本将正确的文件复制到位。 运行 配置文件的位置应该被忽略,所以脚本不会导致 Git 显示任何已修改的内容。或者,在某处保留一个模板,并让脚本根据环境生成合适的模板。如果您有不应签入的生产秘密,这很好;您可以通过环境将它们传递给脚本并生成正确的值。

您的操作与忽略跟踪文件有关,as outlined in the Git FAQ一般无法成功。