I am a longtime CLI fan. I love how the basic Unix commands can be piped through each other to create very robust automation with a few lines of codes.
I also love git, and I use it almost exclusively from command line. But after the learning curve (which was almost 10 years ago as my colleague introduced it to me), I realised I spend too much time on repetitive commands, and it would be nice to extend it with some handy features too!
A wrapper around git with additional feature extension See detailed functionality in the Features section!
Table of Contents
- Predefined git config
Clone the repositoy to a desired folder:
$ git clone email@example.com:pcdevil/g.git ~/.g
Bootstrap it in your
# Export the destionation folder as G_DIR variable export G_DIR=$HOME/.g # Add bin folder to the PATH export PATH=$G_DIR/bin:$PATH # Load the init script of g source $G_DIR/g.plugin.zsh
$ git config --global --add include.path ~/.g/gitconfig
See Predefined git config section for more information about it.
Reload the terminal.
Predefined git config
The project provides an optional
gitconfig to extend the default git
config. Currently it only…
On that notion, I created a small tool called
g! It's a long-term project of mine, and contains lot of subjective decisions based on how I use git. I've recently made it public and added better documentation to help anyone who would like to use it :)
In this post, I'll go through the functionalities to give a high level overview of it!
git status shows information about the current working tree and it's one of the most used git commands. There are several good practices how to make it more accessible with
g st or
gst aliases, but I found these solutions less intuitive, and made it even simpler: just run the
g command and you'll get the same result while in non-git directories it calls the
The entry-point is not only an alias for the
git status, but it's also a wrapper around git and when it is called with argument, it acts according to them. Other functionalities are based on this behaviour.
If we talk about how to remove the repetitiveness of git usage, most of the time the solution is the aliases.
g provides aliases for common git commands, and some more advanced ones including
git commit and
See the following table for some hints of the available aliases, while the full list is in the documentation:
git commit --amend
git commit --amend --no-edit
git merge --no-ff --no-edit
git switch master
Moreover, there are also angular commit and advanced aliases: the first gives shortcut for a below discussed
g feature, while the second consist of a one liner log (
g l), set origin and push the branch to it (
g ph-o), and alternate way to commit where only the message can be specified (
While having shortcuts to existing commands is good,
g gives several small utilities to enhance git usage - there are mostly related to bootstrap a repository.
If you are working in an environment where custom e-mail domain is used, and you want to make sure your commits are bound to you nicely, you can use
git config to set that up.
To achieve the effect you either have to do it locally in every single repository, or only one time globally. The first is troublesome (declaring the name and e-mail in numerous repositories), while the second option eliminates the portability of the config because and you can't put the
.gitconfig in your dotfiles repository.
To resolve this,
g set-user (or
g su for short) comes in handy. You only set up the username, email and potentially signing key once as a url-matched configuration, then running the
g su command sets it on the current repository with no hustle!
$ git config --global 'user.https://github.com.email' 'firstname.lastname@example.org'
$ git config --global 'user.https://example.org.email' 'email@example.com'
$ git config --global 'user.https://example.org.name' 'jakab.gipsz'
$ git config --global 'user.https://example.org.signingkey' '0000000000000042'
Thanks to the url-matched keys, this won't have any effect on your standard config, allowing to symlink the same config file on several computers.
$ cd my-project
$ g set-user example.org
$ git config user.name
$ git config user.email
$ git config user.signingkey
Here the when the command is called, the author changes accordingly to the config without stating your user information! Full details about how the matching config is found or how the signing key is set is in the documentation.
Oh My Zsh provides a
take command which is basically
mkdir && cd. The assumption behind the command is after creating a directory you usually want to use too. For the same reason this can be useful for git too, and
g is equipped a command which mimics the original one:
g take (
g ta as alias) clones a repository then changes the current directory into it.
g take has one more benefit: it runs the
g set-user command after the clone, which makes
g take an end-to-end solution for cloning and immediate usage of a repository.
On bigger projects I often enter a deep sub-directory to perform an action, and afterwards I want to go back to the root directory.
cd - can help you to change the current directory to the previous one, but if the current directory was a result of several changes, you need to remember how many changes were executed and pass it to it. Oh My Zsh helps a little bit (see cheatsheet), but the burden of remembering how much jumping occurred is still present.
g cd command helps with this problem:
- With no argument, it acts like
cdand jumps to the home directory - which is interpreted as the root of the repository
- While passing an argument changes the active directory relative to the root
Example for given argument:
$ cd ~/my-project
$ cd src/routes/api/categories
$ # do some actions
$ g cd test/routes
Creating a new repository can be tedious:
- Init git
- Set up the gitignore (and then forget to include a crucial path by accident)
- Add readme and license files
- Add temp directory
- Create the first commit
To make it simpler, I created the
g super-init (with
g si as alias) command to automatise all these steps and make sure I don't forget anything!
The command has the same procedure as listed above with the following details:
- The gitignore will be populated with:
- The output of gitignore.io with Linux, MacOS, Windows, IntelliJ (+all), Vim, and Visual Studio Code related ignores.
- The ignores related to the specified programming language.
tmpdirectory and a
README.mdfile will be created with the name of the project and the given description (if any).
LICENSE.mdfile will be created with MIT license.
- The commit will follow the Angular's Contributing Commit Message Format, in form of
build(<projectname>): initial commit.
g super-init acts as
g take, meaning it will change the current directory to the new project too.
The programming language and the descriptions can be specified during invocation.
$ g super-init my-project node "My awesome new project."
$ ls -1A
$ tail -6 .gitignore
# End of https://www.toptal.com/developers/gitignore/api/linux,macos,windows,node,intellij+all,vim,visualstudiocode
### Project ###
$ cat README.md
My awesome new project.
Available under the [MIT license](LICENSE.md).
g switch-main (with an alias of
g sw-m) command helps you to change the current branch to the
In case of needing to change the default branch, you can specify it in the git config with the
init.defaultBranch variable - this added to git very recently and
g switch-main uses it to line up with the standard usage of git.
Example to change the default branch locally:
$ cd my-project
$ git config --local branch.default gh-pages
$ git switch --create fix/footer-visibility
$ # work and commit
$ g switch-main
$ g # invoking git status
On branch gh-pages
Your branch is up-to-date with 'origin/gh-pages'.
nothing to commit, working tree clean
If you made it this far thank you for reading my article, and I hope you find some of these features useful.
Have a nice day!