I've been managing my UNIX
$HOME repository with version control
for almost two decades now (first under CVS, then with git). Once in a
while, I find a little hack to make this work better.
Today, it's
dconf/
gsettings, or more specifically,
Workrave that I want to put in git. I noticed my laptop was
extremely annoying compared with my office workstation and realized
I never figured out how to write Workrave's configuration to git. The
reason is that its configuration is stored in dconf, a binary database
format, but, blissfully, I had forgotten about this and tried to
figure out where the heck its config was.
I was about to give up when I re-remembered this, when I figured I
would just do a quick search ("dconf commit to git") and that brought
me to
Josh Triplett's Debconf 14 talk about this exact topic. The
slides are... a little terse, but I could figure out the gist of
it. The key is to change the
DCONF_PROFILE environment to point to a
new config file (say in your
.bashrc):
export DCONF_PROFILE=$HOME/.config/dconf/profile
That file (
~/.config/dconf/profile) should be created with the
following content:
user-db:user
service-db:keyfile/user
- The first line is the default: store everything in this huge
binary file.
- The second is the magic: it stores configuration in a precious
text file, in
.config/dconf/user.txt specifically.
Then the last step was to migrate config between the two. For that I
need a
third config file, a
DCONF_PROFILE that has
only the text
database so settings are forcibly written there, say
~/.config/dconf/profile-edit:
service-db:keyfile/user
And then I can migrate my workrave configuration with:
gsettings list-recursively org.workrave while read schema key val ; do DCONF_PROFILE=~/.config/dconf/profile-edit gsettings set "$schema" "$key" "$val" ; done
Of course, a bunch of those settings are garbage and do not differ
from the default. Unfortuantely, there doesn't seem to be a way to
tell
gsettings to only list non-default settings, so I had to do
things by hand from there, by comparing my generated config with:
DCONF_PROFILE=/dev/null gsettings list-recursively org.workrave
I finally ended up with the following
user.txt, which is now my
workrave config:
[org/workrave/timers/daily-limit]
snooze=1800
limit=25200
[org/workrave/timers/micro-pause]
auto-reset=10
snooze=150
limit=900
[org/workrave/timers/rest-break]
auto-reset=600
snooze=1800
limit=10800
[org/workrave/breaks/micro-pause]
max-preludes=0
That's a nice setup: "YOLO" settings end up in the binary database
that I don't care about tracking in git, and a precious few snowflakes
get tracked in a text file. Triplett also made a command to change
settings in the text file, but I don't think I need to bother with
that. It's more critical to
copy settings between the two, in my
experience, as I rarely have this moment: "oh I know exactly the key
setting I want to change and i'll write it down". What
actually
happens is that I'm making a change in a GUI and
later realize it
should be synchronized over.
(It looks like Triplett
does have a tool to do those diffs and
transitions, but unfortunately
git://joshtriplett.org/git/home
doesn't respond at this time so I can't find that source code.)
(Update: that git repository can be downloaded with:
git clone https://joshtriplett.org/git/home
It looks like
dconfc is designed to copy settings between the two
databases. So my above loop would be more easily written as:
dconf dump /org/workrave/ DCONF_PROFILE=~/.config/dconf/profile-edit dconf load /org/workrave/
Certainly simplifies things.
dconfd is also nice although it relies
on the above
dconfe script which makes it (IMHO) needlessly hard to
deploy.)
Now if only Firefox bookmarks were reasonable again...