How does Git create unique commit hashes, mainly the first few characters?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Git does not generate a commit ID by inventing a few unique starting characters and then filling in the rest. It hashes the entire serialized commit object, and the short prefix you usually see is only a human-friendly abbreviation of that full object ID.
What Git Actually Hashes
A commit hash comes from the commit object contents. That object includes data such as:
- the root tree object ID
- parent commit IDs
- author name, email, and timestamp
- committer name, email, and timestamp
- the commit message
Git serializes that commit object, prefixes it with an object header, and hashes the result. Historically, most repositories use SHA-1 object IDs. Newer repositories can use SHA-256 object format, but the basic idea is the same in both cases: the object ID is derived from the full object contents.
That means even a tiny change to the commit object changes the commit ID.
The First Few Characters Are Not Special
Suppose a commit ID begins with:
a1b2c3d...
Those first characters are not created by a separate uniqueness algorithm. They are simply the first part of the full hash.
They feel special because Git lets you abbreviate object IDs as long as the abbreviation is unambiguous in the current repository.
You can see this directly:
git rev-parse --short HEAD asks Git to print a short prefix that is unique enough right now. If the repository later contains another object with the same prefix, Git may need a longer abbreviation.
So the prefix is a usability feature, not the source of uniqueness.
Why the Hash Looks Random
Cryptographic hash functions are designed so that small input changes produce outputs that look unrelated. That is why amending a commit message, changing the tree snapshot, or even adjusting metadata such as timestamps produces a dramatically different commit ID.
This property is useful because it means the commit ID acts as a content-derived fingerprint. Git is not storing a separate counter or sequence number for commits.
Two nearby commits may differ by one line of code, but their IDs can look completely unrelated because the hash function diffuses that small change across the entire output.
Inspecting the Commit Object
You do not have to treat the commit as magic. Git can show you the stored object:
The second command prints the commit contents, including tree, parents, author, committer, and message. That is the data whose identity Git is protecting with the object hash.
If any of it changes, the object is different, and therefore the hash is different too.
Repository-Local Uniqueness of Short Hashes
A short hash such as seven characters is not globally unique. It only needs to identify one object unambiguously in the repository and context where Git is resolving it.
This is why:
- one repository may accept a 7-character prefix
- another repository may need 9 or 10 characters
- the same repository may need longer prefixes later as it accumulates more objects
So when people say "the first few characters are unique," the accurate version is:
"Git is currently able to resolve that prefix uniquely in this repository."
That is a convenience rule, not a mathematical property of the first few characters alone.
Why Amending or Rebasing Changes Commit IDs
Because commit IDs are content-derived, rewriting history changes the IDs. Amending a message or rebasing onto a different parent changes the commit object, which changes the hash.
That is why commands such as:
produce new commit IDs even when the source files look very similar afterward.
From Git's perspective, those are genuinely new commit objects with different contents and parent relationships.
Common Pitfalls
The most common mistake is thinking Git creates the first few characters with a special uniqueness rule. It does not. The prefix is just an abbreviation of the full object ID.
Another mistake is assuming short hashes are globally unique. They are only required to be unambiguous in the repository where Git resolves them.
People also sometimes think commit IDs are based only on file contents. The full commit object includes metadata and parent relationships too, so those also affect the hash.
Finally, do not assume every repository uses SHA-1 forever. Git now supports repositories with different object hash algorithms, even though SHA-1 remains historically common.
Summary
- Git hashes the full serialized commit object, not just part of it.
- The first few visible characters are only a short prefix of the full object ID.
- Short hashes work because Git checks whether the prefix is unambiguous in the current repository.
- Changing commit contents or metadata changes the resulting commit hash.
- The real identity is the full object ID; the prefix is only a convenience for humans.
Related reading
- How does Git handle symbolic links?
- How does 'git log --graph' or 'hg graphlog' work?
- How does Git save space and is fast at the same time?
- How does Git store files?
- How does kafka consumer auto commit work?
- How does one iteratively write merge sort?
- How external merge sort algorithm works?
- How git works when two peers push changes to same remote simultaneously
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.