【问题标题】:Using conditional configuration files with Git在 Git 中使用条件配置文件
【发布时间】:2014-08-21 08:08:32
【问题描述】:

我经常发现自己在开发分支(在 JavaScript 中,所以我不能使用预处理器定义)时,在 Git 中更改项目中的单个变量以连接到不同的服务器。

Git 中是否有某种方法可以根据我所在的分支有条件地使用一个文件或另一个文件?

我不能只使用指定的不同 URL 提交该更改,因为这样做会将其保留在我的提交历史记录中,并且如果我稍后在合并后回到该版本的 Master 上,它将拥有开发服务器网址。

【问题讨论】:

标签: git config


【解决方案1】:

不,没有,但这是一个很好解决的问题。

你有几个选择:

版本控制示例配置文件

  • 不要在版本控制中存储特定于环境的数据
  • 创建一个config.example 文件,其中列出所有需要指定的配置选项,并为开发提供合理的默认值。
  • 克隆你的仓库的用户应该将config.example复制到真实的配置文件名,并添加真实的值
  • 将真实配置文件的名称添加到.gitignore
  • 将您的生产凭据存储在 git 之外,但已备份,
  • 作为奖励,您可以添加一个 setup.sh 脚本,该脚本将 config.example 复制到实际配置的位置,并使用本地环境的变量填充它

例如,您可能有一个 JavaScript 应用程序需要知道其数据库在哪里,并从 config/database.json 读取此信息。你可能会使用这样的东西:

// config/database.example.json
DATABASE = {
  "host": "localhost",
  "user": "#TODO",
  "pass": "#TODO",
}

要在开发环境中运行,您需要将此文件复制到 config/database.json,并填写适合您的开发环境的值。

在生产中,您将拥有一个包含生产值的 config/database.json,但不受版本控制。

回购将在其.gitignore 中包含config/database.json

版本控制环境特定的配置文件

  • 存储 X 个不同的配置文件,每个环境一个,调用它们 config.developmentconfig.production
  • 为您的环境使用正确的符号链接。
  • 将符号链接添加到 .gitignore

如果您的配置文件中有任何远程敏感信息,例如 AWS 密钥或任何形式的密码,您应该使用第一个选项 - 存储配置选项的名称,而不是其值,并且要求用户提供他们自己的凭据,这些凭据是通过版本控制之外的安全渠道获得的。

【讨论】:

  • 谢谢。然后我可以添加一个钩子来复制我认为取决于哪个分支的默认值。
  • 嗯,我回答的真正要点是您不应该使用特定于环境的分支。你的环境特定的东西应该存储在 repo 之外。
  • 我明白,但在这种情况下,我通常会在开发分支上使用开发服务器
【解决方案2】:

请注意,条件包括配置即将推出,从 Git 2.13(2017 年第二季度)开始。
目前唯一支持的条件是项目名称,而不是主机名。

在您的情况下,如果每个分支都在其自己的文件夹中签出(使用git worktree:请参阅“Multiple working directories with Git”),这将起作用。

commit 86f9515commit 4aad2f1(2017 年 4 月 5 日)Nguyễn Thái Ngọc Duy (pclouds)
(由 Junio C Hamano -- gitster -- 合并到 commit a2e2c04,2017 年 4 月 24 日)

config:添加条件包含

有时一组存储库想要共享配置设置 与其他此类存储库集不同。
一个用户可以处理两个项目,每个项目都有多个存储库,一个项目使用一个user.email,另一个项目使用另一个。

设置$GIT_DIR/.config 有效,但如果忘记 更新$GIT_DIR/.config 很高(尤其是当您最终克隆时 通常),这可能不是最好的方法。
~/.gitconfig 中设置仅适用于一组存储库的设置在这种情况下不太适用。
拥有单独的${HOME}s 可能会带来比它解决的问题更多的问题。

扩展include.path 机制,让一个配置文件包含另一个配置文件,这样只有在某些条件成立时才可以包含。
然后~/.gitconfig 可以说“包括config-project-A 仅在为用户处理的每个 project A 处理 project-A" 时。

在这个补丁中,唯一支持的分组是基于$GIT_DIR(在 绝对路径),因此您需要按目录对存储库进行分组,或者 类似的东西来利用它。

我们已经有include.path 用于无条件包含。
此补丁与 includeIf.<condition>.path 一起使用,以更清楚地表明需要条件。
新配置具有与 include.path 相同的向后兼容性方法:不理解 includeIf 的旧 git 版本将 直接忽略它们。


Git 2.14(2017 年第三季度)澄清了文档。

参见Jeff King (peff)commit ce933ebcommit a076df2commit 994cd6ccommit 9d71d94(2017 年 5 月 11 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit ed98060,2017 年 5 月 29 日)

The documentation 现在读取并包含:

包括

includeincludeIf 部分允许您包含配置 来自其他来源的指令。这些部分的行为与 除了 includeIf 部分可以被忽略之外 如果他们的条件不评估为真;请参阅“有条件的包含” 下面。

相同的 Git 2.14 加强了该功能。
请参阅 Ævar Arnfjörð Bjarmason (avar)commit 0624c63(2017 年 5 月 16 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit b784d0b,2017 年 5 月 30 日)

最近引入的“[includeIf "gitdir:$dir"] path=...”机制进一步被教导要考虑符号链接。

gitdir:$dir”中指定的目录“$dir”可能是指向 一个真实的位置,而不是 $(getcwd) 可能返回的位置。
在这种情况下,将“$dir”的真实路径与 当前存储库,以确定是否来自命名路径的内容 应该包括在内。

【讨论】:

  • 支持使用 realpath 进行符号链接比较的信息。
【解决方案3】:

听起来您可能对hook 感兴趣;具体来说,查看结帐后挂钩。基本上,您将编写一个小脚本,在签出后根据$(git branch) 的值修改文件。您没有具体提到需要发生什么,但它可能涉及 sed。

您可以将相关文件添加到 .gitignore 文件中,或者编写一个预提交挂钩,这样您的更改就不会意外传播到公共存储库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-14
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    相关资源
    最近更新 更多