loading...

Be more productive with shell aliases

easyaspython profile image Dane Hillard ・3 min read

The most valuable time as a software developer is usually time spent collaborating and thinking. To get as much of that time as possible, reduce the time you spend typing things with your mortal fingers!

Git

Git is a ubiquitous version control system, and becomes more important as many developers begin collaborating on the same code base. If your organization uses Agile development practices, you'll also be creating many branches and updating master a lot.

I use oh-my-zsh's Git plugin which provides an amazing variety of aliases for common (and not-so-common) Git subcommands. A common workflow in git is to:

  1. Check out the master branch
  2. Update your local master branch with the latest changes from the remote
  3. Create a new branch for your changes
  4. Commit your changes with a good commit message
  5. Push your branch to the remote

Without any aliases, this workflow looks like this on the command line:

$ git checkout master
$ git pull origin master
$ git checkout -b my-feature
# Make changes...
$ git add .
$ git commit -am 'Add my feature'
$ git push origin my-feature
Enter fullscreen mode Exit fullscreen mode

This is fine, but sometimes I forget that pesky -b flag when creating a branch and also get annoyed that I need to state which branch I'm pushing when it's almost always the current one.

With the Git plugin aliases, this workflow takes a lot less work:

$ gcm
$ gl origin master
$ gcb my-feature
# Make changes...
$ ga .
$ gcam 'Add my feature'
$ ggpush  # this takes advantage of oh-my-zsh's git_current_branch
Enter fullscreen mode Exit fullscreen mode

Sometimes you need to stash your changes while looking at another branch or doing more complex things in Git:

$ git stash
# Do some stuff and come back
$ git stash pop
Enter fullscreen mode Exit fullscreen mode

But these aliases come in handy:

$ gsta
# Do some stuff and come back
$ gstp
Enter fullscreen mode Exit fullscreen mode

There are a lot of handy aliases, including plenty with the various flags you might use for a particular Git subcommand:

$ gd  # git diff
$ gdca  # git diff --cached
$ gds  # git diff --staged
Enter fullscreen mode Exit fullscreen mode

I love using these, and the shorthand for them is generally intuitable kind of like Vim. I've added a few of my own for command+flag combinations I use commonly, like:

$ goop  # "git oops": git reset --soft HEAD~1
$ gun  # "git unstage": git reset HEAD --
Enter fullscreen mode Exit fullscreen mode

I also checkout and update master then prune cleaned up remote branches so often that I made a single command, upr (for "update repo"), that does this all for me.

Python

I work in Python and Django most days. The ease and length of my aliases in this arena reflect that; the more frequently I run a command, the shorter its alias:

$ python manage.py runserver  # Nope
$ ./manage.py runserver  # Nope
$ run  # There we go
Enter fullscreen mode Exit fullscreen mode
$ pipenv shell  # Nope
$ psh  # Yep
Enter fullscreen mode Exit fullscreen mode
$ pip install -r requirements.txt  # Hmmm
$ prq  # Indeed!
Enter fullscreen mode Exit fullscreen mode

Odds and ends

There are a few general command utilities that I use often enough to slim them down too. The one I use the absolute most is named, which expands to find . -name. Then I just ask for files named "*.py"! I also default grep to using colors and line numbers by aliasing it to grep -n --color=auto. I can use the bare grep by typing \grep on the rare occasions where it's needed.

You can see all of my aliases here.

Conclusion

The point of all this is that you should spend time thinking about what you want to do and as little time as possible doing what you want to do when using the command line or writing code. I'm able to reincorporate all the time I save into more thinking—usually about all the bugs I've introduced 😉

Discussion

pic
Editor guide
Collapse
dlains profile image
David Lains

You could actually shorten your pull and push git commands a bit. Oh My Zsh also has ggl which is an alias for git pull origin $(current_branch). The plugin keeps track of which branch you are on in the current_branch variable. When you are on the master branch the alias would end up being git pull origin master, if you were on a branch named feature it would be git pull origin feature. The same rules apply to the ggp alias, defined as git push origin $(current_branch).

