Skip to content

Instantly share code, notes, and snippets.

@robballou
Last active May 10, 2018 14:53
Show Gist options
  • Save robballou/98eab507c9e24d9d6c1a5207fe4b7a75 to your computer and use it in GitHub Desktop.
Save robballou/98eab507c9e24d9d6c1a5207fe4b7a75 to your computer and use it in GitHub Desktop.
Updated commit everything script
#!/bin/bash
#
# Usage: ./commit_everything.sh "Commit message"
#
# This script will commit everything! This means that it will commit changes
# in submodules, subprojects, and the parent repo (if there is one). This came
# about after working on several projects with varying git repo setups and
# provides a single interface for all kinds of committing!
#
# The commit message provided is used on all commits except those commits
# related to updating the submodules for a parent.
#
# Customize it!
#
# - Change the prompt by setting the COMMIT_EVERYTHING_PROMPT environment
# variable.
# - Change the error prompt by setting COMMIT_EVERYTHING_ERROR_PROMPT
# environment variable.
#
# Need to have a script run before committing things? You can create a `.gce`
# file (and make it executable!) at the root of your project which will get
# run before committing anything. Useful for compressing/compiling/etc steps.
#
# Gist: https://gist.github.com/robballou/98eab507c9e24d9d6c1a5207fe4b7a75
#
source ~/.dotfiles/sh/formatting.sh
if [[ -z "$COMMIT_EVERYTHING_PROMPT" ]]; then
COMMIT_EVERYTHING_PROMPT="🤓 "
fi
if [[ -z "$COMMIT_EVERYTHING_ERROR_PROMPT" ]]; then
COMMIT_EVERYTHING_ERROR_PROMPT="❎ "
fi
RUN_PRE_SCRIPT=1
if [[ ! -z "$COMMIT_EVERYTHING_RUN_PRE_SCRIPT" ]]; then
RUN_PRE_SCRIPT=$COMMIT_EVERYTHING_RUN_PRE_SCRIPT
fi
PUSH=1
if [[ ! -z "$COMMIT_EVERYTHING_PUSH" ]]; then
PUSH=$COMMIT_EVERYTHING_PUSH
fi
PULL_UPSTREAM=1
if [[ ! -z "$COMMIT_EVERYTHING_PULL_UPSTREAM" ]]; then
PULL_UPSTREAM=$COMMIT_EVERYTHING_PULL_UPSTREAM
fi
ISGIT=1
DIR=$(git rev-parse --show-toplevel 2> /dev/null)
if [[ $? -ne 0 ]]; then
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ISGIT=0
fi
main () {
ceprompt "DIRECTORY: ${WHITE}$DIR"
load_config
if [[ "$RUN_PRE_SCRIPT" -eq 1 ]]; then
if [[ -f $DIR/.gce ]]; then
ceprompt "Running pre-script: $DIR/.gce"
$DIR/.gce
if [[ $? -ne 0 ]]; then
ceerror "${RED}ERROR:${NORMAL} Could not execute pre-script"
exit $?
fi
fi
fi
if [[ $ISGIT -eq 1 ]]; then
update_parent $1
fi
update_folders $1
if [[ $ISGIT -eq 1 ]]; then
update_submodules $1
update_subprojects $1
# Push everything
ceprompt "UPDATING EVERYTHING"
git pull --rebase && git status --short --branch
if [[ $? -ne 0 ]]; then
ceerror "${RED}ERROR:${NORMAL} Could not pull rebase"
exit $?
fi
# check for upstream
number_of_remotes=$(git remote | wc -l)
has_upstream_remote=$(git remote | grep upstream | wc -l)
if [[ $number_of_remotes -gt 1 ]]; then
if [[ $has_upstream_remote -eq 1 ]]; then
if [[ $PULL_UPSTREAM -eq 1 ]]; then
ceprompt "PULLING UPSTREAM"
git pull --rebase upstream $(git branch-name) && git status --short --branch
if [[ $? -ne 0 ]]; then
ceerror "${RED}ERROR:${NORMAL} Could not pull upstream changes"
exit $?
fi
fi
fi
fi
if [[ $PUSH -eq 1 ]]; then
git push
fi
fi
ceprompt "DONE"
}
load_config() {
if [[ -f $DIR/resources/scripts/config.sh ]]; then
source $DIR/resources/scripts/config.sh
fi
}
ceerror() {
2>&1 echo "$COMMIT_EVERYTHING_ERROR_PROMPT $1"
}
ceprompt() {
echo "$COMMIT_EVERYTHING_PROMPT ${GREEN}$1${NORMAL}"
}
update_folders() {
# if this isn't a git folder itself and no folders are configured already,
# use the folders within this directory.
if [[ $ISGIT -eq 0 ]]; then
if [[ -z "$FOLDERS" ]]; then
FOLDERS=($(find . -type d -maxdepth 1))
fi
fi
# if we have folders, check those
if [[ ! -z "$FOLDERS" ]]; then
for FOLDER in "${FOLDERS[@]}"; do
if [[ -d "$FOLDER/.git" ]]; then
if [[ "$FOLDER" != "." ]]; then
pushd $FOLDER > /dev/null
STATUS=$(git status --porcelain --ignore-submodules | wc -l)
if [[ $STATUS -ne 0 ]]; then
ceprompt "UPDATING:${WHITE} ${FOLDER}"
git add .
git commit -am "$1"
git pull --rebase && git status --short --branch
if [[ $PUSH -eq 1 ]]; then
git push
fi
fi
popd > /dev/null
fi
fi
done
fi
}
update_parent() {
# Figure out if the parent repo has changed and make a commit with the
# commit message that was passed in
STATUS=$(git status --porcelain --ignore-submodules | wc -l)
if [[ $STATUS -ne 0 ]]; then
ceprompt "UPDATING PARENT REPO"
git add .
git commit -am "$1"
if [[ $? -ne 0 ]]; then
exit 1;
fi
fi
}
update_submodules() {
# Now go to each submodule and update those with the same commit message
SUBMODULES=($(git submodule 2> /dev/null | awk '{print $2}'))
SUBMODULES_UPDATED=0
for SUBMODULE in "${SUBMODULES[@]}"; do
pushd $SUBMODULE > /dev/null
STATUS=$(git status --porcelain | wc -l)
if [[ $STATUS -ne 0 ]]; then
ceprompt "UPDATING SUBMODULE:${WHITE} ${SUBMODULE}"
git add .
git commit -am "$1"
if [[ $? -ne 0 ]]; then
exit 1;
fi
SUBMODULES_UPDATED=1
git pull --rebase && git status --short --branch
if [[ $PUSH -eq 1 ]]; then
git push
fi
fi
popd > /dev/null
done
# When submodules are updated, we need to commit that as well
if [[ $SUBMODULES_UPDATED -eq 1 ]]; then
ceprompt "UPDATING SUBMODULES"
git add .
git commit -am "Updated submodules"
fi
}
update_subprojects() {
if [[ ! -z "$FOLDERS" ]]; then
# Finally check for subprojects and update those
STATUS=$(git status --porcelain | wc -l)
if [[ $STATUS -ne 0 ]]; then
ceprompt "UPDATING SUBPROJECTS"
git add .
git commit -am "$1"
if [[ $? -ne 0 ]]; then
exit 1;
fi
fi
fi
}
if [[ "$#" -ne 1 ]]; then
echo 'Usage:' $0 '"Commit message"'
exit 1
fi
main $1
#!/bin/bash
BOLD=$(tput bold)
BLACK=$(tput setaf 0)
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 2)
BLUE=$(tput setaf 4)
MAGENTA=$(tput setaf 5)
CYAN=$(tput setaf 6)
WHITE=$(tput setaf 7)
NORMAL=$(tput sgr0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment