Author Topic: Creating New Git Commands  (Read 113 times)

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4654
Creating New Git Commands
« on: January 22, 2019, 02:25:49 PM »
Today I learned you can create new git commands simply by creating a script named "git-commandName", marking it as executable, and putting it anywhere in your path. Running "git commandName" will then run your script.

I was looking back at the SVN -> Git conversions. I had a rather long command that I wanted to wrap into something easy to remember and type:
Code: [Select]
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | awk '/^blob/ {print substr($0,6)}' | sort --numeric-sort --key=2 | cut --complement --characters=13-40 | numfmt --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest

My first attempt was to try setting an alias.
Code: [Select]
git config --global alias.listobjects "..."

Unfortunately when I tried running that it informed me that "`git` was not a git command". At first I tried removing the "git" to run the sub command directly, however, it didn't like the "|" part. I soon found you need to add a "!" prefix to run them as shell commands. This didn't work either, at least not really. Something ran, but I just got a screen full of blank text. It was about this point that I found out you can create new commands by adding shell scripts to your path.

I removed the alias with:
Code: [Select]
git config --global --unset alias.listobjects

Then I added the code into a shell script (~/bin/git-listobjects):
Code: [Select]
#!/bin/sh

git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | awk '/^blob/ {print substr($0,6)}' | sort --numeric-sort --key=2 | cut --complement --characters=13-40 | numfmt --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest

Note that I did not include an extension ".sh" for this script. If you do, it becomes a required part of the command name. Git does at least give you a warning, mentioning the similarly named file. After marking it as executable, and naming it without the ".sh", it all worked perfectly.