处理项目配置文件的最简单方法是什么?


78

在任何项目中至少都有一个配置文件是很常见的。每次与共享项目时git,都会遇到以下相同问题:

  • 敏感信息(每个开发人员具有不同的数据库密码等)
  • 特定于任务的信息(当开发人员从事某些需要更改某些设置的任务时)

显然,必须以某种方式忽略配置,以防止开发人员特定的数据淹没主存储库。现在,我使用了几种方法,每种方法都有一些缺陷:

  • .gitignore 配置文件
    • 最基本的方法
    • 当开发人员克隆存储库时,缺少配置文件,必须找出配置在哪里重新创建配置文件
  • 配置文件不会被忽略。它包含一些虚拟信息,每个开发人员要么取消跟踪,然后将其放置到他的文件中,.git/info/exclude要么设置git update-index --assume-unchanged ...到文件中
    • 克隆回购的任何人都可以使用这些文件
    • 它包含先进的技术,可能会使第一次使用git的人感到困惑
    • 当有人偶然提交配置文件时,它将不允许人们进行拉取/提取操作(因为排除操作与的操作方式不同.gitignore
  • 分发带有后缀的配置文件,例如,_original将实际文件包含在中.gitignore。然后,每个开发人员将文件重命名为真实名称
    • 克隆回购的任何人都可以使用这些文件
    • 必须搜索整个应用程序中的所有配置并将其重命名

还有其他可能更好的方法来解决此问题吗?我怀疑我至少缺少一些插件。


stackoverflow.com/questions/5132152/…也可以在这里提供帮助。
VonC

好的,我随后添加了有关过滤器驱动程序选项的详细信息作为答案。
VonC

大家好,这句话是什么意思?when someone commits config files by accident, it won't allow people to pull/fetch (as excludes don't work the same way as .gitignore)
AnnieFromTaiwan

我尝试过的一切都没有了。如果有人无意间推送了排除文件,则拉上另一台计算机似乎会从上游一一覆盖被排除文件。至少在我的git 2.5.4中。不知道它是否曾经有所不同。
OndrejSlinták'16

Answers:


22

过滤器驱动程序是实现选项3的“自动”方式,如“在您的项目中有密钥时,如何将其推送到GitHub ”中所述:

在此处输入图片说明

smudge脚本在结帐时将:

  • 检测正确的配置文件进行修改
  • 获取所需的信息(最好保留在任何Git存储库之外),并将模板值替换为实际值。

从那里开发人员可以对这些配置文件进行任何类型的修改。
没关系,因为clean脚本在提交时会将文件的内容还原到其原始(模板)值。没有意外的推动。


到目前为止,我最喜欢这个。该污迹脚本将放置在哪里?据我了解,应该将其放置在放置了中央git repo的计算机上,但是它将如何检测应更改为正常状态的传入提交?
2011年

1
@Ondrej:涂抹脚本应该由用户引用,PATH或者应该可以通过公共共享目录(如果在同一个LAN上讨论组,则在开发人员之间共享)进行访问。它不会更改提交。它仅在签出时更改文件的内容。干净的脚本会在提交前更改其内容。
VonC

@Ondrej:请参见stackoverflow.com/questions/2316677/…作为示例,但请记住,这些脚本基于文件的内容,而不是文件名或路径:请仔细阅读stackoverflow.com/questions/2562523/…:这是关于使用过滤器驱动程序将文件的路径放入文件内容本身中,而这是不可能的:过滤器驱动程序仅将文件的内容作为输入。不是其名称或路径。
VonC

17

我们在上一个工作的项目中所做的方式是拥有一个主配置文件,如果存在,它将加载用户本地配置文件;如果指定了本地配置文件,则该文件可以覆盖主文件中的默认设置;如果不存在,则声明其自己的配置信息在主人。本地文件已添加到gitignore。这样,所有常见的东西都可以共享,并且始终存在某些配置,并且每个开发人员都可以修改其本地内容。


4
加上一个自述文件,说明将本地配置文件放在何处。
haydenmuhl 2011年

6

由于花了我一段时间才想出使用@VonC提示的可行解决方案,因此这里有一个完整的示例,说明如何使用Objective-C头文件中的git clean过滤器忽略密码。

  1. 假设您有一个Config.h包含以下内容的默认配置脚本:

    // Change "12345" to your password
    #define kPass @"12345"
    #define kConstant 42
    
  2. 创建hidepass.sh与关键行匹配的脚本,并打印默认行

    #!/bin/sh
    awk '{ if (/#define kPass/) print "#define kPass @\"12345\""; else print $0; }'
    exit 0
    
  3. 使脚本可执行并添加到仓库中

  4. 告诉git通过添加以下行来过滤您的配置文件.gitattributes(还将.gitattributes添加到您的仓库中)

    Config.h filter=hidepass
    
  5. 告诉git在清理过程中将hidepass.sh脚本用于hidepass过滤器:

    git config filter.hidepass.clean ./hidepass.sh
    

就是这样,您现在可以更改密码了,Config.h但是git不会提交此更改,因为它总是将该行替换为签入中的默认行。

这是单行密码的快速解决方案,您可以发疯,例如使用特殊的字符串结束要忽略的行,并检查该字符串是否存在。


3

在我去过的项目中,我们有一个默认配置,开发人员在版本控制(约定优于配置)之外的特定位置拥有自己的配置-后者的值用于覆盖前者的值。

我们开始对配置中的敏感细节使用加密:处理生产配置中的密码以进行自动部署

在git的情况下,您可以考虑以git attributes filter attribute自动方式进行本地值的替换和敏感值的解密。

您也可以使用子模块,该子模块具有production.yml和,并且对子模块存储库的访问权限受到限制。


2

我能想到的一件事类似于上面的方法2和方法1。您有一个目录,用于存储站点特有的复杂内容,例如配置文件目录,用户上载文件等。

您只保留配置文件本身不受版本控制,但是您拥有的虚拟副本的名称与站点实际使用的名称略有不同,并且该文件包含有关config参数和制作重命名副本的详细说明。

例如,假设您有一个“ site_profile”目录。在此目录中,您将创建一个名为“ README.settings.php”的文件,以及一个包含用户上载文件(来自管理员和前端用户)的“文件”目录。所有这些都在版本控制下。

但是,该站点将从“ settings.php”运行其设置,此处不存在该设置。但是,如果要将“ README.settings.php”重命名为“ settings.php”,那么您将拥有所需的配置文件(当然,在输入自定义设置之后)。

这样一来,您就可以告诉其他开发人员他们的配置文件中需要什么,同时又可以避免自己的配置文件。只需将您的配置文件设置为忽略即可,或者永远不要对该目录及更低版本进行全面提交。

这是我们在我工作过的Drupal网站上所做的事情,而且效果很好。


2

对于这两种情况,您提到:

  • 敏感信息(每个开发人员具有不同的数据库密码等)

    将您的脚本编写为,以便将这些敏感文件存储在开发人员的主目录中,而不是项目目录中。

  • 特定于任务的信息(当开发人员从事某些需要更改某些设置的任务时)

    通常,我会将默认设置签入存储库,然后在准备提交时,可以轻松地检查是否已修改了这些设置中的任何一个,并在提交之前将其还原。


2

我将本地配置更改保存到git stash。我使用git stash apply而不是pop,所以我从不从stash队列中删除它。这样,我可以随时使用reset --hard。


0

没有使用Git的经验,但是在其他上下文(Spring JUnit套件中的Hibernate登录凭据,或ANT脚本)中处理过相同的问题,涉及任何特定于用户或取决于用户本地环境的问题:

  1. 有一个自述文件,列出了那些依赖性以及如何配置本地环境以运行脚本。
  2. 用对系统属性的调用或某种获取外部值的框架方法来替换conf中的那些依赖项。例如,在ANT脚本中,可以将替换为<sysproperty key="jdbc.username" value="${jdbc.username}"/>,其中jdbc.username是系统变量(可以在Eclipse中设置)。

开发人员可以签入所需的任何内容,因为conf与用户无关。


0

列出了很多不错的选择。还有更多选择要提及:

  • 将所有配置添加到.gitignore。然后有一个单独的git项目,仅包含配置文件。(将此GIT#2放在一个完全不同的文件夹中。)在此GIT#2中,制作一些与相似的脚本apply-config /path/to/my_git1save-config /path/to/my_git1这些脚本可以复制或保存主GIT存储库的配置文件。
    • 我更喜欢使用子模块。我发现在一个大型团队中使用子模块很麻烦。
    • 然后,您可以跟踪配置,或将多个GIT存储库用于生产设置,调试设置,更优化的设置等。
    • 使用每个人都可以理解的一种工具(GIT)。
  • 我喜欢在主文件夹中查找诸如数据库连接信息之类的敏感内容的想法。(由@avh提及)
  • 对于devOps,您可能需要考虑使用Ansible / Salt / Chef / Puppet等工具来自动化部署和设置。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.