# Git-Privacy ## ❌ Default Git Privacy ❌ [Git is generally good about not preserving any metadata](https://git.wiki.kernel.org/index.php/ContentLimitations), except when it comes to timestamps. With only 3 commands, anyone can find out the time zones and exact clock times a developer makes commits. ```sh git clone cd git log --format=fuller ``` This can leak personal information about a developer's life. The time zones reveal the developer's approximate location in the world and exact commit times recorded over a sufficient timespan may be used to deduce a developer's sleep patterns for example. ## 📅 Git Timestamps 📅 [Git commit objects](https://git-scm.com/docs/user-manual.html#commit-object) always have at least 2 timestamps. They are controlled by the following environment variables: * `GIT_AUTHOR_DATE` represents when the changes were made * `GIT_COMMITTER_DATE` represents when the changes were committed Annotated [Git tag objects](https://git-scm.com/docs/user-manual.html#tag-object) always have at least 1 timestamp. It is also controlled by the `GIT_COMMITTER_DATE` environment variable. There is another timestamp which comes from the optional GnuPG signature on a commit or annotated tag. It is controlled by GnuPG. ### ⚠ Warning ⚠ Before you follow any of the steps below to obfuscate Git timestamps, be aware that it can cause certain features of Git to break in unexpected ways. The author takes no responsibility for any breakage that occurs. The author is not a lawyer and this is not legal advice, but obfuscating Git's timestamps may also result in more difficulty refuting copyright claims. The author takes no responsibility for this either. ### Obfuscating Timestamps for Commits and Annotated Tags Git can't remove timestamps altogether, but the `GIT_AUTHOR_DATE` and `GIT_COMMITTER_DATE` environment variables can be set to any arbitrary date. Preferably, use dates from before Git was invented to clearly signal the timestamps are forged: ```sh export GIT_AUTHOR_DATE="2000/01/01T00:00:00+0000" export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" ``` To retain the day on which changes and commits are made, set `GIT_AUTHOR_DATE` and `GIT_COMMITTER_DATE` to the output of the date command, like so: ```sh export GIT_AUTHOR_DATE="$(date -u +%DT00:00:00%z)" export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" ``` Environment variables don't change after being set, so the dates update when a new shell is opened, not at midnight. ### 🔑 Obfuscating Timestamps for Digital Signatures 🔑 GnuPG can't remove its signature timestamps altogether, but they can be forged by configuring Git to run a custom version of GnuPG: ```sh #!/bin/sh gpg --faked-system-time ! $@ ``` For GnuPG signatures with a fixed forged timestamp to be verifiable, `` must be manually set to a time between the expiry date of the signing key and when it was generated. See gpg(1) for how to format ``. To retain the day on which GnuPG signatures are made, use the output of the date command: ```sh #!/bin/sh gpg --faked-system-time "$(date -u +%Y%m%dT000000)!" $@ ``` The last step is to set the script as executable with `chmod +x /path/to/custom-gpg.sh` and point Git to it with `git config --global gpg.program /path/to/custom-gpg.sh`. ## 📝 Additional Notes 📝 Github is known to record [when commits are pushed](https://api.github.com/repos/cirosantilli/china-dictatorship/events). See the ticket about [Github contribution activity](https://github.com/isaacs/github/issues/142). To obfuscate push times, one could push code with cron at regular time intervals. It's possible to use Git hooks to accomplish timestamp obfuscation, but it's still necessary to manually override the date for some Git commands, making it very inconvenient. The developers of Git should make timestamp obfuscation a feature in order to make doing all this unnecessary. ## License This README file is licensed under [CC-BY-SA 4.0](LICENSE).