3

We have a developer toolchain, governed by a config file. Each developer can have their own version of the config file. What is a good way to store separate versions of that config for each developer in a single Git repo? All I am thinking is just separating it by developer's name and putting all the config files in directory. After that, each developer would use an env var to point to the right file with their name.

That seems kinda lame tho, is there a sleeker way to do this?

4
  • Are the developers using multiple computers? Are the differences per developer or per computer? How extensive are the differences? – 1201ProgramAlarm Sep 25 '18 at 3:07
  • Differences probably not that extensive, but definitely using different computers (every dev has their own laptop etc). Difference per dev and per machine, let's assume that. – user290257 Sep 25 '18 at 3:10
  • 6
    Yes. Stop. Use .gitignore. Don't write code that would make me care about your custom config. Keep your customizations to yourself. – candied_orange Sep 25 '18 at 3:10
  • Ermmm well if each dev has their own config file checked into version control, they'd never conflict obviously, but I don't like that solution that much. – user290257 Sep 25 '18 at 3:14
6

This is a commonly recurring issue in past project I've worked on. There are several approaches, but they all have their drawbacks:

  1. Git ignore

Simply put a default file on the Git repo, so that developers can check out the default file. However, developers should ignore changes to this file and never check them in.

Pro: Really simple and I think the commonly preferred option.
Con: Prone to developer error, can lead to needing to fix the repo.


  1. Environment variable

I hadn't considered this yet but you did raise an interesting possibility. However, I'm not a fan of this approach though.

Pro: It works.
Con: It makes it harder to start developing on a new machine + setting up environment variables is a chore.

There are other ways to achieve a similar thing (see 5.) that do not involve environment variables, so I suggest steering clear of environment variables. They're an unwanted dependency.


  1. Machine.config

The machine.config file was created specifically to use machine-specific settings. However, there are some drawbacks that make it a less desirable approach.

Pro: It works, sort of.
Con: Your application's config file takes precedence over the machine.config, which leads to undersirable consequences: Either your server (production environment) has to also use a machine.config for its settings, or you have to change the config setup between dev and prod. Neither is a good option.

As far as I'm aware, there is no way to make the machine.config take precedence over the web.config (similar to e.g. !Important in CSS). If there is a way to do this, then this approach becomes more viable. However, I'm not sure if this is going to cause conflicts for developers who are working on more than one project on that machine, as you'd be relying on the same machine.config for all projects.


  1. My preferred approach:

I tend to create two files. default.config and web.config (or app.config). Feel free to use other names.

  • default.config is registered in the git repo, and it contains the actual default config file.
  • web.config is not registered in the git repo. Developers simply save the default.config file as a (newly created) web.config file, and can then make adjustments as they see fit.
  • The default.config file is "just a file" in the Git repo.
  • The VS solution is set up to use the web.config file.
  • If a developer ends up adding new config keys for a change they're committing, they are expected to add these keys to the default.config and commit those to Git.

This has a few benefits that, in my opinion, make it worthwhile. To me, the most important benefit is that if someone commits a change that adds/deletes config keys, everyone automatically checks out the new keys (so they are aware of the update), but the added/removed keys does not immediately affect their local config file.

Pro: What I just said.
Con: Developers need to manually synchronize settings between the two config files. In my experience so far, that usually amounts to a 30 second copy/paste job so it's not an excessive hassle. However, it's not uncommon for a developer to commit a change and forget to update the default.config, which can lead to other developers running into issues after doing a pull.


  1. (untested) Custom config composition

This is something a coworker suggested, which, like your environment variables, is an interesting idea. But I haven't used this yet.

The idea would be to programmatically compose the config file. Just like how you can add a reference in your web.config to a secondary config file, you can add this reference programmatically. The benefit of doing it via code is that you can decide the second config gile's name dynamically (e.g. based on the username).
Additionally, you can disable this additional loading behavior by e.g. using a config switch, which means that you can ensure only using your basic config file in production.

This means that you could effectively have a separate config directory with USERNAME.config files which override specific settings of the web.config file. All of these files can be checked in, and it would even make it possible for one developer to use another developer's config settings (e.g. when trying to reproduce an issue).

Note: instead of developer-specific config files, you could do the same for a hardcoded "localDevOverride.config" file, but then you can't check in that local file. I'd prefer to check in those files, so that if a dev needs to work on another machine (e.g. if their old one dies), they don't lose their settings.

1
  • MrCholo likes this answer very much – user290257 Sep 25 '18 at 18:00
1

How I handled a related problem:

The config files support a line that says Load=name of config file

The config file in the normal location consists of exactly one line--one that specifies a config file to load from a network-accessible location. These files have not been touched since initial deployment, all the real configuration is in a directory of config files on the network. These files all have different names and would be no problem to put in source control if that was desired.

5
  • I upvoted since this seems reasonable but I can't say I completely understand it, if you can elaborate that would help other ppl – user290257 Sep 25 '18 at 18:01
  • @MrCholo What don't you understand? – Loren Pechtel Sep 25 '18 at 21:07
  • "The config files support a line that says...", can you show what such a config might look like? Like an .env file? what about using bash instead? – user290257 Sep 25 '18 at 22:17
  • 1
    @MrCholo I'm a Windows guy, not Linux. Looking at the file on my system: c:\Users\Loren\AppData\Roaming\Boardwalk\Config.Ini contains Load=D:\Boardwalk\Data\Config.Ini. It's still named Config.Ini because I only have one version, but the deployed stuff has about 20, each of which loads a config named after the station that's running on that computer. A whole pile of config files in one directory without any source code differences to invoke the right one. – Loren Pechtel Sep 26 '18 at 0:20
  • Nice, MrCholo is OK with Windows ppl – user290257 Sep 26 '18 at 0:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy