Skip to content

Instantly share code, notes, and snippets.

@biran0079
Forked from canton7/0main.md
Created September 25, 2013 06:36
Show Gist options
  • Select an option

  • Save biran0079/6695875 to your computer and use it in GitHub Desktop.

Select an option

Save biran0079/6695875 to your computer and use it in GitHub Desktop.

How to have local versions of tracked config files in git

This is a fairly common question, and there isn't a One True Answer.

These are the most common techniques.

  1. Modify your app such that, before loading its config from e.g. config.ini, it first looks for e.g. config.mine.ini. Track a standard config.ini in your repo, but if you need to override the values in it, copy it to config.mine.ini and modify. Then configure git to ignore config.mine.php.
  2. Have your app just look for e.g. config.ini, but don't track this file. Instead create and track e.g. config.sample.ini. Everyone who clones the repo has to copy config.sample.ini to config.ini, but they can modify config.ini as much as they want.
  3. Have your app look at environmental variables for its config, before using the values from its config file. Then set your your shell to load those environmental variables on login. Only works if your app doesn't need much config.
  4. Use some gitattributes clean/smudge magic as suggested by SethRobertson, see the other file in this gist.

Having per-repo untracked config using gitattributes

This approach was presented by SethRobertson on #git. I haven't had a chance to play with it, and it has some caveats (see below), but it's a nice idea.

First, read up on gitattributes. One Two. Pay attention to the smudge/clean filterss.

Create a local branch called "private", which contains your personal config.

Setup script

The following script sets up the the smudge/clean filters for all files in SUBDIR

#!/bin/sh
#
#
SUBDIR=z
x=0
find $SUBDIR -type f | while read f
do
  echo "/$f     filter=private_$x" >> .gitattributes
  git config filter.private_$x.clean "/tmp/clean $f"
  git config filter.private_$x.smudge "/tmp/dirty $f"
  x=$(($x+1))
done

/tmp/dirty

The smudge filter is executed on git checkout, and replaces the contents of every file identified by the setup script with the corresponding file from the "private" branch.

#!/bin/sh
git show "private:$1"

/tmp/clean

The clean filter is executed on git add, and replaces the contents of the (locally modified) files identified by the setup script with their tracked versions from the current branch.

#!/bin/sh
git show "HEAD:$1"

Notes

Note that there's no way to tell which branch is being checked out. Therefore, before checking out out the "private" branch, you have to disable the filters. Renaming .gitattributes is one way of doing this.

Also, SethRobertson alluded to the presence of an undocumented "%f", which would remove the need to create a separate smudge/clean filter pair for every file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment