Streamlining my Git workflow with bash
Tags: git, bash, shell
Published: 2020-09-24 21:22:25

# 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`](https://ss64.com/bash/read.html), 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](https://dev-to-uploads.s3.amazonaws.com/i/84vnozqg8z2vzbqi0au5.png)
 

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](https://dev-to-uploads.s3.amazonaws.com/i/5o40sp1zoful3l7rbyfa.png)


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