Skip to content

Instantly share code, notes, and snippets.

@fluffysquirrels
Created April 9, 2023 16:15
Show Gist options
  • Save fluffysquirrels/383671069c6a9ae9c34bef8c1a18f71f to your computer and use it in GitHub Desktop.
Save fluffysquirrels/383671069c6a9ae9c34bef8c1a18f71f to your computer and use it in GitHub Desktop.
Search a git branch log for revert commits, and output a csv file containing details of the revert commit, the commit that was reverted, and the time in seconds between the two.
#!/usr/bin/env bash
set -eu -o pipefail
# Set default values for unset variables
: ${OUT_DIR:="${HOME}/tmp/git-revert-time"}
: ${REMOTE:='origin'}
: ${BRANCH:='master'}
: ${SINCE:='2020-01-01'}
echo "Output and temp files will be written to ${OUT_DIR}"
mkdir -p "${OUT_DIR}"
echo 'Fetch latest commits'
git fetch --quiet "${REMOTE}" "${BRANCH}"
echo 'Computing log'
git log "${REMOTE}/${BRANCH}" \
--since "${SINCE}" \
--extended-regexp \
--grep 'This reverts commit [0-9a-f]{40}\.' \
--format=format:'%H,%cI,%aI%n%B' -z \
> "${OUT_DIR}/reverts_log"
echo 'Computing pre-fetch list'
echo 'commit_hash,revert_hash,revert_author_time' > "${OUT_DIR}/pre-fetch_list.csv"
cat "${OUT_DIR}/reverts_log" \
| while IFS='' read -r -d $'\0' commit; do
echo "${commit}" | (
IFS=',' read -r -d $'\n' revert_hash revert_commit_time revert_author_time
# Do a 2 step egrep rather than a lookahead (with --perl-regexp),
# because macOS / BSD egrep doesn't support --perl-regexp.
commit_hash="$(egrep -o -e 'This reverts commit [0-9a-f]{40}\.' \
| head -n1 \
| egrep -o -e '[0-9a-f]{40}')"
echo "${commit_hash},${revert_hash},${revert_author_time}"
)
done >> "${OUT_DIR}/pre-fetch_list.csv"
echo 'Pre-fetching commits'
tail -n +2 "${OUT_DIR}/pre-fetch_list.csv" \
| cut -d ',' -f 1 \
| xargs git fetch --quiet "${REMOTE}"
echo 'Computing final output'
echo 'commit_hash,commit_author_time,revert_hash,revert_author_time,time_diff_secs' \
> "${OUT_DIR}/reverts.csv"
tail -n +2 "${OUT_DIR}/pre-fetch_list.csv" \
| while IFS=',' read -r commit_hash revert_hash revert_author_time; do
# commit_author_time="$(git show ${commit_hash} --format=format:'%aI' --no-patch)"
commit_author_time="$(git log -n 1 ${commit_hash} --format=format:'%aI' --no-patch)"
commit_author_secs="$(date +%s -d "${commit_author_time}")"
revert_author_secs="$(date +%s -d "${revert_author_time}")"
time_diff_secs="$(( ${revert_author_secs} - ${commit_author_secs} ))"
echo "${commit_hash},${commit_author_time},${revert_hash},${revert_author_time},${time_diff_secs}"
done >> "${OUT_DIR}/reverts.csv"
echo -e "\nDone! See final output in ${OUT_DIR}/reverts.csv"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment