Skip to content

Instantly share code, notes, and snippets.

@LouManglass
Last active October 21, 2021 20:40
Show Gist options
  • Save LouManglass/70353afe3f00fb3c052f266bde51d96e to your computer and use it in GitHub Desktop.
Save LouManglass/70353afe3f00fb3c052f266bde51d96e to your computer and use it in GitHub Desktop.
#!/bin/bash
# Reference: https://stackoverflow.com/questions/12850030/git-getting-all-previous-version-of-a-specific-file-folder
#
# This is a shell script to find all commits where a file was touched inside a repository, and export copies of the file at
# the time of those commits to a /tmp directory. The files are organized in reverse-chronological order (most recent is #1)
# and include the time stamp and commit hash for reference. The full file is exported for each time it is changed/committed.
#
# With the full history of the file at every change, we can compare any arbitrary point in the file's history with
# another. Specifically, we can look at the state of the API as represented by the OpenAPI file, and compare that to
# another version of the file to look for differences just as if it were part of an Optic Proposal/behavior PR.
#
# To extract the OpenAPI history:
#
# Save this shell script locally, make sure it is executable, and run it with the relative path to your OpenAPI file
# from the root of your Git repository.
# For example, to get all revisions of a spec named openapi/spec.json in your repository:
#
# ./get-revs.sh openapi/spec.json
#
# The files will be written to /tmp/all_versions_exported. Zip these and send them to us. On MacOS, for example:
#
# zip -r openapi-revs.zip /tmp/all_version_exported
# ------
# we'll write all git versions of the file to this folder:
EXPORT_TO=/tmp/all_versions_exported
# take relative path to the file to inspect
GIT_PATH_TO_FILE=$1
# ---------------- don't edit below this line --------------
USAGE="Please cd to the root of your git proj and specify path to file you with to inspect (example: $0 some/path/to/file)"
# check if got argument
if [ "${GIT_PATH_TO_FILE}" == "" ]; then
echo "error: no arguments given. ${USAGE}" >&2
exit 1
fi
# check if file exist
if [ ! -f ${GIT_PATH_TO_FILE} ]; then
echo "error: File '${GIT_PATH_TO_FILE}' does not exist. ${USAGE}" >&2
exit 1
fi
# extract just a filename from given relative path (will be used in result file names)
GIT_SHORT_FILENAME=$(basename $GIT_PATH_TO_FILE)
# create folder to store all revisions of the file
if [ ! -d ${EXPORT_TO} ]; then
echo "creating folder: ${EXPORT_TO}"
mkdir ${EXPORT_TO}
fi
## uncomment next line to clear export folder each time you run script
#rm ${EXPORT_TO}/*
# reset coutner
COUNT=0
# iterate all revisions
git rev-list --all --objects -- ${GIT_PATH_TO_FILE} | \
cut -d ' ' -f1 | \
while read h; do \
COUNT=$((COUNT + 1)); \
COUNT_PRETTY=$(printf "%04d" $COUNT); \
COMMIT_DATE=`git show $h | head -3 | grep 'Date:' | awk '{print $4"-"$3"-"$6}'`; \
if [ "${COMMIT_DATE}" != "" ]; then \
git cat-file -p ${h}:${GIT_PATH_TO_FILE} > ${EXPORT_TO}/${COUNT_PRETTY}.${COMMIT_DATE}.${h}.${GIT_SHORT_FILENAME};\
fi;\
done
# return success code
echo "result stored to ${EXPORT_TO}"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment