Skip to content

Instantly share code, notes, and snippets.

@msnelling
Created October 11, 2018 13:49
Show Gist options
  • Save msnelling/aeac1d4862cb32f0a11873d7381e054f to your computer and use it in GitHub Desktop.
Save msnelling/aeac1d4862cb32f0a11873d7381e054f to your computer and use it in GitHub Desktop.
Script to update git repos under directory
#!/bin/bash
# GitSync
#
# Syncs all remotely-tracked branches on a git repo passed as first argument ($1). It also pulls any new branches
# and tags attached to the repo.
#
# $1 - The dir to check
#
GitSync()
{
# Check if $1 is a git repository
stat "$1" > /dev/null || return 1;
cd $1; echo "Checking $PWD...";
git status --porcelain || return 1; # A fatal error if $PWD is not a git repo
local MESSAGE=""
# Use `git fetch` to fetch all updates across branches from all remotes. This will also fetch any NEW branches from the remote.
# Use --tags to fetch any additional tags not associated with these branches.
# Use --prune to remove local branches no longer on remote
git fetch --tags --prune
# Loop through all local remote-tracking branches and count how many commits differ.
# If required, merge fast-forward changes into branch
declare -a LOCAL_BRANCHES=$(git branch -l | cut -c3- | tr "\n" " ")
for BRANCH in ${LOCAL_BRANCHES[*]}; do
# If a local branch does not track a remote, skip it
local REMOTE_BRANCH=$(git rev-parse --abbrev-ref --symbolic-full-name $BRANCH@{u}) || continue;
local REMOTE_COMMITS=$(git log $BRANCH..$REMOTE_BRANCH --oneline | wc -l) # Remote commits not in my local
local LOCAL_COMMITS=$(git log $REMOTE_BRANCH..$BRANCH --oneline | wc -l) # Local commits not pushed to remote
local CURR_BRANCH=$(git branch | grep '*' | cut -c3-) # Check the current branch at the last minute.
if [ $REMOTE_COMMITS != "0" ]; then
# If on a checked-out branch, only pull if all there are no uncomitted local changes. Skip otherwise
# For other branches, merge remote changes
if [ "$CURR_BRANCH" = "$BRANCH" ]; then
if [ "$(git status --porcelain)" = "" ]; then
git pull
fi
else
git fetch origin $BRANCH:$BRANCH
fi
MESSAGE+="$REMOTE_COMMITS new commits from '$REMOTE_BRANCH'.\n"
fi
done
# If there were any updates, notify the user. Include the latest commit on the current branch
if [ "$MESSAGE" != "" ]; then
MESSAGE+="\nLatest commit on '$(git rev-parse --abbrev-ref HEAD)'\n"$(git log --format=format:"%h by %an, %ar%n'%s'%n" -n 1)
echo $MESSAGE
fi
}
if [[ $# -lt 1 ]];
then
echo "Usage: $0 DIR";
echo "Synchronizes git repos under 'DIR'.";
exit 1;
fi
DIR="$1"
find $DIR -maxdepth 1 -type d ! -path $DIR | while read d; do
GitSync $d
chown -R mark:mark $d &>/dev/null
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment