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 .
orgit 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
:
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!
Anyways, thanks for reading and remember that as a developer, you never stop learning.
Thoughts? Found a typo? Leave a comment!
Top comments (0)