Gitbook2. ÿารบัญ
เรื่อง Āนšา
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
3. ÿถานการณŤที่ 13 : ติด Tag ใĀš Commit 65
ÿถานการณŤที่ 14 : ignore ไฟลŤ65
Workflow 66
Fork และ Pull Request 69
Chapter 5 : Git GUI
ตัวอยŠางการใชš72
Chapter 6 : บรรณานุกรม
บรรณานุกรม 76
คนเขียน 77
4. Āนšา 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 ซึ่งĀากไมŠÿำเร็จมันก็จะเรียกขšอมูล
กŠอนĀนšาซึ่งทำงานไดšปกติมาใชš
5. Āนšา 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
6. Āนšา 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
7. Āนšา 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 เดือนในการเอาโปรเจกออกไปจาก
8. Āนšา 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 ตŠอ
9. Āนšา 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 ไป
10. Āนšา 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 ในแตŠละรุŠนไลŠมาจนถึงรุŠนที่ตšองการ
11. Āนšา 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 ไดš)
12. Āนšา 9
ระบบ Git Snapshot จะนำไฟลŤไปเขšาฟŦงกŤชัน Hash ที่ชื่อüŠา SHA1
(ชื่อเลŠนüŠาชาละüัน) ขนาด 160 Bits
ซึ่งตัü SHA1
จะนำขšอมูลไปปูŜยี้ปูŜยำแลšüใĀšคŠาออกมาคŠาĀนึ่งคüามยาü 40 ตัüอักþร (09
และ af)
เรียกüŠา
Checksum ซึ่งเมื่อมีขšอมูลเปลี่ยนไป คŠา Checksum ของมันก็จะเปลี่ยนตามไปดšüย ถึงแมšขšอมูลจะตŠางกันแคŠบิท
เดียü Checksum ก็จะÿามารถระบุคüามแตกตŠางไดš ดังนั้นมันจึงใชšเอาไüšบอกüŠาไฟลŤมีการเปลี่ยนแปลงĀรือไมŠและ
ยืนยันüŠาขšอมูลไมŠเกิดคüามผิดพลาด แตŠไมŠนานมานผมไดšขŠาüüŠา SHA1
ไมŠปลอดภัยแลšüครับ
ลšอเลŠนครับ มันเกิดจากการที่นักüิจัยพบüŠาแมšมันจะมี 160 Bits แตŠคüามปลอดภัยที่แข็งแกรŠงมีเพียง 60 Bits
13. Āนšา 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
14. Āนšา 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 ไป)
15. Āนšา 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 กŠอน
ไดš
16. Āนšา 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 ไĀนบšางถึงจะทำใĀšเรากูšขšอมูลคืนมาไดšถูกตšอง
17. Āนšา 14
Commit
เก็บขšอมูลที่ใชšในการอšางอิงถึง Tree และขšอมูลประüัติของ Commit นั้นๆ
+ Tree บอกüŠามันอšางอิงไปที่ Tree ไĀน จะไดšตามไฟลŤไปไดšถูก
+ Parent บอก Commit กŠอนĀนšามัน
+ Author บอกคนที่ทำĀนšาที่รับผิดชอบการเปลี่ยนแปลง
+ Committer คือชื่อคนที่ Commit เขšามาในระบบ
Object Model
18. Āนšา 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
19. Āนšา 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
20. Āนšา 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 อีกครั้ง ดังนั้นเราไมŠไดš
21. Āนšา 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
22. Āนšา 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 ก็จะเĀ็นÿถานะของไฟลŤ
23. Āนšา 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
24. Āนšา 21
$ git commit
ใชšยืนยันüŠาเราตšองการเก็บไฟลŤที่อยูŠใน Staging area ลงไปไüšใน Git Repository จริงๆ ÿั่งไดšโดยใขš $ git
commit ตามดšüยตัüเลือก และพารามิเตอรŤของตัüเลือก โดยปกติแลšüตัüเลือกที่ใชšก็จะใชšแคŠ m
และมีพารามิเตอรŤ
คือขšอคüามคอมเมนตŤÿั้นๆลงไปใน Commit เüลากลับมาดูจะไดšดูงŠายขึ้นüŠาที่คอมมิทนั้นเราทำอะไรกับมันไป
$ git commit m
"Initial Git basic" แตŠถšาพลาดมือ Commit ไปแลšüแตŠตšองการแกšไขไฟลŤ
25. Āนšา 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
26. Āนšา 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
27. Āนšา 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
28. Āนšา 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 ปŦจจุบัน)
29. Āนšา 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 ÿองตัüที่มีขšอมูลเĀมือนกัน เüลามาดูก็จะงง
ปล. ถšาอŠานไมŠรูšเรื่องก็ลืมๆมันไปกŠอน ฝřกปรือเดินลมปรานเพียงพอแลšüคŠอยกลับมาแกšแคšนก็ยังมิÿาย
30. Āนšา 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
31. Āนšา 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 และการอŠานเนื้อĀาเพิ่มเติมจะทำใĀšทŠานมีบารมีแกŠ
กลšาขึ้น จากนั้นคŠอยกลับมาอŠานอีกก็จะเขšาใจไดšไมŠยาก
32. Āนšา 29
Chapter 3 : Installation
Āลังจากที่เรารูšขšอมูลเบื้องตšนเกี่ยüกับ Version control, ประüัติของ Git และคำÿั่งพื้นฐานของ Git ไปแลšü
ก็ถึงขั้นตอนที่ยากที่ÿุดในการที่จะใชšงาน Git ก็คือขั้นตอนการติดตั้งเนี่ยแĀละฮะทŠานผูšชม
========================================================================
3.1 Windows
========================================================================
1) ไปที่ http://gitscm.
com/downloads
กด Download ของ Windows แลšüรอโĀลด
2) ติดตั้ง Git ลงในเครื่อง
ถšามีการเตือนก็กดตามภาพดšานลŠางเลย ถšาไมŠมีก็ผŠานไปไดšเลย
35. Āนšา 32
เลือก Component üŠาจะเอาอะไรไüš เอาอะไรออก กด Next ไดšเลย
กำĀนดชื่อของ Shortcut กด Next
36. Āนšา 33
ตัüเลือกแรก : ใชšคำÿั่ง Git ไดšเฉพาะใน Git Bash
ตัüเลือกที่ÿอง : แกšไข Windows Command Prompt ใĀšÿามารถใชšคำÿั่ง Git ไดšดšüย แนะนำใĀšเลือกตัüนี้
ตัüเลือกÿุดทšาย : แกšไข Windows Command Prompt ใĀšÿามารถใชšคำÿั่ง Git และติดตั้งคำÿั่งที่คลšายของ UNIX
ลงไปดšüย (มีคำเตือนüŠาบางคำÿั่งอาจจะทับกัน ซึ่งอาจจะทำใĀšการใชšงาน Command ใน CMD เปลี่ยนไป)
จากนั้น กด Next
37. Āนšา 34
เปŨนตัüเลือกในการจบบรรทัด ใĀšเลือกตัüเลือกแรก เพราะการจบบรรทัดของ Windows กับของตระกูล UNIX เนี่ย
จะไมŠเĀมือนกัน การเลือกตัüเลือกนี้จะทำใĀšÿามารถทำงานขšาม Platform ไดšโดยไมŠติดปŦญĀานี้ จากนั้นกด Next
38. Āนšา 35
เมื่อติดตั้งเÿร็จแลšüกด View ReleaseNotes.rtf ถšาตšองการอŠานไฟลŤขšอมูลประüัติการแกšไข จากนั้น Finish ไป
ลองเขšา Git bash ดูโดยไปที่ Start menu > All
Programs > Git > Git bash จากนั้นลองใชšคำ
ÿั่ง git version ลองüŠาทำงานไดšจริงไĀม
ถšาขึ้นเลข Version ของ Git ก็เปŨนอันใชšไดš
41. Āนšา 38
Āลังจากติดตั้งเÿร็จแลšüใĀšเปŗด Terminal แลšüลองพิมพŤ git version แลšüแÿดงผลออกมาแบบนี้เปŨนใชšไดš
========================================================================
3.3 Others operating system
========================================================================
ในระบบปฏิบัติการอื่นก็ÿารมารถ Donwload และติดตั้งไดšตามลิงกŤ http://gitscm.
com/downloads üิธีการติด
ตั้งก็คลšายๆกัน
42. Āนšา 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 ขึ้นมาใชšงาน
43. Āนšา 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 ชื่อไฟลŤ
44. Āนšา 41
แตŠถšาเราแกšไขไฟลŤจะมีคำÿั่ง 2 แบบที่ทำไดš คือการเพิ่มไฟลŤเขšาใน Commit แบบปกติ ($ git add ชื่อไฟลŤ) และไมŠ
เก็บไฟลŤเüอรŤชั่นนั้นไüšใน Commit นั้น แตŠเอาไüš Commit ĀลังตอนĀลังก็ไดš ($ git checkout ชื่
อไฟลŤ)
การลบไฟลŤ ÿั่ง $ git rm ชื่อไฟลŤ ไดšเลย แตŠถšาเปŨน โฟลเดอรŤตšองใÿŠพารามิเตอรŤ r
ใĀš recursive ไฟลŤในโฟลเดอรŤ
ÿั่ง $ git rm r
ชื่อโฟลเดอรŤ มันตŠางจากการลบปกติตรงที่นอกจากไฟลŤจะĀายไปจากโฟลเดอรŤแบบปกติแลšü Git ยัง
รูšดšüยüŠาเราลบไฟลŤออกไปจาก Working directory ของเรา
การเปลี่ยนชื่อ ก็ใชš $ git mv ชื่อไฟลŤปŦจจุบัน ชื่อไฟลŤที่จะเปลี่ยน
45. Āนšา 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)
46. Āนšา 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 ติดมาแลšü
47. Āนšา 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 คือมันÿามารถใĀšเฉพาะคนที่ÿิทธิ์ถึงจะดูโคšดไดš
48. Āนšา 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"
49. Āนšา 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
50. Āนšา 47
จากนั้นก็ไปที่Āนšาเü็บของ github.com เพื่อเพิ่ม Public key ของเราที่ÿรšางเมื่อกี้ใĀš github รูšจัก กดปุśม Setting
> SSH Keys > กรอก Title (ปกติจะใÿŠชื่อเครื่องคอม) > üางคียŤที่กŢอปปŘŪมาจากในชŠอง Key > กด Add key
เปŨนอันเรียบรšอย
(5) ÿรšาง Repository
> กด New repository
> ตั้งชื่อ Repo
51. Āนšา 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 git@github.com:aorjoabook/basic_git.git
(7) ลอง Push ขšอมูลไปเก็บที่ Repo ที่เราÿรšาง
มา ÿั่ง $ git push origin master
ถšาใÿŠ Passphrase ไüšจะมี Dialog ขึ้นมาถาม
52. Āนšา 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 เĀมือนยังกะกŢอปกันมา)
53. Āนšา 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 ดูประüัติอีกที