ฉบับอนุบาล ๒ @AorJoa
Jun 27, 2015
ฉบับอนุบาล ๒
@AorJoa
สารบัญ เรื่อง หนา
Chapter 1 : Introduction
1.1 เครื่องมือควมคุมตนรหัสขอมูล (Version Control System : VCS) 1
Local Version Control System : LVCS 1
Centralized Version Control System : CVCS 2
Distributed Version Control System : DVCS 3
1.2 ประวัติของ Git 4
1.3 การทำงานของ Git 6
Chapter 2 : Git basic
2.1 ศัพทแสง 16
2.2 คำส่ังพื้นฐานของ Git 18
Chapter 3 : Installation 3.1 Windows 29
3.2 Mac OS X 36
3.3 Others operating system 38
Chapter 4 : Git scenario สถานการณที่ 1 : มือใหม มึนตึ๊บ !@#%!@ 39
สถานการณที่ 2 : ฝากไวใน Remote repo เธอ 44
สถานการณที่ 3 : กลับมาเหมือนเดิมนะ,,ขอมูล 50
สถานการณที่ 4 : เจอ Conflict 53
สถานการณที่ 5 : เพิ่ม Alias ยอคำสั่งใหใชงายๆ 55
สถานการณที่ 6 : Fast Forward กับ 3way Merge 55
สถานการณที่ 7 : จัดการ Branch 56
สถานการณที่ 8 : แกไข Commit หรือ History 58
สถานการณที่ 9 : ดู Difference 60
สถานการณที่ 10 : งานหาย แกไดดวย Reflog 62
สถานการณที่ 11 : Optimize 63
สถานการณที่ 12 : Stash ซอนการแกไข 63
สถานการณที่ 13 : ติด Tag ให Commit 65
สถานการณที่ 14 : ignore ไฟล 65
Workflow 66
Fork และ Pull Request 69
Chapter 5 : Git GUI ตัวอยางการใช 72
Chapter 6 : บรรณานุกรม บรรณานุกรม 76
คนเขียน 77
หนา 1
Chapter 1 : Introduction
Git เปนหนึ ่งในหลายเครื่องมือควบคุมตนรหัสขอมูล (Version control) ซึ่งทำหนาท่ีจัดเก็บการ
เปลี่ยนแปลงขอมูลในไฟลขอมูล ทำใหผูใชงานสามารถเรียกขอมูลกอนที่มันจะถูกแกจนเละหาทางไปตอไมถูก กลับ
มาไดในระดับไฟลหรือกระแมแตโฟลเดอร ยิ่งกวานั้นมันยังสามารถระบุไดวาใครทำมันเจงและทำไปตอนไหน ดังนั้น
เราจะมาทำความรูจักกับ Version control กันซะกอน จะไดรูวามันคืออะหยัง?
1.1 เครื่องมือควมคุมตนรหัสขอมูล (Version Control System : VCS)
อยางที่บอกไปแลวขางตน วา Version control (ชื่ออื่นเชน Revision control, Source control) คือตัว
ควบคุมตนรหัสขอมูล ซึ่งขอมูลในที่นี่ก็หมายความรวมไปถึงทุกอยางที่อยูในรูปแบบของรหัสคอมพิวเตอร เชน
ขอความ รูปภาพ โปรแกรม เพลง ( & Something like that) โดย Version control จะทำใหท่ีเก็บขอมูล เปนการ
สำรองขอมูลใหกับไฟลหรือโฟลเดอรที่เราตองการ รวมทั้งบอกไดวาใครเปนคนแกไข แกไขเวลาไหน รวมถึงความ
แตกตางระหวางกอนแกไขและหลังแกไขไฟล ซึ่งคุณสมบัติเหลาน้ีทำใหเราไมตองปวดหัวกับการตองกอปป ไปไวใน
โฟลเดอร Backup แลวเปลี่ยนชื่อเรียงตามวันที่ซึ่งเปนวิธีที่เซาะกราวดมากๆ (ขอเสียคือเจานายจะรูวาเราแอบอูงาน)
ซึ่ง Version control ก็จะแบงเปน 3 ประเภทใหเลือกใช คือ Local, Centralized และ Distributed
Local Version Control System : LVCS
จากโปรแกรมเมอรยุคดึกดำบรรพที่ตอง
กอปปโคดไปไวในโฟลเดอร Backup กอนท่ีจะ
แกไขไฟล ทำใหโปรแกรมเมอรคิดวามันไมนาจะ
เวิรคแลว จึงมีการพัฒนาฐานขอมูลงายๆ เพื่อใช
เก็บขอมูลในเคร่ืองของโปรแกรมเมอรเอง ระบบที่
ดังมากคือ Revision Control System : RCS ท่ี
ริเริ่มพัฒนาโดย Walter F. Tichy โปรแกรมเมอร
ชาวเยอรมัน ระบบ RCS จะติดมากับ Developer
Tools ของ Mac OS X เพื่อสำรองขอมูลกอนการ
อัพเดท Patch ซึ่งหากไมสำเร็จมันก็จะเรียกขอมูล
กอนหนาซึ่งทำงานไดปกติมาใช
หนา 2
Centralized Version Control System : CVCS
จากโปรแกรมเมอรในยุค Local Version Control ที่สามารถสำรองไดเฉพาะบนเครื่องตัวเองจึงเหมาะกับ
การทำงานแบบฉายเดี่ยวซะมากกวา แลวถาเรามีทีมงานหลายคนที่ตองชวยกันรุมปูยี้ปูยำโปรเจกนี้ก็จะเกิดปญหา
เรื่องการใชงานรวมไฟลรวมกันขึ้น เพื่อแกปญหาวาถาเพื่อนเราแกไฟล เราก็ไมตองเอา USB Drive ไปเสียบกอป
ขอมูลออกมา เพราะกวาจะครบทุกคนก็แกกันหมดพอดี แตเราจะใชวิธีใหคนที่ทำเสร็จแลวสงขอมูลไปเก็บไวท่ี
Server กลาง ซึ่ง Server กลางตัวนี้ก็ทำหนาที่สำรองขอมูลไวดวย ถาใครอยากไดขอมูลรุนไหนก็มาดึงเอาจาก
Server ตัวนี้ได ซึ่งขอมูลที่อยูใน Server กลางโดยทั่วไปแลวจะเปนรุนที่ใหมลาสุดและทดสอบวาใชงานไดแลว (ควร
ทดสอบวามันรันไดจริงๆกอนท่ีจะสงขอมูลขึ้นไป ไมง้ันอาจจะโดนดาผูปกครองเอาได)
ระบบแบบนี้มีขอดีคือการทำงานรวมศูนยไวที่เดียวกัน คนที่เปน Project manager ก็ดูไดงายวาทำงานกันไปถึงไหน
แลว ไฟลขอมูลก็จะใหมอยูเสมอ และทุกคนสามารถมีไฟลขอมูลที่เหมือนกันไดงาย เพียงแคใหคนที่ตองการใชดึง
ไฟลขอมูลจาก Server ไปไวในเครื่องของตัวเอง แตขอเสียก็คือหาก Server มีปญหาหรือเราไมไดเชื่อมตอกับเครือ
ขาย จะไมสามารถสงขอมูลขึ้นไปหรือดึงขอมูลลงจาก Server ได และถา Harddisk พังก็จะมีไฟลสำรองแคท่ีอยูใน
เครื่องแตละคนเทาน้ัน (Server ขอมูลหายแต Client ขอมูลยังอยู) ขอมูลที่หายไปจาก Server นั้นรวมท้ัง Log
ประวัติการแกไขไฟลตางๆ ก็จะหายไปดวย (มีเก็บแคใน Server เทาน้ันจาา ถาขอมูลที่ Server หายก็ตัวใครตัวมัน)
โดย Version control ที่ใชการเก็บขอมูลแบบ Centralized หรือรวมศูนยนี้ก็เชน CVS, SourceSafe,
Subversion, Team Foundation Server
หนา 3
Distributed Version Control System : DVCS
จากขอเสียหลักๆของ Centralized Version Control System ที่ถาเกิดเครื่อง Server พังหรือหากเรา
เดินทางอยูไมสามารถเชื่อมตอกับเครือขายได ก็จะไมสามารถทำงานได ดังนั้นจึงมีคนคิดคนระบบ Distributed หรือ
แบบกระจายศูนยขึ้นมาแกปญหา เพราะระบบนี้จะไมดึงหรือสงเฉพาะไฟลขอมูลจาก Server ไปเทานั้น แตจะกอปป
ฐานขอมูลรุนแบบเดียวกับที่มีอยูใน Server ไปดวยเพื่อที่วาถา Server มีอันเปนไปหรือเราไมสามารถเช่ือตอเครือ
ขายกับ Server ไดเราก็ยังจะสามารถทำงานไดและยังสามารถเก็บรุนของไฟล พรอมท้ังประวัติการแกไขและเวลาไว
เสร็จสรรพ โดยที่เราไมจำเปนตองมี Server ดวยซ้ำไป จึงทำใหเราไมมีขออางวาไฟลหายกอนสงงานไดอีกตอไป (เย
T___T)
และระบบนี้สนับสนุนใหมีการทำงานแบบหลายทีมในโปรเจกเดียวกัน เชน Team A เห็นงานฟเจอรลับ สวน Team
B ไมเห็น หรือโปรแกรมเมอรก็ไมตองรอใหกราฟฟกดีไซนวาดภาพเสร็จ แคดราฟมากอนก็จะมีไฟลในระบบ
โปรแกรมเมอรก็สามารถเรียกใชไดและหากกราฟฟกดีไซนแกไขภาพแลวสงข้ึน Server กลาง แลวเมื่อเราดึงขอมูล
ใหมลงมาก็จะไดรูปที่แกไขแลวไดเลยงายๆ แถมความเร็วเขาถึงขอมูลยังสูงเวอร เพราะในขั้นตอนการทำงานปกติมัก
จะทำงานที่ฐานขอมูลรุนภายในเครื่องเราเอง ตางกับระบบ Centralized ที่ตองวิ่งไปถามท่ี Server กอน ตัวอยาง
ระบบที่ใชงานแบบกระจายศูนยก็เชน Git (พระเอกของเรา), BitKeeper(ตัวราย), Mercurial, Bazaar หรือ Darcs
หนา 4
1.2 ประวัติของ Git
กาลครั้งหนึ่งนานมาแลวตอนพัฒนา Linux kernel ใหมๆ ประมาณป
ค.ศ. 19912002 Linus Benedict Torvalds คนตนคิดสราง Linux
kernel ก็ใชวิธีสง Patch ไฟล ไมงั้นก็สงไฟลซิป Source code กันไป
มาระหวางโปรแกรมเมอร (เราเรียกวิธีน้ีวา Tarball) ใครแกอะไรไดก็สงมา
ให Linus เพิ่มใน Linux kernel รุนดั้งเดิมท่ีเขาสรางขึ้นมาเพื่อใหคน
หลังๆ ที่ตองการใชจะไดมาโหลดรุนของ Linus ซึ่งไดรับการเพ่ิมฟเจอร
หรือ Patch แกบ๊ักไปแลวเน่ียแคศูนยกลางเพี่ยงท่ีเดียว แตพอโปรเจก
ขยายตัวขึ้น Linus ก็ไดรับ Patch และ Source code เปนรอยเปนพันชุด
ซึ่งทำใหจัดการไดยาก แถมยังไมรูวา Patch ที่สงมาพอเอาไปรวมกับของที่
มีอยูแลวมันจะยังทำงานไดถูกตองหรือเปลา ดังนั้นในป 2002 จึงไดเริ่ม
เอา DVCS ที่ชื่อวา BitKeeper ซึ่งเปนทรัพยสินทางปญญาของบริษัท
BitMover มาใช โดยตัว BitKeeper เองเปน Commercial software แต
Larry McVoy ซึ่งเปน CEO ของ BitMover อนุญาตใหนักพัฒนา Open
source สามารถใชไดฟร ี
แตใชไปไดชวงหนึ่งจนถึงป 2005 ปญหาก็เกิดขึ้นจาก Andrew Tridgell (มักจะถูกเรียกวา "Tridge") คน
สรางระบบจัดการทรัพยากรในเครือขาย Samba นั้นไดสรางระบบติดตอกับ BitKeeper ในสวนท่ีเก็บขอมูล ซึ่งเปน
Open source ขึ้นมาใหมชื่อวา SourcePuller แทนที่จะใช BitKeeper
client ซึ่งเปนของเสียตังค (แตไดใชฟรีเพราะ Larry McVoy อนุญาต)
Tridge ถูกกลาวหาวาเขาใชวิธี Reverseengineered เพื่อดูการทำงาน
ของ BitKeeper ดังนั้น Larry จึงโมโหบอกวา Tridge ไมไดจายตังคซื้อ
ซอฟแวร และใครที่ไมซื้อซอฟแวรก็ไมมีสิทธิ์ที่จะไดดู Metadata ของซื้อ
ของขาย จบปะ? Tridge ก็สวนกลับวามันไมไดผิดกฏนะเออที่จะด ู
Metadata เพราะ BitKeeper และ SourcePuller ตางก็ใชฟรีเหมือนกันแตสรางขึ้นมาปนทางเลือกใหผูใช แถมไอ
Metadata เนี่ยชาวบานชาวชองเขาก็ไมไดปดกันหรอก บางที่สนับสนุนกันดวยซ้ำและวิเคราะหแค Telnet เขาไป
BitKeeper server แลวสั่งคำสั่ง HELP เทานั้นและเขาก็ไมเคยใช BitKeeper client ดวย ยังไงก็ยืนยัน นั่งยัน นอน
ยัน ตีลังกายัน วาทำถูกกฏหมายและอยูในศีลธรรมอันดี สวนปา Linus ก็ไมเห็นดวยกับการกระทำของ Tridge ถึง
กับบอกวาเปนวิธีการที่ Tridge ทำเปนวิธีที่สกปรก และก็ขอให Tridge หยุด แตตัว Tridge ตนเหตุก็ยืนกรานวาสิ่งที่
เขาทำถูกตองแลว Larry จึงบอกวาถางั้นก็ไมตองชงตองใชมันแหละ ใหเวลา 3 เดือนในการเอาโปรเจกออกไปจาก
หนา 5
BitKeeper server ซะ ถึงตอนนี้ใครที่ดา Tridge อยูก็ตองคิดถึงในแงอื่นดวยนะครับ Linus เปนคนเริ่มก็จริงแตก็
ตองฟงเสียงของ Community ดวยเพราะการจะพัฒนาของที่เปน Open source จากของที่ติด License อื่นเนี่ย
Community ไมคอยเห็นดวย (ถึงมันจะเปน Tools ที่ดีมากๆ อยาง BitKeeper ก็ตาม)
Linus บอกวาเขามักตั้งชื่อ Project ตามสิ่งที่เขาเปนเหมือนกับชื่อระบบปฏิบัติการ Linux และ Git ก็เปน
ศัพทแสลงที่หมายความวา “คนโงหัวแข็ง” , “คนที่ไมเปนที่นาพอใจ”, “คนนารังเกียจ” หรือ “พวกคนท่ีคิดวาตัว
เองถูกอยูตลอดเวลา” สวนคำวา Git ยอมากจากอะไรนั้นขึ้น
อยูกับอารมณมันจะยอมาจาก “Global information
tracker” ตอนที่อารมณดีๆ หรือ "Goddamn idiotic
truckload of sh*t" ตอนที่มันเจง (แนวประชดกลายๆ)
Linus จึงมองหา Version control ที่จะใชงานที่มี
ใหใชไดฟรีๆ แตก็ไมเห็นที่เหมาะกับ Linux kernel เลย
จำเปนตองสราง Version control ขึ้นมาเองโดยใชประสบการณจาก BitKeeper มาปรับปรุงใน Version control
ตัวใหมซึ่งตองมีคุณสมบัติดังนี ้
ความเร็วสูง
สนับสนุนการแยกพัฒนาหลายๆทาง (แตก branch ไดหลักพันเปนอยางนอย)
ทำงานแบบ Distributed Version Control System
ทำงานกับโปรแจกใหญๆไดดีเชน Linux kernel (ทั้งความเร็วและปริมาณขนาดขอมูล)
โปรเจกเริ่มสราง Git เริ่มเมื่อ 3 เมษายน 2005 พัฒนาโดยภาษา C,Shell script และ Perl, ประกาศวันท่ี 6
เมษายนให Git เปนโปรเจก Open source โดยใชสัญญาอนุญาตแบบ GNU GPL version 2 หลังจากนั้นเร่ิม
Selfhosting (ใชตัว Git เองดูแล Source code ของ Git เอง) ในวันที่ 7 เมษายน, สามารถรวม Branch ที่แตก
ออกมาไดในวันที่ 18 เมษายน และไดประสิทธิภาพตามที่คาดหวังในวันที่ 29 เมษายน (ทำ Patch Linux kernel
Tree ไดในเวลา 6.7 วินาที) หลังจากนั้นในที่ 26 กรกฏาคม 2005 Linus ให Junio Hamano เปนคนดูแล Git ตอ
หนา 6
1.3 การทำงานของ Git
ถึงแมวา Version control จะมีหนาที่เหมือนกันแตมันไมได ทำงานเหมือนกันทั้งหมดทุกตัว (ไมงั้นเขาจะมี
หลายๆตัวทำแมวอะไร) และตัว Version control มักจะเก็บขอมูลแบบเพิ่มพูน (ไมลบของที่เก็บไวแลวแตเพิ่มของ
ใหมเขาไปเรื่อยๆแทน) ดังนั้น Git ก็จะโตขึ้นเรื่อยๆ
การเก็บขอมูล
ใน Version control อื่นๆที่ทำงานคลายกันเชน CVS, Subversion, Perforce, Bazaar จะมองการเก็บ
ขอมูลเปนแบบความแตกตางกันของขอมูลในไฟล ดังนั้นการเก็บขอมูลแบบนี้ตองเก็บขอมูลกอนหนามันเอาไวตาม
ลำดับดวยถึงจะทำงานไดถูกตอง เรียกวา Delta Storage ( Δ คือคาผลตาง หรือ Differences ของไฟลนั่นแหละ)
การเก็บขอมูลแบบนี้ถามีไฟลอยู 3 ไฟลตามรูปตัวอยาง เม่ือเรา Commit (สราง Version น่ันเอง) ใน
Commit 1 จะเก็บขอมูลทั้งหมดในไฟล A,ฺ ไฟล B และไฟล C ไว
Commit 2 จะเก็บขอมูลที่แตกตางกันเทาน้ัน (เพราะมีไฟลเดิมอยูแลว) หากเรามีการแกไฟลขอมูลที่แตกตางก็คือ
Δ A และ Δ B สวนไฟล C นั้นไมมีการแกไขจึงไมมี Δ หรือขอมูลท่ีแตกตางกัน ดังนั้น ไฟล C (วงกลมเขียว C ) จึง
จะเปน Pointer ชี้กลับไปที่ไฟล C ตัวหลัก ใน Commit 1
Commit 3 ไฟล A ไมมีการแกไข ขอมูลก็ยังเหมือนเดิม ดังนั้นจึงมี Pointer ชี้ไปท่ี Commit กอนหนา ซึ่งก็คือ
Commit 2 สวนไฟล B มีการเปล่ียนแปลงก็ทำงานตามปกติ และสุดทายไฟล C นั้นจากเดิม Commit 2 ไมมีการ
แกไข แตใน Commit 3 มีการแกไขเปน Δ C จึงมี Pointer ชี้กลับไปที่ Commit กอนหนา (ก็ Commit 2 นั่น
แหละ) แตที่ Commit 2 บอกวาที่มันไมมีอะไร ไมไดแกอะไร งั้นก็ไปตามที่ Pointer ตอไปเลย ดังนั้น Δ C จะมี
ขอมูลกอนหนาคือไฟล C ใน Commit 1 เพราะเปนไฟลท่ี C วงกลมเขียวชี้ Pointer ไป
หนา 7
หากมีการดำเนินการแกไขไฟลแบบพิเศษ เชนแกไขชื่อไฟล ลบไฟลหรือกอปปใน Commit ไหน ตัว Commit นั้นก็
จะมีอางอิงไปไฟลกอนหนาดวยคาคำส่ังพิเศษที่บอกความแตกตางกับระหวางตัวที่เรากำลัง Commit และ Commit
กอนหนามัน
(Note : ใน Commit 3 Origin.c ถูก Rename ไปแลว แตใน Commit 4 กอปปมาเปนอีกไฟลเลยมองเห็นในตำแหนงปจจุบัน)
นอกจากการเก็บไฟลแบบ Delta storage แลวก็ยังมีการเก็บไฟลอีกแบบหนึ่งที่เรียกวา Snapshot
storage การเก็บไฟลของระบบ Snapshot storage มองไฟลที่ถูกแกไขเปน Snapshot ใหม (แบบ Delta มองวา
เก็บไวแคความเปลี่ยนแปลง) ดังนั้นใน Snapshot storage ขอมูลก็คลายๆเปนไฟลอีกไฟลหนึ่งเลย เวลาตองการ
Revision กลับไปรุนกอนระบบก็จะไปหา Snapshot หรือ Snapshot ที่ถูก References ไปเพราะไมไดถูกแกใน
Commit นั้น แตในสวนของ Delta storage แบงการยอนเวอรชั่นเปนสองสวนคือแบบ Reverse delta และ
Forward delta ตัวอยางน้ีสมมุติวามีไฟลอยู 4 เวอรชั่น และกำลังจะทำเวอรชั่นที่ 5 (ยังไมได Commit) แตอยาก
กลับไปเวอรชั่น 2
Reverse เปนการถอยจากตำแหนง File ปจจุบันที่เราทำงานอยูวาตางจากเวอรชันกอนหนา
Forward เปนการเริ่มว่ิงจาก File ตงตน เพิ่ม Delta ในแตละรุนไลมาจนถึงรุนที่ตองการ
หนา 8
จากรูปจะเห็นวา
ในรูปมี 3 ไฟล คือ ไฟล A , ไฟล B และไฟล C
Commit 1 จะเปน Commit เริ่มตนเก็บขอมูลในไฟลเปนรุนแรก ซึ่งขอมูลที่เก็บไวเราจะเรียกวา Snapshot ซ่ึง
เหมือนภาพถายที่มีขอมูลในไฟลที่แกไวครบถวนโดยที่ไมตองอางอิง Snapshot หรือไฟลกอนหนามัน ก็คือ A1,B1
และ C1
Commit 2 จะเห็นวาถามีการแกไขไฟล A และ ไฟล B ระบบจะเก็บ Snapshot ไวทั้งไฟลไว จึงได A2 และ B2
สวนไฟล C ที่ไมมีการแกไขก็จะมี Reference ชี้ไปที่ Snapshot ของ C1
Commit 3 ไฟล A ไมมีการแกไขดังนั้นจึงมี Reference ชี้ไปที่ Snapshot ของ A2 ซึ่งเปนตัว Snapshot ลาสุด
โดยไมตองวิ่งไปถึง A1 สวนไฟล B และไฟล C ถูกแกไข เลยได Snapshot ตัวใหมคือ B3 และ C2 ขึ้นมา
ถึงตอนนี้เราก็ทราบกันแลววาการเก็บขอมูลแบงออกเปน 2 แบบใหญๆ คือ Delta storage และ
Snapshot storage ระบบ Git จะใชงาน Storage แบบ Snapshot เปนหลัก (แต Git ก็มีบางคำสั่งเชน git pack
เพื่อลดขนาดไฟลเหมาะกับการเก็บไวในระบบสำรอง ซึ่งเปนการเก็บไฟลแบบ Delta ได)
หนา 9
ระบบ Git Snapshot จะนำไฟลไปเขาฟงกชัน Hash ที่ช่ือวา SHA1 (ชื่อเลนวาชาละวัน) ขนาด 160 Bits
ซึ่งตัว SHA1 จะนำขอมูลไปปูยี้ปูยำแลวใหคาออกมาคาหนึ่งความยาว 40 ตัวอักษร (09 และ af) เรียกวา
Checksum ซึ่งเมื่อมีขอมูลเปลี่ยนไป คา Checksum ของมันก็จะเปล่ียนตามไปดวย ถึงแมขอมูลจะตางกันแคบิท
เดียว Checksum ก็จะสามารถระบุความแตกตางได ดังนั้นมันจึงใชเอาไวบอกวาไฟลมีการเปลี่ยนแปลงหรือไมและ
ยืนยันวาขอมูลไมเกิดความผิดพลาด แตไมนานมานผมไดขาววา SHA1 ไมปลอดภัยแลวครับ
ลอเลนครับ มันเกิดจากการที่นักวิจัยพบวาแมมันจะมี 160 Bits แตความปลอดภัยท่ีแข็งแกรงมีเพียง 60 Bits
หนา 10
จะเห็นวาในแตละ Git Snapshot จะมีเลขกำกับไว 40 ตัวอักษรซึ่งเปนคาของ
Checksum แตละ Snapshot ที่เห็นมีแค 3 ตัวเชน c3d, f13, 6d4 และ 84f ก็อยา
เพิ่งแกลงงง เขายอเหลือ 3 ตัวแรกเฉยๆใส 40 ตัวมามันเยอะไป (แค 3 ตัวพอแลวไม
ซ้ำกันแลว) และส่ิงที่ Git Commit บอกในตอน Commit ก็คือคู KeyValue ของ
แตละไฟลโดย Key ก็จะชี้ไปที่ Snapshot ที่เราบันทึกไว สวน Value ก็จะเปนชื่อ
ไฟล และในกรณีที่มีการเปลี่ยนชื่อไฟล หรือทำกอปปไฟลแลวเปลี่ยนชื่อ Git
Commit จะมองวามันมีหลายไฟลก็จริง แตตัวอางอิง Snapshot จะชี้ไปที ่
Snapshot เดียวกัน
ไมวาจะ Delta หรือ Snapshot มองการเก็บขอมูลแบบ Conceptual หรือการมองคอนเซ็บเทานั้น
การเก็บขอมูลของ Git จริงๆแลวก็ใชงานแบบ Delta เหมือนกัน
การทำงานเกือบทั้งหมดอยูในเครื่องเราเอง
เปนขอไดเปรียบของ Distributed VCS เพราะเครื่องเราเปรียบเสมือน Server
ตัวหน่ึง เวลาเราตองการดู Log หรือ Commit ก็สามารถดูไดเลยไมจำเปนตองใช
งานเครือขายเพื่อลิงกไปที่ Server ซึ่งพวก Subversion หรือ Version control
ที่ใชระบบ Centralized VCS สามารถแกไขไฟลในเคร่ืองไดก็จริง แตไมสามารถด ู
Log หรือ Commit ไปที่ Server ไดหากขาดการเช่ือมตอเครือขาย ทำใหไมมี
ขอมูลสำรองเอาไวในเครื่อง แต Git สามารถ Coding ระหวางการเดินทางได
สบายๆ แตก็ตองการใชเครือขายหากเราตองการสงหรือดึงขอมูลจาก Server
หนา 11
เพิ่มขอมูลเสมอ
การทำงานของ Git เมื่อไฟลถูกแกแลวเราทำการ Add และ Commit แลวมันจะ
เปนการเพิ่มขอมูลไปเรื่อยๆ การลบขอมูลยากมากเกือบจะเปนไปไมไดเลย ซึ่ง Git มองการ
แกไขไฟลเปน Snapshot ใหมๆ ไปเรื่อยๆ ไมลบของเดิมทิ้งเวนแตวามันจะเปนของที่เราไมไดใช
สถานะของไฟลขอมูล
สถานะของไฟลใน นั้นมี 4 สถานะคือ
Untrack เปนขอมูลที่ถูกสรางขึ้นใหมยังไมไดสงเขาเปนไฟลของ Git หรือไฟลที่เราไมตองการให Git นำไปเก็บ
สำรองไวเชนไฟลที่เปน Stack trace, ไฟลที่เอาไวติดตามการทำงาน หรือ Error เราก็จะไม Track มัน
Committed คือไฟลขอมูลที่ถูก Commit เขาในฐานขอมูลไปแลวจากนั้น Git จะดึงสถานะไฟลกลับมาเพื่อรอ
แกไขอีกรอบ แตระหวางที่มันยังไมไดแกไขในรอบใหมนี้มันจะคางอยูในสถานะ Committed
Modified คือไฟลขอมูลที่มีอยูในฐานขอมูลของ Git และถูกแกไขแลว แตยังไมได Staged ไฟล และ Commit ไป
ไวในฐานขอมูลของ Git อีกรอบหนึ่ง
Staged คือไฟลขอมูลที่อยูในสถานะเตรียม Commit โดยไฟลไหนที่อยูในสถานะ Untrack หรือ Modified แลว
ตองการเอาไปเก็บไวในฐานขอมูลของ Git ตองเปลี่ยนใหอยูในสถานะ Staged กอน ทำใหเลือกไดวาไฟลไหนจะถูก
Commit บาง เพราะบางทีอาจจะไมตองการเก็บไฟลบางไฟลไป (แมวาจะแกไฟลไปแลว เชนไฟล Config ใชเฉพาะ
เครื่องเราก็ไป Commit ไป)
หนา 12
จากขั้นตอนการทำงานกับไฟลขอมูลของ Git จะเห็นวาหากมีไฟลเพิ่มเขามา ใน Working directory ที่ (โฟลเดอรที่
เรากำลังทำงานอยูเน่ียแหละ) จะตองเพิ่มเขาในพื้นที่ Staging area (คำสั่ง git add) เพ่ือจะบอกวาไฟลใดบางที่เรา
ตองการเอาเขาใน Git Repository จากนั้น Git จะสราง Snapshot ไวและตอนที่เรา Commit (คำสั่ง git
commit) เพื่อใหเอา Snapshot ไฟลจาก Staging area ไปเก็บในฐานขอมูลของ Git แลวเปลี่ยนสถานะไฟลเปน
Committed ซึ่งการทำงานของ Git จะตางกับการทำงานของ Version control อื่น ซ่ึงหลายๆตัวมักจะมีแคการ
Commit ไฟลเทาน้ัน (ไมมีสถานะ Staging แต Commit จาก Working directory เลย) ขอดีของการ Commit
สองตอแบบนี้ก็คือถาเรากำลังแกบางไฟลแตไมเสร็จก็ยังสามารถ สราง Snapshot ไฟลเก็บไวใน Staging area กอน
ได
หนา 13
Git object model
อยางที่เคยบอกไววาในการเก็บประวัติไฟลไว Git จะนำไฟลไปเขาฟงกชัน Hash ดวย SHA1 จำนวน 40
ตัวอักษร เพื่อใชบอกถึง Object แตละตัว เชน
6ff87c4664981e4397625791c8ea3bbb5f2279a3
ในทุกๆ Object จะประกอบไปดวย 3 สวนคือ Type ซึ่งใชบอกวา Object นั้นเปนประเภทไหน, Size ใช
บอกขนาดของ Object และ Content ที่ใชบอกขอมูลตาง โดย Type หรือประเภทของ Object กีมี 4 ประเภท
คือ Blob,Tree,Commit และ Tag ซึ่งการเก็บขอมูลแบบนี้จะเปนแคการยาย Pointer ที่ชี้ไป Object ตางๆทำให
Git ทำงานไดเร็วสมวาก
Blob มาจาก Binary Large Object เปนไฟลที่ใชในการเก็บขอมูลไฟลทั่วไปในลักษณะของไบนาร่ีไฟล ใน
Object แบบนี้จะไมมีเวลา ชื่อไฟล และ Metadata อื่น
Tree ลักษณะคลายกราฟที่เอาไวเก็บ Directory ยอยๆและอางอิงถึง Blob ท่ีจะใชบอกวา Snapshot น้ันที่มีคา
SHA1 คาใด มีชื่อไฟลวาอะไร (คลายกับโฟลเดอรที่เอาไวเก็บไฟลหรือโฟลเดอรยอยๆไดอีก) Tree จะบอกเราวา
ตองเดินไปหา Snapshot ไหนบางถึงจะทำใหเรากูขอมูลคืนมาไดถูกตอง
หนา 14
Commit เก็บขอมูลที่ใชในการอางอิงถึง Tree และขอมูลประวัติของ Commit น้ันๆ
+ Tree บอกวามันอางอิงไปที่ Tree ไหน จะไดตามไฟลไปไดถูก
+ Parent บอก Commit กอนหนามัน
+ Author บอกคนที่ทำหนาที่รับผิดชอบการเปลี่ยนแปลง
+ Committer คือชื่อคนที่ Commit เขามาในระบบ
Object Model
หนา 15
Flow การทำงานของ Commit ใน Git (cc: schacon.github.io) Git commit
จะอางถึง Tree จากนั้น Tree จะอางถึง Tree ชั้นยอยๆลงไป หรือไฟล Blob ที่
เก็บ Snapshot ไว ทำใหบอกไดวาในถามีการเรียก Commit นั้นไฟลไหน
เปลี่ยนบาง
Tag เปนดัว Commit แบบพิเศษ ใชชี้แหลงเก็บขอมูล Digital signature
หรือใชในการเปน Tag ที่ชวยในการยอนกลับไปที่ Object ก็ได เชน เรากำลัง
พัฒนา Software แลวมี Commit เยอะๆ เพราะพัฒนามานานแลว เราก็
สามารถติด Tag ไดวา Commit น้ีเปน Release รุน V1.0 ได เวลาจะหาก็ไม
ตองรื้อหา Commit แคใช Tag ไปเรียกก็ได
สนับสนุนการทำงานแบบคูขนาน
Git สนับสนุกการแยก Branch ทำใหเราพัฒนาฟเจอรใหมๆ พรอมๆกับแกบั๊คไปไดพรอมกัน หรือระหวาง
ที่เรากำลังแกไขลูกคาหรือหัวหนาตองการดูขอมูลก็สามารถ Checkout ออกมาใหดูไดเลย
จากรูปจะเห็นวาปกติเราอยูที่ Branch ชื่อ Master ถามี Feature เราก็จะแตก Branch แลวไปพัฒนาที่ Feature
ระหวางนั้นพอดีเราเจอปญหาอะไรบางอยางที่สงผลกับ Software ท่ีเรากำลังพัฒนา เราก็็เลยตองการแกไขมันกอน
จึงแตก Branch Issue ออกมาจาก Master แกแลวก็ Merge รวมกลับมาไวที่ Master ดังนั้น Master ตัวนี้จะถูกแก
บั๊กไปแลว จากนั้นก็พัฒนา Feature ตอไปจากของเดิมที่ทำคางไว หลังจากเสร็จแลวเลย Merge กลับ Master
หนา 16
Chapter 2 : Git basic
2.1 ศัพทแสง
Init
Init หรือ Initial คือการเริ่มตนสรางระบบของ Git ในโฟลเดอรนั้นเพื่อใชเปน Version control
Clone
ในกรณีที่เราไมไดเริ่มสรางระบบของ Git เอง เราก็สามารถที่จะ
Clone ขอมูลจาก Repository ที่มีอยูแลวได ซึ่งหลังจากการ Clone เราจะได
ระบบของ Git ประวัติการแกไขไฟล และขอมูลตางๆ ครบถวนเหมือนกับที่อยู
ใน Repository ตนทาง
Snapshot
Snapshot คือการเก็บสถานะของไฟลตางๆ เอาไวอางอิง คลายๆกับการที่เราถายรูป
ในรูปนั้นเราก็จะสามารถบอกไดวาวัตถุไหนรูปรางแบบไหน อยูตำแหนงใด เชนถาแมใหเราจัด
กระถางตนไมใหม แลวบอกวาไมสวยจะใหยกกลับมา เราก็จะใชภาพอางอิงกอนเราจะยาย
เพื่อจัดกระถางตนไมกลับได ในทำนองเดียวกัน Git snapshot ก็เอาไวบอกวาไฟลเรามีรูปราง
เปนยังไงบางน่ันเอง และถาตอนนั้นไมมีการเปลี่ยนแปลงมันก็จะเก็บแคตัวช้ี ไมถายภาพใหม
Repository
Repository มักเรียกสั้นๆวา Repo เปนฐานขอมูลที่จะเก็บ Git object model ไว
เพื่อสำรองขอมูล ขอมูลที่ถูกแกไขและ Commit มาเก็บไวที่ Repo แทบจะเรียกไดวาเปนขอมูล
ที่ถูกเก็บไวแลวถาวร ตอไปถากลาวผมถึง Repo หรือ Repository มันก็คือตัวเดียวกันครับ มี
ทั้งแบบ Local repo ที่อยูบนเครื่องเรา และ Remote repo ที่อยูบนเครือขาย
Branch
Branch เปนลักษณะของการแตกกิ่งออกไปพัฒนา
โดยมีพื้นฐานจาก Branch ตั้งตนหรือแมชองมัน หากเรา
เริ่มการใชงานระบบ Git ก็จะสราง Branch หลักใหเรา
เปน Branch เริ่มตนชื่อวา Branch Master จากนั้นถาเรา
แยกไปพัฒนาใน Branch Feature ขอมูลตั้งตนใน Branch Feature ก็จะมีคาเทากับ Master ซ่ึงเปนแมของมันใน
ขณะนั้น และหลังจากที่แยก Branch ไปแลวขอมูลจะไมเกี่ยวกัน ตอใหเราทำพังใน Branch Feature ตัว Master ก็
ยังจะเปนขอมูลชุดเดิมกอนที่จะแตก Branch ไป เราจะเรียก Branch ปจจุบันที่เรากำลังทำงานอยูวา HEAD
หนา 17
Add
เมื่อเรา Add ระบบจะสราง Snapshot ของไฟลและโฟลเดอรยอยๆแลว Add เขาไปใน
Staging area เปนการบอกระบบวา Commit ตอไปมี Snapshot อะไรบาง เพื่อจะเอาไปเก็บไวใน
Git Repository แตอยาลืมวาแคเราตองการเก็บยังไมพอ เราตอง Commit ดวย เพราะสถานะการ
เก็บขอมูลไวในฐานขอมูลที่แทจริงเกิดขึ้นตอน Commit
Commit
เรามักจะกลาวถึง Commit ในความหมายสถานะหนึ่งของการทำงาน เชน Commit ไฟลน้ี
หรือยัง? การ Commit ไฟลก็คือการเอา Snapshot ของไฟลที่อยูใน Staging area ไวใน Git
Repository นั่นเอง
เพื่อเปนการยืนยันวาเราตองการแกไขขอมูลที่ตำแหนงนั้น เราตองทำการ Commit มันซะ
กอน เชน เวลาใชงานหลายๆ Branch เราจะแกไขไฟลที่ตำแหนงเดียวกัน ไฟลชื่อเหมือนกัน หากเรา
ไม Commit ไวซะกอนที่จะเปลี่ยน Branch ระบบของ Git ก็จะมองเห็นเปนการแกไฟลใน Branch
ที่เราเพิ่ง Switch ไปซึ่งผิดไปจากที่เราตองการ
Remote
Remote เปนคำที่ใชเรียก Repository ของ Git ที่อยูบนเครื่องอ่ืนๆในระบบเครือ
ขาย ลักษณะเปน Repo กลาง ปกติจะใชทำเปน Official version เพราะถึงแมวา Git จะ
ไมตองการ Server เพราะเปน DVCS ก็จริง แตคงจะงงกันไมนอยถาไมมี Repo ตัวกลาง
เพื่อใหเขาใจตรงกันวา Code ที่อยู Repo ไหนเปนหลัก โดยปกติใน Repo แบบนี้จะ
พัฒนาไฟลบน Repo ไมได (ทำไดแค Merge เขาไปรวมตัวเกา
กับตัวใหม)
Push
สงขอมูลข้ึนไป Update ใหกับ Remote repository
Pull
ดึงขอมูลลงมาจาก Remote repository
Merge
รวมไฟลที่เกิดจากการแกไขแลวใน Branch อื่นเขามา เชนเรามี Master
อยูแลวแตกกิ่งออกไปพัฒนาฟเจอรสงอีเมลใชชื่อ Branch วา Dev_send_email
เมื่อพัฒนาเสร็จแลวเราจึง Merge ขอมูลกลับมาที่ Master อีกครั้ง ดังนั้นเราไมได
หนา 18
แกขอมูลที่ Master ตรงๆ แตเราใชวิธีพัฒนาที่อื่นแลวรวมกลับทำให Master ทำงานไดเสมอ ดังนั้นเราจึงไมมีบาป
ติดตัว
2.2 คำส่ังพื้นฐานของ Git $ git config
เปนคำส่ังที่ใชกำหนดขอมูลสวนตัวของผูพัฒนา
แตละคน ทำใหรูวาใครทำอะไรไดใน Log ของ Git
ซึ่งตัวที่เราจะตั้งคากันบอยๆ ก็เชน
$ git config global user.name “AorJoa”
ใชตั้งคาชื่อผูใช
$ git config global user.email aorjoa@iaor.com ใชตั้งคา email ผูใช
หากเราตองการให Git ตั้งคาเปนคาตั้งตนจะใส global เขาไปดวย จากน้ันตั้งคาเสร็จแลวใช $ git config list ด ู
$ git config global color.ui true
ตั้งคาให UI เวลาแสดงผลใหเปนสีเวลาดูจะไดดูงายๆ
$ git init
เปนคำส่ังสรางระบบ Git ขึ้นมา โดยที่ Git จะสรางโฟลเดอรที่
เก็บขอมูลการทำงาน Commit หรือ Repo ตางๆ เก็บไวที่นี่ และจะถูก
ซอนเอาไวภายใตโฟลเดอรชื่อวา .git (โฟลเดอรก็ใช . ไดนะ เพราะระบบ
OS ก็มองโฟลเดอรเปนไฟลแบบหนึ่ง) ดังนั้นอยาเผลอลบโฟลเดอรน้ีทิ้ง
หละเพราะมันเก็บเกือบทุกอยางที่เปน Repo ภายในเครื่องเราเลยทีเดียว
$ git init สรางระบบของ Git
หนา 19
$ git clone
กรณีที่เรามีโปรเจกใน Remote Repo อยูแลว และเราก็ตองการที่จะดึงขอมูลออกมาใช ลักษณะการ
ทำงานก็คลายกับ Git init ที่เปนการเริ่มตนโปรเจกจากการที่ไมมีอะไรเลย แต Git clone นั้นไมไดเริ่มตนใหมซะที
เดียว เพราะมันคือการนำเอาขอมูลใน Remote Repo ที่เจาของโปรเจกเขาสรางไวแลวมาแกตอ ซึ่งจะมีขอมูลเกือบ
ทั้งหมดในโฟลเดอร .git ของคนอ่ืนติดมาดวย ตัวอยางนี้ลอง Clone มาจาก Repo
https://github.com/chanwit/spockreporthtml.git
$ git clone https://github.com/chanwit/spockreporthtml.git ใช Clone ขอมูลจาก Remote Repo
$ git status
ขณะที่เรากำลังทำงานอยู เราสามารถตรวจสอบไฟลทำถูกแกไข และสถานะของไฟลไดโดยการใชคำส่ัง
$ git status ก็จะเห็นสถานะของไฟล
$ git add
ใชในการเพิ่มไฟลไปที่ Staging area เพื่อเตรียม Commit เขา Git Repo ดวยคำสั่ง
$ git add . เอาทุกไฟลที่อยูภายในโฟลเดอรนี ้
$ git add sub_folder/*.txt เอาทุกไฟลที่อยูภายในโฟลเดอร sub_folder ที่มีนามสกุลของไฟลเปน .txt
$ git add index.txt เอาเฉพาะไฟล index.txt
จากนั้นลอง ส่ัง $ git status ก็จะเห็นสถานะของไฟล
หนา 20
ในตัวอยางเรา Add ไฟลไปที่ Staging area แค 2 ไฟลคือ index.txt และไฟล test.txt ที่อยูในโฟลเดอร
sub_folder และถาเรา Add ไฟลเขาไปผิดแลวอยากเอาออกในขั้นตอนนี้ก็ใชคำสั่ง
$ git rm cached sub_folder/test.txt เพื่อลบออกจาก Cached เปนตน
สวนหากเปนการแกไขไฟลที่อยูในระบบอยูแลว แตเราไมตองการสง version นั้นออกไป ก็ใชคำสั่ง $ git checkout
index.txt
$ git mv
ใชเปลี่ยนชื่อไฟลหรือโฟลเดอร วิธีการใชก็ไมยาก $ git mv ตนทาง เวน Space และปลายทาง
$ git mv sub_folder/test.txt sub_folder/bio.txt
หนา 21
$ git commit
ใชยืนยันวาเราตองการเก็บไฟลที่อยูใน Staging area ลงไปไวใน Git Repository จริงๆ สั่งไดโดยใข $ git
commit ตามดวยตัวเลือก และพารามิเตอรของตัวเลือก โดยปกติแลวตัวเลือกท่ีใชก็จะใชแค m และมีพารามิเตอร
คือขอความคอมเมนตสั้นๆลงไปใน Commit เวลากลับมาดูจะไดดูงายขึ้นวาที่คอมมิทนั้นเราทำอะไรกับมันไป
$ git commit m "Initial Git basic" แตถาพลาดมือ Commit ไปแลวแตตองการแกไขไฟล
หนา 22
$ git rm
ใชลบไฟลหรือโฟลเดอร วิธีการใชก็ไม
ยาก $ git rm หรือ $ git remove ตามดวย
ไฟลที่ตองการลบ แตถาเปนโฟลเดอรตองใสตัว
เลือก r เขาไปดวย
$ git rm r sub_folder
จากภาพดานจะเห็นวา Git ลบแคไฟลเดียว ทั้ง
ที่ในโฟลเดอรมี 2 ไฟล นั่นก็เพราะเรา Commit
ไฟลเขา Git Repo ไปแคไฟลเดียว
และเมื่อส่ังลบไปแลวถาจะใหเกิดผลตองส่ัง Commit เพื่อยืนยันดวย แตจะเก็บไว Commit ยืนยันพรอมกับการ
แกไขไฟลครั้งใหมก็ไมวากันครับ
$ git branch
ใชตรวจสอบ Branch ปจจุบันที่เรากำลัง
ทำงานอยู จะสราง Branch ใหม หรือจะลบ Branch
ออกไปก็ได
$ git branch ดู Branch ปจจุบัน
$ git branch dev แตก Branch ใหมชื่อ dev
$ git branch d dev ลบ Branch ชื่อ dev ซะ
$ git checkout
ใชสลับไป Branch หรือ Commit ที่เราตองการ หรือจะสั่งใหสราง Branch จากคำส่ังนี้ก็ได
$ git checkout dev สลับไป Branch ชื่อ dev ในกรณีที่มี Branch dev อยูแลว
$ git checkout b dev ใชสราง Branch dev แลว Checkout ไปดวย
เหมือนใข $git branch dev แลวตามดวย $git checkout dev
หนา 23
$ git merge
เปนคำส่ังที่ใชในการรวมอัพเดทไฟลที่ถูกแกไขใน Branch สอง Branch เขาดวยกัน เชนถาเราจะแกพื้น
หลังไฟล about.html ใหเปนสีแดง ก็แตกกิ่ง Branch background_red ออกไปจาก master จากน้ันถาแกโคดให
พื้นหลังเปนสีแดงพอเสร็จแลวเราก็จะ Checkout ไปที่ master แลว Merge กิ่ง background_red กลับเขามาให
master ทำใหตอนนี้เราไมไดแกไขโคดที่ master แตเราก็ไดพื้นหลังของไฟล about.html
$ git checkout b background_red แตกกิ่ง background_red จากน้ันก็แกไขโคด
เสร็จแลวส่ัง $ git add . ตามดวย Commit ที่ Branch background_red สั่ง $ git commit m "change
about.html backgound to red"
จากนั้น $ git checkout master เพื่อกลับไปที่ master จากนั้นก ็
merge $ git merge background_red
หนา 24
$ git remote
เปนคำส่ังที่ใชจัดการ Remote repository กลางที่ใชในการเก็บขอมูลซ่ึงมัก
เปน Repository ที่อยูในระบบเครือขาย ถาเราตองการเพื่ม Remote repository ชื่อ
origin ชี้ไปที่ Server ของ Github.com ที่ผมลงทะเบียนไวแลว และ Repository
ตาม Path น้ี https://github.com/Aorjoa/basic_git.git
$ git remote add origin https://github.com/Aorjoa/basic_git.git
ถาจะลบก็ใชคำส่ัง $git remote rm origin
$ git push
โดยปกติแลวตัว Repo ที่อยูบนระบบเครือขายหรือที่เรียกวา Remote repo จะถูกตั้งคาใหไมสามารถทำ
บางอยางไดเชน แกไขไฟล หรือ Commit โคดที่ Repo แบบนี้ไดเพราะขอมูลที่อยูขางในจะเปนการเก็บขอมูลท่ีอยู
ในแบบที่ระบบของ Git จัดการแลว ไมมี Working directoty ที่เก็บไฟลปกติที่เอาไวแกไข (คลายๆสงโฟลเดอร .git
ที่อยูในโปรเจกเราขึ้นไปยังไงยังงั้นเลย) เราเรียก Repo ที่อยูบน Server แบบนี้วา Bare repository (เพิ่ม bare
ใน $ git init bare หรือ $ git clone bare https://github.com/chanwit/spockreporthtml.git) เวลาเรา
จะปรับมันใหเปนรุนใหมเราก็ push โคดชุดใหมขึ้นไปใหมันแทน โดยใชคำสั่ง git push แลวตามดวย Remote
repo และ Branch (ปกติแลวชื่อ Branch จะตรงกันทั้งที่ Local และ Remote และใส Branch เพราะเราสงไปแค
master ตัวเดียว)
$ git push origin master
หนา 25
$ git fetch
เปนคำส่ังที่ใชดึงขอมูลจาก Remote Repo มากองไวที่เคร่ืองเรากอน
(จริงๆแลวมันไปดึงขอมูลใน Remote Repo มา Update ตัว Local Repo ที่
เครื่องเราในสวนท่ีเปนตัวติดตาม Remote Repo ใหเปนขอมูลที่ลาสุด แตจะไม
แตะไฟลที่อยูใน Working directory ที่เรากำลังทำงานอยู) คำสั่งนี้มักใชคูกับคำ
สั่ง Merge ครับเพราะ Merge จะเปนการเอาขอมูลที่ดึงมากองไวไปอัพเดทใน
Working directory ที่เรากำลังทำงานอยูจริงๆ
$ git fetch origin master ดึงขอมูลจาก Remote Repo origin มากองไว (ดึงมาแค Branch master)
$ git pull
ถาจะวากันงายๆ คำสั่ง git pull ก็คือคำสั่งที่รวมรางกันระหวาง git fetch กับ git merge นักพัฒนาบาง
ทานแนะนำใหใช git fetch แลวตามดวย git merge เพราะสามารถตรวจสอบกอนการ Merge รวมได แตเพื่อ
ความงายเราก็จะใช git pull ดึงขอมูลกันเปนหลัก
$ git pull origin master ดึงขอมูลจาก Remote Repo origin มาอัพเดทใน Local repo ในสวนที่ติดตาม
Remote repo และ Merge มันเขากับ Branch ปจจุบัน)
หนา 26
$ git rebase
เปนการรวม Branch คลายกับ Merge แตตัว Rebase น้ันสามารถแกไขประวัติการเปลี่ยนแปลงไฟลได
ทำใหมันซับซอนกวา และเพราะการที่มันแกประวัติการเปลีี่ยนแปลงไฟลไดนี่แหละอาจจะทำใหขอมูลเราหายได สิ่ง
ที่ควรจำก็คือ หาม Rebase commit ที่ถูก Push ขึ้น Remote repo ไปแลว ลักษณะของการ Rebase คือการที่
เปลี่ยนฐานของโคดชุดใหม ลองนึกถึงตอนที่เราแตก Branch จาก master ออกมาสราง Feature สักตัวขณะที่กำลัง
ทำอยู เราก็เจอ Bug เลยกลับไปที่ Branch master แลวแก Bug จนเสร็จ จากนั้นก็กลับมาทำงานที่ Branch ของ
Feature อีกรอบ แตอยาลืมวาในขณะน้ี master เปลี่ยนไปแลว เราก็เลยทำการเปลี่ยนฐานหรือ Rebase ใหฐานมัน
กลายเปนรุนใหมนั่นเอง ทีนี้ที่ Branch ที่พัฒนา Feature ก็ไมมี Bug ตัวนั้นแลว
หลังจากส่ัง $ git rebase master หากดู Log แบบ Graph หลังจากการ Rebase ใน Branch ท่ีพัฒนา Feature ก็
จะเห็น Commit เรียงกันเปนเสนตรง
จากภาพจะเห็นตัว Commit B’ , C’ และ F’ ซึ่งไอ 3 Commit นี้จะเปนคนละตัวกับ B, C และ F ใน Commit
timeline แตขอมูลขางในเหมือนกันทุกประการ นั่นเปนเหตุผลที่วาทำไมหาม Rebase Commit ที่ถูก Push ขึ้น
Remote repo ไปแลว เพราะถามี Commit ที่ถูก Push ไป มันจะสราง Object ของ Commit ใหม และเมื่อไหรท่ี
เรา Push ข้ึน Remote rep อีกครั้ง มันจะได Object Commit สองตัวที่มีขอมูลเหมือนกัน เวลามาดูก็จะงง
ปล. ถาอานไมรูเรื่องก็ลืมๆมันไปกอน ฝกปรือเดินลมปรานเพียงพอแลวคอยกลับมาแกแคนก็ยังมิสาย
หนา 27
$ git log
ใชดู Log หรือประวัติการทำงาน ฟเจอรก็
มีหลากหลายใหเลน เชน Commit มี Hash SHA1
เปนอะไร ใชดูแบบกราฟได ดูไดวาใคร Commit
สวนวิธีใชหลักๆก็คือ $ git log แคนี้ก็จะไดประวัติ
ของ Repository ออกมา โดยสวนนี้ก็จะสามารถดู
รายละเอียดการการ Commit ผูใชงาน Commit
การเสนทางของการพัฒนา แตก Branch ไหน
อยางไร ก็สามารถเห็นได
$ git reset
เปนคำส่ังที่ใชยอนประวัติการทำงานกลับไปรุนกอนๆหนา คำส่ังนี้มีที่ใชบอยๆ 2 แบบคือ soft reset โดยใช
พารามิเตอร soft ในการยอน Commit แตไมลบสิ่งที่เรากำลังทำ กับแบบ hard reset โดยใชพารามิเตอร hard
ยอน Commit แบบทับส่ิงที่เรากำลังทำดวย (ไฟลตางๆจะถูกทับดวยขอมูลใน Snapshot ที่เราสั่งให Reset ไป) คำ
สั่ง git reset hard คอนขางอันตรายเพราะมันจะทำใหประวัติหายไป จึงไมแนะนำใหใชสำหรับมือใหมครับ
$ git reset hard ed51e23
หนา 28
$ git revert
เปนคำส่ังที่ใชยอนประวัติการทำงาน
กลับไปรุนกอนๆหนา คำสั่งนี้ปลอดภัยกวา $
git reset เพราะโดยปกติแลวมันจะสราง
Commit ใหมโดยไมไปยุงกับของเดิม จาก
ตัวอยางผมใชคำส่ัง
$ git revert noedit ed51e23..HEAD
บอกวาใหยอนจาก Commit ed51e23 ไป
จนถึง HEAD ซึ่งก็คือตำแหนงที่เราอยูปจจุบัน
(ที่ทำอยางนี้เพราะปองการ Conflict หรือ
การแกไขไฟลชนกันในกรณีที่เราแกไฟลหลาย
ครั้ง) เลยจะเห็นวา มี Commit ใหมโผลขึ้นมา 2 ตัว คือ ca764a3 กับ 4e8849b และในคำสั่งผมใส noedit
เพราะตองการใชขอความ Comment ใน Commit เปนคาตั้งตนของระบบ คือ Revert แลวตามดวย Comment
ที่อยูใน Commit ตัวตนแบบ ถาสังเกตจะเห็นวาเวลา Revert มันยอนกลับจาก Commit ใหมกวาไปหาเกากวา
(Add line two ใหมกวา Add line one)
จะเห็นวาคำสั่งบางคำสั่งที่ผมยกตัวอยางมาหลายๆ ตัวเราสามารถใชแทนกันได และบางตัวมีการใช
พารามิเตอรเพื่อความงายในการใชงาน หากอานการใชงานคำสั่งขางบนแลวยังรูสึกงงก็ไมแปลกเพราะบางคำส่ังเกี่ยว
เนื่องกันเปน Flow ตอกัน หรือใชงานรวมกัน การลองใชงาน Git และการอานเนื้อหาเพิ่มเติมจะทำใหทานมีบารมีแก
กลาขึ้น จากนั้นคอยกลับมาอานอีกก็จะเขาใจไดไมยาก
หนา 29
Chapter 3 : Installation
หลังจากที่เรารูขอมูลเบ้ืองตนเกี่ยวกับ Version control, ประวัติของ Git และคำสั่งพื้นฐานของ Git ไปแลว
ก็ถึงข้ันตอนที่ยากที่สุดในการที่จะใชงาน Git ก็คือขั้นตอนการติดตั้งเนี่ยแหละฮะทานผูชม
========================================================================
3.1 Windows
========================================================================
1) ไปที่ http://gitscm.com/downloads
กด Download ของ Windows แลวรอโหลด
2) ติดตั้ง Git ลงในเครื่อง
ถามีการเตือนก็กดตามภาพดานลางเลย ถาไมมีก็ผานไปไดเลย
หนา 30
ตัว Installer จะเดงขึ้นมา กด Next ไปเลย
หนา 31
ตัวนี้เปนคำอธิบายลิขสิทธิ์การใชงาน กด Next ไป
เลือก Directory ปลายทางที่จะเอาไฟลของ Git ไปเก็บไว จากนั้นกด Next
หนา 32
เลือก Component วาจะเอาอะไรไว เอาอะไรออก กด Next ไดเลย
กำหนดชื่อของ Shortcut กด Next
หนา 33
ตัวเลือกแรก : ใชคำส่ัง Git ไดเฉพาะใน Git Bash
ตัวเลือกที่สอง : แกไข Windows Command Prompt ใหสามารถใชคำส่ัง Git ไดดวย แนะนำใหเลือกตัวนี ้
ตัวเลือกสุดทาย : แกไข Windows Command Prompt ใหสามารถใชคำสั่ง Git และติดต้ังคำสั่งที่คลายของ UNIX
ลงไปดวย (มีคำเตือนวาบางคำส่ังอาจจะทับกัน ซึ่งอาจจะทำใหการใชงาน Command ใน CMD เปล่ียนไป)
จากนั้น กด Next
หนา 34
เปนตัวเลือกในการจบบรรทัด ใหเลือกตัวเลือกแรก เพราะการจบบรรทัดของ Windows กับของตระกูล UNIX เน่ีย
จะไมเหมือนกัน การเลือกตัวเลือกนี้จะทำใหสามารถทำงานขาม Platform ไดโดยไมติดปญหานี้ จากน้ันกด Next
หนา 35
เมื่อติดตั้งเสร็จแลวกด View ReleaseNotes.rtf ถาตองการอานไฟลขอมูลประวัติการแกไข จากน้ัน Finish ไป
ลองเขา Git bash ดูโดยไปที่ Start menu > All
Programs > Git > Git bash จากนั้นลองใชคำ
สั่ง git version ลองวาทำงานไดจริงไหม
ถาขึ้นเลข Version ของ Git ก็เปนอันใชได
หนา 36
========================================================================
3.2 Mac OS X
========================================================================
1) ไปที่ http://gitscm.com/downloads แลวก็ Download ตัวติดตั้งใน Mac OS X มา
2) ติดตั้ง Git ลงในเครื่อง
หนา 37
กด Continue รัวๆไดเลย
หนา 38
หลังจากติดตั้งเสร็จแลวใหเปด Terminal แลวลองพิมพ git version แลวแสดงผลออกมาแบบนี้เปนใชได
========================================================================
3.3 Others operating system
========================================================================
ในระบบปฏิบัติการอื่นก็สารมารถ Donwload และติดตั้งไดตามลิงก http://gitscm.com/downloads วิธีการติด
ตั้งก็คลายๆกัน
หนา 39
Chapter 4 : Git scenario
การใชงาน Git หลังจากที่เราติดตั้งและรูจักกับคำสั่งแลว สิ่งที่ควรทราบอีกนิดคือ Git นั้นมีคำสั่งท่ีคลายๆ
กันในทุกๆระบบปฏิบัติการ และไฟลตางๆ ก็จะคลายกัน สวนตัวผมจะใชงานใน Mac OS X และใชไฟล Source
code ของ Software เปนหลักในการแสดงตัวอยาง แตก็จะสามารถใชคำสั่งเดียวกันในระบบปฏิบัติการอ่ืนได และ
ผมมีคำแนะนำการใชงานสำหรับ Windows คือใหเปดใชงานดวย Git bash เพราะคำสั่งบางคำสั่งนั้นทำไดเฉพาะใน
UNIX ซึ่ง Git bash จะจำลองใหเราใชได (ขอจำกัดของคำส่ังใน Command Prompt)
สถานการณที่ 1 : มือใหม มึนตึ๊บ !@#%!@
อันดับแรกใหตั้งคาขอมูลทั่วไปของนักพัฒนากอนครับ
$ git config global user.name “AorJoa” ใชตั้งคาชื่อผูใช (ไมใส “ ก็ได)
$ git config global user.email aorjoa@iaor.com ใชตั้งคา Email
$ git config global color.ui true
$ git config global user.ui true
ขอมูลขางบนเปน 2 คำส่ังแรกเปนขอมูลของผมนะ อยาลืมเปลี่ยนเปนของตัวเอง ไมงั้นผิดมหันตยังกะลอกการบาน
แลวลอกชื่อเพื่อนมาดวยยังไงยังงั้น
จากนั้นมาดูตัว Git ซึ่งมี flow แบบที่งายที่สุดในการที่เราจะเก็บโคดดังนี้ครับ
สำหรับมือใหมไมมีอะไรที่จะดีไปกวาการพิมพตามตัวอยางแลวหละครับ ดังน้ันก็จัดการเลยครับสรางโฟลเดอรขึ้นมา
สักที่หน่ึงแลว ส่ังไปเลย $ git init เริ่มสรางระบบ Repository ของ Git ขึ้นมาใชงาน
หนา 40
จากตอนนี้ไฟลในระบบผมยังไมมีเพราะผมเพิ่งสรางโฟลเดอรตะกี้เอง ดังนั้นเราจะลองสรางไฟลสักไฟลหนึ่งช่ือ
readme.txt ผมใชคำสั่ง $ nano readme.txt คำสั่ง nano คือ Text editor ตัวหนึ่งใน Unix ซึ่งผมเอามาใชสราง
ไฟลและแกไขขอความ ความจริงจะใช Notepad ก็ได เอาเปนวาใหมันสรางและแกไฟลไดเปนพอ
จากนั้นกด Ctrl + X (กดปุมคอนโทรลพรอมกับปุม X บนคียนบอรด)
มันจะถามวาตองการ Save หรือเปลาก็กดปุม Y ไป
จากนั้นจะถามชื่อไฟล ก็กดปุม Enter ไปไดเลย เพราะเราตั้งช่ือให ตั้งแกตอนเรียกคำส่ัง nano แลว
จากนั้นมันจะเดงออกมาที่หนาจอ Command ปกติเรา ใหลองส่ัง ls เพื่อดูไฟลวามาหรือเปลา ถาเห็นช่ือไฟลแสดง
วาสรางไดแลว
ถาใช Text editor ตัวอื่นก็ใชงานตามปกติของมันนะครับ Notepad ก็กด Save ไฟลไดเลย ไมตองทำหลายขั้นตอน
แบบผมก็ได ขอแคไดไฟลออกมา ถัดมาก็สั่ง $ git status ซึ่งใชดูสถานะ Working directory ของเรา
> ขอคั่นเวลา Add/Delete/Rename
การเพิ่มไฟลที่ยังไมเคยเพิ่ม ปกติไฟลที่ยังไมเคยเพิ่มไมจำเปนตองดำเนินการ Add ก็ได แตตัวนี้มันเปน Commit
แรกเลยจำเปนตองเพิ่มขอมูลเขาไปไมงั้นมัน Commit ไมได (ผมพยายามจะบอกวาปกติไฟลที่สรางใหมจะยังไม
Track และ Commit เก็บก็ได แตนี่มันเปน Commir แรกเลยจำเปนตอง Add) คำสั่งท่ีใชคือ $ git add ชื่อไฟล
หนา 41
แตถาเราแกไขไฟลจะมีคำส่ัง 2 แบบที่ทำได คือการเพิ่มไฟลเขาใน Commit แบบปกติ ($ git add ชื่อไฟล) และไม
เก็บไฟลเวอรชั่นนั้นไวใน Commit น้ัน แตเอาไว Commit หลังตอนหลังก็ได ($ git checkout ชื่อไฟล)
การลบไฟล สั่ง $ git rm ชื่อไฟล ไดเลย แตถาเปน โฟลเดอรตองใสพารามิเตอร r ให recursive ไฟลในโฟลเดอร
สั่ง $ git rm r ชื่อโฟลเดอร มันตางจากการลบปกติตรงที่นอกจากไฟลจะหายไปจากโฟลเดอรแบบปกติแลว Git ยัง
รูดวยวาเราลบไฟลออกไปจาก Working directory ของเรา
การเปลี่ยนชื่อ ก็ใช $ git mv ช่ือไฟลปจจุบัน ชื่อไฟลที่จะเปลี่ยน
หนา 42
จะเห็นวาไฟล readme.txt เพิ่มขึ้นมา ในสถานะ Untracked files คือยังไมไดติดตามการเปลี่ยนแปลง และระบบ
แนะนำใหใช git add ตามดวยชื่อไฟล ทำตามมันเลยครับสั่ง $ git add readme.txt แลวสั่ง $ git status ดูวาเขา
จริงปะ
ถาเขาไปแลวจะขึ้นสีเขียวๆในกรอบที่บอกวา Change to be committed คือสถานะที่มีการเปล่ียนแปลง และไป
อยูที่ Staging area แลว (สราง Snapshot) ถัดมาเราก็สั่ง $ git commit m "Initial Git repository" เพื่อเอา
Snapshot ใน Staging area ไปเก็บในฐานขอมูลของ Git
ถาเราส่ัง $ git status จะเห็นวา woking directory วางแลว
ถามีการแกไขไฟล readme.txt นี้อีก เราก็แคทำตามลำดับคือ git add readme.txt แลวก็ git commit m แลวใส
comment ไป เชน “Edit#1 add line” วนอยูแบบนี้ (ตัวอยางขางลางผมแอบใช Sublime แกไฟลแทน nano)
หนา 43
ถาจะดูประวัติการทำงานก็ดูไดจากคำสั่ง $ git log ก็จะมีประวัติการ Commit โผลขึ้นมา
และนั่นคือ Flow ปกติที่เราใช Git เริ่มเก็บประวัติการแกไขไฟลครับ ถาหากเรามี Repo อยูแลวหรือตองการจะ
Clone มาจากที่อื่นเชน Github ก็แคเปล่ียนคำสั่ง $ git init เปน $ git clone แลวตามดวยที่อยู Repo
$ git clone https://github.com/chanwit/spockreporthtml.git ใช Clone ขอมูลจาก Remote Repo
โคดที่ไดมาจะเปนโคดที่ตนทางมีการสรางไวแลว สวนการทำงานก็เหมือนกับการเริ่มโปรเจกใหมดวยตัวเองครับ ตาง
กันที่จะมีโคดและ Remote repo ติดมาแลว
หนา 44
สถานการณที่ 2 : ฝากไวใน Remote repo เธอ
โปรแกรมเมอรรุนดึกดำบรรพใชวิธีการบีบอัดไฟลเชน .zip หรือ .tar วิธีการนี้เรียกวาทำ Tarball แตะสง
กันไปมาทาง Email พอมันหลายๆครั้งเขาก็พบวามันไมเวิรก เพราะดูไมออกแลววารุนไหนเปนรุนไหน แถมเนื้อที่
เก็บ Email ก็จะเต็มอีก เลยมีการคิดคน Version control ขึ้นมาใชซึ่ง Git ก็เปนเวอรชั่นคอนโทรลแบบที่มี
Remote repositoy ไวเปนตัวกลางใหคนที่ทำงานเดียวกันมาอัพเดทที่เดียวกันจะไดไมม่ัวตั้ว
มีหลายเจาที่รับเปนตัวแทนการเปน Git remote
repository เชน Github.com, Gitlab.org หรือ Bitbucket.org
ตัวอยางนี้จะลองใช Remote repo ของ Github.com เพราะใช
งานงาย มี Tutorial สอนใชที่ try.github.io เหมาะกับทั้งมือใหม
และมือเกา แถมประโยชนในการใชเปนเหมือน Portfolio ในการสมัครงานไดดวยนะเออ (ประเด็นหนึ่งที่สำคัญคือ
ผมเปนทาสแมวหมึก Octocat ที่เปนมาสคอตของ Github เขาหละ >__<”) เอาเปนวาเร่ิมตนแบบ
StepbyStep กันเลยนะ
(1) ไปที่ https://www.github.com แลวก็สมัครสมาชิก
กรอกขอมูล
กด Sign up for GitHub
(2) เลือกแผนการใชและแนนอนผมเลือกตัวสุดทายเพราะใชฟรี (แตถาใครยังเรียนอยูก็ขอเขาใช Micro Plan
ไดนะครับฟรีผมเคยขอมาแลว) ขอดีของ Provate repo คือมันสามารถใหเฉพาะคนที่สิทธ์ิถึงจะดูโคดได
หนา 45
(3) กด Finish sign up ไปไดเลยจากนั้นก็ไปเช็ค Email ที่เรากรอกไปจะเห็นเมลที่สงมาจาก Github เพ่ือขอ
ยืนยันตัวตน ก็ใหเรากด link มา แลวกด Confirm เปนอันจบพิธีการสมัคร แตยังเหลือการเพิ่มใบรับรองผู
ใชกับสราง Repo
(4) เพิ่มใบรับรองผูใช ตอนที่เรา Connect เขามาเพื่อ Pull หรือ Push ขอมูลเขามาที่ Github แลว Github
จะรูไดไงวาคุณเปนตัวจริง ลำพังชื่อกับ Email มันก็ปลอมกันไดงายๆ ดังน้ัน Github จึงใชการรับรอง SSH
key (Secure Shell key) ยืนยันตัวผูใชซึ่งเปนแบบ Publickey cryptography เวลาสรางจะไดไฟลสอง
ไฟลคือ Public key (นามสกุล .pub) กับ Private Key (ไมมีนามสกุล) คียทั้งสองสามารถใชเขารหัสขอมูล
ได แตถาจะเปดอานตองใชอีกใบที่เปนคูกัน ถาใช Public key ในการเขารหัสตองถอดรหัสดวย Private
Key เทานั้น และในทางกลับกันถาเขารหัสดวย Private Key ตองถอดรหัสดวย Public key เทานั้น จะใช
ตัวที่เขารหัสตัวมันเองถอดรหัสตัวมันเองไมได ดังนั้นวิธีการน้ีทำใหรับรองสิทธิ์วาผูรับและผูสงเปนคนที่เรา
ตองการจริงๆ เพราะจะมีแคผูรับและผูสงเทานั้นที่มีคียเปดอานของกันและกันได
เราจะสง Public key ไปเก็บไวที่ Github และเก็บ Private key ไวที่เครื่องเรา วิธีการสราง SSH key ใหสั่ง
$ sshkeygen t rsa C "aorjoa@iaor.com"
หนา 46
Enter file in which to save the key (/Users/dekcom/.ssh/id_rsa): กดปุม Enter ผานไปไดเลย
/Users/dekcom/.ssh/id_rsa already exists.
Overwrite (y/n)? ไฟลใบรับรองผมมีอยูแลว ตอบ y ใหมันเขียนทับเปนตัวใหม (ของใครไมมีก็จะไมถูกถาม)
Enter passphrase (empty for no passphrase): ใส Passphrase (คำลับที่เอาไวเปดใชใบรับรองปองกันเผ่ือมี
คนไดใบรับรองเราไป) คำในนี้จะไมแสดงออกทางหนาจอ ถาไมอยากใสก็กด Enter ผานไปเลย
Enter same passphrase again: ใส Passphrase อีกรอบ
ขางลางบอกที่อยูของไฟลทั้งสองคือ Private key (identification) และ Public key
Your identification has been saved in /Users/dekcom/.ssh/id_rsa.
Your public key has been saved in /Users/dekcom/.ssh/id_rsa.pub.
จากนั้นก็เปดดู Public key ส่ัง
$ cat ~/.ssh/id_rsa.pub
เพื่อดูขอมูลขางในไฟล แลวก็
กอปปขอความขางในออกมาไว
รอเอาไปเพิ่มใน Github
หนา 47
จากนั้นก็ไปที่หนาเว็บของ github.com เพื่อเพิ่ม Public key ของเราที่สรางเมื่อก้ีให github รูจัก กดปุม Setting
> SSH Keys > กรอก Title (ปกติจะใสชื่อเครื่องคอม) > วางคียที่กอปปมาจากในชอง Key > กด Add key
เปนอันเรียบรอย
(5) สราง Repository
> กด New repository
> ตั้งชื่อ Repo
หนา 48
> คำอธิบาย Repo ไมใสก็ได
> เลือกวา Repository จะเปนแบบ Public หรือ Private
> Git เตรียมไฟล README ,ไฟล .gitignore (ไฟลที่เอาไวบอกวาไฟลประเภทไหนท่ีจะไมถูกเก็บใน Git
repo) และไฟลคำอธิบาย License (ถาไมเอาก็ไมตองเลือกนะ)
จากนั้นก็กด Create repository
ในหนาถัดมา กดที่ SSH แลวกอปป URL ของ Repo ไว
(6) กลับไปที่หนาจอ Command line เพิ่ม Remote repository เขาใน Git โดยส่ัง
$ git remote add origin [email protected]:aorjoabook/basic_git.git
(7) ลอง Push ขอมูลไปเก็บที่ Repo ที่เราสราง
มา สั่ง $ git push origin master
ถาใส Passphrase ไวจะมี Dialog ขึ้นมาถาม
หนา 49
หลังจากที่เราใส Passphrase เรียบรอยก็กด OK ไป (บาง OS อาจจะถามใน Command line เลยก็ได)
จากนั้น Git ก็จะสงขอมูลขึ้นไปที่ github.com ตาม Repo ที่เราบอก ถาเสร็จแลวก็เปดดูไดท่ีหนาแรก เลือก
Repositories จากนั้นก็เลือกเขาไปที่ Repo ที่ Push ขึ้นไป ก็จะเห็นความเปลี่ยนแปลงท่ีเกิดขึ้น
เลือก basic_git
เปดไฟล readme.txt
ดานในไฟล readme.txt จะแสดงเวอรช่ันลาสุด
แคนี้เราก็จะมี Remote repo ของ Github ไวใชแลว สวนใครที่ตองการใชของเจาอื่น ก็มีวิธีทำคลายๆกันครับ ไม
ยากแนนอนครับเพราะวายน้ำในสระไดแลว จะใหไปวายในคลองก็ไมมีปญหา ใช Github เปนแลว ไปใช Bitbucket
หรือ GitLab ก็สบายมาก (คือมันคลายกันมากเลยครับ อยางการเซ็ต SSH keys เหมือนยังกะกอปกันมา)
หนา 50
สถานการณที่ 3 : กลับมาเหมือนเดิมนะ,,ขอมูล
การยอนเวอรชั่นขอมูลกลับ มีวิธีอยู 3 อยางที่ใชกันใหเห็นบอยๆ ก็คือ Checkout, Revert และ Reset
ครับ คำแนะนำคือกอนเราจะทำอะไรใหสั่ง $ git status ดูกอน ถามีการแกไขขอมูลก็ให Commit มันเก็บไวกอน
เรามักจะทำงานกันใน Working directory
ที่อยูสถานะ Clean เพื่อลดการ Conflict
หรือสับสนเวลายอนกลับไปกลับม
> Checkout
Checkout เปนการมองยอนกลับไปจาก
ตำแหนงปจจุบัน ลักษณะคลายๆเปน Branch หน่ึง ที่มี
ขอมูลเปนไฟลรุนที่อยูใน Commit นั้นๆ และถาเรา
Checkout กลับมาที่ Branch master ก็จะเปนขอมูล
ปกต ิ
(1) ลองส่ัง $ git log ดูประวัต ิ
(2) ลองกลับไปที่คอมมิท 8ba8bb9… สั่ง $ git checkout 8ba8bb9
(3) ใช $ git log ดูประวัติอีกที
หนา 51
(4) ถาลองใช $ git branch ดูจะเห็นวามี Detached branch ซึ่งเปน branch ลอยๆขึ้นมา ถา checkout ไป
branch จริงตัวนี้จะหายไป
ถาดูขอมูลก็จะเห็นวามันกลับไปเปนรุนที่เราตองการแลว
> Revert
Revert เปนการคืนคา Commit โดยจะ
สราง Commit ใหม ไมทับของเดิม เชนถาเราอยาก
Revert Commit B มันก็จะสราง Commit D ขึ้น
มาใหมโดยตอจาก Commit C ซึ่งเปน Commit
ลาสุด ขอนำนำการใชคือควรจะ Revert เปนลำดับ
ถาอยาก Revert Commit A เราก็จะสั่งให Revert ตั้งแต Commit A ไปจนถึง HEAD ปองกันการ Conflict (หรือ
จะแก Conflict เองก็ไดนะ ถามีการ Conflict)
(1) ลองดู Log กอน สั่ง $ git log
(2) สั่ง $ git revert 8ba8bb9..HEAD (ที่ ..HEAD ไวกันการ Conflict อยางที่บอก)
พอเราส่ังอาจจะมีหนาจอ Editor ขึ้น
มาถามวาจะแกประวัติ Commit ไหม ใหกดปุม
:q! แลว Enter ไปเลย หรือจะไมเปด Editor
สั่ง $ git revert noedit 8ba8bb9..HEAD
หนา 52
(3) ถาลองส่ัง $ git log ดูอีกทีจะเห็นวามีการ Revert ขาม commit 2e7885 ไป
(4) ลองดูในไฟล readme.txt จะเห็นวาชอมูลเปลี่ยนกลับเปนรุนเราอยากยอนไปแลว
> Reset
การใชงานคำส่ัง Reset เปนการยอนกลับและเขียนทับประวัติการทำงานดวย ยกตัวอยางเชนถาผมพัฒนา
ฟเจอรมาเรื่อยๆ แลวเขาใจ Spec ของ Software ผิดพลาดไปแบบ
คนละทิศละทางเลย ผมยอนดูพบวามี 2 Commit ลาสุดที่ผมทำผิด
และผมไมตองการมันเลย ลังนั้นผมจึงจะยอนกลับและลบประวัติการ
ทำงานที่ผมทำมา 2 Commit ดวย ไหนๆก็ไมไดใชอีกแลว เผื่อเพื่อนมา
ดูจะไดไมงงวาผม Commit อะไรเขาไป ซึ่งก็มีสองแบบหลักๆ คือ
soft จะไมยอนกลับไฟลที่เรากำลังแกอยู กับ hard ยอนกลับทุกอยางแมแตไฟลท่ีเรากำลังแกไขอยู ไปเปนรุน
ปลายทางที่เราอยากได
(1) ดู log สั่ง $git log oneline (ดู log แบบบรรทัดเดียว)
(2) สั่ง $ git reset hard
(3) ขอมูลเปลี่ยนไปแลว
หนา 53
(4) ดู Log อีกครั้งส่ัง $ git log oneline จะเห็นวา Log ก็เปล่ียนไปดวย
สถานการณที่ 4 : เจอ Conflict
ถาใช Version control ตั้งแตเร่ิมจนจบโปรเจกแลวไมเกิด Conflict นี่นับไดวาชาติกอนทำบุญใหญระดับ
สรางศาลาหรือมหาวิหารมาเลยทีเดียว เพราะปกติจะเห็น Conflit กันอยูบอยๆ โดย Conflict ก็เกิดจากที่เราแกไข
ขอมูลตำแหนงเดียวกันทำให git สับสนวาเราตองการเอาโคดชุดไหนกันแน ผมยกตัวอยางวาถาเพ่ือนแกโคดใน
Branch master (Remote repo) แลว Push ขึ้น Github มา ขณะเดียวกันผมก็แกไขไฟลที่ Branch master บน
เครื่องผม (Local repo) บังเอิญวาแกไฟลที่ตำแหนงเดียวกันซะดวยทำให Git สับสนวาเอะจะเอาเวอรชันไหนกันแน
วาแลวก็มาลองกันเลย
(1) อันดับแรกผมจะแอบเขาไปแกขอมูลใน Github ทำนองวาเพื่อนแกแลว Push ขึ้นมา และจะแกไฟลบน
เครื่องที่ตำแหนงเดียวกัน จากนั้นก็ Commit เก็บไว (สังเกตุบรรทัดท่ี 3) และ ทำที่ Branch เดียวกันคือ
Branch master
คำสั่ง $ git commit am มันคือการรวม git add (เฉพาะไฟลที่เคย add แลว) กับ git commit ไวในคำสั่งเดียว
(2) ลองส่ัง $ git pull origin master ดู (คงจำไดนะ วา git pull คือ git fetch + git merge นั่นเอง)
จะเห็นวามี Conflict เกิดขึ้น เพราะแกไฟลที่ตำแหนงเดียวกัน
หนา 54
(3) ลองเปดดูที่ Editor
จะเห็นวามี 2 Commit ที่ Conflict กันครับ คือ จาก HEAD ในเครื่องเรา และ Commit ที่มีเลข 9a570f… ใน
ตัวอยางนี้ผมจะเก็บ HEAD ไว
จากนั้นก็ส่ัง Commit เก็บไว
(4) ลองดู Log
อันที่จริงแลว Git มี Tools ที่เอาไวชวย Merge conflict ไดในกรณีที่มี Conflict เกิดข้ึนสามารถเลือกไดวาจะเอา
อันไหน และถามี Conflict หลายๆอันมันก็จะเลื่อนๆมาใหเราดูไดดวย แตปกติแลวใช Editor ปกติก็เอาอยู
หนา 55
สถานการณที่ 5 : เพิ่ม Alias ยอคำสั่งใหใชงายๆ
Alias หรือนามแฝง เปนการยอคำส่ังที่ใชบอยๆ ใหใชงายๆ ดูตัวอยางเลยแลวกัน
ถามี $ git log graph decorate pretty=oneline abbrevcommit all สราง alias ช่ือ lol โดยส่ัง $ git
config global add alias.lol "log graph decorate pretty=oneline abbrevcommit all"
คำสั่ง $ git log graph ชวยใหเห็นการเขาออกของ Commit
(cc : http://uberblo.gs/2010/12/gitloltheothergitlog)
สถานการณที่ 6 : Fast Forward กับ 3way Merge
> Fast forward เกิดขึ้นเวลาเราใชคำ
สั่ง Merge แลว Git พบวามันมีประวัติ
มาจากที่เดียวกัน มันก็จะพยายาม
ทำใหเปนเสนตรงแนวเดียวกัน
> 3way Merge เปนการ Merge มี
ประวัติรวมกัน แลวสราง Commit
ใหมขึ้นมา จากรูปจะเห็นวงสีแดง 3
จุด ไดวงสีฟาเปนที่มาของ 3way
Merge
เนื่องจาก 3way Merge แบบนี้เห็น
ภาพการเขาออกไดดี จึงแนะนำใหใช
โดยเราสามารถบังคับใหเปน 3way
Merge โดยสั่ง $ git merge noff
ตามดวยชื่อ branch
หนา 56
สถานการณที่ 7 : จัดการ Branch
เรามักจะสราง Branch เพื่อพัฒนาฟเจอรหรือแกบั๊ค และเมื่อเราพัฒนาฟเจอรเสร็จแลว เราก็ไมอยากได
Branch แลว ตามสำนวนเสร็จนาฆาโคทึก เสร็จฟเจอรเราก็ลบ Brach ที่ไมตองการท้ิงไปเพื่อไมใหมันเยอะเกินไปจน
สับสนวา Branch ไหนเปน Branch ไหน ดังนั้นมาดูวิธีสรางและลบ Branch กัน
> เพิ่ม Local branch
การเพิ่ม Branch บน Local ทำไดงายๆ ส่ัง $ git checkout b 'bugfix' และ $ git branch ด ู
> เพิ่ม Remote branch
หลังจากที่เพิ่ม Local branch แลวผมอยากสง Branch นี่ไปไวที่ Remote repo ดวย วิธีการคือผมแกไฟล
จากนั้น Commit ไฟลไวใหเปนรุนปจจุบัน $ git commit am 'bugfix branch'
ถัดมาก็สั่ง $ git push origin bugfix:issue ซึ่งคำสั่งนี้บอกวาเอา Branch bugfix บนเครื่องเราไปเปน Branch
issue บน Remote repo ที่ชื่อวา originปกติเราสั่ง $ git push origin master มันก็ $ git push origin
master:master ฝงซายคือชื่อ Branch บนเครื่องเราสวนฝงขวาคือ Branch บน Remote repo แตถาช่ือเหมือน
กันรวบมาเขียนตัวเดียวได
หนา 57
ถาดูใน Github ซึ่งเปน Remote repo (ตัว origin) จะเห็นวามี Branch ช่ือ issue เพิ่มขึ้นมา และถากดมา
Branch นี้ก็จะเห็นขอมูลเปนขอมูลใน Branch issue (ซึ่งก็คือ Branch bugfix ใน Local repo นั่นแหละ) แตถากด
มา master ก็จะเห็นขอมูลใน Branch master
> ลบ Local branch
การลบ Local branch ก็ทำไดงายๆ แตตองไปที่ Branch อื่นกอน เพราะตัวมันเองจะลบมันเองไมได
จากนั้น Checkout ไป master
จากนั้นจึงส่ังลบดวย $ git branch D bugfix
> ลบ Remote branch
สั่ง $ git push origin delete issue เพื่อลบ Branch issue ใน Remote repo
ใน Github ก็จะเหลือแค Branch master เพียงตัวเดียว
มีอีกคำส่ังหน่ึงที่เอาไวลบคือ $ git push origin :issue ไดผลเหมือนกัน (เหมือนไมสง Branch อะไร ไปไวที ่
Remote repo ก็คือการลบนั่นเอง)
หนา 58
สถานการณที่ 8 : แกไข Commit หรือ History
กรณีที่เราทำ Commit ลั่น แลวตองการแกไขโดยรวมเอาตัวใหมกับตัวเกาเขาไวดวยกัน เชนผมกำลังแกไข
ไฟล readme.txt ผมเขาใจวาผมทำถูกหมดแลวก็เลย Commit เก็บไว พอเพื่อนมาเห็น เหยย! ทำผิดน่ีหวา แตผม
Commit ไปแลว เพื่อไมใหเสียฟอรมจนเกินไปและลดความวุนวายหลาย Commit ผมเลยรวมมันไวดวยกันเลย (
ลองนึกดู สมมติวาผม Commit คร้ังแรกพรอมกับ Comment วา “Done” แตเพ่ือนมาเห็นวามันผิด หลังจากที่ผม
แกแลวจะ Commit วา “Done#2” มันก็คงแปลกพิลึกอยูที่งานจะเสร็จสองคร้ัง)
> กรณีที่ Commit ตอกัน
กรณีที่เราตองการจะแกไข Commit กอนหนานี้ (เปน Commit ลาสุดนะครับ) $ git commit amend
m 'Edit comment' ตัวอยางนี้ผมจะแก Comment ใน Commit ลาสุด
> แก History โดยเลือก Commit เพื่อ Rebase
Git เปดโอกาสใหเราไดแกไขประวัติการเก็บไดดวย โดยใช $ git rebase i ซ่ึงเปนการ Rebase แบบมี
ปฏิสัมพันธกับผูใช ผูใชสามารถเลือกไดวาจะเอา Commit ไหน ไมเอา Commit ไหน หรือจะแกลำดับการ
Commit ก็ได (มีเงื่อนไขคือมันตองอยูบน base เดียวกัน)
(1) ลองดู Log สั่ง $ git lol
หนา 59
(2) สั่ง $ git rebase i 8ba8bb9
จะเดงหนาจอใหเราเลือก Commit จาก base ที่ตองการคือ 8ba8bb9 (สังเกตุวาไมมี Commit 8456e87 เพราะ
มันคนละ base)
โดยผมจะลบ Commit af13edd ออก ก็เอา Cursor ไปชี้ที่มัน กดปุม dd บนคียบอรด (กด d สองคร้ัง)
จากนั้นก็กดปุม :wq เพื่อบันทึกและออก
Git ก็จะพยายาม Rebase ถาผานก็แลวไป ก็กรณีผมทำบุญมานอย มี Conflict ติดมา
ผมเลยสั่ง $ git status ดูวาไฟลไหนที่มันติด Conflict
หนา 60
จะเห็นไฟล readme.txt แดงแจ พรอมกับบอกวา both modified คือมันสับสนวาจะเอาอันไหนแน จากนั้นผมก็ไป
ดูไฟล readme.txt ที่ติด Conflict แลวก็แกใหงดงามตามตองการ
จากนั้นก็ Commit เก็บไว
แลวก็สั่ง rebase ตอ จากคำสั่ง $ git rebase continue
ถาสั่ง $ git lol หรือ $ git log ดูก็จะเห็นประวัติมันเปลี่ยนไปแลว
สถานการณที่ 9 : ดู Difference
โดยทั่วไป Version control จะมี Option ที่จะสามารถใชดูความแตกตางของไฟลในแตละเวอรชั่นไดถือวา
เปนฟงกชันพื้นฐานเลยทีเดียว และเชนกัน Git ก็มีความสามารถนี้ การใชงานก็ไมยากแคส่ัง $ git diff ตนทาง ปลาย
ทาง เชน
เทียบระหวาง Commit ลาสุด กับปจจุบัน $ git diff
หนา 61
เทียบระหวาง Branch $ git diff master dev
จากดานบนจะเห็นวาถามองจาก dev ไป master จะเห็นบรรทัดหายไป (สีแดง) แตมุมมองของ master ไป dev
จะเห็นบรรทัดเพิ่มข้ึนมาในไฟล
เทียบระหวาง Commit $ git diff 2e78857 9a570f6
หนา 62
ที่เจงกวานั้นคือ$ git whatchanged since="2 day ago" oneline หรือ $ git whatchanged since="2
weeks ago" oneline ถามกันตรงๆแบบนี้เลย
สถานการณที่ 10 : งานหาย แกไดดวย Reflog
ขณะที่ผมกำลังทำงานอยู สั่ง Git 23 คำสั่ง ทันใดขอมูลทั้งหมดหายไปตอหนาตอตา ไมตองจับมือแมวตัว
ไหนดม ผมเองแหละที่ทำมันเจง!! แตยังชิวๆอยูเพราะรูวาส่ัง $ git reset ขอมูลก็กลับมาได แตมือก็ดันเลือก
Commit ผิดซะงั้น Holy Sh**t นี่มันวันอะไรของผม นอกจากขอมูลหายเกลี้ยงแลว ประวัติยังหายไปดวย!
โชคยังดีที่ผมใช Git ซึ่งระบบของ Git ยังคงเก็บประวัติทุกอยางไวยอนหลังไปเปนเดือนๆ แถมยังบอกวา
เปนการกระทำอะไร Commit, Checkout บลาๆ บอกไดหมด ฟเจอรนี้เรียกวา Reflog เราก็จะสั่ง $ git reflog
….
จากนั้นผมก็จะส่ัง $ git reset hard 2e78857
หนา 63
จากนั้นผมจะสั่ง $ git cherrypick af13edd เพื่อรวม Commit af13edd เขามา (ดูเลข Commit จาก Reflog)
สถานการณที่ 11 : Optimize
Git มีความสามารถในการปรับแตง และเคลียรขอมูลที่ไมจำเปนใน Local repo ทำให Repo เร็วสและใช
เนื้อที่นอยลง แตก็มีขอแนะนำคือมันอาจจะทำให Reflog ที่หมดอายุแลวถูกเคลียรหายไปดวย
คำสั่งท่ีใชคือ $ git gc
จะเห็นวามีการใช Delta compression ดวย
สถานการณที่ 12 : Stash ซอนการแกไข
เมื่อเราทำงานอยู เราอาจจะมีการ Pull, Merge, Rebase หรือมีการเปลี่ยนแปลงของมูลใน Working
directory แตจะทำยังไงถาเรายังทำงานคางอยูเพราะยังไมเสร็จ และยังไมอยาก Commit เราก็จะซอนการแกไข
ขอมูลดวย
$ git stash จากนั้นก็ Pull, Merge, Rebase หรือมีการเปล่ียนแปลงของมูลใน Working directory ตามตองการ
พอเสร็จแลวก็สั่ง $ git stash pop เพื่อดึงขอมูลที่เก็บไวออกมา
หนา 64
ผมลองแกขอมูล เพิ่มบรรทัดที่ 2 เขาไป
ถาสั่ง $ git status ดูจะเห็นการเปล่ียนแปลง
ใช $ git stash ซอนขอมูลไว
ถาสั่ง Git status ดูจะเห็นวา Working directory มันวางแลว (เห็นการเปลี่ยนแปลงขอมูล เพราะซอนไวแลว)
ไฟลก็จะกลับไปเหมือนเดิม
ถัดจากนั้นจะ Pull , Merge หรือ Rebase ก็ตามสบาย และเมื่อเสร็จแลวก็ใช $ git stash pop ดึงขอมูลกลับคืนมา
หนา 65
สถานการณที่ 13 : ติด Tag ให Commit
อยางที่เคยอธิบายเกี่ยวกับ Object ของ Git แลวจะเห็นวามันมี Tag object อยูดวย ยกตัวอยาง
เราสามารถใชมันไดจากคำสั่ง git tag a v1.0 d256a7f m 'Tag release V.1.0' (จะมองเห็น Tag เฉพาะเคร่ือง
เรา ถาอยากใหคนอื่นเห็นดวยตองใสพารามิเตอร tags ไปตอนที่ Push ดวย $ git push origin tags
สถานการณที่ 14 : ignore ไฟล
ไฟลบางไฟล หรือโฟลเดอรบางโฟลเดอรที่เราไมตองการใหเ Git ไปเก็บขอมูลหรือยุงเกี่ยวได เชนโฟลเดอรที่
ใชเก็บไฟล .war เพื่อเตรียม Deploy เราสามารถสั่งให Git ไมสนใจไฟลเหลานั้นได ดวยการสรางไฟลชื่อ .gitignore
ขึ้นมาแลวเอาชื่อไฟลหรือโฟลเดอรที่ไมตองการไปเก็บไวในไฟล .gitignore จากนั้นก็สั่ง $ git add .gitignore เขาไป
ในระบบ
เพียงนี้ Git ก็มองไมเห็นไฟล readyou.me แลว
หนา 66
Workflow
ถึงตอนนี้ยังงงหละซะวาจะแตก Branch อะไรกันเวลาไหน ตอนเรียนนี่ผมก็เรียกไดวาผานมาแบบรากเลือด
กันเลยทีเดียว แตก็มี Flow ที่เรานับถือเปนที่พึงที่อาศัยอยูคือ Clone โปรเจกเพื่อน > แตก Branch dev ฟเจอร
ของเรา > แกโคดบน Branch dev > เมื่อแกเสร็จแลวกอนจะ Merge กลับก็ Checkout master > Pull โคด
เวอรชั่นลาสุดลงมาอัพเดทให Branch master > Checkout branch dev > Rebase branch dev กับโคดใหม >
Checkout ไปที่ master > Merge branch dev > Push โคดกลับไปที่ Remote repo เปนอันเสร็จพิธี
ถึงแตมาดู Flow ที่เทพๆ แนะนำกัน (ผมขออธิบายตามที่ผมเขาใจนะครับ)
แตก Branch จาก master (master ติด Tag เวอรชั่น 0.1 อยางที่เคยบอกไป Tag ทำให Commit ใหเรียกไดงาย)
Dev แตก ออกมาพัฒนาฟเจอร(สีชมพู) ระหวางนั้นก็มีบั๊กเกิดขึ้น เราจึงตองแกบั๊กกอนใน hotfix (สีแดง) จากน้ันก ็
Merge กลับ Master ไดเปน master Tag 0.2 และไหนๆก็แกบ๊ักไปแลวจำให Dev เปนตัวเกาก็มีความเสียงท่ีโคด
เราจะทำงานไมถูกตอง เลย Merge hotfix มาที่ Dev
หนา 67
Merge ฟเจอร(สีชมพู) มาที่ Dev (สีเหลือง) และเขา Release (สีเขียว)
มี Checkout dev และไปพัฒนาฟเจอรตอ สวนใน Release มีการแกบั๊ค
จากนั้นก็ Merge Branch Dev ดวย Release (สีเขียว) จากนั้นก็ Merge เขา Master
มีการ Merge ฟเจอรกลับ มาที่ Dev และ Dev ก็ Merge กลับมาที่ Release และ Release ก็ Merge เขา Master
หนา 68
(cc : http://nvie.com/posts/asuccessfulgitbranchingmodel)
หนา 69
Fork และ Pull Request
Fork
ถาเราอยากไดโปรเจกของคนอื่นในโดยปกติเราก็จะ Clone จาก Remote repo ของคนอ่ืนมาแลวก็สราง
Remote repo ของเราไวจากนั้นก็ Push ขอมูลขึ้นไปไว ก็จะไดกอปปหนึ่งของ Repo ท่ีเราเปนเจาของ สามารถ
Push โคดหรือจัดการ Repo ได แต Github สรางฟงกชันการใชงานทีี่ทำใหเราทำของแบบท่ีเหมือนกันนี้ไดภายใน
การคล๊ิกเดียวเพียงครั้งเดียว เรียกวาการ Fork
(1) Login Github จากนั้นไปที่ Repository ที่ตองการ Fork
(2) กด Fork
ตัวเลขแสดงจำนวนคนที่ Fork
(3) ลองไปดูที่ Repo ของเราจะมีบอกวา Fork มาจากไหน
Pull Request
ถาเรา Fork repo มาจาก Repo ของคนอื่น Guthub จะรูวา Repo เรามีความเชื่อมโยงกัน ทำใหสามารถ
Pull Request หรือขอใหตนฉบับเอาโคดของคุณไปรวมกับของเขา ยกตัวอยางถาผม Fork ขอมูลของ Library
graph มาแลวทำการแกไข ผมไดพัฒนาฟเจอรกราฟแทงมาตัวหนึ่งเห็นวาโคดสวยไดที่แลว เลยขอใหเจาของ
Library graph ทำการ Pull Request รวมโคดกราฟแทงที่ผมสรางไปใน Repo ของเขา
ฝงของคนขอ Pull Request
(1) ไปที่ Repo ที่ Fork มา
หนา 70
Repo ที่ Fork มาแลว ผมแก็โคดเพิ่ม
(2) เมื่อเขาไปใน Repo แลวเลือก Pull Requests
(3) สราง New pull request
ลองดูประวัต ิ
ถาโอเคแลวก็กด Create pull request
เขียน Comment แลวก็กด Create pull request อีกรอบ
หนา 71
ตอนนี้ Pull Request ก็ถูกเปดแลว
ฝงของเจาของ Repo ตนฉบับ
(1) เช็ค inbox message
เมื่อกดเขาไปเจะเห็นวสามีคนขอ Update readme.txt
(2) กด Merge pull request ขอมูล
(3) Confirm merge
(4) สถานะของ Request ก็จะเปลี่ยนไป
จะเห็นวาขอมูลมีการเปล่ียนไปแลว
หนา 72
Chapter 5 : Git GUI
เห็นใช Command line มาตลอดใชวา Git จะไมมี GUI หรือ Graphical User Interface สวยๆ แบบที ่
Version control ดังๆตัวอื่นมีนะ แตที่อธิบาย แบบ Plain
Text กอนเพราะคิดวาดูขั้นตอนไดดีกวา ซึ่งการใชงาน Git GUI
เราจะมาลองใช Software ที่ชื่อวา SourceTree โดยปุมใน
แตละ OS ก็จะคลายๆ กัน
ตัวอยางการใช
ตัวอยางการ Git GUI ผมจะลองใช SourceTree ในการ Commit ไฟลท่ีเคยมีอยูในระบบของ Git แลว
และผมแกไขไฟลไป จากนั้นจะ Commit และ Push ไป
(1) เขาไปที่เว็บ http://www.sourcetreeapp.com จากน้ันก็โหลด SourceTree
(2) ติดตั้ง สวนนี้ผมไมขออธิบายครับ การติดตั้งงายมาก ถาใครติดตั้งไมไดยกเครื่องมาหาผมเดี๋ยวลงให (กลา
ยกมาก็กลาลงใหอะ)
(3) ไปที่ Settings…
(4) กด Add Account เพื่อเพิ่ม Account Git ใน SourceTree
(5) เพิ่ม Username ขอ GitHub เขาไป
หนา 73
(6) จะเห็นขอมูลของ Remote repo ที่ Add ไป
(7) ไปที่ + New Repository > Add existing local repository
(8) Browse หาจนเจอโฟบเดอรที่เก็บ Local repo ของเรา
(9) ดับเบ้ิลคลิ๊ก เขา scenario_git
(10) เมื่อเขามาจะเห็นหนาจอและขอ
(11) ไปที่ Setting แลวเลือก Advanced
(12) เลือก Use global user settings สำหรับใชการตั้งคาจาก global หรือ เอาตัวเลือกออกแลวตั้งคาเอง
หนา 74
(13) ประวัติการแกไข
(14) ลองแกไขไฟลที่อยูใน Folder ของ Repo จะเห็น Uncommitted changes
(15) ตรง Unstaged files ติ๊กเลือก แลวมันจะเดงไป Staged files ให
(16) Commit
(17) เพิ่ม Comment จากนั้นก็กด Commit
(18) หลังจาก Commit ก็จะเห็นการอัพเดท Master ก็จะยายไปแลว และ Origin ยังอยูที่เดิม
หนา 75
(19) Push ไปที่ Origin (Github) เลือก Branch master
(20) สังเกตวา master และ origin/master อัพเดทแลว
(21) ลองเขาไปดูใน Gitghub
การใชงาน Git GUI ก็ชวยอำนวยความสะดวกไดดี แตฟงกชันการทำงานก็คลายๆกับในแบบ Command
line ตัวอยางดานบนผมแสดงแควิธีการ Commit ไฟลที่แกไข แตสวนฟงกชันการทำงานอยางอ่ืนก็ไมยากเกินไปที่
จะเรียนรูดวยตัวเอง
หนา 76
Chapter 6 : บรรณานุกรม
(1) Pro Git, [Scott Chacon, Ben Straub], ISBN13: 9781484200773
(2) Pro Git Grean Edition, https://github.com/opendream/progit
(3) อยาก commit รวมกับ commit กอนหนานั้น,
http://pphetra.blogspot.com/2011/02/gitcommitcommit.html
(4) git(1) Manual Page, https://www.kernel.org/pub/software/scm/git/docs/
(5) Getting Git Right, https://www.atlassian.com/git/
(6) Software Engineering (บทที่ 5), https://sites.google.com/site/chanwit/courses/se562
(7) มาเริ่มใชงาน Feature Branch กับ Pull Request กัน,
http://www.narisa.com/forums/index.php?app=blog&blogid=9&showentry=3070
(8) git lol the other git log, http://uberblo.gs/2010/12/gitloltheothergitlog
(9) Git workflow, http://scottchacon.com
(10) Git introduction, http://en.oreilly.com/rails2008/public/asset/attachment/2816
(11) Git Magic by Ben Lynn Students of Stanford,
http://wwwcsstudents.stanford.edu/~blynn/gitmagic/book.pdf
(12) สราง Git Alias สำหรับคำส่ังที่ใชงานบอย, http://armno.in.th/2012/10/25/creatinggitalias
(13) version control Delta Storage,
http://versioncontrol.net/versioncontrolhowto/versioncontroldeltastorage
Thanks Wikipedia, Google, StackOverflow, Github and another source. :)
หนา 77
คนเขียน
ปกติผมเขียน Blog เพื่อทบทวนและเผยแพรขอมูลพวกนี้แตผมพบวาปญหาของการเขียน Blog คือขอมูลไม
คอยจัดเรียงเปนระเบียบเวลาจะอานหาอานยาก(ถึงจะมีติด Tag ก็เถอะ) เลยกะจะเขียนเร่ือง Git ใหเปนเรื่องเปน
ราวเลยนาจะดีกวา พอเริ่มเขียนไปก็พบวามีหลายคำสั่งและขอมูลหลายสวนที่ผมก็ไมเคยรู แตจำเปนตองรู หรือรูไว
จะมีประโยชนผมก็ไปหาขอมูลแลวก็เอามาเพ่ิมเปนเอกสาร เพ่ิมไปเพิ่มมามันก็เยอะไปเร่ือยเลยทำเปนหนังสือมันซะ
เลย ดังนั้นหากผิดพลาดสวนไหนก็ขอใหแจงผมมาดวยจะดีมากครับ
ขอสารภาพมา ณ ที่นี้วาตอนเรียนนี่แอบลักไกกันเปนประจำ พอใชๆไปแลว
มีปญหา มึนตึ๊บ ก็ลบ Git ทั้งโฟลเดอรออก แลว Clone ลงมาใหมประจำ (>.<)” แต
ก็ยังดีที่มี Community ที่พอจะเปนที่พึ่งที่อาศัยไดถาใครมีคำถามขอสงสัยก็ลอง
เขาไปดูกันไดที่กลุม “Gitฮับ” :
https://www.facebook.com/groups/440497309296387
สุดทายหนังสือเลมนี้ใชสัญญาอนุญาต Creative Common 4.0 ซึ่งสามารถทำ
ซ้ำ ทำสำเนา เผยแพรตอ แกไข และใชไดสำหรับงานทุกวัตถุประสงคแมแตทำการคาก็
ใชได แตจำเปนตองแสดงแหลงที่มาของเอกสารน้ี
สามารถติดตอผมไดทาง
Email : [email protected]
Website : www.iaor.com
WebBlog : aorjoa.blogspot.com
GitHub : https://github.com/Aorjoa
“ขอ Source code จงสถิตอยูแดทาน”