git 处理项目配置文件的最简单方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6782017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the easiest way to deal with project configuration files?
提问by Ondrej Slinták
It's very common to have at least one configuration file in any project. Every time I share project with git
, I have the same problem with:
在任何项目中至少有一个配置文件是很常见的。每次我与 共享项目时git
,我都会遇到同样的问题:
- sensitive information (each developer have different DB passwords etc)
- task specific information (when developer works on certain task where one needs to change some settings)
- 敏感信息(每个开发者有不同的数据库密码等)
- 任务特定信息(当开发人员处理某些需要更改某些设置的任务时)
Obviously, configs have to be ignored somehow to prevent developer specific data to flood main repository. Now there are several ways I used to use, each with some flaws:
显然,必须以某种方式忽略配置,以防止开发人员特定数据淹没主存储库。现在有几种我曾经使用过的方法,每种方法都有一些缺陷:
.gitignore
the config files- the most basic way
- when developer clones repo, config file is missing and one has to find out where configs were recreate them
- config file isn't ignored. It contains some dummy info and each developer either untracks and puts it to his
.git/info/exclude
or setgit update-index --assume-unchanged ...
to the file- files are available for anyone who clones repo
- it contains advanced techniques which could confuse people that work with git for the first time
- 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
)
- distribute config files suffixed with, for example,
_original
while having the real files in.gitignore
. Each developer then renames files to real names- files are available for anyone who clones repo
- one has to search for all configs throughout application and rename them
.gitignore
配置文件- 最基本的方法
- 当开发人员克隆 repo 时,配置文件丢失,必须找出重新创建配置的位置
- 配置文件不会被忽略。它包含一些虚拟信息,每个开发人员要么取消跟踪并将其放入他的
.git/info/exclude
或设置git update-index --assume-unchanged ...
到文件中- 任何克隆 repo 的人都可以使用文件
- 它包含一些先进的技术,这些技术可能会让第一次使用 git 的人感到困惑
- 当有人不小心提交配置文件时,它不会允许人们拉/取(因为 excludes 的工作方式与 不同
.gitignore
)
- 例如,分发后缀为 的配置文件,
_original
同时将真实文件放在.gitignore
. 然后每个开发人员将文件重命名为真实姓名- 任何克隆 repo 的人都可以使用文件
- 必须在整个应用程序中搜索所有配置并重命名它们
Are there any other, possibly, better ways to handle this? I suspect I'm missing something, some plugin at least.
有没有其他可能更好的方法来处理这个问题?我怀疑我错过了一些东西,至少是一些插件。
采纳答案by VonC
Filter driversare the "automatic" way of implementing option 3, as detailed in "when you have secret key in your project, how can pushing to GitHub be possible?":
过滤器驱动程序是实现选项 3 的“自动”方式,如“当您的项目中有密钥时,如何可以推送到 GitHub?”中详述:
The smudge
script will, on checkout:
该smudge
脚本将在结帐时:
- detect the right config files to modify
- fetch the information needed (best kept outside any Git repo) and will replace the template values by the actual one.
- 检测要修改的正确配置文件
- 获取所需的信息(最好保存在任何 Git 存储库之外),并将用实际值替换模板值。
From there the developers can make any kind of modification they want to those config files.
It won't matter, because the clean
script will, on commit, restore the content of that file to its original (template) value. No accidental push there.
从那里开发人员可以对这些配置文件进行任何他们想要的修改。
没关系,因为clean
脚本会在提交时将该文件的内容恢复为其原始(模板)值。没有意外推到那里。
回答by plague
The way we did it on the last project i worked on was to have a master config file that loaded a users local config file if it was present which could overwrite the defaults set in the master if specified and declared its own config info if not present in master. The local file was added to gitignore. That way all common stuff could all be shared and some config always present and each developer can modify their local.
我们在我工作的最后一个项目中这样做的方式是拥有一个主配置文件,如果存在则加载用户本地配置文件,如果指定,则可以覆盖在主配置中设置的默认值,如果不存在则声明自己的配置信息在主人。本地文件已添加到 gitignore。这样,所有常见的东西都可以共享,并且始终存在一些配置,并且每个开发人员都可以修改他们的本地配置。
回答by Pascal
Since it took me a while to figure out a working solution with @VonC 's hints, here's a full example of how to ignore passwords with a git clean filter in an Objective-C header file.
由于我花了一段时间才找到带有 @VonC 提示的可行解决方案,这里有一个完整示例,说明如何在 Objective-C 头文件中使用 git clean 过滤器忽略密码。
Assume you have a default config script named
Config.h
containing this// Change "12345" to your password #define kPass @"12345" #define kConstant 42
Create a script
hidepass.sh
that matches the critical line(s) and prints the default line instead#!/bin/sh awk '{ if (/#define kPass/) print "#define kPass @\"12345\""; else print
; }' exit 0Config.h filter=hidepass
Make the script executable and add it to the repo
Tell git to filter your config file by adding this line to
.gitattributes
(also add .gitattributes to your repo)git config filter.hidepass.clean ./hidepass.sh
Tell git to use the
hidepass.sh
script for the hidepassfilter during clean:// Change "12345" to your password #define kPass @"12345" #define kConstant 42
假设您有一个名为的默认配置脚本,
Config.h
其中包含此#!/bin/sh awk '{ if (/#define kPass/) print "#define kPass @\"12345\""; else print
; }' exit 0Config.h filter=hidepass
创建一个
hidepass.sh
匹配关键行的脚本并打印默认行git config filter.hidepass.clean ./hidepass.sh
使脚本可执行并将其添加到 repo
通过将此行
##代码##.gitattributes
添加到(还将 .gitattributes 添加到您的存储库)来告诉 git 过滤您的配置文件告诉 git在清理期间使用hidepass过滤器的
##代码##hidepass.sh
脚本:
That's it, you can now change the password in Config.h
but git will not commit this change because it always replaces that line with the default line on checkin.
就是这样,您现在可以更改密码,Config.h
但 git 不会提交此更改,因为它总是在签入时用默认行替换该行。
This is a quick solution for a one-line password, you can go crazy and e.g. end the lines to be ignored with a special string and check for lines with that string.
这是单行密码的快速解决方案,您可以发疯,例如用特殊字符串结束要忽略的行并检查带有该字符串的行。
回答by manojlds
In projects I have been, we have a default config, and developers have their own config at a particular location outside version control ( convention over configuration ) - the values from latter are used to override those in the former.
在我参与过的项目中,我们有一个默认配置,开发人员在版本控制之外的特定位置拥有自己的配置(约定优于配置)——后者的值用于覆盖前者的值。
We started using encryption for sensitive details in the config: Handling passwords in production config for automated deployment
我们开始对配置中的敏感细节使用加密:在生产配置中处理密码以进行自动化部署
In case of git, you can look at git attributes filter attribute
to do both the replacement of local values and decryption of sensitive values in an automated way.
在 git 的情况下,您可以考虑以git attributes filter attribute
自动方式替换本地值和解密敏感值。
You can also have submodules which have say the production.yml
and with restricted access to the submodule repo.
您还可以拥有子模块,这些子模块具有production.yml
对子模块 repo 的限制访问权限。
回答by avh
For the two cases you mention:
对于您提到的两种情况:
sensitive information (each developer have different DB passwords etc)
Write your scripts to so that these sensitive files are stored in the developer's home directory, rather than in the project directory.
task specific information (when developer works on certain task where one needs to change some settings)
I usually have the default settings checked into the repository, and then when you prepare your commits, you can easily check if you've modified any of those settings, and revert them before you commit.
敏感信息(每个开发者有不同的数据库密码等)
编写脚本,以便将这些敏感文件存储在开发人员的主目录中,而不是项目目录中。
任务特定信息(当开发人员处理某些需要更改某些设置的任务时)
我通常将默认设置签入存储库,然后当您准备提交时,您可以轻松检查是否修改了任何这些设置,并在提交之前恢复它们。
回答by Patrick
One thing I can think of is similar to method 2 and method 1 above. Where you have a directory where you store complex things that are unique to the site such as directories for config files, user uploaded files, etc.
我能想到的一件事类似于上面的方法2和方法1。您有一个目录,您可以在其中存储站点独有的复杂内容,例如配置文件的目录、用户上传的文件等。
You keep just the config file itself out of version control, but then you have a dummy copy that is named slightly differently from what the site actually uses and this file contains detailed instructions as to the config parameters and to make a renamed copy.
您只将配置文件本身置于版本控制之外,但是您有一个虚拟副本,该副本的名称与站点实际使用的名称略有不同,并且该文件包含有关配置参数和制作重命名副本的详细说明。
For example, lets say you have a "site_profile" directory. In this directory you create a file called "README.settings.php" along with a "files" directory that contains user uploaded files (from both admin and front-end users). All of this is under version control.
例如,假设您有一个“site_profile”目录。在此目录中,您创建一个名为“README.settings.php”的文件以及一个包含用户上传文件(来自管理员和前端用户)的“文件”目录。所有这些都在版本控制之下。
However, the site will run its settings from "settings.php" which won't exist in here. But if you were to rename the "README.settings.php" to "settings.php" then you would have the config file you need (after you put in your custom settings of course).
但是,该站点将从此处不存在的“settings.php”运行其设置。但是,如果您要将“README.settings.php”重命名为“settings.php”,那么您将拥有所需的配置文件(当然是在您输入自定义设置之后)。
This will allow you to tell the other developers what they need out of their config file while keeping your own config file out of the mix. Just set your config file to be ignored or never do a blanket commit for that directory and lower.
这将允许您告诉其他开发人员他们需要从他们的配置文件中获得什么,同时将您自己的配置文件排除在外。只需将您的配置文件设置为忽略或永远不要对该目录及更低的目录进行全面提交。
Its what we do with Drupal sites where I work and it works really well.
这就是我们对我工作的 Drupal 站点所做的事情,而且效果非常好。
回答by Casebash
I saved my local config changes to a git stash. I use git stash apply rather than pop, so that I never remove it from the stash queue. That way I can use reset --hard whenever I feel like it.
我将本地配置更改保存到 git stash。我使用 git stash apply 而不是 pop,所以我永远不会将它从 stash 队列中删除。这样我就可以随时使用 reset --hard 。
回答by SilentSteel
A lot of good options listed. A few more options to mention:
列出了很多不错的选择。还有几个选项要提到:
- Add all configs to .gitignore. Then have a separategit project, with the just the configuration files. (Keep this GIT #2 in a totally different folder.) In this GIT #2, make a few scripts similar to
apply-config /path/to/my_git1
,save-config /path/to/my_git1
which copy in, or save configuration files for the main GIT repo.- I prefer this to using submodules. I've found working with submodules cumbersome across a large team.
- You can then track configurations, or use multiple GIT repos for things like production settings, debug settings, more optimized settings, etc.
- Uses one tool (GIT) that everyone understands.
- I like the idea of looking in the home folder for sensitive things like DB connection info. (Mentioned by @avh)
- For devOps, you may want to consider things like Ansible / Salt / Chef / Puppet for automating deployments and settings.
- 将所有配置添加到 .gitignore。然后有一个单独的git 项目,只有配置文件。(将这个 GIT #2 保存在一个完全不同的文件夹中。)在这个 GIT #2 中,制作一些类似于 的脚本
apply-config /path/to/my_git1
,save-config /path/to/my_git1
它们复制或保存主 GIT 存储库的配置文件。- 我更喜欢使用子模块。我发现在大型团队中使用子模块很麻烦。
- 然后,您可以跟踪配置,或使用多个 GIT 存储库进行生产设置、调试设置、更优化的设置等。
- 使用一种每个人都能理解的工具 (GIT)。
- 我喜欢在主文件夹中查找敏感内容(如数据库连接信息)的想法。(@avh 提到)
- 对于 devOps,您可能需要考虑使用 Ansible/Salt/Chef/Puppet 之类的东西来自动化部署和设置。
回答by Ondrej Slinták
Another very common option, popularized by The Twelve-Factor App, is to not have any configuration variables hardcoded into files, but rather load them from environmental variables. This way, the files in repository don't need any special treatment.
另一个由十二因素应用程序推广的非常常见的选项是不将任何配置变量硬编码到文件中,而是从环境变量中加载它们。这样,存储库中的文件不需要任何特殊处理。
回答by atrain
Having no experience with Git, but having dealt with the same issues in other contexts (Hibernate login creds in a Spring JUnit suite, or ANT scripts), for anything that is user-specific or depends on a user's local environment:
没有使用 Git 的经验,但在其他上下文(Spring JUnit 套件中的 Hibernate 登录凭证或 ANT 脚本)中处理过相同的问题,对于任何特定于用户或依赖于用户本地环境的内容:
- Have a README listing those dependencies and how to configure your local env to run the script.
- Replace those dependencies in your conf with calls to system properties, or some framework way to pull in external values. In an ANT script, for instance, you can replace strings with
<sysproperty key="jdbc.username" value="${jdbc.username}"/>
, wherejdbc.username
is a system variable (that you can set in Eclipse).
- 使用 README 列出这些依赖项以及如何配置本地 env 以运行脚本。
- 用对系统属性的调用或某种框架方式来拉入外部值来替换 conf 中的这些依赖项。例如,在 ANT 脚本中,您可以将字符串替换为
<sysproperty key="jdbc.username" value="${jdbc.username}"/>
,其中jdbc.username
是系统变量(您可以在 Eclipse 中设置)。
Developers can check in whatever they want, because the conf is user-agnostic.
开发人员可以签入他们想要的任何内容,因为 conf 与用户无关。