The Spark
My daughter is currently navigating the intense, fast-paced world of software engineering. Recently, she hit that universal developer wall—the tedium of the "Git Triple-Step." After a long session of coding, she exclaimed, "There has to be a faster way to do this. I'm tired of typing the same three commands every time I want to save my work!"
As a tinkerer who can’t resist a good challenge, I told her, "Don't worry, I’ll write you a script. One command, and you're done."
It sounded simple and it was simple. But as I quickly learned, Bash has a way of humbling even the most experienced scripters when you least expect it.
The "Simple" Script That Failed
I cobbled together a string of commands which I thought was a foolproof one-liner. I wanted the script to take her message, add the files, commit them, and push.
#!/bin/bash
msg=$1
git add .
git commit -m \"$msg\"
git push
I tested it with a single word: ./push Test. It worked perfectly. It felt real good.
Then she tried a real-world commit message: ./push "Added the new NN logic"
The Result? Disaster. The terminal started screaming: error: pathspec 'new' did not match any file(s).
The Anatomy of the "Pathspec" Bug
What went wrong? As it would happen, I had fallen into the Literal Quote Trap.
By using backslashes (\"$msg\"), I thought I was being proactive by "forcing" the quotes to stay around the message. Instead, I was telling Bash to treat the quotation marks as literal text characters rather than functional shell wrappers.
When the script executed, Git didn't see a single string. It saw:
- -m: The flag
- "Added: The message—including a literal opening quote
- the, new, NN...: Git thought these were filenames I wanted to commit.
Since those files didn't exist, Git threw a "pathspec" error and died.
The Fix: Double-Quote to the Rescue
In Bash, you don't need to "force" quotes with backslashes. You just need to wrap your variable expansion in standard double quotes. This acts as the "glue" that keeps your multi-word message together, no matter how many spaces it has.
The "Pro" Solution: push.sh
After fixing the quoting bug, I decided to take it a step further. If I was going to give my daughter a tool, it should be robust, safe, and informative.
Here is the final "Pro" version of the script. It includes:
- Branch Protection: Prevents accidental pushes to
mainormaster. - Color-Coded Feedback: Green for success, Red for "Stop and Look."
- Safety Checks: If the commit fails, it won't try to push.
The Script
#!/bin/bash
# -----------------------------------------------------------------------------
# Script Name: push
# Description: Automates the 'git add .', 'git commit', and 'git push' workflow
# with built-in branch protection and error handling.
# Developer: Mukul Dharwadkar
# License: MIT (Open Source - Please retain developer credit)
# -----------------------------------------------------------------------------
# --- CONFIGURATION ---
# Colors for high-visibility feedback
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# --- HELP MENU ---
function show_help {
echo -e "${YELLOW}push - Automated Git Workflow${NC}"
echo -e "Developed by: Mukul Dharwadkar"
echo -e ""
echo -e "${YELLOW}Usage:${NC} ./push \"Your commit message\""
echo -e "Example: ./push \"Refactored navigation bar CSS\""
exit 1
}
# 1. Validation: Ensure a message was provided
if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]] || [[ -z "$1" ]]; then
show_help
fi
# 2. Capture the Message
# We use "$*" to grab every word passed to the script as one string.
msg="$*"
# 3. Branch Safety Check
current_branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$current_branch" == "main" ] || [ "$current_branch" == "master" ]; then
echo -e "${RED}⚠️ WARNING: You are on the $current_branch branch.${NC}"
read -p "Are you sure you want to push directly to production? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}Push aborted. Safe choice!${NC}"
exit 1
fi
fi
# 4. The Execution Chain
echo -e "${GREEN}Staging all changes...${NC}"
git add .
echo -e "${GREEN}Committing with message:${NC} \"$msg\""
# Wrapping $msg in double quotes (no backslashes!) is the secret sauce.
if git commit -m "$msg"; then
echo -e "${GREEN}Pushing to origin/$current_branch...${NC}"
if git push; then
echo -e "${GREEN}✅ Success! Local and Remote are synced.${NC}"
else
echo -e "${RED}❌ Error: Push failed. Check your network or remote permissions.${NC}"
fi
else
echo -e "${RED}❌ Error: Commit failed. (Likely no changes to save).${NC}"
fi
How to Use It
- Save it: Copy the code into a file named
push.sh. - Permit it: Run
chmod +x push.shto make it executable. - Deploy it: Move it to your
/usr/local/binfolder to use it from any project.
Note: To make it even easier to run, you can choose to omit the
.shextension and just keep it aspushor whatever name you choose.
Final Thoughts
Automation isn't just about saving time; it's about building guardrails. Now, the git workflow moves faster, but the script is there to ensure the developer indeed wants to push to the main (or master) branch.
The next time you’re building a "simple" script and it breaks, remember: Check your quotes. Bash is a powerful ally, but it demands literal precision.
