Created
October 11, 2018 13:49
-
-
Save msnelling/aeac1d4862cb32f0a11873d7381e054f to your computer and use it in GitHub Desktop.
Script to update git repos under directory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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