เหตุใด git จึงใช้แฮชแทนหมายเลขการแก้ไข


80

ฉันสงสัยอยู่เสมอว่าทำไม git ชอบแฮชมากกว่าหมายเลขการแก้ไข หมายเลขการแก้ไขมีความชัดเจนและง่ายต่อการอ้างถึง (ในความคิดของฉัน): มีความแตกต่างระหว่างการบอกใครสักคนให้ดูการแก้ไข 1200 หรือกระทำ 92ba93e! (เพียงยกตัวอย่างหนึ่ง)

ดังนั้นมีเหตุผลสำหรับการออกแบบนี้หรือไม่?


3
คุณสามารถแท็กการคอมมิทด้วย "v1.0" จากนั้นอ้างอิงการคอมมิชชันด้วยแท็กนั้น ดูgit-scm.com/book/en/v2/Git-Basics-Tagging
Michael Durrant

คำตอบ:


114

หมายเลขการแก้ไขเดียวที่เพิ่มขึ้นแบบ monotonic นั้นเหมาะสมสำหรับระบบควบคุมเวอร์ชันรวมศูนย์ที่การแก้ไขทั้งหมดไหลไปยังที่เดียวที่สามารถติดตามและกำหนดหมายเลขได้ เมื่อคุณเข้าสู่โลกของ DVCS ที่ซึ่งมีที่เก็บสำเนาจำนวนมากอยู่และมีการดึงการเปลี่ยนแปลงและผลักดันพวกเขาในเวิร์กโฟลว์ตามอำเภอใจแนวคิดก็ไม่ได้นำมาใช้ (ตัวอย่างเช่นไม่มีที่เดียวที่จะกำหนดหมายเลขการแก้ไข - ถ้าฉันแยกที่เก็บของคุณและคุณตัดสินใจว่าจะดึงการเปลี่ยนแปลงในอีกหนึ่งปีต่อมาระบบจะมั่นใจได้อย่างไรว่าหมายเลขการแก้ไขของเราจะไม่ขัดแย้งกัน)


11
คุณอาจต้องการดูวิธีการ Bazaar - DVCS ที่ยังคงรักษาหมายเลขการแก้ไข การรับประกันเพียงอย่างเดียวคือหมายเลขการแก้ไขนั้นไม่ซ้ำกันภายในสาขา
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 ก็มีปัญหาคล้ายกัน ในทางกลับกันหากพวกเขาใช้คอมไพล์พวกเขาต้องการอ้างอิงที่เหมือนกันสำหรับการกระทำแต่ละครั้ง
Izkata

1
@Izkata: P1: "Do you have revision with the GUID gdlmsnblngoijlafd-35345-fg?"... ตลาดสดยังมี GUID อยู่ ...
krlmlr

5
@Izkata Mercurial ไม่ได้มีปัญหาที่คล้ายกัน พวกเขาใช้แฮชเหมือนgitกัน พวกเขายังให้หมายเลข rev เฉพาะท้องถิ่นเพื่อความสะดวกในการพิมพ์
แฮงค์เกย์

1
ด้วย git ตัวอักษรแฮช 5 ตัวแรกมักจะไม่ซ้ำกันมากพอที่จะใช้ชวเลขสำหรับรหัสการแก้ไขแบบเต็ม
mendota

40

คุณต้องการแฮ็ชในระบบกระจาย สมมติว่าคุณและเพื่อนร่วมงานกำลังทำงานในพื้นที่เก็บข้อมูลเดียวกันและคุณทั้งสองยอมรับการเปลี่ยนแปลงในพื้นที่แล้วผลักดันมัน ใครจะได้รับการแก้ไขหมายเลข 1200 และใครจะเป็นหมายเลขการแก้ไข 1201 เนื่องจากไม่มีฝ่ายใดมีความรู้เกี่ยวกับกันและกันบ้าง โซลูชันทางเทคนิคที่เหมือนจริงเพียงอย่างเดียวคือการสร้างแฮชของการเปลี่ยนแปลงโดยใช้วิธีการที่เป็นที่รู้จักและเชื่อมโยงสิ่งต่าง ๆ ตามนั้น

HG ที่น่าสนใจสนับสนุนหมายเลขรุ่น แต่เป็นคุณสมบัติเฉพาะที่อย่างชัดเจน - ที่เก็บของคุณมีหนึ่งชุด repo ของเพื่อนร่วมงานของคุณจะมีชุดที่แตกต่างกันขึ้นอยู่กับวิธีที่พวกเขาผลักและดึง มันทำให้การใช้บรรทัดคำสั่งเป็นมิตรมากกว่า Git เล็กน้อย


34

ความสมบูรณ์ของข้อมูล.

ฉันไม่เห็นด้วยกับคำตอบปัจจุบันอย่างเคารพ hashes ไม่จำเป็นสำหรับ DVCS ดูวิธีท์บาซาร์ คุณสามารถทำได้เช่นกันกับตัวระบุที่ไม่ซ้ำใครอื่น ๆ ทั่วโลก แฮชเป็นตัวชี้วัดที่รับประกันความถูกต้องของข้อมูล: มันเป็นตัวแทนของข้อมูลที่มีอยู่ในวัตถุ (กระทำ, ต้นไม้, ... ) ที่ถูกอ้างถึงโดยแฮช การดัดแปลงเนื้อหาโดยไม่ดัดแปลงแฮช (เช่นการโจมตีก่อนเกิดเหตุการณ์หรือการชนกันของข้อมูล ) เชื่อว่าเป็นเรื่องยากแม้ว่าจะเป็นไปไม่ได้ก็ตาม (ถ้าคุณเป็นจริงลงไปดูที่2011 กระดาษโดย Marc Stevens )

ดังนั้นการอ้างอิงถึงวัตถุโดยการแฮช SHA ของพวกเขาอนุญาตให้ตรวจสอบว่าเนื้อหาได้รับการดัดแปลง และเนื่องจากพวกเขา (เกือบ) รับประกันว่าจะไม่ซ้ำกันพวกเขาสามารถใช้เป็นตัวระบุการแก้ไขได้เช่นกัน

ดูบทที่ 9ของหนังสือ Git สำหรับรายละเอียดเพิ่มเติม


8
ไม่ใช่มาตรการรักษาความปลอดภัยเนื่องจากสามารถคำนวณแฮชใหม่ได้ง่ายสำหรับการคอมมิทที่แก้ไข ใช้เพื่อความสมบูรณ์เท่านั้นเพื่อตรวจสอบเนื้อหากับแฮชที่คำนวณได้ - ดูความคิดเห็นนี้จาก Linus Torvalds เกี่ยวกับการใช้ SHA-1 ใน Git
Lee

@Lee: หากที่เก็บของ Chuck นั้นแตกต่างจากที่เก็บของ Alice และ Bob ในแง่ของ hash revision ก็รับประกันได้ว่า Chuck นั้นก็มีเนื้อหาที่แตกต่างกัน ในทางกลับกันมันยากมากสำหรับ Chuck ที่จะสร้างที่เก็บที่มีเนื้อหาแตกต่างกันซึ่งมีลักษณะเหมือนกันกับแฮชของการแก้ไข
krlmlr

@Lee: พลาดลิงค์ของคุณ ลองเรียกมันว่า "data integrity" จากนั้น ...
krlmlr

ควรเป็นคำตอบที่ถูกต้อง
SuperUberDuper

8

ในคำพูดของคนธรรมดา:

  • แฮชมีจุดประสงค์เพื่อให้มีลักษณะเฉพาะที่เป็นสากลเกือบทั้งหมด ไม่รับประกัน แต่ไม่น่าเป็นไปได้อย่างยิ่งที่ SHA เดียวกันนั้นจะสร้างขึ้นสำหรับเนื้อหาที่แตกต่างกัน ในภาคปฏิบัติสำหรับโครงการที่กำหนดคุณสามารถถือว่าเป็นโครงการที่ไม่เหมือนใคร
  • ด้วยหมายเลขการแก้ไขคุณจะต้องใช้เนมสเปซเพื่อให้การอ้างอิงซ้ำเป็นการแก้ไข 1200
  • Git สามารถทำงานได้ทั้งแบบกระจายและ / หรือรวมศูนย์ ดังนั้นคุณจะได้รับหมายเลขการแก้ไขที่ถูกต้องและไม่ซ้ำกันได้อย่างไร
  • การใช้หมายเลขการแก้ไขจะสร้างการแสดงผลที่ผิดพลาดซึ่งการแก้ไขที่ใหม่กว่าควรมีจำนวนที่สูงกว่าและนั่นจะไม่เป็นจริงเพราะการแยกการรวมการรวมการรีบูต ฯลฯ
  • คุณมีตัวเลือกที่จะนำแท็กไปใช้ในการคอมมิท

32
ไม่รับประกันว่าจะไม่ซ้ำใครมีแนวโน้มว่าจะไม่เหมือนใคร :)
dsw88

@ mustang2009cobra นั่นเป็นเรื่องจริง
Tulains Córdova

1
เป็นไปได้ว่าการเปลี่ยนแปลงของฉันไม่ได้รับการยอมรับเนื่องจากแฮชไม่เปลี่ยนแปลง มีโอกาสมากขึ้นที่อุกกาบาตสองตัวโจมตีคอมพิวเตอร์ของฉันและคอมพิวเตอร์ด้วยที่เก็บในเวลาเดียวกันทำลายคอมพิวเตอร์และฆ่าทุกคนที่เกี่ยวข้อง
gnasher729

5

ในแง่คณิตศาสตร์:


1

Hash ไม่ใช่โซลูชันเฉพาะสำหรับ VCS แบบกระจาย แต่เมื่อจัดการกับระบบกระจายการบันทึกเหตุการณ์บางส่วนเท่านั้น (สำหรับ VCS เหตุการณ์นั้นสามารถกระทำได้) นั่นคือเหตุผลที่ว่าทำไมการรักษาหมายเลขการแก้ไขที่เพิ่มขึ้นอย่างน่าเบื่อนั้นเป็นไปไม่ได้ โดยปกติเราจะนำบางสิ่งบางอย่างเช่นนาฬิกาแบบเวกเตอร์ (หรือการประทับเวลาของเวกเตอร์) เพื่อบันทึกความสัมพันธ์ที่เรียงลำดับบางส่วน นี้เป็นวิธีการที่ใช้ในการบาซาร์

แต่ทำไม Git ไม่ใช้นาฬิกาแบบเวกเตอร์ แต่เป็นแฮช ผมคิดว่าสาเหตุที่แท้จริงคือเชอร์รี่เลือก เมื่อเราทำการเลือกที่เก็บเชอร์รี่, การสั่งซื้อบางส่วนของการกระทำที่มีการเปลี่ยนแปลง นาฬิกาแบบเวกเตอร์ของ commits บางอันต้องถูกกำหนดใหม่เพื่อเป็นตัวแทนของการสั่งซื้อบางส่วนใหม่ อย่างไรก็ตามการกำหนดใหม่ดังกล่าวในระบบกระจายจะทำให้นาฬิกาเวกเตอร์ไม่สอดคล้องกัน นั่นคือปัญหาจริงที่แฮชจัดการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.