7

As the title says: I'd like all commits I push to GitHub to appear with the timestamp of the push rather than of the commit, in the GitHub's commits tab.

I use quite a standard workflow:

<do some work>
git add -u
git commit -m "Message 1."
...
<do some work>
git add -u
git commit -m "Message N."
git push myrepo master

This makes all N commits show in GitHub, which is fine and good. But the time of the commits is shown as well, which I don't like. I would much more prefer to show only the timestamp of the last of them (or of the push).

yo'
  • 811
  • 11
  • 22
  • Do you want to keep the time for yourself. Or don't you mind whether that info is available? – Willem Van Onsem Mar 03 '15 at 12:59
  • @CommuSoft I would be fine with the true timestamp being lost completely. I don't need to know that I worked on it until 3am :D I just don't want to merge commits, because that can be threatening. – yo' Mar 03 '15 at 13:00

2 Answers2

5

GitHub stores push time in their database forever

The time at which you push is for example forever viewable on the GitHub Events API.

For example, https://api.github.com/repos/cirosantilli/china-dictatorship/events now contained the actual push data "2020-12-29T11:37:26Z":

          "message": "66d9be0cb84c9650d6181b4b0fc2b70e2178bd9e",
          "distinct": true,
          "url": "https://api.github.com/repos/cirosantilli/china-dictatorship/commits/0817ad58873c5656d2828613a5a24ca8f286e910"
        }
      ]
    },
    "public": true,
    "created_at": "2020-12-29T11:37:26Z"
  },

even though the actual commit is "Tue Dec 29 00:00:00 2020 +0000".

This API data stored directly in their database, not in the Git commit data, and there is no way to fake it.

If you want to hide that, there is no alternative AFAIK, you have to:

  • push at a different time e.g. with a cron job
  • delete the repository, then the push data goes away from the API

This is a privacy concern, although of course, a determined attacker would be able to achieve similar results by polling profiles of certain users of interest. Related tickets:

Commit data time

The commit time on the commit data can be controlled with the environment variables:

GIT_COMMITTER_DATE=2000-01-01T00:00:00+0000 \
GIT_AUTHOR_DATE=2000-01-01T00:00:00+0000 \
git commit -m 'my message'

For --amend, there use the --date option for the author date: How can one change the timestamp of an old commit in Git?

There are no further time indications on the commit message object, so that is enough for privacy.

You might want to do this automatically from post-commit hook as explained at: Can GIT_COMMITTER_DATE be customized inside a git hook?

Here is a more advanced hook that makes your commits will start at midnight every day, and increment by one second for every new commit. This keeps commits sorted by time, while still hiding the commit time.

.git/hooks/post-commit

#!/usr/bin/env bash
set -eu
echo post-rewrite
if [ ! "${CIROSANTILLI_GITHOOKS_DISABLE:-0}" = 1 ]; then
  declare -a olds
  declare -A oldnew
  while IFS= read -r line; do
    echo "$line"
    old="$(echo "$line" | cut -d ' ' -f1)"
    new="$(echo "$line" | cut -d ' ' -f2)"
    oldnew[$old]="$new"
    olds+=("$old")
    news+=("$new")
  done
  # Save unstaged changes. Otherwise e.g. git commit --amend destroys them!
  # https://stackoverflow.com/questions/24520791/check-if-git-stash-stashed-anything/38785582#38785582
  nstash="$(git stash list | wc -l)"
  git stash
  git reset --hard "${news[0]}~"
  for old in "${olds[@]}"; do
    new="${oldnew[$old]}"
    git cherry-pick "$new" &>/dev/null
    olddate="$(git log --format='%cd' -n 1 "$old")"
    CIROSANTILLI_GITHOOKS_DISABLE=1 \
      GIT_COMMITTER_DATE="$olddate" \
      git commit \
      --amend \
      --no-edit \
      --no-verify \
      &>/dev/null \
    ;
  done
  # Restore unstaged changes.
  if [ "$(git stash list | wc -l)" -ne "$nstash" ]; then
    git stash apply
  fi
  echo
fi

GitHub upstream.

Don't forget to:

chmod +x .git/hooks/post-commit

Tested on git 2.19, Ubuntu 18.04.

Don't forget to also handle:

or else the committer date still leaks.

Bulk history modification

Here is a way to fix the commit times for all commits in an existing range to midnight while keeping the date unchanged:

git-hide-time() (
  first_commit="$1"
  last_commit="${2:-HEAD}"
  git filter-branch --env-filter '
d="$(echo "$GIT_COMMITTER_DATE" | sed "s/T.*//")T00:00:00+0000)"
export GIT_COMMITTER_DATE="$d"
export GIT_AUTHOR_DATE="$d"
' --force "${first_commit}~..${last_commit}"
)

See also: How can one change the timestamp of an old commit in Git?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
0

You have several options:

  • Write your webhooks, catch the push event and modify the date to the current timestamp.
  • A better approch is to write local hook that on the pre-push modify your timestamp
CodeWizard
  • 128,036
  • 21
  • 144
  • 167