处理项目configuration文件最简单的方法是什么?
在任何项目中至less有一个configuration文件是很常见的。 每次我用git
共享项目,我都git
同样的问题:
- 敏感信息(每个开发人员有不同的DB密码等)
- 任务特定信息(当开发人员在需要更改某些设置的特定任务上工作时)
显然,configuration必须被忽略,以防止开发人员的具体数据洪水主要存储库。 现在有几种方法我曾经使用,每个都有一些缺陷:
-
.gitignore
configuration文件- 最基本的方法
- 当开发人员克隆回购,configuration文件丢失,一个必须找出configuration重新创build他们
- configuration文件不会被忽略。 它包含一些虚拟信息,每个开发者或者解开并将其放到
.git/info/exclude
或者将git update-index --assume-unchanged ...
设置为文件- 任何克隆回购的人都可以使用这些文件
- 它包含先进的技术,可能会混淆第一次使用git的人
- 当有人不小心提交configuration文件时,它不会允许用户拉/取(不包括与
.gitignore
不同的方式)
- 在具有
.gitignore
中的实际文件的同时分发以_original
为后缀的configuration文件。 然后每个开发人员将文件重命名为实名- 任何克隆回购的人都可以使用这些文件
- 必须在整个应用程序中search所有configuration并重命名它们
还有其他可能的更好的方法来处理这个吗? 我怀疑我至less错过了一些插件。
filter驱动程序是实现选项3的“自动”方式,如“ 当项目中有密钥时,如何推送到GitHub中 ”中详细介绍的:
smudge
脚本将在结帐时:
- 检测正确的configuration文件进行修改
- 获取所需的信息(最好保存在任何Git仓库之外 ),并将模板值replace为实际值。
从那里开发人员可以对这些configuration文件进行任何forms的修改。
这并不重要,因为clean
脚本将在提交时将该文件的内容恢复到其原始(模板)值。 没有意外推到那里。
我们在最后一个项目上做过的方式是拥有一个主configuration文件,它载入一个用户本地configuration文件(如果存在的话),如果指定的话可以覆盖在主服务器中设置的默认值,并且如果不存在则声明它自己的configuration信息在主人。 本地文件被添加到gitignore。 这样所有常见的东西都可以共享,一些configuration总是存在的,每个开发人员可以修改他们的本地。
在我已经有的项目中,我们有一个默认configuration,开发人员在版本控制之外的特定位置有自己的configuration(约定优于configuration) – 后者的值用于覆盖前者中的值。
我们开始在configuration中使用encryption来处理敏感细节: 在生产configuration中处理密码以进行自动部署
在git的情况下,您可以查看git attributes filter attribute
,以自动方式执行replace本地值和解密敏感值。
你也可以有一些子模块,它们拥有production.yml
和对子模块repo的访问权限。
由于我花了一段时间才弄清楚使用@VonC提示的工作解决scheme,下面是一个如何在Objective-C头文件中用git clean filter忽略密码的完整示例。
-
假设你有一个名为
Config.h
的默认configuration脚本包含这个// Change "12345" to your password #define kPass @"12345" #define kConstant 42
-
创build一个与关键行匹配的脚本
hidepass.sh
,然后打印默认行#!/bin/sh awk '{ if (/#define kPass/) print "#define kPass @\"12345\""; else print $0; }' exit 0
-
使脚本可执行并将其添加到回购
-
告诉git通过将这行添加到
.gitattributes
来过滤你的configuration文件(也可以添加.gitattributes到你的仓库)Config.h filter=hidepass
-
告诉git在清理过程中使用
hidepass.sh
通道filter的hidepass.sh
脚本:git config filter.hidepass.clean ./hidepass.sh
就这样,你现在可以在Config.h
更改密码,但是git不会提交这个改变,因为它总是用签入时的默认行replace那一行。
这是一个单行密码的快速解决scheme,你可以发疯,例如用一个特殊的string结束行被忽略,并检查该string的行。
我能想到的一件事与上面的方法2和方法1相似。 如果您有一个目录,您可以在其中存储站点特有的复杂内容,如configuration文件的目录,用户上传的文件等。
你只保留configuration文件本身的版本控制,但是你有一个虚拟副本,这个虚拟副本的名称与网站实际使用的名称有些不同,这个文件包含了关于configuration参数的详细说明,并且做了一个重命名的副本。
例如,假设你有一个“site_profile”目录。 在这个目录中,您将创build一个名为“README.settings.php”的文件以及包含用户上传文件(来自admin和前端用户)的“files”目录。 所有这些都在版本控制之下。
但是,该网站将从“settings.php”运行它的设置,这将不存在于这里。 但是,如果您要将“README.settings.php”重命名为“settings.php”,那么您将拥有所需的configuration文件(在放入自定义设置之后)。
这将允许您告诉其他开发人员他们需要什么他们的configuration文件,同时保持你自己的configuration文件混合。 只要设置你的configuration文件被忽略或从不为该目录和更低的一揽子提交。
它是我们在Drupal站点上所做的工作,而且工作得很好。
对于你提到的两种情况:
-
敏感信息(每个开发人员有不同的DB密码等)
编写脚本,以便这些敏感文件存储在开发人员的主目录中,而不是存储在项目目录中。
-
任务特定信息(当开发人员在需要更改某些设置的特定任务上工作时)
我通常会将默认设置选中到存储库中,然后在准备提交时,可以轻松地检查是否修改了这些设置中的任何一个,并在提交之前还原它们。
我保存我的本地configuration更改为一个git存储。 我使用Git存储应用而不是stream行,所以我永远不会从存储队列中删除它。 这样,我可以使用重置 – 每当我觉得喜欢它。
对于Git没有经验,但是在其他上下文(Spring JUnit套件中的Hibernatelogin声明,或ANT脚本)中处理过相同的问题,对于特定于用户或依赖于用户本地环境的任何内容:
- 有一个自述文件列出这些依赖关系,以及如何configuration您的本地env运行脚本。
- 将你的conf中的依赖关系replace为对系统属性的调用,或者用一些框架的方法来引入外部值。 例如,在ANT脚本中,可以用
<sysproperty key="jdbc.username" value="${jdbc.username}"/>
replacestring,其中jdbc.username
是一个系统variables(可以在Eclipse中设置)。
开发人员可以检查他们想要的任何东西,因为conf是用户不可知的。
列出了很多不错的select。 再提几个选项:
- 将所有configuration添加到.gitignore。 然后有一个单独的 git项目,只有configuration文件。 (把这个GIT#2保存在一个完全不同的文件夹中)在这个GIT#2中,制作一些类似于
apply-config /path/to/my_git1
,save-config /path/to/my_git1
,或者保存主GIT仓库的configuration文件。- 我更喜欢使用子模块。 我发现在一个庞大的团队中使用子模块很麻烦。
- 然后,您可以跟踪configuration,或使用多个GIT仓库来进行生产设置,debugging设置,更多优化设置等。
- 使用一个人人都知道的工具(GIT)。
- 我喜欢在主文件夹中寻找诸如数据库连接信息之类的敏感内容。 (提及@avh)
- 对于devOps,您可能需要考虑诸如Ansible / Salt / Chef / Puppet等自动化部署和设置。
由Twelve-Factor App推广的另一个非常常见的select是不要将任何configurationvariables硬编码到文件中,而是从环境variables中加载它们。 这样,存储库中的文件就不需要任何特殊的处理。