왜 git은 개정 번호 대신 해시를 사용합니까?


80

항상 git이 개정 번호보다 해시를 선호하는 이유가 궁금했습니다. 개정 번호는 훨씬 명확하고 참조하기 쉽습니다 (제 의견으로는) : 누군가에게 개정 1200을 보도록하거나 92ba93e를 커밋하도록 지시하는 것에는 차이가 있습니다! (한 가지 예만 제시하십시오).

이 디자인에 대한 이유가 있습니까?


3
"v1.0"으로 커밋에 태그를 지정한 다음 해당 태그로 커밋을 참조 할 수 있습니다. 참조 git-scm.com/book/en/v2/Git-Basics-Tagging
마이클 듀런트

답변:


114

단조롭게 증가하는 단일 개정 번호는 모든 버전이 단일 번호로 추적 및 할당 할 수있는 단일 위치로 흐르는 중앙 집중식 버전 제어 시스템에만 적합합니다. 수많은 저장소 사본이 존재하고 임의의 워크 플로우에서 변경 사항을 가져 와서 푸시하는 DVCS 세계에 들어간 후에는 개념이 적용되지 않습니다. (예를 들어, 개정 번호를 할당 할 곳이 없습니다. 리포지토리를 포크하고 1 년 후 변경 사항을 풀기로 결정한 경우 시스템이 개정 번호가 충돌하지 않도록 어떻게 할 수 있습니까?)


11
여전히 수정 번호를 유지하는 DVCS 인 Bazaar 방식 을보고 싶을 것 입니다. 지사 내에서 개정 번호가 고유하다는 보장이 있습니다.
krlmlr

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..."올바르게 기억하면 Mercurial에도 비슷한 문제가 있습니다. 반면에 git을 사용하는 경우 각 커밋에 대해 동일한 참조가 있습니다.
이즈 카타

1
@Izkata : P1: "Do you have revision with the GUID gdlmsnblngoijlafd-35345-fg?"... Bazaar는 여전히 GUID를 가지고 있습니다.
krlmlr

5
@Izkata Mercurial도 비슷한 문제 가 없습니다 . 그들은처럼 해시를 사용합니다 git. 또한 쉽게 입력 할 수 있도록 로컬 전용 개정 번호를 제공합니다.
행크 게이

1
git을 사용하면 해시의 처음 5자는 종종 전체 개정 ID에 속기를 사용할 수있을 정도로 고유합니다.
mendota

40

분산 시스템에는 해시가 필요합니다. 귀하와 동료가 모두 동일한 저장소에서 작업 중이고 로컬에서 변경 사항을 커밋 한 다음 푸시한다고 가정 해 보겠습니다. 수정 번호 1200은 누구이며 어느 당사자도 서로에 대해 아는 바가없는 수정 번호 1201은 누구입니까? 유일한 현실적인 기술 솔루션은 알려진 방법을 사용하여 변경 사항을 해시하고이를 기반으로 연결하는 것입니다.

흥미롭게도 HG는 버전 번호를 지원하지만 명시 적으로 로컬 전용 기능입니다. 리포지토리에는 하나의 세트가 있으며 동료의 저장소는 푸시 및 풀 방식에 따라 다른 세트를 갖습니다. 커맨드 라인 사용법은 Git보다 조금 더 친숙합니다.


34

데이터 무결성.

나는 현재 답변에 정중하게 동의하지 않습니다. DVCS에는 해시가 필요하지 않습니다 . Bazaar 방법을 참조하십시오 . 다른 종류의 전역 고유 식별자와 함께 할 수도 있습니다. 해시는 데이터 무결성을 보장하는 척도입니다. 해시가 참조하는 객체 (커밋, 트리 등)에 포함 된 정보의 요약을 나타냅니다. 해시를 변경하지 않고 내용을 변경하는 것 (즉, 사전 이미지 공격 또는 충돌 공격 )은 불가능하지는 않지만 어렵다고 생각됩니다. (실제로 Marc Stevens2011 논문을 살펴보십시오 ).

