Build (and Abuse) Complex Git Aliases

I am not the first, nor will I be the last, to have Git Alias tips and tricks to recommend. It’s possible you’ve seen quite a few “Top 10 git aliases I use” articles by now. But how else can we harness this simple but powerful tool beyond what’s described in the official Git Basics Manual? In this article, we’re going to build an alias that formats, adds change interactively, writes a detailed commit message with formatting and variables, and push up the committed changes.

What are Git Aliases?

Git aliases are an easy way to, as the name suggests, rename a command or set of commands with a more concise, more personal nickname. Maybe you have specific formatting to use for viewing a branch’s commit history and don’t want to type it every time. Or perhaps you simply find typing git commit -m too tedious. With git aliases, that’s an easy fix. All you have to do is run this:



//a commit with message alias
git config –-global alias.cm ‘commit -m’

And now your commit with message command is accessible through the very simple



// example usage
git cm “insert commit message here”

This added the command to your global .gitconfig file and thus is a global alias that can be used in any project you have. If you’d like to put one in a local project, you can use this flag:



// local version
git config –-local alias.cm ‘commit -m’

This will place the alias in your project’s .gitconfig file.

For more on simple aliases, the official page from Pro Git is a great resource.

How do you use variables (and git functions)?

This basic function can be used for any number of one-line commands. One common one is this one to pretty print git history with formatting, colors — the works. Such a complex command, accessible immediately with just a few keystrokes.

But can we do more?

Limits

Let’s say I am on a project and my team would like to apply this formatting standard to our commits.


// example branch format
“PROJ_{ticket number}_{author}: {commit message}”

I could still use our previous cm command, but I’d still have to type out the formatted commit message every time. I’m the only one authoring my commits, and these are only for one project. It’d be nice to have that formatting be autofilled. Then I can provide the ticket number as a variable, and the commit message as another to create the full formatted string. But how?

Shell commands

The answer? Shell commands!

Git allows us to use the ! to indicate that we are escaping to the shell. We can use this, combined with shell functions, to use variables, use pipes, call external non-git functions and shell scripts, and all kinds of things.

Let’s start with our commit message. You can technically write all of these using the same syntax as above, but you may find it easier to open up an editor or use vim to edit your git config files directly. Depending on personal preference, you can do this either in your global .gitconfig file or your local project’s .gitconfig file.


[alias]
        cm = commit -m
        cmproj = "!f() { \
           git commit -m \"PROJ_$1_mtirimie1: $2\"; \
        }; f"

This format is an anonymous function. We call this function f, and say that the first parameter this function gets will be placed at $1, and should be the ticket number. The second parameter will go to $2, and will be our commit message.

And now, instead of typing out the whole commit header, we now have much less work to do. All we really need is the ticket number, and we’re good to go!


// example commit message usage
git cmproj 999 “I love git aliases”

This allows us to combine multiple lines of commands together as well. For example, let’s say I also have another git alias:



// git alias to view code changes to add to commit
git config –-global alias.ap ‘add -p’

We can put these together now, with: 


[alias]
        cm = commit -m
        ap = add -p
        cmproj = "!f() { \
           git commit -m \"PROJ_$1_mtirimie1: $2\"; \
        }; f"
       done = “!g() { \
          git ap; \
          git cmproj $1 $2; \
       }; g”

If you’d like, you can even add a push step.


[alias]
        cm = commit -m
        ap = add -p
        cmproj = "!f() { \
           git commit -m \"PROJ_$1_mtirimie1: $2\"; \
        }; f"
       done = “!g() { \
          git ap; \
          git cmproj $1 \”$2\”; \
          git push; \
       }; g”

And now we have a simple, custom git command that we can use to view all our changes, write our commit and message, and push to the repository. Tread carefully though, and make sure you Ctrl + C to get out of the git add -p step if you need to instead of using q, or you’ll accidentally push unfinished commits straight to the repository (Not that I’m speaking from personal experience).

How to use external shell commands

Let’s take it further. People often use the formatting standard called ktfmt for Android projects. It has its own command that runs on a gradle daemon, which isn’t a git command.



// ktfmt run command using gradle
./gradlew ktfmtFormat

In order to use this, we use the same ! operator.



// fmt git alias using external shell commands
fmt = "!cd ~/AndroidStudioProjects/my-project/my-app  && ./gradlew ktfmtFormat"

This can be used with just about anything else you can think of in shell scripts.

Put it all together.

With that, we can now create our final git alias, one that formats our project, adds all changes one by one, writes our commit message, and pushes our work up


complete = "!a() { \
           git fmt; \
           git ap; \
           git cmproj $1 \"$2\"; \
           git push; \
        }; a"

And we’ve done it! That’s how you, too, can overcomplicate git aliases to your heart’s content.

Conversation

Join the conversation

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