คู่มือ Git ของ Beej
(beej.us)- หน้านี้เป็นหน้าคู่มือที่จัดเตรียม ฉบับเผยแพร่แบบ HTML·PDF หลายรูปแบบ สำหรับผู้อ่านที่ต้องการเรียนรู้หรือใช้อ้างอิง Git
- ตัวคู่มือเองเปิดรับความเป็นไปได้ที่จะมี ข้อผิดพลาด และหากมีเนื้อหา Git ที่ไม่ถูกต้อง ก็รับข้อเสนอแก้ไขทางอีเมล
- ฉบับ HTML สามารถเลือกได้ตามสภาพแวดล้อมการอ่าน เช่น แบบแยกหน้า, หน้าเดียว, จอกว้าง, ZIP เป็นต้น
- PDF สามารถดาวน์โหลดได้เป็นชุดผสมของ US Letter·A4, หน้าเดียว·สองหน้า, แบบเน้นไวยากรณ์·ขาวดำ
- ผู้แปลและผู้เขียนสามารถ clone เอกสารทั้งหมดจาก GitHub แล้วทำงานตาม README ได้
รูปแบบเผยแพร่สำหรับอ่าน
-
HTML
-
PDF
ข้อเสนอการแก้ไขและเอกสารต้นฉบับสำหรับทำงาน
- คู่มือเปิดรับความเป็นไปได้ที่จะมี ข้อผิดพลาด และรับข้อเสนอแก้ไขทางอีเมล
- ผู้แปลและผู้เขียนสามารถโคลน GitHub repository และทำตาม README ได้
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ถ้าเจอส่วนที่ผิด ช่วยส่งเข้ามาได้เลย เดี๋ยวจะจัดการแก้เอง — Beej
:cqไว้ด้วย มันช่วยออกจากโปรแกรมด้วยสถานะการจบการทำงานที่ไม่ใช่ 0 ทำให้ Git ไม่สามารถทำ commit หรือจบงานนั้นได้https://beej.us/guide/bggit/html/split/branches-and-fast-for... ระบุว่า “สาขาหลักคือ main” และ “เมื่อก่อนคือ master และใน repository เก่ายังมี master อยู่” ซึ่งไม่ถูกต้อง Git ยังใช้
masterเป็นค่าปริยายอยู่ และเพียงแค่อนุญาตให้เปลี่ยนสำหรับgit initในอนาคตผ่านgit config --global init.defaultBranchเท่านั้นอ้างอิง: https://github.com/git/git/blob/bc204b742735ae06f65bb20291c9...
นอกจากนี้ คำว่า “repository เก่า” ก็ให้ภาพที่คลาดเคลื่อน GitHub เป็นผู้ตัดสินใจเปลี่ยนแปลงนี้ แล้วที่อื่นก็ค่อยทำตาม ส่วนตัว Git เองก็เพียงแค่อนุญาตการตั้งค่าข้างต้น ดังนั้นมันไม่ใช่เรื่องของ repository ใหม่/เก่า แต่ใกล้เคียงกับเรื่องของความนิยมมากกว่า
มันเป็นวิธีที่ดีในการทำให้แต่ละสาขาไม่พันกันโดยไม่ต้องวุ่นวายกับ stash
Beej's Guide to Network Programming และ Beej's Guide to Unix IPC ที่อ่านตอนเป็นวัยรุ่นนั้นทั้งเข้าถึงง่ายและลึกซึ้ง และมีอิทธิพลอย่างมากต่อการที่ฉันกลายมาเป็นโปรแกรมเมอร์แบบทุกวันนี้
[0] https://beej.us/guide/bgnet/
[1] https://beej.us/guide/bggit/
ฉันซื้อ Slackware Linux unleashed มือสองที่แถม CD-ROM มาด้วย ซึ่งมีตัวอย่าง C networking อยู่ แต่โค้ดพวกนั้นทำให้งง เลยไปเจอเว็บไซต์ด้าน networking ของ Beej จากนั้นก็ยิ่งอินและดำดิ่งลึกลงไปอีก และมักจะเดินหาหนังสือโปรแกรมมิงตามร้านหนังสือต่าง ๆ
หลังจากซื้อหนังสืออ้างอิงชั้นยอดของ Richard Stevens แล้วก็ไม่หันกลับไปมองอีกเลย และทุกวันนี้ก็ยังขอบคุณ Beej ที่ทำให้ความหลงใหลนั้นเกิดขึ้นได้
selectฉันอยากทำให้พอร์ตสแกนเนอร์ตัวหนึ่ง (น่าจะชื่อ “grabb”?) เร็วขึ้น เลยแปล คู่มือเครือข่ายของ Beej เป็นภาษาอิตาลี เป็นช่วงเวลาที่สนุกมากเป็นยุคที่ต้องเซฟหน้าเว็บไว้อ่านออฟไลน์เพื่อไม่ให้พ่อโกรธเรื่องค่าโทรศัพท์ และเมื่อโค้ดทำงานได้ มันให้ความรู้สึกเหมือนได้รับการยืนยันที่อยู่เหนือความล้มเหลวและการถูกปฏิเสธก่อนหน้านั้น ความสุขจากการส่งข้อความจากคอมพิวเตอร์เครื่องหนึ่งไปอีกเครื่องหนึ่งนั้นยิ่งใหญ่มาก
พอเห็นคำว่า “คำสั่งแบบเก่า:
git checkout” ก็เพิ่งรู้ด้วยซ้ำว่ามีgit switchและไม่เคยรู้ว่าgit checkoutถูกมองเป็นตัวเลือกแบบเก่าแล้ว รู้สึกแก่เลยก็พอเข้าใจได้เพราะฉันเริ่มเรียน Git เกือบ 10 ปีที่แล้ว แต่ก็ยังรู้สึกแปลกที่คนซึ่งเพิ่งเรียน Git ตอนนี้อาจสงสัยว่าทำไมฉันถึงใช้
git checkoutมันเหมือนใช้สำนวนแบบคนรุ่นก่อนกลับมาที่เนื้อหา คู่มือนี้น่าจะมีประโยชน์มากถ้ามีอยู่ตอนที่ฉันเริ่มเรียน มันตามได้ง่ายและตอบคำถามที่พบบ่อยได้ดี
ยังจำได้ดีว่าหลังจากตกใจกับ merge conflict ครั้งแรกแล้วก็ยกเลิก จากนั้นก็พยายามอ้อมหลีกเลี่ยง conflict อยู่พักหนึ่ง
git switchเป็นคำสั่งที่ค่อนข้างใหม่ และปล่อยออกมาครั้งแรกในปี 2019มีทั้งกระทู้คุยกันในปี 2021 และอีกกระทู้เมื่อไม่กี่สัปดาห์ก่อน โดยกระทู้หลังยังพูดถึงด้วยว่าในเอกสาร
git switchยังถือเป็น ฟีเจอร์ทดลอง อยู่https://news.ycombinator.com/item?id=28024972
https://news.ycombinator.com/item?id=42649858
git checkoutยังถูกมองว่าเป็น “ตัวเลือกแบบเก่า” ตอนที่ฉันเช็กล่าสุดswitchยังเป็นของทดลองอยู่ และฉันก็ไม่คิดจะเลิกใช้ workflow กับคำสั่งที่เรียนมาตั้งแต่เริ่มใช้ Git เมื่อราว 15 ปีก่อนทุกอย่างที่อยากทำก็ยังทำงานเหมือนเดิม
git checkoutก็ยังทำหน้าที่เดิมเหมือนเมื่อก่อน และก็ไม่มีปัญหาในการทำงานร่วมกับคนอื่นผ่าน Git ดังนั้นจึงไม่มีเหตุผลจำเป็นที่จะต้องเปลี่ยน workflowการที่ต้องมี คู่มือมากกว่า 30 ตอน เพื่ออธิบายวิธีใช้ Git เอง ก็ให้ความรู้สึกเหมือน Git พลาดภาพใหญ่ไป
commit คือ snapshot ของ tree และมีรายการบรรพบุรุษ โดยปกติมีหนึ่งรายการแต่ไม่เสมอไป tag คือป้ายชื่อคงที่ของ commit และ branch คือป้ายชื่อที่เปลี่ยนได้ของ commit ส่วน index คือ proto-commit ขนาดเล็กที่กำลังอยู่ระหว่างทำ ซึ่งคุณเติมมันด้วย
addก่อน commitนี่แหละคือ Git ถ้าอยากรู้อะไรเพิ่มก็ไม่ต้องอ่านคู่มือ ให้ค้นหาประมาณว่า “วิธีสลับไปยัง Git commit ที่กำหนดโดยไม่กระทบ tree”, “วิธี commit แค่บางส่วนของไฟล์ที่แก้ไข”, “วิธีคัดลอก commit จากที่อื่นมาไว้ใน tree ปัจจุบัน”
abstraction พื้นฐานนั้นเรียบง่ายแบบมินิมอลและเข้าใจง่าย สิ่งที่คุณอยากทำด้วย abstraction นั้นต่างหากที่ประณีตและซับซ้อน เรียนอย่างแรกแล้วค้นหาอย่างหลังเอาก็พอ ไม่จำเป็นต้องอ่านคู่มือ
git clone,git checkout,git pull,git add+commit+push,git reset/rebaserebase -iมีคำอธิบายกำกับว่าแต่ละคำสั่งทำอะไรอยู่แล้ว และการจัดรูปแบบผลลัพธ์ของgit logให้เข้ากับรสนิยมและจุดประนีประนอมของตัวเองก็อธิบายได้ในไม่กี่ย่อหน้า โดยทั่วไปคำสั่งฝั่งผู้ใช้มักนับรวมของค่อนข้างปะปนอย่างgit gc,git fsck,git rev-parseด้วยคำสั่งระดับล่างนั้นอ่านยากกว่าแน่นอน และยังทำสิ่งต่าง ๆ ได้เองอีกมากที่คำสั่งฝั่งผู้ใช้ซึ่งปรับมาเพื่อกรณีใช้งานทั่วไปไม่ได้ทำให้สะดวกเสมอไป
สรุปคือ Git ใหญ่ และถึงขั้นใหญ่มากด้วยซ้ำ แต่สำหรับนักพัฒนาส่วนใหญ่ ความสามารถจำนวนมากของมันอยู่ไกลจากเส้นทางใช้งานหลักมาก
สิ่งที่น่ากลัวคือคู่มือนี้ยาวขนาดนี้
รู้ว่าโดยทั่วไปคู่มือของ Beej มักครอบคลุมมากอยู่แล้ว แต่ยังไม่เคยรู้สึกถึงความกว้างใหญ่และความละเอียดอ่อนของ Git ได้ชัดเท่านี้มาก่อน
ถ้าเป็น Jujutsu ก็น่าจะเป็นคู่มือที่บางกว่านี้มาก หรืออย่างน้อยก็เป็นคู่มือที่คนค่อย ๆ ค้นพบและเรียนรู้ได้ง่ายกว่า
ฉันรู้สึกว่าคู่มือนี้ครอบคลุม Git แค่ราว 10% แต่หวังว่าจะครอบคลุม 90% ของการใช้งานทั่วไป
ที่ทำงาน ฉันสอนคอร์ส Git data model เบื้องต้น ความยาว 2 ชั่วโมง ปีละครั้งหรือสองครั้ง
ผมเข้าไปดูในไดเรกทอรี
.gitจริง ๆ แล้วแกะไฟล์ให้ดู เพื่อแสดงให้เห็นว่าทุกอย่างเป็นเพียง representation แบบ plain text ของโครงสร้างข้อมูลพื้นฐานเท่านั้น การได้เห็นจังหวะที่คนเข้าใจมันขึ้นมาในหัวทันทีนั้นยอดเยี่ยมมากเราแชร์เอกสารสูตรสำเร็จ Git พื้นฐานให้พนักงานใหม่เพื่อให้เริ่ม commit โค้ดได้ แต่คนส่วนใหญ่ก็แค่ทำตามโดยไม่เข้าใจว่าเกิดอะไรขึ้น
ในทางกลับกัน คนที่เรียนคอร์สนี้ แม้จะไม่ได้รู้คำสั่งทั้งหมด ก็มีความเข้าใจเชิงปฏิบัติที่ค่อนข้างสมเหตุสมผลว่าเกิดอะไรขึ้นจริงใน Git คำสั่งค้นหาได้ง่ายอยู่แล้ว ดังนั้นถ้า mental model ถูกต้อง ตัวคำสั่งเองก็ไม่ใช่ปัญหาใหญ่ แต่ถึงอย่างนั้น การถกเถียงเรื่อง Git บน HN แทบทั้งหมดก็มักไหลไปเป็นเรื่อง command line
น่าสนใจที่คอร์สนี้ฟังดูคล้าย alt text ของ https://xkcd.com/1597/ ความต่างคือสำหรับผู้อ่านสายเทคนิค นั่นคือวิธีที่ถูกต้องในการสอน Git จริง ๆ และเมื่อเข้าใจแล้ว คุณจะได้ความเข้าใจพื้นฐานที่ไม่ลืมง่าย
พูดตามตรง มันให้ผลตอบแทนต่อเวลาสูงมากจนผมมองว่าแปลกถ้าไม่ทำ
ในสไลด์สุดท้ายของการนำเสนอ ฉันใส่คำถามให้เพื่อนร่วมงานตอบโดยอิงจาก Git data model เช่น “สามารถย้าย commit ไปยัง branch อื่นได้หรือไม่?”, “อะไรเป็นตัวรับประกันว่าไม่มีวงจรใน commit graph?”
มันน่าพอใจมากที่เห็นผู้คนไม่ได้แค่ใช้ Git แต่เริ่ม คิดแบบ Git
โชคดีที่ช่วงแรกฉันได้ดูวิดีโอที่อธิบายโมเดลภายในของ Git บางส่วน และพบว่าในความเป็นจริงไม่จำเป็นต้องมีความรู้ภายในมากหรือลึกขนาดนั้นก็สร้างความแตกต่างได้มาก แค่รู้สัก 5% ของวิธีทำงานของ Git ก็ช่วยให้เข้าใจมากขึ้นมากว่าคำสั่งทำอะไรและควรใช้อย่างไร
ถ้ามีเป็นสาธารณะและกระชับพอจะใส่ใน 2 ชั่วโมงได้ ก็คงดีถ้าแชร์ในเธรดนี้หรือเป็นโพสต์ HN ผมเชื่อว่ายิ่งมีสื่อการเรียนรู้หัวข้อเดียวกันที่มีสมมติฐาน อุปมา และจุดเน้นต่างกันมากเท่าไร ก็ยิ่งดี
ผมพอทำเรื่อง workflow ทั่วไปของ Git, merge, rebase และอื่น ๆ ได้อยู่บ้าง แต่แทนที่จะพยายามให้เก่ง Git ขึ้น ผมกำลังคิดอย่างจริงจังว่าจะย้ายไปใช้ jujutsu ดีกว่า
jjเข้ากันได้กับ Git และผมก็สามารถใช้มันคนเดียวได้ในขณะที่เพื่อนร่วมงานยังใช้ Git ตามปกติรู้สึกว่ามีเคล็ดลับอย่างหนึ่งที่ไกด์หลายอันและ Git GUI ส่วนใหญ่มักมองข้ามไป โดยมีข้อยกเว้นคือ magit ที่จัดการเรื่องนี้ได้ดี
นั่นคือการตั้งค่า upstream branch ให้เป็นเป้าหมายที่จะ merge เช่น
masterหรือorigin/masterแทนที่จะเป็นorigin/feature/fooของfeature/fooแบบนี้จะทำให้หลายอย่างง่ายขึ้นมาก เวลารัน
git statusก็จะบอกได้ว่ามันแยกจาก integration branch ไปมากแค่ไหน ซึ่งมีประโยชน์ และถ้ารันgit rebaseแบบไม่ใส่อาร์กิวเมนต์ ก็จะ rebase ขึ้นไปบน upstream ได้ทันทีการตั้ง
origin/feature/fooเป็น upstream มีประโยชน์น้อยกว่า เพราะโดยทั่วไปนักพัฒนาก็มัก “เป็นเจ้าของ” branch ของตัวเองบน remote อยู่แล้ว จึงไม่ค่อยมีความหมายว่ามันแยกจากตรงนั้นไปแค่ไหน และก็ไม่ค่อยมีเหตุผลที่จะอยาก rebase ไปที่ตรงนั้นถ้าตั้ง
push.defaultเป็น"current"แล้วgit pushก็จะ pushfeature/fooไปที่origin/feature/fooตามที่คาดไว้ด้วยเลยสงสัยว่าทำไมการตั้งค่าแบบนี้ถึงไม่เป็นที่นิยมกว่านี้
ในส่วนการทำงานร่วมกันไม่ได้พูดถึง feature branch เลย ทั้งที่น่าจะเป็นรูปแบบการทำงานที่พบได้ค่อนข้างบ่อย
น่าจะมีประโยชน์ถ้าเอามาเทียบกับแนวทาง “ทุกคนใช้ branch ของตัวเอง” ที่อยู่ในไกด์ และในข้อ 17 ก็น่าจะพูดถึงทั้งการ reuse branch สำหรับ GitHub pull request กับการสร้าง branch ใหม่สำหรับแต่ละ PR ด้วย
ยังไม่ได้ตรวจบทความ แต่คิดว่าน่าจะดี อีกคำแนะนำหนึ่งคือคอร์ส Git ของ boot.dev ที่ Primeagen เป็นคนสอน
เป็นคอร์สแบบ interactive และลงลึกถึงระดับที่ให้แก้ไขไฟล์ในไดเรกทอรี
.gitโดยตรงเลย หลังจากเรียนคอร์สนั้นแล้ว ก็ทำให้มี mental model แบบใหม่หมดจด เกี่ยวกับการทำงานของ Git