Programming

주어진 코드베이스에서 변경 사항을 고유하게 식별하는 데 필요한 git sha의 양은 얼마나됩니까?

procodes 2020. 5. 16. 11:20
반응형

주어진 코드베이스에서 변경 사항을 고유하게 식별하는 데 필요한 git sha의 양은 얼마나됩니까?


예를 들어 Git 리포지토리에서 커밋에 대한 디렉토리의 이름을 가진 디렉토리 구조를 만들려고 할 때 눈이 번지지 않도록 충분히 짧을 것이지만 충돌 할 가능성이 충분히 길기를 원한다면 무시할 수 있습니다. 일반적으로 SHA 하위 문자열이 얼마나 많이 필요합니까?

https://github.com/wycats/handlebars.js/commit/e62999f9ece7d9218b9768a908f8df9c11d7e920 을 고유하게 식별하고 싶다고 가정 해 봅시다.

처음 네 문자 만큼만 사용할 수 있습니다 : https://github.com/wycats/handlebars.js/commit/e629

그러나 나는 그것이 위험하다고 생각합니다. 그러나 몇 년 동안 30k 개의 변경 사항이있을 수있는 코드베이스를 가정하면 8자를 사용할 경우 충돌 가능성은 무엇입니까? 12? 이런 종류의 물건에 일반적으로 허용되는 숫자가 있습니까?


이 질문은 실제로 Pro Git 책의 7 장 에서 대답합니다 .

일반적으로 8-10 문자는 프로젝트 내에서 고유하기에 충분합니다. 가장 큰 Git 프로젝트 중 하나 인 Linux 커널은 고유성을 유지하기 위해 가능한 40 개 중 12자를 필요로합니다.

짧은 SHA의 경우 Git 기본값은 7 자리이므로 대부분의 프로젝트에 적합합니다. 커널 팀은 언급 한 것처럼 수십만 개의 커밋 이 있기 때문에 여러 차례 증가했습니다 . ~ 30k 커밋의 경우 8 자리 또는 10 자리가 완벽하게 좋습니다.


참고 : git rev-parse --short가장 짧지 만 고유 한 SHA1을 요청할 수 있습니다 .
자세한 내용은 " 일반 해시에서 짧은 해시를 얻을 수 힘내 "

git rev-parse --short=4 921103db8259eb9de72f42db8b939895f5651489
92110

예제에서 볼 수 있듯이 SHA1의 길이는 4를 지정하더라도 길이는 5입니다.


포지션의 경우 2010 년 이후 7만으로는 충분하지 않으며 Linus Torvalds가 직접 dce9648커밋 합니다 (git 1.7.4.4, 2010 년 10 월) :

기본값 7은 git 개발 초기에 7 개의 16 진수가 많았을 때 발생합니다 (약 2 억 5 천만 + 해시 값 포함).
당시에는 65k 개정판이 많았고 (BK에서 맞닥뜨릴 예정 임) 각 개정판이 약 5-10 개의 새로운 객체 인 경향이 있으므로 백만 개의 객체가 많았습니다.

(BK = 비트 키퍼)

요즘 커널은 가장 큰 git 프로젝트가 아니며 커널조차 약 220k 개정 ( BK 트리보다 훨씬 큼 )이 있으며 우리는 2 백만 개의 객체에 접근하고 있습니다.
그 시점에서, 일곱 16 진수는 여전히 많은 고유이지만, 우리가 객체의 수와 해시 크기 사이의 크기 차이에 대한 두 주문을 얘기 할 때,이 잘립니다 해시 값의 충돌합니다.
더 이상 비현실적이지 않으며 항상 발생합니다.

우리는 모두 비현실적으로 작았 기본 약칭을 증가해야 하고 사람들이 자식 설정 파일에 당 프로젝트 자신의 기본값을 설정할 수있는 방법을 추가 .

core.abbrev

길이 오브젝트 이름을 약자로 설정하십시오.
지정하지 않으면 많은 명령이 7 개의 16 진수로 축약되며, 축약 된 오브젝트 이름이 충분히 오랫동안 고유하게 유지되기에 충분하지 않을 수 있습니다.

environment.c:

int minimum_abbrev = 4, default_abbrev = 7;

