Last active
October 31, 2018 23:41
-
-
Save nrclark/e315e0439d9b04fc017594262e1a8956 to your computer and use it in GitHub Desktop.
Git Diffgen
This file contains hidden or 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/sh | |
#------------------------------------------------------------------------------# | |
MERGE="no" | |
CHECK_ONLY="no" | |
PROGNAME=`echo "$0" | sed 's@.*/@@g'` | |
#------------------------------------------------------------------------------# | |
USAGE="Usage: $PROGNAME [-m] [-c] [-b BRANCH] GITDIR" | |
HELP_MSG=" | |
Unconditionally update a repo to match the remote. Generate a changelog. | |
$USAGE | |
Options: | |
-b BRANCH, Manually specify the remote's branch. | |
-c, Check for updates, but take no other action. Exit success | |
the repo is up-to-date. | |
-m, Merge the remote after fetching. | |
-h, Print this message and exit. | |
" | |
usage() { | |
local exit_code="$1" | |
local stream="1" | |
if [ "$exit_code" = "" ]; then | |
stream="2" | |
exit_code=0 | |
fi | |
printf "$USAGE\n" >&$stream | |
exit $exit_code | |
} | |
help() { | |
local exit_code="$1" | |
local stream="1" | |
if [ "$exit_code" = "" ]; then | |
stream="2" | |
exit_code=0 | |
fi | |
printf "$HELP_MSG\n" >&$stream | |
exit $exit_code | |
} | |
#------------------------------------------------------------------------------# | |
for arg in $@; do | |
if [ "$arg" = "--help" ]; then | |
help | |
fi | |
done | |
while getopts "mchb:" name $ARGS 2>/dev/null | |
do | |
case $name in | |
b) BRANCH="$OPTARG";; | |
m) MERGE="yes";; | |
c) CHECK_ONLY="yes";; | |
h) help;; | |
*) usage 1;; | |
esac | |
done | |
shift "$(($OPTIND-1))" | |
GITDIR="$1" | |
shift | |
if [ "$*" != "" ]; then | |
usage 1 | |
fi | |
#------------------------------------------------------------------------------# | |
if [ "x$GITDIR" = "x" ]; then | |
usage 1 | |
fi | |
if [ "x$BRANCH" = "x" ]; then | |
BRANCH=`git -C "$GITDIR" branch | grep -oP '(?<=[*] )[^(].*'` | |
fi | |
if [ "x$BRANCH" = "x" ]; then | |
echo "Error: couldn't guess branch of $GITDIR. Please specify with -b." >&2 | |
exit 1 | |
fi | |
#------------------------------------------------------------------------------# | |
in_set() { | |
# Succeeds if $query is in $set, and fails otherwise. | |
local set="$1" | |
local query="$2" | |
local item="" | |
for item in $set; do | |
if [ "$item" = "$query" ]; then | |
return 0 | |
fi | |
done | |
return 1 | |
} | |
difference() { | |
# Returns set_a - set_b. | |
local set_a="$1" | |
local set_b="$2" | |
local result="" | |
local item="" | |
for item in $set_a; do | |
if ! in_set "$set_b" "$item"; then | |
result="$result $item" | |
fi | |
done | |
echo "`echo $result`" | |
} | |
#------------------------------------------------------------------------------# | |
git -C "$GITDIR" fetch -f origin "$BRANCH" 1>/dev/null 2>&1 | |
#------------------------------------------------------------------------------# | |
CURRENT="`git -C "$GITDIR" rev-parse HEAD`" | |
TARGET="`git -C "$GITDIR" rev-parse "origin/$BRANCH"`" | |
if [ "$CHECK_ONLY" = "yes" ]; then | |
if [ "$CURRENT" = "$TARGET" ]; then | |
exit 0 | |
fi | |
exit 1 | |
fi | |
#------------------------------------------------------------------------------# | |
BOTTOM="`git -C "$GITDIR" merge-base $CURRENT origin/$BRANCH`" | |
OLD_COMMITS=$(git -C "$GITDIR" log --pretty=format:"%H" $BOTTOM...$CURRENT) | |
NEW_COMMITS=$(git -C "$GITDIR" log --pretty=format:"%H" $BOTTOM...$TARGET) | |
TO_DELETE=`difference "$OLD_COMMITS" "$NEW_COMMITS"` | |
TO_ADD=`difference "$NEW_COMMITS" "$OLD_COMMITS"` | |
#------------------------------------------------------------------------------# | |
for record in $TO_ADD; do | |
git -C "$GITDIR" show -s $record --pretty=format:"+%h: %s" | cat | |
printf "\n" | |
done | |
for record in $TO_DELETE; do | |
git -C "$GITDIR" show -s $record --pretty=format:"-%h: %s" | cat | |
printf "\n" | |
done | |
#------------------------------------------------------------------------------# | |
if [ "$MERGE" != "yes" ]; then | |
exit 0 | |
fi | |
git -C "$GITDIR" checkout origin/$BRANCH 1>/dev/null | |
git -C "$GITDIR" branch -m $BRANCH __old_$BRANCH 1>/dev/null | |
git -C "$GITDIR" branch $BRANCH 1>/dev/null | |
git -C "$GITDIR" checkout $BRANCH 1>/dev/null | |
git -C "$GITDIR" branch -D __old_$BRANCH 1>/dev/null | |
git -C "$GITDIR" branch -u origin/$BRANCH $BRANCH 1>/dev/null |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment