Assuming you can use bash
, there are at least two ways:
#!/bin/bash
set -e
OLD_COMMIT="$1"
NEW_COMMIT="$2"
if test -z "$OLD_COMMIT" || test -z "$NEW_COMMIT"; then
echo 'fatal: must provide OLD_COMMIT and NEW_COMMIT commits' >&2
exit 1
fi
shift 2
The first, using declarative arrays introduced back in bash 4 (emulates right outer join in imperative fashion):
declare -A OLD_AUTHORS
while read -r OLD_AUTHOR; do
OLD_AUTHORS["$OLD_AUTHOR"]=1
done < <(git log --pretty=format:%aN "$OLD_COMMIT")
declare -A NEW_AUTHORS
while read -r NEW_AUTHOR; do
if test -z ${OLD_AUTHORS["$NEW_AUTHOR"]}; then
NEW_AUTHORS["$NEW_AUTHOR"]=1
fi
done < <(git log --pretty=format:%aN "$OLD_COMMIT"~1.."$NEW_COMMIT")
for NEW_AUTHOR in "${!NEW_AUTHORS[@]}"; do
echo "$NEW_AUTHOR"
done | sort
Or, the second, using pipes and somewhat more declarative way:
diff
<(git log --pretty=format:%aN "$OLD_COMMIT" | sort | uniq)
<(git log --pretty=format:%aN "$OLD_COMMIT"~1.."$NEW_COMMIT" | sort | uniq)
| grep '^> '
| cut -c 3-
Both of the above solutions can process the following history (git log --pretty=format:'%h %d% aN'
):
c3d766e (tag: v2) Keith
cffddc6 New John
ee3cc52 Dan
c307f13 (tag: v1) New John
ae3c4a3 New John
9ed948e Old John
7eb548a Old John
like this (show-new-authors.sh v1 v2
):
Dan
Keith
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…