我的项目中有一个配置文件,其中包含数据库的连接字符串,以及多个应用程序设置,例如:
...
<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忽略文件中的特定更改,但是如果发生任何其他更改,则将其标记为已修改?或者是否有另一个类似的解决方案来解决这个问题?
请假设我无法对配置文件本身的架构进行任何更改 - 我想要一个仅限本地的解决方案。
答案 0 :(得分:6)
filters是为这样的东西而制作的。在你的回购中,
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
答案 1 :(得分:1)
我认为git
没有这样的便利。建议的管理app.config
文件的方法,处理控制文件版本的一部分而不处理其他部分,对我来说并不适合。
在您的情况下,我会寻找一种方法来安排从两个文件生成app.config
。 ConnectionString
设置将放置在用户创建(构建)配置文件中,其他部分将放在某种模板文件中(从概念上讲)。用户创建的配置文件可以添加到.gitignore
文件中。模板文件将由git
控制。我们需要一个方法来构建app.config
文件,方法是将构建配置文件中的设置应用到模板文件中。
我们缺乏有关开发设置的背景信息,以告知如何实现所有这些。如果您正在使用make
或ant
或类似的东西,那么这将是一个简单的依赖项和规则来创建app.config
以确保文件创建(如果它不存在)或者构建配置文件或模板文件更改。另外,如何从模板文件生成app.config
文件的自然选择取决于您的构建环境和app.config
文件的性质。对于超过几行文本,甚至可以使用shell脚本轻松扩展给定模板文件(扩展$ {VARIABLE}构造的几行行,但如果文件需要包含美元则会变得更复杂标志或背蜱或反斜杠等)。更复杂的扩展我们可以使用eruby
,或eperl
或类似的东西(甚至可能是PHP
)。每当您需要更改设置时,也可以手动生成app.config
文件。但如果没有进一步的背景,所有这些都是无用的推测。
答案 2 :(得分:1)
让我就如何做到这一点提出一些建议。
向索引添加更改时,您可以使用git add -p app.config
并手动跳过文件中的某些更改。如果在执行提交之前未向索引添加更改,则不会提交这些更改。这是一种“仅限本地”的解决方案。但总是看到git status
报告中修改过的文件可能真的很无聊。
所有其他建议可能需要对架构进行更改,因此不能将其视为“仅限本地”解决方案。无论如何,我认为他们可能值得回顾。
所有更改的主要思想是将本地文件添加到.gitignore
,其中包含本地系统特定设置。我们在这里使用了几种略有不同的解决方案。
app-original.config
文件,在app.config
忽略列表中拥有git
文件。应从app.config
文件手动创建app-original.config
文件。所有这些解决方案真正令人厌烦的是,当配置文件的结构被更改时,需要一些手动工作。例如,在每个配置文件更新时,您应检查是否已引入新属性并更新本地属性文件。当您因为某些应用程序更改而更新本地文件时,您需要记住在配置文件中提交相关更改(请记住您的本地文件位于.gitignore
)。
答案 3 :(得分: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”分支,那么配置文件将被覆盖而不会发出警告