Git - Ignoring a specific modification to a config file

I have a config file in our project that holds a connection string to the database, as well as several application settings, e.g:

...
<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>
...

During my development, I always change the ConnectionString value to my local database which causes git to put the file mark the file as "modified".

I read about the option of doing the following:

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

However, that would mean that if I do ANY other change to the file (e.g, change AnotherSetting1) then git would ignore that as well.

Is there a way to tell git to ignore a specific change in file, but to mark it as modified if any other changes occur? Or is there another similar solution to this problem?

Please assume that I can't make any changes to architecture of the config file itself - I'd like a local-only solution.


Solution 1:

filters are made for stuff like this. In your repo,

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

Solution 2:

I do not think git has such facility. And the proposed way of managing the app.config file, treating part of the file version controlled and other part not, does not smell right to me.

In your situation I would seek a way to arrange the app.config to be generated from two files. The ConnectionString setting would be placed in user created (build) configuration file, and the other parts would be put in some sort of template file (conceptually speaking). The user created configuration file could be added to the .gitignore file. The template file would be controlled by git. We would need to have a method to build the app.config file by applying the settings in your build configuration file to the template file.

We are lacking background information about the development setting to tell how all this could be implemented. If you are using make or ant or similar thing, then this would be a simple dependency and rule to create the app.config to make sure the file is created if it does not exist or if the build config file or template file change. Also the natural choice for how to generate the app.config file from the template file depends on your build environment and the nature of the app.config file. For longer than couple of lines of text, even a shell script can be used for simple expansion of a given template file easily (couple of lines of lines to expand ${VARIABLE} constructs, but gets more complicated if the file needs to include dollar signs or back ticks or backslashes etc). More complicated expansion we could use eruby, or eperl or similar thing (even perhaps PHP). The app.config file could also be generated manually whenever you need to change the setting. But all this is somewhat useless speculation without further context.