unixorn/git-extra-commands

View on GitHub
bin/git-divergence

Summary

Maintainability
Test Coverage
#!/usr/bin/env bash
#
# https://github.com/garybernhardt/dotfiles/blob/master/bin/git-divergence

set -e

(
    function branch() {
        # shellcheck disable=SC2063
        git branch 2>/dev/null | grep -e '^*' | tr -d '\* '
    }

    function ensure_valid_ref() {
        ref=$1
        (
            set +e
            git show-ref "$ref" > /dev/null
            if [[ $? == 1 ]]; then
                echo "$0: bad ref: $ref"
                exit 1
            fi
        )
    }

    function show_rev() {
        rev="$1"
        git log -1 "$rev" --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
        echo
        # shellcheck disable=SC2086
        git diff $rev^..$rev | diffstat
        echo
    }

    if [[ $# == 2 ]]; then
        LOCAL=$1
        REMOTE=$2
    elif [[ $# == 1 ]]; then
        LOCAL=$(branch)
        REMOTE=$1
    else
        LOCAL=$(branch)
        REMOTE=origin/$LOCAL
    fi

    ensure_valid_ref "$LOCAL"
    ensure_valid_ref "$REMOTE"

    echo "changes from local ${LOCAL} to remote ${REMOTE}:"
    echo

    echo incoming:
    echo
    # shellcheck disable=SC2086
    for rev in $(git rev-list $LOCAL..$REMOTE); do
        show_rev "$rev"
    done

    echo
    echo outgoing:
    echo
    # shellcheck disable=SC2086
    for rev in $(git rev-list $REMOTE..$LOCAL); do
        show_rev "$rev"
    done
) | less -r