3

To keep all of my config files in sync I have a Github repository with all of my settings. While this works fairly well in most cases, some apps have different versions on different machines.

So now I am wondering... is there any way to set Git global config setting like this one (which causes a warning on my laptop) without causing errors on different machines with older Git versions?

One option might be wrapping the git push command to add the flags when supported but that seems like a hack.

Community
  • 1
  • 1
Wolph
  • 78,177
  • 11
  • 137
  • 148
  • Just to clarify my understanding, what'd be wrong about having a ~/.gitconfig on the different machines? Tailored to the box of course. – mockinterface Feb 09 '14 at 08:10
  • @mockinterface: since I have the configs in a git repo, changing them on one box will effectively (after committing and pushing of course) change them on all of the machines. – Wolph Feb 09 '14 at 21:48

3 Answers3

1

Separate configs for separate machines

Create different config files for different machines and at each machine symlink one of them as the real config. The symlink itself will not be tracked, add it in .gitignore.

The symlinking could be done in a post-checkout hook. You need to identify the current host (e.g. uname -n) and have a file that contains appropriate settings for the hook.

The downside of this solution is that is is not dynamic. Once a new version of Git is installed on a host, you have to check that the appropriate config works with it.

What is impossible

If you want something that checks whether a value is supported for an option and use another value as fallback, you’d have to parse manpages and rely on their contents. Git has nothing similar implemented. You cannot check if a value is supported, you cannot write a config file that dynamically choses the value itself.

Dynamically generated config

However, it is possible to generate the config dynamically. In a similar way to how you replace an ordinary file with a symlink to chose between several static files, you can replace it with a named pipe connected to a daemon that generates the config.

In the daemon you can check git --version and based on that choose the config options’ values. Although this is a clever solution, fully exploiting the capabilities of Unix file system, it is quite a hacky one. You have to keep the daemon running and if it stops, Git will not be able to read the config and will hang.

Palec
  • 12,743
  • 8
  • 69
  • 138
  • I have considered that indeed, just wasn't feeling like it since it's not a dynamic solution of course... I think this will probably be the solution but I'm kind of hoping there's a better way – Wolph Feb 09 '14 at 21:50
  • While I still think that the symlink & multiple config files option is the best one, a fully dynamic one came to my mind. But beware, it is really crazy from my point of view. See my edit. Disclaimer: I never wrote a daemon, although I have seen one simple in shell, and I never used a named pipe directly from my code. I know how they work only in theory. However, if you need help with them, I’ll gladly learn how to use named pipes and how to write daemons. – Palec Feb 09 '14 at 22:23
  • Awesome solution, too hacky to actually execute but I still love the creativity :) I'd be too worried for that if somehow the daemon freezes my shell might not start which makes logging in somewhat difficult (I get all my personal configs this way). Thanks for the idea, it's indeed a nice solution. Let's see if I can think of a problem that can safely use it ;) – Wolph Feb 09 '14 at 22:42
  • @Wolph I found that the named pipe + daemon approach is used for appending different signatures to e-mail messages using `~/.signature`. http://unix.stackexchange.com/a/101248/50602 I think I heard about the same use from one of my friends who sends programming-related quotes and jokes in signature. – Palec Feb 15 '14 at 18:46
  • cool :) Sounds like something I should try to keep up with ;) – Wolph Feb 15 '14 at 21:30
1

Hidden directory with a specially made git porcelain script that you do check in to every repo you work on. ( Or a separate utility repo you could then check out with a manifest and the repo command line utility.) Your script would call push with whatever flags you need based on git version, independent of the machine you're on.

tjborromeo
  • 156
  • 6
0

Not a comprehensive solution, but one trick I use is to put 1.7.12+ options (like push.default=simple) in ~/.config/git/config, which older gits don't read.

I set everything applicable to all git versions in ~/.gitconfig.

kfix
  • 628
  • 4
  • 12