Collapse
easyaspython profile image
Dane Hillard Author

That's how ggpush and ggpull work too, but I didn't know about the shorter-named functions! Guess I really need to read through all the functions in that plugin, heh. Thanks!

Collapse
sergsoares_15 profile image
Sergio Soares

Thanks Man, really like your aliases. Mainly goop (will use now).

One mine that i really like is:

alias new-feature="git reset --hard HEAD && git checkout master && git pull origin master && git checkout -b $@"

I throw actual changes (if need i stash), go to master get all changes from my teammates and create a new branch with actual changes.

This improve a lot my workflow.

Collapse
easyaspython profile image
Dane Hillard Author

Nice! My upr is sort of similar, but favors stashing existing changes and doesn't create a new branch. Maybe I can combo that with another to include the branch creation part, because that's usually what I do next! Thanks for sharing 🤗

Collapse
emgodev profile image
Michael

This is a neat read! I started writing some of my own aliases, but now using EMACS, I'm trying to find a good Git mode that does what I need.

I've tried to use normal words so that chaining aliases is more like speaking a sentence. There are obviously limitations to this; My traversal aliases are go /path/to/file.txt (cd) or m to ../other/directory/ file.txt (mv -vn, -t). For Git my status command is working, or working ofstaged (--cached), or working ofuntracked (--no-index).

Lately I had struggled with finding ways to name my stash commands, I came up with stash (save), stashes (list), unstash (apply), destash (pop).

Collapse
easyaspython profile image
Dane Hillard Author

Nice, I like the expressivity! named is definitely one my favorite aliases for that reason. I would love a clean way to have commands like move {path} to {other path} or compare {branch} to {branch} without writing functions that do too much heavy parsing...at the same time, I do like the brevity of the commands. In my head they still say "git create branch" or "git checkout" rather than "gee-cee-bee" or "gee-cee-oh" 😄

Collapse
sergsoares_15 profile image
Sergio Soares

Make a lot of sense this, i follow it in my alfred commands, will use too. Thanks

Collapse
buphmin profile image
buphmin

Always nice to see ways to make things easier. I usually use the gui in jetbrains ides, but I think it is very important to first know what the gui is doing under the hood, and second have good ways to be productive without a full blown ide.

Collapse
easyaspython profile image
Dane Hillard Author

Such a great point. Productivity is an abstraction layer on top of things you understand well! Otherwise when something bad happens you won't know how to correct it.

Collapse
ocampesato profile image
Oswald Campesato

My handy aliases for *nix commands:
alias lt='ls -lt'
alias ltr='ls -ltr'
alias ltm='ls -lt|more'
alias ltrm='ls -ltr|more'
alias latr='ls -latr'
alias ltr8='ls -ltr|tail -8'
alias ltr22='ls -ltr|tail -22'
alias ltd='ls -lt|grep "d"'
alias ltdm='ls -lt|grep "d"|more'
alias findx='find . -print'
alias findxm='find . -print|more'
alias findxwc='find . -print|wc'

Collapse
moopet profile image
Ben Sinclair

With the Git plugin aliases, this workflow takes a lot less work:

To me, that looks like about 15-20% fewer letters to type to do essentially the same commands as before. It has none of the benefits of a script to make the process idempotent, won't work on someone else's computer and looks inscrutable in your shell history.

Looking over your shoulder or pair-programming? I have no idea what gstp does, because it's not something that exists outside of your alias list and I can't easily infer from context. It does something to do with git, but that's as far as I get before I have to add the next line to my cognitive load.

I know why you want to use aliases, and I know they're handy. From mine:

# ahem.
alias gti=git
Collapse
easyaspython profile image
Dane Hillard Author

To each their own, of course! I also use scripts liberally, and make a point to fully type out my commands if I happen to be working with someone else 😊

Collapse
ocampesato profile image
Oswald Campesato

PS: the ltd and ltdm aliases didn't display a caret: grep "d"