3

我在我们的项目中有一个配置文件,其中包含一个到数据库的连接字符串,以及几个应用程序设置,例如:

...
<setting name="ConnectionString"><value>Server=prodServer;Database=myDataBase;</value></setting>
<setting name="AnotherSetting1"><value>Lorem</value></setting>
<setting name="AnotherSetting2"><value>Ipsum</value></setting>
<setting name="AnotherSetting3"><value>dolor </value></setting>
...

在我的开发过程中,我总是将ConnectionString值更改为我的本地数据库,这会导致 git 将文件标记为“已修改”。

我阅读了有关执行以下操作的选项:

git update-index --assume-unchanged app.config

但是,这意味着如果我对文件进行任何其他更改(例如,更改AnotherSetting1),那么 git 也会忽略它。

有没有办法告诉 git 忽略文件中的特定更改,但如果发生任何其他更改,则将其标记为已修改?或者这个问题还有其他类似的解决方案吗?

请假设我无法对配置文件本身的体系结构进行任何更改 - 我想要一个仅限本地的解决方案。

4

4 回答 4

6

过滤器是为这样的东西制作的。在你的回购中,

cat >.git/info/saved-connection <<EOD
<setting name="ConnectionString"><value>Server=prodServer;Database=myDataBase;</value></setting>
EOD

cat >.git/info/my-connection <<EOD
<setting name="ConnectionString"><value>Server=myprivateserver;Database=myDataBase;</value></setting>
EOD

git config filter.use-my-connection.smudge 'sed -f ".git/info/use-my-connection.smudge"'
git config filter.use-my-connection.clean  'sed -f ".git/info/use-my-connection.clean"'

cat >.git/info/use-my-connection.smudge    <<EOD
/^<setting name="ConnectionString">/ {
     w .git/info/saved-connection
     r .git/info/my-connection
     d
}
EOD

cat >.git/info/use-my-connection.clean     <<EOD
/^<setting name="ConnectionString">/ {
     w .git/info/my-connection
     r .git/info/saved-connection
     d
}
EOD

echo >> .git/info/attributes     path/to/app.config filter=use-my-connection
于 2013-04-10T21:05:12.030 回答
1

我不认为git有这样的设施。并且建议的app.config文件管理方式,对文件版本的一部分进行控制,而对其他部分不进行处理,这对我来说并不合适。

在您的情况下,我会寻求一种方法来安排app.config从两个文件生成的。该ConnectionString设置将放在用户创建(构建)的配置文件中,而其他部分将放在某种模板文件中(从概念上讲)。用户创建的配置文件可以添加到.gitignore文件中。模板文件将由git. 我们需要一种方法来app.config通过将构建配置文件中的设置应用于模板文件来构建文件。

我们缺乏关于开发环境的背景信息来说明如何实现这一切。如果您正在使用makeant类似的东西,那么这将是一个简单的依赖项和规则来创建app.config以确保在文件不存在或构建配置文件或模板文件更改时创建文件。此外,如何从模板文件生成文件的自然选择app.config取决于您的构建环境和app.config文件。对于超过几行的文本,甚至可以使用 shell 脚本轻松地简单扩展给定的模板文件(几行扩展 ${VARIABLE} 结构,但如果文件需要包含美元,则会变得更加复杂符号或反引号或反斜杠等)。我们可以使用更复杂的扩展erubyeperl或者类似的东西(甚至可能PHP)。app.config当您需要更改设置时,也可以手动生成该文件。但这一切在没有进一步背景的情况下有点无用的猜测。

于 2013-03-01T04:25:50.110 回答
1

让我就如何做到这一点提出一些建议。

在向索引添加更改时,您可以使用git add -p app.config并手动跳过文件中的一些更改。如果您在提交之前不向索引添加更改,则不会提交这些更改。这是一种“仅限本地”的解决方案。git status但是总是在报告中看到修改的文件可能真的很无聊。

所有其他建议可能需要更改架构,因此不能被视为“仅限本地”的解决方案。无论如何,我认为他们可能值得审查。

所有更改的主要思想是添加.gitignore包含本地系统特定设置的本地文件。我们在这里使用了几种略有不同的解决方案。

  • 您可以拥有包含所有本地系统特定值的键值对的属性文件。该文件应手动更新。然后在应用程序上使用它并合并到应用程序配置中。详细信息取决于您使用的工具。但我确实相信这不会带来任何大的困难,但很可能需要更改应用程序。
  • 您可以app-original.config在 git 存储库中拥有文件,并app.configgit忽略列表中拥有文件。该app.config文件应从app-original.config文件手动创建。

所有这些解决方案真正令人厌烦的是,当配置文件的结构发生变化时,需要进行一些手动工作。例如,在每次配置文件更新时,您应该检查是否引入了新属性并更新本地属性文件。同样,当您因为某些应用程序更改而更新本地文件时,您需要记住在配置文件中提交相关更改(请记住您的本地文件位于 中.gitignore)。

于 2013-03-01T07:02:03.653 回答
0

我想我找到了解决这个问题的好方法。

正如我所说,在我的项目中有一个配置文件(错误地)将连接字符串存储在该配置文件中。

我希望能够使用修改后的配置版本,但不会在“修改过的”文件列表中不断地看到该文件,也不会完全忽略它的所有更改。

这是我所做的

从我们的服务器克隆后,我的日志图如下所示:

A---B---C master

我所有的开发都将在另一个分支“开发”中完成。所以我分支它。然后我更改配置文件并更改连接字符串并提交。

A---B---C master, origin/master
         \
          X development

接下来,我签出 master 并将更改与“--nocommit”标志合并回来。然后在合并提交中,我恢复配置更改并提交。实际上,我创建了一个空提交,它只是通知 Git 这些更改已合并,无需再次合并它们。

A---B---C---D master, origin/master
         \ /
          X development

现在,随着我继续在 X 上开发新功能,我可以安全地将更改合并回 master - Git 只会尝试合并自上次合并以来的新更改。

A---B---C---D---E---F master, origin/master
         \ /       /
          X---Y---Z development

所以在上面的例子中,只有“Y”和“Z”的变化会被我合并回来。

我已经尝试过了,它似乎工作正常。然而,这确实意味着,每当我切换到主分支时,我都会使用不正确的连接字符串进行配置,但是由于我的大部分开发都是在“开发”分支上完成的,所以它看起来并不大问题给我。

如果我的解决方案有任何问题,请在评论中告诉我。

更新

这样做的一个问题是,如果在“master”上以任何方式更改了配置文件,然后将“master”更改合并到“development”分支,那么配置文件将被覆盖而不会发出警告。

于 2013-03-13T14:29:28.687 回答