Git to your heart’s content

git git git git git git git git git git oops

Is it just me or have you also ever found having entered too many gits in your terminal and wordered if there’s a solution to it? The thing is i quite often type git then go away and come back, then type a full git status after it. This leads to a lovely lovely annoying error out the box:

$ git git status
git: 'git' is not a git command. See 'git --help'.
What a git.

And this has been irritating me so much lately. Like it is my fucking laptop that I paid for with my fucking hard earned money. If I wanna type git git git push I damn well should be able to

So.

Now my initial thought was overriding the git binary in my $PATH and having it strip any leading arguments that match git, so we end up running just the git status at the end of the arguments.

But APPARENTLY after wasting an hr trying to figure that out ugh I found there’s an easier way where you can just use git-config’s alias.* functionality (which is pre cool tbh) to expand the first argument being git to a shell command.

$ git config --global alias.git '!exec git'

Which adds the following git config to your .gitconfig file

[alias]
git = !exec git

And then you’ll find you can git git to your heart’s content

$ git sha
cc9c642663c0b63fba3964297c13ce9b61209313

$ git git sha
cc9c642663c0b63fba3964297c13ce9b61209313

$ git git git git git git git git git git git git git git git git git git git git git git git git git git sha
cc9c642663c0b63fba3964297c13ce9b61209313

(git sha is an alias for git rev-parse HEAD.)

Basically how this works under the hood is when you type

git something args...

git does roughly:

  1. Look for a real subcommand called something (like status, commit, push, etc).
  2. If it doesn’t find one, it looks in your config for an alias called something.
  3. If the alias doesn’t start with !, Git just rewrites the command.
    - e.g. st = status turns git st into git status.
  4. If the alias does start with !, Git goes: “oh this is a shell thing” and runs the rest as a shell command, passing the extra words as arguments.

So with this line:

[alias]
	git = !exec git

you’ve basically taught git:

“If someone runs git git ..., actually run the shell command exec git ... instead.”

to remove an alias use: git config --global --unset alias.git

but yea im kinda liking fucking around with this alias thing to spice up my usual git commands tbh. here's some:

[alias]
    # Undo the last commit
    # "Oops I did it again" - Britney Spears
    oops = reset --soft HEAD^

    # Display only your own commits
    # "It's all about me" - Kim Kardashian
    kardashian = "!_() { \
        git log --oneline --graph --decorate --author=\"`git config user.name`\"; \
    }; _"

    # git please: stomps the upstream branch with your local version
    please = push --force-with-lease

    # git it? creates an empty root commit in one quick step
    it = !git init && git commit -m "root" --allow-empty

    # Display logs as a funky tree :)
    # "Last Christmas, I gave you my heart" - George Michael
    treesmas = log --graph --abbrev-commit --decorate --all --format=format:'%C(bold blue)%h%C(reset) - %C(cyan)%aD%C(reset) - %an %C(blue)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n %C(green)%s%C(reset)'

Now git back to doing useful things!

Subscribe to Kay's Logs

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe