#!/usr/bin/env bash
# git new - show new commits in a branch, based on the reflog

. lib.bash || exit

usage() {
	echo "Usage: $progname [options] [<dir> [<branch>]]"
	echo ""
	echo_opt "-a"		"show full branch history"
	echo_opt "-b REF"	"show new commits in a different branch"
	echo_opt "-C DIR"	"change to specified directory"
	echo ""
	echo_opt "-M"		"add --no-merges to configuration"
	echo ""
	echo_opt "-X PATH"	"exclude specified path"
	echo_opt "-P"		"add *.po exclusion"
	echo_opt "-G"		"add .github exclusion"
}

addconfig() {
	local key="nullroute.git-new.$1" value=$2
	if ! git config --get-all --fixed-value "$key" "$value" > /dev/null; then
		git config --add "$key" "$value"
		vmsg "added ${key##*.} $value"
	fi
}

getconfig() {
	local key="nullroute.git-new.$1"
	git config --get-all "$key" || true
}

opt_showall=0
opt_no_merges=0
opt_exclude=()
opt_chdir=
opt_ref=

while getopts :ab:C:GMPX: OPT; do
	case $OPT in
	a) opt_showall=1;;
	b) opt_ref=$OPTARG;;
	C) opt_chdir=$OPTARG;;
	M) opt_no_merges=1;;
	P) opt_exclude+=("**.po");;
	G) opt_exclude+=(".github/" ".gitlab-ci/" ".gitlab-ci.yml");;
	X) opt_exclude+=("$OPTARG");;
	*) lib:die_getopts;;
	esac
done; shift $[OPTIND-1]

if [[ ! $opt_chdir && ! -d .git && -d $1 ]]; then
	opt_chdir=$1; shift
fi
if [[ ! $opt_ref ]]; then
	opt_ref=${1:-HEAD}; shift
fi
if (( $# )); then
	vdie "excess arguments"
fi

if ! have tig; then
	vdie "tig is not installed"
fi

cd "${opt_chdir:-.}" || exit

if [[ $PWD == $HOME/src/* ]]; then
	~/bin/lib/git-checksrc
fi

# Update configuration only
hadconfig=0
if (( opt_no_merges )); then
	addconfig options "--no-merges"
	hadconfig=1
fi
for path in "${opt_exclude[@]}"; do
	addconfig paths ":!$path"
	hadconfig=1
done
if (( hadconfig )); then
	exit
fi

ref=${opt_ref#".."}
# Verify that the ref exists -- faster than letting `tig` do it
if ! git rev-parse --verify "$ref" &> /dev/null; then
	vdie "nonexistent ref '$ref'"
fi

if (( opt_showall )); then
	range="$ref"
else
	if git rev-parse --verify "$ref@{1}" &> /dev/null; then
		range="$ref@{1}..$ref"
	else
		vmsg "no reflog for '$ref', showing entire branch" >&2
		range="$ref"
	fi
fi

options=(); mapfile -t options < <(getconfig options)
paths=(); mapfile -t paths < <(getconfig paths)

settitle "git new [${PWD/#"$HOME/"/"~/"}]"
settitle -w "${PWD##*/}"

tig "${options[@]}" "$range" "${@:2}" -- "${paths[@]}"
