当我从 github 拉到服务器存储库时,我想避免覆盖某些文件中的本地化敏感信息,例如 config.php。
注意:它不是开源类型的 repo;我对存储库有完全的控制权,我是唯一的用户,它是私有的,但重要的是,它基于一个可能会改变配置文件结构的开源框架。我只是希望能够从中提取以进行测试、登台和生产,而不是意外地让生产的配置最终在测试中结束,等等。但是我无法重新编码配置文件以从其他地方提取数据而不做如果框架得到更新,以后会遇到困难的合并情况。
理想情况下,我希望能够告诉 Git,在拉取时,在从 REPO_URI 获取期间,始终丢弃可能会更改当前在 FILE_PATH 的第 24 行上找到的信息的任何大块。但是我认为这是不可能的(如果我错了,请纠正我)。
但是,除非有人可以提供一种方法来执行上述操作,否则请阅读以下解决方案并让我知道这是否是执行此操作的理想方法:
我会使用这里 git 的用户指南中描述的关键字扩展。下面我将描述我将如何做到这一点,然后在底部询问有关此方法的一些问题。
方法说明
首先,我会编写两个脚本,“sensitive_values_inserter”和“sensitive_values_remover”,它们将某些虚拟关键字(将在 github repo master 中)与特定的敏感信息(如密码、用户名、数据库路径等)交换:
#! /bin/sh -f
sed -e 's/@USERNAME@/dummyvalue/' -e 's/@PASSWORD@/dummyvalue/' $1
等等
其次,我会制作这个脚本的三个版本,每个环境一个:测试/登台/生产。每个版本都将包含与其所属环境相关的特定密码、用户名和数据库路径,而不是虚拟值。我会将这些脚本中的每一个放在相对于这些代码存储库中的每一个的路径中,如下所示:
/live/filters/sensitive_values_inserter
/live/filters/sensitive_values_remover
/live/repo/{LIVE}
/test/filters/sensitive_values_inserter
/test/filters/sensitive_values_remover
/test/repo/{TEST}
/stag/filters/sensitive_values_inserter
/stag/filters/sensitive_values_remover
/stag/repo/{STAG}
这些过滤器中的每一个都将具有相关设置的特定值。
然后整个 repo 的配置将被修改为:
$ git config filter.infosafe.smudge '../filters/sensitive_values_inserter'
$ git config filter.infosafe.clean '../filters/sensitive_values_remover'
最后在服务器存储库中执行以下操作:
$ echo 'config.php filter=infosafe' >> .gitattributes
这样,每当从主服务器拉出时,如果我理解正确,这些过滤器就会用我想要使用的值替换“虚拟”值。
注意:要使其正常工作,正如其他 stackoverflow 问题中所指出的那样,在设置完上述所有内容后,您必须:
cd /path/to/your/repo
git stash save
git checkout HEAD -- "$(git rev-parse --show-toplevel)"
git stash pop
在 checkout 和 stash pop 之间,我必须将所有更改提交到发生清理操作的文件中。别担心,在你提交它们之后,工作目录中的那些会被弄脏。(这有点违反直觉,但它确实有效。)
我能够成功推送到 github,并且只出现了干净的值。
(有一种替代的、更先进的技术,涉及每个分支使用一个 .gitignore,每个分支使用两个驱动程序和两个过滤器。这允许在切换到测试分支时清除实时密码,反之亦然。诀窍是在每个分支的 .gitignore 中为两个分支调用清洁器,但只调用 .gitignore 所在分支的 smudger,因此它恢复了自己的密码。仍然在这种情况下,当推送到github所有敏感信息都被清除了,这很好。如果有人感兴趣,我可以详细说明。)
关于此方法和替代方案的问题
我对此进行了测试,并且可以正常工作。但...
有没有更好的方法使用 git来做到这一点?我可能会补充一点,不能只忽略其中包含敏感信息的文件,也不能在合并时忽略对它们的更改,因为我希望能够在保留某些配置值的同时对这些文件进行更改. 这就是为什么我不想简单地使用git update-index --assume-unchanged FILENAME
来永久忽略未来对整个文件的本地修改。
谢谢。