참고 : marco.m의해 아래언급 된 것처럼 커밋 a71f09f의 동일한 Git 1.7.4.4에서 이름이 변경되었습니다 .core.abbrevLenghtcore.abbrev

core.abbrevlength다시 이름 바꾸기core.abbrev

결국 --abbrev=$n명령 행 옵션에 해당 합니다.


더 최근에 Linus는 커밋 e6c587c (Git 2.11, Q4 2016 용)에 추가했습니다 :
( Mathieu Moy답변 에서 언급했듯이 )

상당히 초기에는 객체 이름을 7 자리 숫자로 줄이기로 결정했지만 프로젝트가 커짐에 따라 이전에 만들어진 짧은 객체 이름이 더 이상 고유하지 않은 로그 메시지에 기록 될 가능성이 높아지고 있습니다.

현재 Linux 커널 프로젝트에는 11 ~ 12 개의 16 진수가 필요하지만, Git 자체는 객체를 고유하게 식별하기 위해 10 개의 16 진수가 필요하지만, 많은 소규모 프로젝트는 여전히 원래 7- 진수의 기본값으로 괜찮을 수 있습니다. 하나의 크기가 모든 프로젝트에 적합하지는 않습니다.

기본 설정으로 객체 이름을 축약하고 리포지토리에 대한 기본값을 설정하라는 요청이있을 때 리포지토리의 객체 수를 추정하는 메커니즘을 소개합니다. 2^(2N)첫 번째 N 비트로 단축 된 오브젝트 이름을 사용할 때 오브젝트 와의 저장소에서 충돌이 발생할 것으로 예상함에 따라 저장소의 오브젝트 수를 포함하기에 충분한 수의 16 진수를 사용하십시오.
단축 이름에 추가 한 각 16 진수 (4 비트)는 저장소에 4 배 (2 비트) 많은 객체를 가질 수 있습니다.

Linus Torvalds ( )의 commit e6c587c (2016 년 10 월 1 일)를 참조하십시오 . 참조 7b5b772 커밋 , 65acfea 커밋 으로 (01 년 10 월 2016) Junio C 하마노 ( ) . (가 합병 - Junio C 하마노 -bb188d0 커밋 2016 03 10 월)torvalds
gitster
gitster

이 새로운 속성 (SHA1 abbrev 값에 대한 합리적인 기본값을 추측)은 Git이 릴리스를 위해 자체 버전 번호를 계산 하는 방법에 직접적인 영향을 미칩니다 .


이것을 생일 문제라고합니다.

1/2보다 작은 확률의 경우 충돌 확률은 다음과 같이 추정 할 수 있습니다.

p ~ = (n 2 ) / (2m)

여기서 n은 항목 수이고 m은 각 항목의 가능성 수입니다.

The number of possibilities for a hex string is 16c where c is the number of characters.

So for 8 characters and 30K commits

30K ~= 215

p ~= (n2)/(2m) ~= ((215)2)/(2*168) = 230/233 = ⅛

Increasing it to 12 characters

p ~= (n2)/(2m) ~= ((215)2)/(2*1612) = 230/249 = 2-19


This question has been answered, but for anyone looking for the math behind - it's called Birthday problem (Wikipedia).

It is about the probability of having 2 (or more) people from group of N people to have birthday on the same day in year. Which is analogical to probabily of 2 (or more) git commits from repository having N commits in total having the same hash prefix of length X.

Look at the Probability table. For example for hash hex string of length 8 the probability of having a collision reaches 1 % when the repository has just about 9300 items (git commits). For 110 000 commits the probability is 75 %. But if you have hash hex string of length 12 the probability of collision in 100 000 commits is below 0.1 %.


Git version 2.11 (or perhaps 2.12?) will contain a feature that adapts the number of characters used in short identifiers (e.g. git log --oneline) to the size of the project. Once you use such version of Git, the answer to your question can be "pick whatever length Git gives you with git log --oneline, it's safe enough".

For more details, see Changing the default for “core.abbrev”? discussion in Git Rev News edition 20 and commit bb188d00f7.

참고URL : https://stackoverflow.com/questions/18134627/how-much-of-a-git-sha-is-generally-considered-necessary-to-uniquely-identify-a

반응형