ประโยชน์ของกระบวนการคอมมิชชันสองขั้นตอน (การจัดเตรียม) ของคอมไพล์


174

ฉันเรียนรู้คอมไพล์และฉันสังเกตว่ามันมีกระบวนการทำสองขั้นตอน:

  1. git add <files>
  2. git commit

ขั้นตอนแรกทำการแก้ไขสิ่งที่เรียกว่า "พื้นที่จัดเตรียม" หรือ "ดัชนี"

สิ่งที่ฉันสนใจคือเหตุผลที่ทำให้การตัดสินใจออกแบบนี้และประโยชน์ของมันคืออะไร

นอกจากนี้ในฐานะผู้ใช้คอมไพล์คุณทำสิ่งนี้หรือแค่ใช้git commit -a?

ฉันถามสิ่งนี้เพราะฉันมาจาก bzr (Bazaar) ซึ่งไม่มีคุณสมบัตินี้


3
+1 สำหรับการถาม ฉันใช้ Tortoise SVN ซึ่งมีวิธีการแบบเดียวกันและฉันไม่เคยเข้าใจว่าทำไม
DPD

3
พื้นที่จัดแสดงไม่ผิดปกติ เทียบเท่าในพูด TFS จะตรวจสอบหรือยกเลิกการทำเครื่องหมายในช่องถัดจากไฟล์ก่อนที่จะตรวจสอบเฉพาะไฟล์ที่ตรวจสอบได้รับความมุ่งมั่น ความแตกต่างกับ Git คือถ้าคุณใช้git add -pคุณสามารถเลือกที่จะคอมไฟล์หนึ่งไฟล์โดยไม่คอมมิทไฟล์อื่น
Kyralessa

ฉันพบว่าลิงก์นี้สรุปสิ่งที่ได้รับคำตอบส่วนใหญ่ที่นี่และเพิ่มกรณีการใช้งานอีกสองสามกรณีเพื่อแสดงความจำเป็นในการจัดเตรียม
Veverke

2
จริง ๆ แล้วคำถามนี้ได้รับคำตอบแล้ว แต่นี่ก็เป็นหนึ่งในคำอธิบายที่ดีเช่นกัน: stackoverflow.com/questions/4878358//
guitar_freak

1
อย่าลืม git statusและอาจเป็นไปgit pushได้ สำหรับโฆษณาทั้งหมดเกี่ยวกับ git (และการแบ่งปันรหัส GitHub เป็นสิ่งที่ยอดเยี่ยม) ชิ้นส่วนนั้นน่ารำคาญมาก
949300

คำตอบ:


83

แบ่งงานออกเป็นส่วนต่าง คุณอาจเปิดไฟล์หลายครั้งเพื่อเขียนโปรแกรมแก้ไขบรรทัดเดียว แต่ในขณะเดียวกันคุณก็เห็นว่าการจัดรูปแบบผิดเอกสารบางอย่างอาจได้รับการปรับปรุงหรือโปรแกรมแก้ไขอื่น ๆ ที่ไม่เกี่ยวข้อง ด้วยRCSอื่น ๆที่คุณต้องจดลงไปหรือจำไว้ในหน่วยความจำทำการแก้ไขที่คุณทำเสร็จแล้วกลับไปแก้ไขสิ่งอื่น ๆ (หรือสร้าง ball-of-mud กระทำกับสิ่งที่ไม่เกี่ยวข้อง) . ด้วย Git คุณเพียงแค่แก้ไขทั้งหมดของมันในครั้งเดียวและเวที + กระทำบรรทัดเดียวแยกกันด้วยหรือgit add -igit-gui

อย่าทำลายโครงสร้าง คุณกำลังทำการดัดแปลงที่ซับซ้อน ดังนั้นคุณลองสิ่งที่แตกต่างกันบางอย่างทำงานได้ดีกว่าสิ่งอื่นบางอย่างก็แตกหัก เมื่อใช้ Git คุณจะทำสิ่งต่าง ๆ เมื่อการดัดแปลงทำให้ดีขึ้นและcheckout(หรือปรับแต่งเพิ่มเติม) เมื่อการดัดแปลงไม่ทำงาน คุณไม่จำเป็นต้องพึ่งพาฟังก์ชั่นการเลิกทำของบรรณาธิการคุณสามารถcheckoutrepo ทั้งหมดแทนที่จะเป็นไฟล์ต่อไฟล์และข้อผิดพลาดระดับไฟล์ใด ๆ (เช่นการลบไฟล์ที่ไม่ได้กระทำหรือบันทึก + ปิดหลังจาก การปรับเปลี่ยนที่ไม่ดี) ไม่ทำให้งานสูญหาย


3
มาจาก DVCS (bzr) ที่ไม่มีคุณสมบัตินี้ซึ่งฟังดูคล้ายกับสิ่งที่ฉันประสบความสำเร็จในปัจจุบันด้วยการใช้การรวมแบบเสรีของบัฟเฟอร์ "เลิกทำ" ของเอดิเตอร์คำสั่ง "ย้อนกลับ <file>" และการกระทำแบบเลือก (" ส่งมอบ <file> ") เสียงเหมือนคุณลักษณะของ git นี้มีศักยภาพที่จะเป็นระเบียบมากขึ้น
thomasrutter

1
เกี่ยวกับ "RCSes อื่น ๆ " นั่นไม่จำเป็นต้องเป็นเรื่องจริง ในความเป็นจริงคุณสามารถบรรลุฟังก์ชันเดียวกันผู้ที่อยู่ใน Mercurial ใช้แพทช์
Lucio Paiva

1
@ l0b0 เกี่ยวกับประเด็นที่สองของคุณ หากมีเพียงขั้นตอนเดียวที่กระทำคุณสามารถยอมรับการเปลี่ยนแปลง (ที่คุณใช้กับ git add) โดยตรงเป็นการกระทำ หากคุณพบว่าคุณทำอะไรผิดพลาดคุณจะต้องลบการกระทำและกลับไปยังที่ที่คุณอยู่ก่อนที่จะทำการส่ง ด้วยแนวคิดการจัดเตรียมคุณไม่เพียงทำอย่างนั้น แต่เพิ่มความซับซ้อนมากขึ้นหรือไม่
alpha_989

ประเด็นแรกของคุณสมเหตุสมผลแล้วแม้ว่าฉันจะไม่ได้ใช้มันจนถึงตอนนี้ ในทางทฤษฎีทำไมคุณไม่สามารถทำบางสิ่งบางอย่างเช่นgit add -iกับสเตจเดี่ยว คุณเพียงแค่เลือกไฟล์ (หรือบรรทัดภายในไฟล์) ที่เกี่ยวข้องกับฟีเจอร์เดียวและทำการคอมมิท จากนั้นคุณจะกลับมาทำข้อผูกพันที่สองที่เกี่ยวข้องกับคุณสมบัติอื่น ..
alpha_989

@thomasrutter จากคำสั่งของคุณดูเหมือนว่าคุณกำลังแนะนำว่าพื้นที่จัดเตรียมสร้าง "จุดแก้จุดบกพร่องด้วยตนเอง" ใน VIM ที่มีการลบถาวรคุณจะได้รับประวัติไม่ จำกัด อย่างน่าเชื่อถือ นอกจากนี้ยังมีการติดตามโดยอัตโนมัติในgit-branchประเภทแฟชั่น ( jovicailic.org/2017/04/vim-persistent-undo ) นอกจากนี้ประวัติการเลิกทำของคุณจะถูกติดตามโดยอัตโนมัติทุกครั้งที่คุณเข้าสู่โหมดปกติ ดังนั้นจึงช่วยลดภาระทางจิตของคุณในการสร้าง "คะแนนการเลิกทำด้วยตนเอง" เหตุใดการใช้บัฟเฟอร์ "เลิกทำ" ของบรรณาธิการถึงไม่เป็นระเบียบ
alpha_989

65

ข้อดีอย่างหนึ่งของฉันคือความสามารถในการ "เพิ่ม" ไฟล์อย่างต่อเนื่อง ก่อนที่จะส่งฉันตรวจสอบแต่ละไฟล์ เมื่อตรวจสอบไฟล์แล้วฉันจะเพิ่ม เมื่อฉันgit statusหรือgit diffgit แสดงให้ฉันเห็นเฉพาะไฟล์ที่ได้รับการแก้ไขและยังไม่ได้เพิ่ม เมื่อฉันได้ตรวจสอบไฟล์ทั้งหมดและเพิ่มพวกเขาแล้วฉันสามารถกระทำ

ใช่ฉันพบว่าพื้นที่จัดเตรียมมีประโยชน์มาก

git commit -aและไม่ฉันไม่เคยใช้ git add -uแต่ผมมักจะใช้ วิธีนี้ฉันยังสามารถเห็นภาพว่าต้องทำอะไร


2
เผง ข้อได้เปรียบคือการควบคุมที่ละเอียดยิ่งกว่าสิ่งที่คุณกำลังทำอยู่
Josh K

จะเกิดอะไรขึ้นเมื่อคุณจัดเก็บไฟล์เดียวหลาย ๆ ครั้ง? จะได้รับการ "รวม" ในพื้นที่การแสดงละคร?
m4l490n

21

ประโยชน์นั้นง่ายมาก: ให้คุณควบคุมได้อย่างเต็มที่ว่าไฟล์ใดที่คุณต้องการส่งมอบ สำหรับเรื่องนั้นคุณสามารถใช้git add -pเพื่อควบคุมบรรทัดที่คุณต้องการส่ง


2
ฉันเคยสงสัยเกี่ยวกับวิธีการทำเช่นนี้เสมอ ฉันหวังว่าจะมีไฟล์.gitignorelinesเพื่อให้คุณสามารถทำการเปลี่ยนแปลงในท้องถิ่นสำหรับแต่ละบรรทัดที่สามารถอยู่รอดได้และยังคงเหมือนเดิม
alex grey

3
@ReinHenrichs ให้คิดเกี่ยวกับไฟล์ปรับแต่งที่ต้องเปลี่ยนโดยนักพัฒนาแต่ละคน
เอียน

1
@Ian ดังนั้นส่วนหนึ่งของไฟล์จึงเปลี่ยนไปไม่บ่อยนักและมีการแชร์และส่วนหนึ่งของไฟล์จะเปลี่ยนแปลงบ่อย ๆ ด้วยวิธีที่ไม่เข้ากันและไม่ได้แชร์หรือไม่ การสนับสนุนความผิดพลาดที่ผิดพลาดนี้ดูเหมือนจะเป็นคุณสมบัติป้องกัน
Rein Henrichs

1
@ReinHenrichs ใช่และเป็นเรื่องปกติมากเมื่อไฟล์มีชื่อของเซิร์ฟเวอร์ฐานข้อมูลและแต่ละ dev มีฐานข้อมูลของตัวเอง
เอียน

4
@Ian ปัญหาของคุณอยู่ที่นั่นจริงๆแล้วคุณมีไฟล์ที่ควรจะเป็นโครงร่างสำหรับแอพพลิเคชั่นนั้นยังมีการกำหนดค่าเฉพาะของเครื่อง / dev ระบบการกำหนดค่าทั้งหมดที่ฉันรู้จักอนุญาตให้คุณแบ่งมันเป็นหลาย ๆ ไฟล์ ตัวอย่างเช่นคุณมีapp.confสิ่งที่คุณต้องการแชร์และสิ่งdb.confที่คุณเพิ่งใส่ในรายการ. gitignore แก้ไขปัญหา. หากคุณกำลังใช้สิ่งที่เป็นกรรมสิทธิ์คุณควรมองหาสิ่งที่ง่ายในนั้น หรือใส่ผ่านตัวประมวลผลล่วงหน้าในเหตุการณ์ที่สร้างล่วงหน้า ทางออกมากมายที่นั่น
Aidiakapi

1

ข้อดีอย่างหนึ่งที่ฉันชอบคือความสามารถในการเปลี่ยนแปลงส่วนหนึ่ง เช่นโดยใช้ git add -e ฉันไม่ได้กระทำบ่อยเท่าที่ควรและคำสั่ง git add -e ทำให้ฉันสามารถแก้ไขการเปลี่ยนแปลงได้

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