As I was updating some gitflow
config today, I noticed that my .gitconfig
is a little messy. Like many things, it’s grown organically and I’ve just never thought about tidying it up. It doesn’t have to be organized, but neat and tidy files always make things more fun.
Sorting .gitconfig
was a bit more challenging than I was expecting. A naive sort mixes sections and values.
$ cat ~/.gitconfig | sort autocorrect = 1 autocrlf = input clean = git-lfs clean %f [core] default = matching editor = nano [filter "lfs"] [help] [push] required = true smudge = git-lfs smudge %f [user]
|
A more complicated sort
might be able to get the job done, but I wasn’t able to figure out a good way to set up the fields and keys properly. If you have a pure sort
solution, I’d love to see it.
I spent a good chunk of time glossing over awk
array sorts and block sorting techniques trying to find a solution I thought I’d read once. Then it hit me. Rather than trying to pipe several clever awk
and sort
combos, I could just add more information, sort
, and remove the extra information.
First thing to do is sanitize the leading spaces. I typically replace tabs with spaces but git
likes tab
bed files.
$ cat ~/.gitconfig \ | sed 's/ +/\t/g' [filter "lfs"] clean = git-lfs clean %f smudge = git-lfs smudge %f required = true [help] autocorrect = 1 [core] autocrlf = input editor = nano [push] default = matching
|
With a guaranteed tab
, we can abuse the field separator in awk
to access the section headings.
$ cat ~/.gitconfig \ | sed 's/ +/\t/g' \ | awk -F '\t' '$1 { print $1 }' [filter "lfs"] [user] [help] [core] [push]
|
By the same token, we can also access the config values.
$ cat ~/.gitconfig \ | sed 's/ +/\t/g' \ | awk -F '\t' '$2 { print $2 }' clean = git-lfs clean %f smudge = git-lfs smudge %f required = true autocorrect = 1 autocrlf = input editor = nano default = matching
|
By putting the two together, we make a more verbose line perfect for sorting.
$ cat ~/.gitconfig \ | sed 's/ +/\t/g' \ | awk -F '\t' '$1 { current = $1; print current } $2 { print current "\t" $2}' [filter "lfs"] [filter "lfs"] clean = git-lfs clean %f [filter "lfs"] smudge = git-lfs smudge %f [filter "lfs"] required = true [help] [help] autocorrect = 1 [core] [core] autocrlf = input [core] editor = nano [push] [push] default = matching $ cat ~/.gitconfig \ | sed 's/ +/\t/g' \ | awk -F '\t' '$1 { current = $1; print current } $2 { print current "\t" $2}' \ | sort [core] [core] autocrlf = input [core] editor = nano [filter "lfs"] [filter "lfs"] clean = git-lfs clean %f [filter "lfs"] required = true [filter "lfs"] smudge = git-lfs smudge %f [help] [help] autocorrect = 1 [push] [push] default = matching
|
We can regain the headings by looking for entries without a second field.
$ cat ~/.gitconfig \ | sed 's/ +/\t/g' \ | awk -F '\t' '$1 { current = $1; print current } $2 { print current "\t" $2}' \ | sort \ | awk -F '\t' '!$2 {print $1}' [core] [filter "lfs"] [help] [push] [user]
|
Similarly, the values can be pulled out from rows with both a first and second field.
$ cat ~/.gitconfig \ | sed 's/ +/\t/g' \ | awk -F '\t' '$1 { current = $1; print current } $2 { print current "\t" $2}' \ | sort \ | awk -F '\t' '$1 && $2 { print $2 }' autocrlf = input editor = nano clean = git-lfs clean %f required = true smudge = git-lfs smudge %f autocorrect = 1 default = matching
|
Now it’s just a simple matter of putting everything back together.
$ cat ~/.gitconfig \ | sed 's/ +/\t/g' \ | awk -F '\t' '$1 { current = $1; print current } $2 { print current "\t" $2}' \ | sort \ | awk -F '\t' '!$2 {print $1} $1 && $2 { print "\t" $2 }' [core] autocrlf = input editor = nano [filter "lfs"] clean = git-lfs clean %f required = true smudge = git-lfs smudge %f [help] autocorrect = 1 [push] default = matching
|