Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

A Bash script can run git add, git commit, and git push in one command. The version worth using does three extra things: it stages only what you mean to stage, refuses to commit without a message, and stops before pushing if any earlier step fails. The script below does that for the repository you run it in, on the branch currently checked out.

Before you run it

Confirm these prerequisites first. Most failures come from one of them.

  • Git is installed and available on your PATH.
  • Bash is available. The script uses Bash features such as [[ ]], so run it with Bash rather than a minimal POSIX sh.
  • You run it inside the intended repository. Git commands act on the repository that contains the current directory.
  • A commit identity is configured (user.name and user.email), or the commit step will fail.
  • The remote is reachable and you can authenticate to it. Credentials, SSH keys, and hosting-service permissions depend on your provider and are outside the scope of this article.

The script

Save this as commit-and-push.sh in a scratch repository first. It is a teaching example, so check its behaviour on a throwaway project before pointing it at real work.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#!/usr/bin/env bash
set -e

if [[ $# -lt 1 || -z $1 ]]; then
  printf 'Usage: %s "commit message"n' "$0" >&2
  exit 2
fi

message=$1

git rev-parse --is-inside-work-tree >/dev/null
git status --short

git add -A
git diff --cached --stat
git commit -m "$message"
git push

What each step does

  1. Guard the message. The script exits with status 2 and a usage line if no argument was given or the argument is empty. Nothing is staged or committed in that case.
  2. Quote the message. The variable is stored as message=$1 and passed as "$message", so a message such as Fix login redirect reaches Git as one argument.
  3. Confirm you are in a work tree. git rev-parse --is-inside-work-tree succeeds only inside a working tree, so the script stops early if you ran it from outside a repository.
  4. Show the current state. git status --short lists modified, deleted, and untracked files in a compact form. Read it before continuing.
  5. Stage changes. git add -A stages the changes in the repository. Git does not add ignored files by default, so .gitignore still applies.
  6. Summarise the staged set. git diff --cached --stat shows which files and how many lines are staged. For a full review, run git diff --cached instead, or git commit --dry-run to see what a commit would include.
  7. Commit. git commit -m "$message" records the index as a new commit with your message.
  8. Push. git push sends the commit to the remote configured for the current branch.

Choosing a staging scope

Staging is the step that decides what ends up in the commit, and it is where automation causes the most damage. Git’s documented model is that git add copies selected working-tree content into the index, and git commit records only what is in the index. A file edited after staging is not included until you stage it again.

Approach What it stages New untracked files Main risk
git add -A (used in the script) Changes across the repository, including removals Included Captures unrelated or sensitive work present in the tree
git commit -a Modifications and deletions of already-tracked files Not included Looks like “commit everything” but silently skips new files
git add <paths> Only the named files or directories Included only if named Forgotten files stay out of the commit

Using explicit paths instead

If the repository holds several tasks or generated output, replace the broad stage with named paths. Pass the paths as arguments after the message so the script’s behaviour is visible in the command line:

#!/usr/bin/env bash
set -e

message=$1
shift

if [[ -z $message || $# -lt 1 ]]; then
  printf 'Usage: %s "commit message" path [path...]n' "$0" >&2
  exit 2
fi

git add -- "$@"
git diff --cached --stat
git commit -m "$message"
git push

Run it as bash commit-and-push.sh "Update parser" src/parser.c tests/parser_test.c. The -- separator stops Git from reading a file name that begins with a dash as an option.

Running the script

Run it with Bash directly, from inside the repository:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
bash commit-and-push.sh "Fix login redirect"

To run it as a command, add an interpreter line (the #!/usr/bin/env bash line in the script) and give it execute permission:

chmod +x commit-and-push.sh
./commit-and-push.sh "Fix login redirect"

The GNU Bash manual describes a shell script as a text file containing shell commands, which is why either invocation works. See the Bash Reference Manual: Shell Scripts section and the Bash manual index for the surrounding material.

When the push fails

Because the script stops at the first error, a failed push leaves the commit in your local branch but nothing on the remote. Check the error message before retrying.

The branch has no upstream

A plain git push needs to know where the current branch should go. Whether it can work out that destination depends on the push.default setting, as described in the Git push manual. For a new branch, set the upstream once, after confirming the remote and branch names:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
git push -u origin feature/login-fix

After that, the script’s plain git push uses the saved upstream.

The remote rejects the update

A normal branch push is limited to fast-forward updates, meaning the remote branch must already contain your local history. If the remote has commits you lack, Git rejects the push. Fetch the remote changes, integrate them into your branch by your usual method, and run the script again. Do not add --force to the script to get past the rejection. The restriction protects commits that other people may have pushed.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Limits of set -e

The set -e line makes Bash exit when a simple command returns a nonzero status, which is what keeps a failed commit from being followed by a push. It is not a complete error-handling system. Commands inside an if condition, commands joined with ||, and pipelines behave differently, so a script that grows beyond this size should check important results explicitly, for example with git commit -m "$message" || exit 1.

Practical safety checklist

  • Run git status in the repository before the script, so you know what the broad stage will capture.
  • Look for secrets, generated files, and local configuration in the git status --short output. Git will not detect every sensitive value for you.
  • Use the explicit-path version when the working tree holds more than one task.
  • Keep the commit message meaningful. The script accepts any non-empty string.

“

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.