Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I always wondered why git prefers hashes over revision numbers. Revision numbers are much clearer and easier to refer to (in my opinion): There is a difference between telling someone to take a look at revision 1200 or commit 92ba93e! (Just to give one example).

So, is there any reason for this design?

share|improve this question
    
You can tag a commit with "v1.0" and then refer to the commit by that tag. See git-scm.com/book/en/v2/Git-Basics-Tagging –  Michael Durrant May 7 at 10:15

6 Answers 6

A single, monotonically increasing revision number only really makes sense for a centralized version control system, where all revisions flow to a single place that can track and assign numbers. Once you get into the DVCS world, where numerous copies of the repository exist and changes are being pulled from and pushed to them in arbitrary workflows, the concept just doesn't apply. (For example, there's no one place to assign revision numbers - if I fork your repository and you decide a year later to pull my changes, how could a system ensure that our revision numbers don't conflict?)

share|improve this answer
10  
You might want to look at the Bazaar way -- a DVCS that still maintains revision numbers. The only guarantee there is that revision numbers are unique within a branch. –  krlmlr Jul 19 '13 at 19:58
    
@krlmlr - Although revision numbers that are unique only within a branch are less useful, you're right; I was overlooking the use of hashes to promote data integrity. –  Josh Kelley Jul 20 '13 at 2:19
3  
@krlmlr Person 1: "Hey, <P2>, what was revision 12345 for?" P2: "Revision 12345 was commited by <P3>." P3: "I don't have a revision 12345..." - If I remember correctly, Mercurial has a similar problem. On the other hand, if they were using git, they'd all have identical references for each commit. –  Izkata Jul 20 '13 at 2:27
1  
@Izkata: P1: "Do you have revision with the GUID gdlmsnblngoijlafd-35345-fg?" ... Bazaar still has GUIDs... –  krlmlr Jul 20 '13 at 10:17
3  
@Izkata Mercurial does not have a similar problem. They use hashes, just like git. They also provide a local-only rev number for ease of typing. –  Hank Gay Jul 25 '13 at 16:03

You need hashes in a distributed system. Let's say you and a colleague are both working on the same repository and you both commit a change locally and then push it. Who gets to be revision number 1200 and who is revision number 1201 given neither party has any knowledge about each other? The only realistic technical solution is to create a hash of the changes using a known method and link things up based on that.

Interestingly HG does support version numbers but they are explicitly a local-only feature -- your repository has one set, your co-worker's repo will have a different set depending on how they pushed and pulled. It does make command line usage a bit more friendly than Git though.

share|improve this answer

Data integrity.

I respectfully disagree with the current answers. Hashes are not necessary for a DVCS, see the Bazaar way. You could do as well with any other kind of globally unique identifier. The hashes are a measure to guarantee data integrity: They represent a digest of the information contained in the object (commit, trees, ...) referred to by the hash. Altering the contents without altering the hash (i.e., a preimage attack or collision attack) is believed to be difficult, although not impossible. (If you're really into it, take a look at the 2011 paper by Marc Stevens).

Hence, referring to objects by their SHA hash allows to check if the contents have been tampered with. And, given that they're (almost) guaranteed to be unique, they can be used as revision identifiers, too -- conveniently so.

See Chapter 9 of the Git book for more details.

share|improve this answer
6  
It's not a security measure, since the hash can easily be re-calculated for a modified commit. It's only used for integrity, to verify the contents against the calculated hash - see this comment from Linus Torvalds on the use of SHA-1 in Git. –  Lee Jul 19 '13 at 20:40
    
@Lee: If Chuck's repository is different from the one that Alice and Bob have in terms of revision hashes, it is guaranteed that Chuck also has different contents. On the other hand, it's very difficult for Chuck to fabricate a repository with different contents that looks identical w.r.t. their revision hashes. –  krlmlr Jul 19 '13 at 20:59
    
@Lee: Missed your link. Let's call it "data integrity" then... –  krlmlr Jul 19 '13 at 21:09

In layman's words:

  • Hashes are intended to be nearly universally unique. It is NOT guaranteed but it is extremely unlikely that the same SHA's are generated for different content. In practical term for a given project you can treat it as unique.
  • With revision numbers you would have to use a namespace in order to reffer specifically to revision 1200.
  • Git can work both distributed and/or centralized. So how do you get revision numbers correct and unique ?
  • Also using revision numbers would create the false spectation that newer revisions should have higher numbers, and that would not be true because of branching, merging, rebasing, etc.
  • You always have the option to put tags to commits.
share|improve this answer
31  
Not guaranteed to be unique, just incredibly likely to be unique. :) –  dsw88 Jul 19 '13 at 14:30
    
@mustang2009cobra That's true. –  user61852 Jul 19 '13 at 14:35
    
It's possible that my change is not accepted because the hash is unchanged. It's much more likely that two meteors strike my computer and the computer with the repository at the same second, destroying the computers and killing everyone involved. –  gnasher729 May 7 at 8:55

In mathematical terms:

share|improve this answer

Hash is not the unique solution for distributed VCS. But when deal with a distributed system, only the partial ordering of events can be recorded. (For VCS, the event can be a commit.) That is why maintain a monotonically increasing revision number is impossible. Usually we adopt something like vector clock (or vector timestamp) to record such partial-ordered relation. This is the solution used in Bazaar.

But why Git not uses vector clock but hash? I think the root cause is cherry-pick. When we perform cherry-pick on a repository, the partial ordering of commits is changing. Some commits' vector clocks must be re-assigned to represent the new partial ordering. However, such reassignment in distributed system would induce inconsistent vector clocks. That is the real problem which hashes deal with.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.