Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Git hasn't used "seven-character prefixes when there are no collisions" in a long time.

It's a combination of the "repo size" (as in, estimated number of objects) and a hard floor of seven characters.

You can see this by running "git log --oneline=7" on any non-trivially sized repository (e.g. linux.git). There's plenty of hashes that uniquely abbreviate to 7 characters, but they're currently all shown with 12 by default.



There may be some extra trigger that causes it to go beyond seven for everything, I don’t know (never worked on a repository anywhere near that large), but there’s certainly still at least some form of collision logic in there (and this is why I said what I said, because I’ve used lucky_commit enough to experience it):

  $ git init x
  Initialized empty Git repository in /tmp/x/.git/

  $ cd x

  $ git commit --allow-empty -m one
  [master (root-commit) 4144321] one

  $ git log --oneline
  4144321 (HEAD -> master) one

  $ lucky_commit

  $ git log --oneline
  0000000 (HEAD -> master) one

  $ git commit --amend --no-edit --reset-author --allow-empty
  [master 3430e13] one

  $ git log --oneline
  3430e13 (HEAD -> master) one

  $ lucky_commit

  $ git log --oneline
  0000000f (HEAD -> master) one

  $ git reflog --oneline
  0000000f (HEAD -> master) HEAD@{0}: amend with lucky_commit
  3430e13 HEAD@{1}: commit (amend): one
  00000005 HEAD@{2}: amend with lucky_commit
  4144321 HEAD@{3}: commit (initial): one

  $ git reflog expire --expire=now --all

  $ git reflog --oneline

  $ git log --oneline
  0000000f (HEAD -> master) one

  $ git gc --aggressive --prune=now
  Enumerating objects: 2, done.
  Counting objects: 100% (2/2), done.
  Writing objects: 100% (2/2), done.
  Total 2 (delta 0), reused 0 (delta 0), pack-reused 0

  $ git log --oneline
  0000000 (HEAD -> master) one


Yes, there's also a collision check, but it's not truncating to 7 characters and adding as needed to get past collisions. Rather it's truncating to N and then adding as needed. N=7 for a new repository, but it'll relatively quickly bump that to 8, then 9 etc

You don't need a very large repository to start bumping it up to 8 etc. E.g. my local redis.git is 9, some local few-thousand commit (partially automated) that I've only ever added to are at 8 etc.

This changed in v2.11 released in late 2016[1], but because the observable default on a new repository is 7 the "it's 7 unless collisions" has persisted in various places online.

All of which is to say that if you brute-force the first commit to be 0000001..., it'll start being displayed as <that><x>, where <x> is a random 0..9a..f character, unless you brute force to 8, 9 etc.

1. https://github.com/git/git/commit/e6c587c733b4634030b353f402...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: