Using conditionals in .gitconfig

Recently I was creating a Git alias for logs that used --date=human for date formatting, before realizing this option had only been added in Git 2.21. After pulling the alias to some of my other machines and seeing that it failed, I decided I wanted a conditional line in my Git config that tested my current version of Git, used --date=human if possible, and --date=short if not.

Git’s config syntax doesn’t allow for conditionals, but it does allow for the running of arbitrary bits of shell script. For instance, something like this will work:

  lg = "!if (( "1 > 2" )); then git log --oneline; else git log; fi"

Because 1 is not greater than 2, git lg will perform a standard git log.

How do we compare our version of Git to a specific value, then? Let’s figure out how to get just our version number of Git first:

$ git --version | sed -E 's/git version ([0-9]+.[0-9]+).*/\1/g'

For me this returns 2.29. We need to check that this is greater than 2.20. Let’s try this:

$ if (( "2.29 > 2.20" )); then echo "Compatible"; else echo "Not compatible"; fi

Why doesn’t this work? I’m getting an invalid arithmetic operator error.

Turns out Bash only handles integer math, so we need to pipe our comparison expression to a basic calculator program:

$ if (( $(echo "2.29 > 2.20" | bc) )); then echo "Compatible"; else echo "Not compatible"; fi

Great! Works for me. Now we just need to get our actual Git version in there instead of the literal 2.29.

After some struggle — the \1 reference in sed needs to be double-escaped here, for some reason — this is the result:

  lg = "!if (( \
      $(echo \"$(git --version | sed -E 's/git version ([0-9]+.[0-9]+).*/\\1/') > 2.20\" | bc) \
    )); then \
      DATE="--date=human"; \
    else \
      DATE="--date=short"; \
    fi; \
    git log --pretty=format:\"%h %ad %s\" $DATE"

Now git lg will show a single-line log with “human”-formatted date if possible, or a “short”-formatted date if not.

I’ve created a Gist that puts this all together.

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: