Skip to content

Instantly share code, notes, and snippets.

@jakejarvis
Created September 7, 2019 07:47
Show Gist options
  • Select an option

  • Save jakejarvis/a04bc9b69a47b128a0dfe1774dce710f to your computer and use it in GitHub Desktop.

Select an option

Save jakejarvis/a04bc9b69a47b128a0dfe1774dce710f to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
#_____________________________________________________________________________
# Git Nowhere
#-----------------------------------------------------------------------------
#
# Use: Run as "$ . ./gitdate" before "$ git commit" to manually set
# the date to UTC in order to obscure timezone-based geodata tracking.
#
# If you would always like your timestamps to be obscured for a specific
# project, then you'll need to either source this file BEFORE EACH COMMIT
# while committing code. You *cannot* set it as a git hook, because git
# hooks open child shell processes which are unable to affect the parent
# shell's environment. To make this easier, however, you could set an
# alias in whichever shell you use:
#
# alias gc=". /path/to/gitdate && git commit -v "
#
# NOTE: If you use "$ git commit -S -v" to create GnuPG signatures for your
# git commits, the timestamp on the GnuPG signature will *NOT* match
# the git AuthorDate and CommitDate lines, giving away that you are
# lying. It would also be suspicious looking if you customarily sign
# your commits, and signature(s) were inexplicably missing.
#
# :authors: Isis Lovecuft <[email protected]> 0xA3ADB67A2CDB8B35
# :version: 0.0.4
# :copyright: (c) 2012-2013 Isis Lovecruft
# :license: AGPLv3, see https://www.gnu.org/licenses/agpl-3.0.txt
#
# v0.0.5: It now knows if it's been sourced or executed, and if it was executed,
# it prints the export commands which need to be run on stdout. Because
# they are printed exacted as they should be run.
#
# We *should* be able to coproc that output from other scripts, piping
# stdout of the coproc into the stdin of the other script, and wrap it
# in an exec call, something like this:
#
# GD=`which gitdate`
# { coproc gitdate { $GD "$@" ;} >&3;} 3>&1
# { echo 'Thu Feb 28 11:47:04 2045 -1000' >&${gitdate[1]} ;} >&0
#
# except that is not right yet and still not working.
#
# v0.0.4: Fix so that timezones east of UTC shift backwards.
# Add better date string parsing and some other fixes.
# v0.0.3: Also changes the months and years, because that would suck if your
# commits were accidentally made last year
# v0.0.2: Changes the days too
# v0.0.1: Changes the hours
#_____________________________________________________________________________
## Uncomment for debugging:
#DEBUG=true
## Uncomment for really verbose debugging, and be sure to uncomment the
## the corresponding line at the end
#set -x -
## Git uses the system time settings through mktime(). Do a "$ git log" to see
## the timezone offset for your system. This script gets your timezone offset
## by doing '$ date +"%z"'. If these two values are different, or for some
## reason you would like to manually specify the offset between timezones to
## change, then you can set this shell environment variable:
##
## TIMEOFFSET=-0400
##
## Which would mean that your current timestamps were made in the UTC-0400
## timezone (i.e. 'America/New_York'), and they will be modified by adding four
## hours to change them into UTC.
#TIMEOFFSET=-0400
if [ "x$0" == 'x-bash' ] ; then
if test "$DEBUG" ; then printf "Detected that we were sourced.\\n"; fi
elif test -n "${0#gitdate}" ; then
if test "$DEBUG" ; then printf "We weren't sourced.\\n"; fi
fi
## git stores datestrings as: Sun Aug 19 08:34:12 2012 -0400
## date uses: Mon May 6 21:00:18 UTC 2013
if test $# -eq 0 ; then
if test "$DEBUG" ; then
printf "We didn't get a datestring argument.\\n"
fi
if [ "$#" = '0' ] ; then
DAY=$(date +"%a")
MONTH=$(date +"%b")
DATE=$(date +"%d")
HOUR=$(date +"%H")
MINSEC=$(date +"%M:%S")
YEAR=$(date +"%Y")
TIMEZONE=$(date +"%z")
fi
elif test $# -eq 1 ; then
if test "$DEBUG" ; then
printf "Converting git datestring: %s\\n" "$1"
fi
DAY=$(echo "$1" | cut -d ' ' -f 1)
MONTH=$(echo "$1" | cut -d ' ' -f 2)
DATE=$(echo "$1" | cut -d ' ' -f 3)
TIME=$(echo "$1" | cut -d ' ' -f 4)
YEAR=$(echo "$1" | cut -d ' ' -f 5)
TIMEZONE=$(echo "$1" | cut -d ' ' -f 6)
HOUR=$(echo "$TIME" | cut -d ':' -f 1)
MIN=$(echo "$TIME" | cut -d ':' -f 2)
SEC=$(echo "$TIME" | cut -d ':' -f 3)
MINSEC="${MIN}:${SEC}"
unset TIME
unset MIN
unset SEC
else
printf "\\nUsage:\\nTo change a specific commit's date, run as:\\n"
printf " . gitdate 'Mon Dec 29 17:45:54 2011 +0800'\\n"
printf "or as:\\n"
printf " gitdate 'Mon Dec 29 17:45:54 2011 +0800'\\n"
printf "and then run the printed export commands to change your shell's\\n"
printf "variables.\\n"
fi
for mnth in Jan Mar May Jul Aug Oct Dec ; do
if [[ "$mnth" = "$MONTH" ]]; then LONG_MONTH=true ; fi
done
TIMEOFFSET=${TIMEOFFSET:=$TIMEZONE}
TIMEOFFSET=${TIMEOFFSET%%00}
if [[ "${TIMEOFFSET:0:1}" = '-' ]] ; then
TIMEOFFSET=${TIMEOFFSET:1}
IS_WEST=true
elif [[ "${TIMEOFFSET:0:1}" = '+' ]] ; then
TIMEOFFSET=${TIMEOFFSET:1}
IS_EAST=true
else
printf "Error: TIMEOFFSET variable did not start with '-' or '+'"
fi
## 'let' requires the leading zero stripped
if [[ "${TIMEOFFSET:0:1}" = '0' ]] ; then
TIMEOFFSET=${TIMEOFFSET:1}
fi
if test "$IS_WEST" ; then
(( SPILLOVER=24-TIMEOFFSET ))
if [ "$HOUR" -lt "$SPILLOVER" ]; then
(( HOUR+=TIMEOFFSET ))
else
(( TILMIDNIGHT=24-HOUR ))
(( HOUR=TIMEOFFSET-TILMIDNIGHT ))
FALSEDAWN=true
unset TILMIDNIGHT
fi
unset TIMEOFFSET
unset SPILLOVER
# If the hour is one digit, prepend a zero.
if [ "${#HOUR}" -eq "1" ]; then
HOUR=$(printf "%02d" $HOUR)
fi
# If it is tomorrow in UTC, make sure we increment the day.
if test "$FALSEDAWN" ; then
if [ "$DAY" = "Mon" ]; then NEXTDAY="Tue" ;
elif [ "$DAY" = "Tue" ]; then NEXTDAY="Wed" ;
elif [ "$DAY" = "Wed" ]; then NEXTDAY="Thu" ;
elif [ "$DAY" = "Thu" ]; then NEXTDAY="Fri" ;
elif [ "$DAY" = "Fri" ]; then NEXTDAY="Sat" ;
elif [ "$DAY" = "Sat" ]; then NEXTDAY="Sun" ;
elif [ "$DAY" = "Sun" ]; then NEXTDAY="Mon" ;
fi
DAY=$NEXTDAY
unset NEXTDAY
if test "$LONG_MONTH" ; then
if [[ "$DATE" -lt "31" ]]; then (( DATE+=1 )) ;
elif [[ "$DATE" -eq "31" ]]; then
if [[ "$MONTH" = "Jan" ]]; then NEXTMONTH="Feb" ;
elif [[ "$MONTH" = "Mar" ]]; then NEXTMONTH="Apr" ;
elif [[ "$MONTH" = "May" ]]; then NEXTMONTH="Jun" ;
elif [[ "$MONTH" = "Jul" ]]; then NEXTMONTH="Aug" ;
elif [[ "$MONTH" = "Aug" ]]; then NEXTMONTH="Sep" ;
elif [[ "$MONTH" = "Oct" ]]; then NEXTMONTH="Nov" ;
elif [[ "$MONTH" = "Dec" ]]; then
NEXTMONTH="Jan"
(( YEAR+=1 ))
fi
DATE=1
fi
elif [[ "$MONTH" = "Feb" ]] && [[ "$DATE" -lt "28" ]]; then
(( DATE+=1 ))
elif [[ "$MONTH" = "Feb" ]] && [[ "$DATE" -eq "28" ]]; then
NEXTMONTH="Mar"
DATE=1
else
if [[ "$DATE" -lt "30" ]]; then (( DATE+=1 )) ;
elif [[ "$DATE" -eq "30" ]]; then
if [[ "$MONTH" = "Apr" ]]; then NEXTMONTH="May" ;
elif [[ "$MONTH" = "Jun" ]]; then NEXTMONTH="Jul" ;
elif [[ "$MONTH" = "Sep" ]]; then NEXTMONTH="Oct" ;
elif [[ "$MONTH" = "Nov" ]]; then NEXTMONTH="Dec" ;
fi
DATE=1
fi
fi
fi
unset FALSEDAWN
if [[ -n "$NEXTMONTH" ]]; then
MONTH=$NEXTMONTH
fi
unset NEXTMONTH
elif test "$IS_EAST" ; then
if [ "$HOUR" -lt "$TIMEOFFSET" ]; then
(( SPILLOVER=24-TIMEOFFSET ))
(( HOUR=HOUR+SPILLOVER ))
MAKE_YESTERDAY=true
else
## 'let' requires the leading zero stripped
if [[ "${HOUR:0:1}" = '0' ]] ; then
HOUR=${HOUR:1}
fi
(( HOUR=HOUR-TIMEOFFSET ))
fi
unset TIMEOFFSET
unset SPILLOVER
# If the hour is one digit, prepend a zero.
if [ "${#HOUR}" -eq "1" ]; then
HOUR=$(printf "%02d" "$HOUR")
fi
# If it is yesterday in UTC, make sure we decrement the day.
if test "$MAKE_YESTERDAY" ; then
if [ "$DAY" = "Mon" ]; then LASTDAY="Sun" ;
elif [ "$DAY" = "Tue" ]; then LASTDAY="Mon" ;
elif [ "$DAY" = "Wed" ]; then LASTDAY="Tue" ;
elif [ "$DAY" = "Thu" ]; then LASTDAY="Wed" ;
elif [ "$DAY" = "Fri" ]; then LASTDAY="Thu" ;
elif [ "$DAY" = "Sat" ]; then LASTDAY="Fri" ;
elif [ "$DAY" = "Sun" ]; then LASTDAY="Sat" ;
fi
DAY=$LASTDAY
unset LASTDAY
if $LONG_MONTH ; then
if [[ "$DATE" -eq "1" ]]; then
if [[ "$MONTH" = "Jan" ]]; then LASTMONTH="Dec";
(( YEAR=YEAR-1 )) ;
elif [[ "$MONTH" = "May" ]]; then LASTMONTH="Apr" ;
elif [[ "$MONTH" = "Jul" ]]; then LASTMONTH="Jun" ;
elif [[ "$MONTH" = "Aug" ]]; then LASTMONTH="Jul" ;
elif [[ "$MONTH" = "Oct" ]]; then LASTMONTH="Sep" ;
elif [[ "$MONTH" = "Dec" ]]; then LASTMONTH="Nov" ;
fi
DATE=30
if [[ "$MONTH" = "Mar" ]]; then LASTMONTH="Feb";
DATE=28 ;
fi
else
(( DATE=DATE-1 ))
fi
else
if [[ "$DATE" -eq "1" ]]; then
if [[ "$MONTH" = "Feb" ]]; then LASTMONTH="Jan" ;
elif [[ "$MONTH" = "Apr" ]]; then LASTMONTH="Mar" ;
elif [[ "$MONTH" = "Jun" ]]; then LASTMONTH="May" ;
elif [[ "$MONTH" = "Sep" ]]; then LASTMONTH="Aug" ;
elif [[ "$MONTH" = "Nov" ]]; then LASTMONTH="Oct" ;
fi
DATE=31
else
(( DATE=DATE-1 ))
fi
fi
unset LONGMONTH
fi
unset MAKE_YESTERDAY
if [[ -n "$LASTMONTH" ]]; then
MONTH=$LASTMONTH
fi
unset LASTMONTH
fi
unset IS_EAST
unset IS_WEST
unset LONG_MONTH
GIT_AUTHOR_DATE="$DAY $MONTH $DATE ${HOUR}:${MINSEC} $YEAR +0000"
export GIT_AUTHOR_DATE
GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE
export GIT_COMMITTER_DATE
## only print what we exported if we were not sourced:
if ! [ "x$0" = 'x-bash' ] ; then
if test -n "${0#gitdate}" ; then
if test "$DEBUG" ; then
printf "\\nPlease copy and run the following export commands:\\n\\n"
fi
printf "export GIT_AUTHOR_DATE='%s'\\nexport GIT_COMMITTER_DATE='%s'\\n" \
"$GIT_AUTHOR_DATE" "$GIT_COMMITTER_DATE"
fi
fi
unset DAY
unset MONTH
unset DATE
unset HOUR
unset MINSEC
unset YEAR
unset TIMEZONE
## If debugging was enabled at the top, make sure it's off when we return
## to a normal shell:
#set +x
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment