如何务实地对配置文件进行版本控制?

Posted

技术标签:

【中文标题】如何务实地对配置文件进行版本控制?【英文标题】:How to version control config files pragmatically? 【发布时间】:2010-12-30 19:12:06 【问题描述】:

假设我们有一个包含敏感密码的配置文件。我想对整个项目进行版本控制,包括配置文件,但我不想分享我的密码。 这可能很好,如果这个配置文件:

database_password=secret
foo=bar

变成

database_password=*
foo=bar

vcs 的其他用户也可以自行设置密码。忽略该文件不是一个好方法,开发人员应该注意,如果配置文件发生更改。

示例:

本地版本:

database_password=own_secret
foo=bar

vcs 中的配置文件:

database_password=*
foo=bar

然后突然,配置文件发生了变化:

database_password=*
foo=bar
baz=foo

本地版本将适用于每个开发人员:

database_password=own_secret
foo=bar
baz=foo

这是我的解决方案。我怎样才能实现这种行为?你如何存储你的配置文件?有没有办法做到这一点,或者我应该破解一些东西?

【问题讨论】:

配置文件不应包含明文密码...... 事实上,最好不要在配置文件中包含任何类型的密码...除非它是服务器保存的配置,即使那样... @Mitch:我的 php webapp(基于 ZF)从纯文本中读取数据库凭证。我应该把它们存放在哪里? 你的意思是编程而不是实用? 我可以使用 svn 的预提交挂钩来删除我的密码。两者都只能以一种方式工作。我需要某种预同步或预更新挂钩。 【参考方案1】:

在我的项目中,我使用一个目录来保存这些类型的文件,但它没有上传到服务器,所以我的 db 配置文件位于该目录中,并且它是为放置项目的服务器配置的。 如果有人更改配置文件,他将更改服务器配置文件,任何更新修订版的人都会看到该文件中的更改,并且需要手动更改他的本地配置。

我没有看到这样做的方法,而不是那样。如果您发现不同的方法,请分享。

【讨论】:

我认为最好保持你的配置文件忽略,修改后,将密码更改为 *,提交,然后再次设置忽略标志,然后将 * 更改回密码。 @erenon 这似乎很麻烦。我希望开发人员最终会规避这一点或避免定期提交(无论如何提交配置文件。)尽管您可以编写整个过程的脚本。【参考方案2】:

是否有一个单独的文件,其中仅包含机密,不受版本控制?

或者理想情况下,完全使用 openssh 或类似方法来取消密码,并为每个用户进行公钥/私钥身份验证。

【讨论】:

PHP 程序使用密码连接数据库。【参考方案3】:

我习惯用configfile的结构制作一个txt文件。 之后,我将复制并更改扩展名,让我的版本控制系统忽略此文件。

因此,当您在配置文件中进行更改时,只需更新它的 txt 版本。 这是我能想到的唯一选择,也是逻辑(在我看来)

【讨论】:

这种做法违反了DRY原则。无论如何,它可以解决。【参考方案4】:

不确定你的配置是如何实现的,但是我会如何处理分层覆盖。

您有一个主配置,其中包含通用配置和虚拟用户名/密码(或完全忽略这些)。然后每个开发人员使用他们的特定用户名/密码创建一个本地 override.config(或其他)。主配置受源代码控制,开发人员(或机器)本地覆盖没有。

我是在 .NET 中完成的,但不是 PHP,所以恐怕我不知道这有多容易。

【讨论】:

这看起来很聪明。为了实现这一点,我可能只需要对我的框架配置解析器进行子类化。 +1 这正是我们在几乎所有项目中处理配置文件的方式,具有不同的层次结构。【参考方案5】:

如何使用预提交挂钩来清除敏感字段?当然,这首先假设您很乐意通过网络发送文件。

更新问题的另一端: 要处理更新,您要么想要强制手动合并敏感文件,要么修改本地构建过程以使用本地/私有/忽略文件中的内容覆盖敏感行。

【讨论】:

我刚刚在我的评论中提到了预提交钩子,但这种技术只能以一种方式工作。每个开发者都应该在每次更新和覆盖后更新自己的密码字段。【参考方案6】:

我有类似的东西,但我不知道它是否适合你。我有一个目录,其中包含包含密码的文件。此目录不受版本控制。这些文件以使用它们的应用程序命名,在配置文件中,我在需要时“获取”了适当的密码文件。这将要求您的配置解析器能够处理采购。

【讨论】:

【参考方案7】:

创建一个本地覆盖文件,其中包含作为 PHP 变量的用户特定信息。

例如创建一个名为 local_overrides.php 的文件,其中包含以下内容:

$local_password = 'qUzaEAFK13uK2KHy';

然后在包含您的数据库密码的文件中执行类似的操作

$overrides = 'local_overrides.php';

if (file_exists($overrides)) 
   #include_once($overrides);
   $db_password = $local_password;
 else 
   // perform appropriate action: set default? echo error message? log error?    
   $db_password = 'l1m1t3d!'

源代码管理永远不会看到本地覆盖文件。

【讨论】:

【参考方案8】:

代替对实际配置文件进行版本控制,您可以将模板或默认文件放在版本控制中,以及一个脚本会要求数据库信息和凭据以生成真正的配置文件,这些文件将被排除在外(即被)版本控制忽略。在结帐时,开发人员可以运行此脚本以获得工作环境。该脚本也可以作为您的应用程序使用的任何安装过程的一部分来调用。

也可以see my answer 回答类似的问题。

【讨论】:

【参考方案9】:

我的首选答案已在此处提及:签入一个虚拟文件,通过在运行时复制该虚拟文件生成“真实”文件,然后忽略 VCS 中的“真实”文件。

我已经回答了一个类似的问题,并提供了如何在 Visual Studio 中执行此操作的完整示例:how to ignore files in kiln/mercurial using tortoise hg "that are part of the repository"

【讨论】:

以上是关于如何务实地对配置文件进行版本控制?的主要内容,如果未能解决你的问题,请参考以下文章

如何有效地对 SQL 数据库中的记录进行版本控制

在多项目环境中独立地对模块进行版本控制并压缩所有依赖项

dotnet 核心包版本控制

svn怎么忽略有版本控制的本地问题?

CentOS 7 使用SVN+Apache搭建版本控制服务器

您如何在版本控制下处理开发人员的个人文件?