How to Timestamp Source Code and Git Repositories
Git commit dates do not show when your code existed. Anyone can set them to any value, and a rebase rewrites them. To fix a date for a codebase that a stranger, a client or a court has to accept, take one exact snapshot of the code, usually a ZIP of a tagged commit, and put a qualified electronic timestamp on its fingerprint. Only the fingerprint leaves your machine, so this works for private and proprietary code too. Below is the exact procedure, what it establishes, and what it does not.
This is general information about evidence, not legal advice for a specific dispute.
Why your Git history is not independent evidence of a date
Git records two dates on every commit, the author date and the committer date, and both come from the machine that made the commit. Nothing checks them. Setting GIT_AUTHOR_DATE and GIT_COMMITTER_DATE before a commit, or running git commit --amend --date, produces a history that says whatever you want it to say. Interactive rebase, squash merges and cherry-picks rewrite dates as a side effect of ordinary work.
That does not make your history worthless. It is excellent evidence of how the code was built: small steps, reasoning in commit messages, issues, reviews, abandoned branches. It is weak evidence of when, because the person relying on it is the person who could have written it.
Hosted platforms help but do not close the gap. GitHub, GitLab and Bitbucket record when a push reached them, but those records are held by a private company, can be hard to obtain later, and disappear with a deleted repository or account. A force-push replaces what was there.
What a qualified timestamp adds
A qualified electronic timestamp is issued by a supervised trust service provider under the EU's eIDAS Regulation. Under Article 41(2), courts in every member state presume that its date and time are accurate and that the data it covers has not changed since. The date does not come from you, so it cannot be challenged on the grounds that you set it.
The timestamp is bound to a SHA-256 fingerprint of a file. Change a single byte and the fingerprint no longer matches. That is why the method below is about choosing and keeping one exact file.
Method 1: timestamp a ZIP of a tagged commit (strongest)
- Tag the state you want to fix.
git tag v1.4.0(or use a commit you already tagged). - Export exactly that state.
git archive --format=zip -o myproject-v1.4.0.zip v1.4.0. This contains the tracked files at that commit and nothing else: no.env, no build output, no uncommitted changes. - Issue a certificate for that ZIP. The fingerprint is calculated in your browser; the ZIP itself is not uploaded. Files up to 500 MB are accepted.
- Store the ZIP unchanged next to the certificate PDF, in at least two places. Do not unzip and re-zip it: a new archive of identical files can still have a different fingerprint.
Why a ZIP and not the folder: the certificate covers one file. An archive turns the whole tree into one file whose fingerprint you can recompute later with any SHA-256 tool. git archive output can differ between Git versions, which is exactly why you keep the archive you stamped rather than plan to regenerate it.
Method 2: timestamp a commit record (lightweight)
If you want to date many commits cheaply, or the repository is larger than 500 MB, write a short text file and timestamp that instead:
repository: git@example.com:me/myproject.git
tag: v1.4.0
commit: 3f9c2e7d0a5b8c1e4f6a9d2b7c0e3f5a8b1d4c6e
tree: 9b2e4d6f8a0c1e3b5d7f9a1c3e5b7d9f0a2c4e6b
note: release candidate sent to client on request
Fill the commit and tree lines with the real values from git rev-parse v1.4.0 and git rev-parse v1.4.0^{tree}. A Git commit ID is a hash over the commit's tree, its parents and its message, so it ties the timestamp to that exact state of the code and to all history before it. Keep the repository, including that commit, safe; the text file alone shows nothing without it.
The trade-off: the link from the text file to your code depends on Git's own hashing. Most repositories still use SHA-1 for object IDs, which has known collision attacks, even though Git ships with detection for the known one. For a routine milestone that is usually enough. For the version you are most likely to rely on in a dispute, use Method 1, where the timestamp covers the files themselves.
Which to use when
| Situation | Use | Why |
|---|---|---|
| Before sending code to a client, investor or potential employer | Method 1 | Fixes the exact files you are about to hand over |
| Before open-sourcing or changing licence | Method 1 | Fixes what existed under the old terms |
| Ending a freelance contract or collaboration | Method 1 | Fixes the state at the point responsibilities change |
| Monthly or per-release milestones | Method 2 | Cheap, and each one also covers all earlier history |
| Repository over 500 MB | Method 2, or Method 1 on the source directories only | Keeps the stamped file under the size limit |
Private and proprietary code
The fingerprint is computed on your device. Unless you explicitly choose to store a copy of the file, StampR receives only the fingerprint, the file name and size, and the details you enter. The fingerprint cannot be reversed into the code. For proprietary code, leave the option to store and display the original unticked: a stored original is shown on the certificate's public page.
Choose the file name and description with the same care. Both are printed on the certificate. myproject-v1.4.0.zip is fine; a name that reveals an unannounced product may not be.
What this does not do
- It does not show that you wrote the code. It shows that this exact code existed at that moment and that you declared it yours. Your commit history, issues and design notes show the work being done.
- It does not decide who owns the code. Within the EU, when an employee writes a program in the course of their duties, the employer is entitled to exercise the economic rights unless the contract says otherwise (Directive 2009/24/EC, Article 2(3)). Freelance and agency work depends on the contract. A timestamp fixes dates; it does not override an agreement.
- It does not protect an idea or algorithm as such. EU software copyright covers the expression of a program, not the ideas and principles behind it (Directive 2009/24/EC, Article 1(2)). Patent questions are separate, and publishing can affect them.
- It does not replace a licence. If you publish code, choose and include a licence; the timestamp is evidence, not permission.
Timestamp a snapshot of your code – the first certificate on an account is €4.90.
Checking it later
Anyone can check the certificate without trusting you. Run sha256sum myproject-v1.4.0.zip (macOS: shasum -a 256, Windows: Get-FileHash), then compare the result with the fingerprint on the certificate, or enter it on the verification page. A match means the file is byte-for-byte the one that was timestamped.
Related reading
- Timestamp hundreds of files with one certificate – the manifest method, for when a ZIP is not practical.
- Do timestamp certificates hold up in court? – what the eIDAS presumption does in a dispute.
- Every option for evidencing authorship, compared – including when a timestamp is the wrong tool.
Frequently asked questions
Can Git commit dates be used as evidence of when code was written?
They can be shown, but they are weak on timing because they are set by the machine making the commit and can be changed with environment variables, amend or rebase. They are strong evidence of how the work developed, and work best alongside an independent date such as a qualified timestamp.
Do I have to upload my source code?
No. The SHA-256 fingerprint is calculated in your browser and only the fingerprint is sent, unless you choose to store a copy of the file. For proprietary code, do not store a copy.
Should I timestamp the ZIP or the commit hash?
The ZIP of a tagged commit is the stronger option because the timestamp covers the files directly. A text file containing the commit ID is cheaper for regular milestones and covers all earlier history, but its link to the code depends on Git's own hashing.
Is a GitHub push time enough?
It is useful supporting evidence, but it is held by a private platform, can be hard to obtain later and disappears if the repository or account is deleted. A qualified timestamp is held by you and is presumed accurate by EU courts.
Does a timestamp show that I own the code?
No. Ownership depends on who wrote it and on employment or freelance agreements. The timestamp fixes that this exact code existed at a given moment and that you declared it yours.
How often should I timestamp?
At the moments you might later need to point to: before handing code to someone else, before a licence change, at the end of a contract and at major releases. Many developers add a monthly commit record in between.
Certify your work with a trusted date.
Create a certificate →Your first certificate is €4.90 with an account.