My favorite productivity hack: git newmr

My favorite productivity hack: git newmr

How you tried to automate any daily tasks of your programming? You should!

A git workflow I do every day is code something, stash it, checkout latest master, create a new branch, push my new code and create a mr/pr for it. This gets tedious over time given I usually do it 5+ times a day. Git aliases to the rescue!

My workplace uses gitlab and they support push options, one of which is creating a Merge Request (Pull Request equivalent for GitHub). Thanks to this you can easily create a Gitlab merge request using the CLI. Let me present you the alias git newmr, allowing you to do all of the above things with one command!

git config --global alias.newmr "!f() { git stash save && git checkout master && git pull && git checkout -b $1 && git stash apply && git add . && git commit -m $1 && git push -u origin HEAD -o merge_request.create; }; f"

I can trigger the command with git newmr <branchname> and it:

  1. Stashes the current changes
  2. Checks out and pulls the latest master branch
  3. Creates a new branch based on <branchname>
  4. Applies the stash
  5. Commits changes
  6. Pushes the new branch as a remote
  7. Creates a PR/MR

At my workplace we use Jira for issue tracking, and by setting the branch name to the issue number the issue will automatically close on jira when the branch is merged. Example: git newmr TL-1337.

Creating your own

Creating a custom git alias is super easy. Looking at the example on the linked page adding a “unstage” alias is as easy as:

git config --global alias.unstage 'reset HEAD --'

In our case we want do do a lot of different things and pass parameters and that's were basic git aliases start to limit us. Luckily there is a solution to this!

Escaping to the shell

We can access the shell by using the ! (bang). We can now have a lot more possibility including multiple commands and passing parameters. Let's add the commands we're looking for based on the list above. $1 means the first parameter we pass, so let's add it as our branch name and commit message. The -o option in our git push is gitlabs push option, in this case we’re using it to create a merge request.

git config --global alias.newmr "!f() { git stash save && git checkout master && git pull && git checkout -b $1 && git stash apply && git add . && git commit -m $1 && git push -u origin HEAD -o merge_request.create; }; f"

After running the command above you can use it with git newmr <branch_name> ✌️✨

Adopting it for GitHub

If you are using GitHub you can can use their cli instead of push options for creating the pull request with gh pr create.

First install the GitHub cli with brew

brew install gh

Then add our alias, note that I've renamed it to git newpr to separate it from the gitlab version.

git config --global alias.newpr "!f() { git stash save && git checkout master && git pull && git checkout -b $1 && git stash apply && git add . && git commit -m $1 && git push -u origin HEAD && gh pr create; }; f"

Editing you aliases or troubleshooting

All your aliases are stored in the global git config located in ~home/<username>/.gitconfig. My complete file now looks like this:

[user]
  name = Kuan-Yin Chen
  email = samuelkraft@me.com
[alias]
  newmr = "!f() { git stash save && git checkout master && git pull && git checkout -b $1 && git stash apply && git add . && git commit -m $1 && git push -u origin HEAD -o merge_request.create; }; f"
  newpr = "!f() { git stash save && git checkout master && git pull && git checkout -b $1 && git stash apply && git add . && git commit -m $1 && git push -u origin HEAD && gh pr create; }; f"

Do you have any other tips for custom aliases? Let me know on Twitter!