DEV Community

CarlyRaeJepsenStan
CarlyRaeJepsenStan

Posted on • Updated on

Streamlining my Git workflow with bash

Intro

Think about your every-day github workflow. You wrap up your code, make sure everything works fine, and then open your terminal. You would then:

  • git pull
  • git stage . or git add .
  • git commit
  • Type your commit message and press :x! to exit
  • git push

Or, if you use the git GUI in an IDE, you would click a bunch of buttons to get your changes sent to your Github/Gitlab/Gitwhatever repo.

Although I have ohmyzsh installed and can run short commands for a lot of git actions (gc instead of git commit, gp instead of git push, etc), I still found the process of committing to Github very...inefficient. Do I really have to write :x! every time? And moving the cursor around to click buttons is always slower than straight typing. How could I make this faster and less error-prone?

Enter bash

I talked with some friends and learned about bash. bash files (extension .sh) combine a programming language with basic shell commands - like git commands!

If I wanted to write a bash script to do my git commits for me, it would need to do the following:

  • git pull
  • cd into my git repo
  • Accept my input
  • Stage the files and commit with my input as the message.

So I did some quick searching, and found the man page for read, and also found that you use variables my typing a $ in front of the variable name.

Writing something like read myvar means you can get user input, and you can use myvar by writing $myvar. Now I had the beginnings of my script:

echo "Enter your commit message below:"
read myvar
echo "Your commit message is:"
echo $myvar

You can also use optional flags to limit the character input - I used the flag -n to set the character input to 1, just so I could make a cool y/n thing:

echo "Would you like to commit? [y/n]"
read -n 1 -s input

And, the -s flag makes the read "silent," so it doesn't output the character you pressed.

Cool! Now, I thought I could work this into my script: display the commit message, and then confirm my intent to commit. So then I looked up how to write an if/else block.

If/else blocks

Ah, the if/else statement - the basis of beginner programmers and things like IFTTT. In bash, an if/else block looks like:

if [statement];
 then
  # do something
elif [statement];
 then # do something
else 
 # do something - no then! 
fi 

This is where I started finding errors - things like "Unexpected syntax error near else". Whaaat?

So after extensive searching, I figured out this:

myvar = "foo"
myvar="foo"

Is there a difference in the above script? In python and javascript, there isn't - spaces don't matter.
But. In shell...
spaces matter.

This was a huge source of frustration for me - it turns out, declaring a variable means you can't have any spaces, but comparing variables requires spaces. That means

if [ myvar = "foo" ];

is different from:

if [ myvar="foo" ];

🤦‍♀️
I spent 20 minutes figuring this out. I hope by reading this article, you'll avoid the same!

Stupid mistakes aside, the if/else statement was pretty simple - if my input was y, commit, if it was n exit and say "You aborted the process," and if it wasn't either of them, exit and say "Your input wasn't y or n".

Recalling our previous line of code read -n 1 -s input, and remembering that we can use input as $input:

Screen Shot 2020-09-24 at 2.29.07 PM

And remember, the thens are important! I forgot the then for the elif statement, causing more headaches.

Here's the final product:

#!/bin/bash
cd vanillanimate
git pull
echo "Enter your commit message below:"
read myvar
echo "Your commit message is:"
echo $myvar
echo "Would you like to commit? [y/n]"
read -n 1 -s input

if [ $input = "y" ];
 then 
  git stage .
  git commit -m "$myvar"
  git push
  exit 0
elif [ $input = "n" ];
 then
  echo "process abort exit code 0"
  exit 0
else
  echo "process abort exit code 1 - your input $input is not y or n"
  exit 1
fi

If I were to make this even better, I might make it so the script asks for a path to repo first, instead of having a hard-coded path. But, it worked and only took about an hour. And it worked!

Screen Shot 2020-09-24 at 2.21.38 PM

Anyways, thanks for reading and remember that as a developer, you never stop learning.
Thoughts? Found a typo? Leave a comment!

Latest comments (0)