따라서 SHA 해시로 개체를 참조하면 내용이 변조되었는지 확인할 수 있습니다. 그리고 그것들은 (거의) 독창적이라고 보장되므로 수정 식별자로도 편리하게 사용할 수 있습니다.

자세한 내용 은 Git 책의 9 장 을 참조하십시오.


8
수정 된 커밋에 대해 해시를 쉽게 다시 계산할 수 있으므로 보안 조치가 아닙니다. 무결성을 위해서만 사용되며 계산 된 해시와 비교하여 내용을 확인합니다. Linus Torvalds의 Git에서 SHA-1 사용에 대한 주석 을 참조하십시오 .
Lee

@Lee : Chuck의 리포지토리가 Alice와 Bob이 리비전 해시와 다른 리포지토리와 다른 경우 Chuck도 다른 내용을 갖습니다. 반면 척은 수정 해시와 동일하게 보이는 다른 내용의 저장소를 제작하기가 매우 어렵습니다.
krlmlr

@이 : 링크가 누락되었습니다. 그런 다음 "데이터 무결성"이라고하겠습니다.
krlmlr

정답이어야합니다
SuperUberDuper 2016 년

8

평신도의 말로 :

  • 해시는 거의 보편적으로 독특합니다. 그것은 보장하지만은되지 않습니다 극단적 같은 SHA 년대 서로 다른 콘텐츠를 생성 가능성. 주어진 프로젝트에 대한 실질적인 용어로 프로젝트를 고유 한 것으로 취급 할 수 있습니다.
  • 개정 번호를 사용하면 개정판 1200을 구체적으로 참조하기 위해 네임 스페이스를 사용해야합니다.
  • Git은 분산 및 / 또는 중앙 집중식으로 작동 할 수 있습니다. 그렇다면 수정 번호를 정확하고 고유하게 얻는 방법은 무엇입니까?
  • 또한 개정판 번호를 사용하면 최신 개정판의 번호가 높아야한다는 잘못된 추측이 생길 수 있으며 분기, 병합, 리베이스 등으로 인해 사실이 아닙니다.
  • 커밋에 태그를 넣을 수있는 옵션이 항상 있습니다.

32
독특하다고 보장되는 것은 아니며, 독특 할 가능성도 있습니다. :)
dsw88

@ mustang2009cobra 사실입니다.
Tulains Córdova

1
해시가 변경되지 않았기 때문에 변경 사항이 적용되지 않을 수 있습니다. 두 명의 유성이 내 컴퓨터와 컴퓨터에 같은 시간에 저장소를 두드려 컴퓨터를 파괴하고 관련된 모든 사람을 죽일 가능성이 훨씬 큽니다.
gnasher729


1

해시는 분산 VCS를위한 고유 한 솔루션이 아닙니다. 그러나 분산 시스템을 처리 할 때는 부분 순서의 이벤트 만 기록 할 수 있습니다. (VCS의 경우 이벤트가 커밋 될 수 있습니다.) 따라서 단조롭게 증가하는 개정 번호를 유지하는 것은 불가능합니다. 일반적으로 이러한 부분 순서 관계를 기록하기 위해 벡터 클록 (또는 벡터 타임 스탬프) 과 같은 것을 채택합니다 . 이것이 Bazaar 에서 사용되는 솔루션 입니다.

그러나 왜 Git은 벡터 클럭을 사용하지 않고 해시를 사용합니까? 근본 원인은 체리 픽 이라고 생각합니다 . 저장소에서 cherry-pick을 수행하면 커밋의 부분 순서가 변경됩니다. 새로운 부분 순서를 나타 내기 위해 일부 커밋의 벡터 클럭을 다시 할당해야합니다. 그러나 분산 시스템에서 이러한 재 할당은 벡터 클록이 일치하지 않을 수 있습니다. 이것이 해시가 다루는 실제 문제입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.