Top Banner
ฉบับอนุบาล ๒ @AorJoa
80

Git ฉบับอนุบาล 2

Jun 27, 2015

Download

Education

หนังสือการใช้งาน Git ฉบับไล่แจกฟรี แต่ไม่รู้จะมีใครเอาไหม
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Git ฉบับอนุบาล 2

ฉบับอนุบาล ๒

@AorJoa

Page 2: Git ฉบับอนุบาล 2

สารบัญ เรื่อง หนา

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 กับ 3­way Merge 55

สถานการณที่ 7 : จัดการ Branch 56

สถานการณที่ 8 : แกไข Commit หรือ History 58

สถานการณที่ 9 : ดู Difference 60

สถานการณที่ 10 : งานหาย แกไดดวย Reflog 62

สถานการณที่ 11 : Optimize 63

สถานการณที่ 12 : Stash ซอนการแกไข 63

Page 3: Git ฉบับอนุบาล 2

สถานการณที่ 13 : ติด Tag ให Commit 65

สถานการณที่ 14 : ignore ไฟล 65

Workflow 66

Fork และ Pull Request 69

Chapter 5 : Git GUI ตัวอยางการใช 72

Chapter 6 : บรรณานุกรม บรรณานุกรม 76

คนเขียน 77

Page 4: Git ฉบับอนุบาล 2

หนา 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 ซึ่งหากไมสำเร็จมันก็จะเรียกขอมูล

กอนหนาซึ่งทำงานไดปกติมาใช

Page 5: Git ฉบับอนุบาล 2

หนา 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

Page 6: Git ฉบับอนุบาล 2

หนา 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

Page 7: Git ฉบับอนุบาล 2

หนา 4

1.2 ประวัติของ Git

กาลครั้งหนึ่งนานมาแลวตอนพัฒนา Linux kernel ใหมๆ ประมาณป

ค.ศ. 1991­2002 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 ถูกกลาวหาวาเขาใชวิธี Reverse­engineered เพื่อดูการทำงาน

ของ BitKeeper ดังนั้น Larry จึงโมโหบอกวา Tridge ไมไดจายตังคซื้อ

ซอฟแวร และใครที่ไมซื้อซอฟแวรก็ไมมีสิทธิ์ที่จะไดดู Metadata ของซื้อ

ของขาย จบปะ? Tridge ก็สวนกลับวามันไมไดผิดกฏนะเออที่จะด ู

Metadata เพราะ BitKeeper และ SourcePuller ตางก็ใชฟรีเหมือนกันแตสรางขึ้นมาปนทางเลือกใหผูใช แถมไอ

Metadata เนี่ยชาวบานชาวชองเขาก็ไมไดปดกันหรอก บางที่สนับสนุนกันดวยซ้ำและวิเคราะหแค Telnet เขาไป

BitKeeper server แลวสั่งคำสั่ง HELP เทานั้นและเขาก็ไมเคยใช BitKeeper client ดวย ยังไงก็ยืนยัน นั่งยัน นอน

ยัน ตีลังกายัน วาทำถูกกฏหมายและอยูในศีลธรรมอันดี สวนปา Linus ก็ไมเห็นดวยกับการกระทำของ Tridge ถึง

กับบอกวาเปนวิธีการที่ Tridge ทำเปนวิธีที่สกปรก และก็ขอให Tridge หยุด แตตัว Tridge ตนเหตุก็ยืนกรานวาสิ่งที่

เขาทำถูกตองแลว Larry จึงบอกวาถางั้นก็ไมตองชงตองใชมันแหละ ใหเวลา 3 เดือนในการเอาโปรเจกออกไปจาก

Page 8: Git ฉบับอนุบาล 2

หนา 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 หลังจากนั้นเร่ิม

Self­hosting (ใชตัว Git เองดูแล Source code ของ Git เอง) ในวันที่ 7 เมษายน, สามารถรวม Branch ที่แตก

ออกมาไดในวันที่ 18 เมษายน และไดประสิทธิภาพตามที่คาดหวังในวันที่ 29 เมษายน (ทำ Patch Linux kernel

Tree ไดในเวลา 6.7 วินาที) หลังจากนั้นในที่ 26 กรกฏาคม 2005 Linus ให Junio Hamano เปนคนดูแล Git ตอ

Page 9: Git ฉบับอนุบาล 2

หนา 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 ไป

Page 10: Git ฉบับอนุบาล 2

หนา 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 ในแตละรุนไลมาจนถึงรุนที่ตองการ

Page 11: Git ฉบับอนุบาล 2

หนา 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 ได)

Page 12: Git ฉบับอนุบาล 2

หนา 9

ระบบ Git Snapshot จะนำไฟลไปเขาฟงกชัน Hash ที่ช่ือวา SHA­1 (ชื่อเลนวาชาละวัน) ขนาด 160 Bits

ซึ่งตัว SHA­1 จะนำขอมูลไปปูยี้ปูยำแลวใหคาออกมาคาหนึ่งความยาว 40 ตัวอักษร (0­9 และ a­f) เรียกวา

Checksum ซึ่งเมื่อมีขอมูลเปลี่ยนไป คา Checksum ของมันก็จะเปล่ียนตามไปดวย ถึงแมขอมูลจะตางกันแคบิท

เดียว Checksum ก็จะสามารถระบุความแตกตางได ดังนั้นมันจึงใชเอาไวบอกวาไฟลมีการเปลี่ยนแปลงหรือไมและ

ยืนยันวาขอมูลไมเกิดความผิดพลาด แตไมนานมานผมไดขาววา SHA­1 ไมปลอดภัยแลวครับ

ลอเลนครับ มันเกิดจากการที่นักวิจัยพบวาแมมันจะมี 160 Bits แตความปลอดภัยท่ีแข็งแกรงมีเพียง 60 Bits

Page 13: Git ฉบับอนุบาล 2

หนา 10

จะเห็นวาในแตละ Git Snapshot จะมีเลขกำกับไว 40 ตัวอักษรซึ่งเปนคาของ

Checksum แตละ Snapshot ที่เห็นมีแค 3 ตัวเชน c3d, f13, 6d4 และ 84f ก็อยา

เพิ่งแกลงงง เขายอเหลือ 3 ตัวแรกเฉยๆใส 40 ตัวมามันเยอะไป (แค 3 ตัวพอแลวไม

ซ้ำกันแลว) และส่ิงที่ Git Commit บอกในตอน Commit ก็คือคู Key­Value ของ

แตละไฟลโดย 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

Page 14: Git ฉบับอนุบาล 2

หนา 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 ไป)

Page 15: Git ฉบับอนุบาล 2

หนา 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 กอน

ได

Page 16: Git ฉบับอนุบาล 2

หนา 13

­ Git object model

อยางที่เคยบอกไววาในการเก็บประวัติไฟลไว Git จะนำไฟลไปเขาฟงกชัน Hash ดวย SHA­1 จำนวน 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 น้ันที่มีคา

SHA­1 คาใด มีชื่อไฟลวาอะไร (คลายกับโฟลเดอรที่เอาไวเก็บไฟลหรือโฟลเดอรยอยๆไดอีก) Tree จะบอกเราวา

ตองเดินไปหา Snapshot ไหนบางถึงจะทำใหเรากูขอมูลคืนมาไดถูกตอง

Page 17: Git ฉบับอนุบาล 2

หนา 14

­ Commit เก็บขอมูลที่ใชในการอางอิงถึง Tree และขอมูลประวัติของ Commit น้ันๆ

+ Tree บอกวามันอางอิงไปที่ Tree ไหน จะไดตามไฟลไปไดถูก

+ Parent บอก Commit กอนหนามัน

+ Author บอกคนที่ทำหนาที่รับผิดชอบการเปลี่ยนแปลง

+ Committer คือชื่อคนที่ Commit เขามาในระบบ

Object Model

Page 18: Git ฉบับอนุบาล 2

หนา 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

Page 19: Git ฉบับอนุบาล 2

หนา 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

Page 20: Git ฉบับอนุบาล 2

หนา 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 อีกครั้ง ดังนั้นเราไมได

Page 21: Git ฉบับอนุบาล 2

หนา 18

แกขอมูลที่ Master ตรงๆ แตเราใชวิธีพัฒนาที่อื่นแลวรวมกลับทำให Master ทำงานไดเสมอ ดังนั้นเราจึงไมมีบาป

ติดตัว

2.2 คำส่ังพื้นฐานของ Git $ git config

เปนคำส่ังที่ใชกำหนดขอมูลสวนตัวของผูพัฒนา

แตละคน ทำใหรูวาใครทำอะไรไดใน Log ของ Git

ซึ่งตัวที่เราจะตั้งคากันบอยๆ ก็เชน

$ git config ­­global user.name “AorJoa”

ใชตั้งคาชื่อผูใช

$ git config ­­global user.email aorjoa@i­aor.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

Page 22: Git ฉบับอนุบาล 2

หนา 19

$ git clone

กรณีที่เรามีโปรเจกใน Remote Repo อยูแลว และเราก็ตองการที่จะดึงขอมูลออกมาใช ลักษณะการ

ทำงานก็คลายกับ Git init ที่เปนการเริ่มตนโปรเจกจากการที่ไมมีอะไรเลย แต Git clone นั้นไมไดเริ่มตนใหมซะที

เดียว เพราะมันคือการนำเอาขอมูลใน Remote Repo ที่เจาของโปรเจกเขาสรางไวแลวมาแกตอ ซึ่งจะมีขอมูลเกือบ

ทั้งหมดในโฟลเดอร .git ของคนอ่ืนติดมาดวย ตัวอยางนี้ลอง Clone มาจาก Repo

https://github.com/chanwit/spock­report­html.git

$ git clone https://github.com/chanwit/spock­report­html.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 ก็จะเห็นสถานะของไฟล

Page 23: Git ฉบับอนุบาล 2

หนา 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

Page 24: Git ฉบับอนุบาล 2

หนา 21

$ git commit

ใชยืนยันวาเราตองการเก็บไฟลที่อยูใน Staging area ลงไปไวใน Git Repository จริงๆ สั่งไดโดยใข $ git

commit ตามดวยตัวเลือก และพารามิเตอรของตัวเลือก โดยปกติแลวตัวเลือกท่ีใชก็จะใชแค ­m และมีพารามิเตอร

คือขอความคอมเมนตสั้นๆลงไปใน Commit เวลากลับมาดูจะไดดูงายขึ้นวาที่คอมมิทนั้นเราทำอะไรกับมันไป

$ git commit ­m "Initial Git basic" แตถาพลาดมือ Commit ไปแลวแตตองการแกไขไฟล

Page 25: Git ฉบับอนุบาล 2

หนา 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

Page 26: Git ฉบับอนุบาล 2

หนา 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

Page 27: Git ฉบับอนุบาล 2

หนา 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/spock­report­html.git) เวลาเรา

จะปรับมันใหเปนรุนใหมเราก็ push โคดชุดใหมขึ้นไปใหมันแทน โดยใชคำสั่ง git push แลวตามดวย Remote

repo และ Branch (ปกติแลวชื่อ Branch จะตรงกันทั้งที่ Local และ Remote และใส Branch เพราะเราสงไปแค

master ตัวเดียว)

$ git push origin master

Page 28: Git ฉบับอนุบาล 2

หนา 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 ปจจุบัน)

Page 29: Git ฉบับอนุบาล 2

หนา 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 สองตัวที่มีขอมูลเหมือนกัน เวลามาดูก็จะงง

ปล. ถาอานไมรูเรื่องก็ลืมๆมันไปกอน ฝกปรือเดินลมปรานเพียงพอแลวคอยกลับมาแกแคนก็ยังมิสาย

Page 30: Git ฉบับอนุบาล 2

หนา 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

Page 31: Git ฉบับอนุบาล 2

หนา 28

$ git revert

เปนคำส่ังที่ใชยอนประวัติการทำงาน

กลับไปรุนกอนๆหนา คำสั่งนี้ปลอดภัยกวา $

git reset เพราะโดยปกติแลวมันจะสราง

Commit ใหมโดยไมไปยุงกับของเดิม จาก

ตัวอยางผมใชคำส่ัง

$ git revert ­­no­edit ed51e23..HEAD

บอกวาใหยอนจาก Commit ed51e23 ไป

จนถึง HEAD ซึ่งก็คือตำแหนงที่เราอยูปจจุบัน

(ที่ทำอยางนี้เพราะปองการ Conflict หรือ

การแกไขไฟลชนกันในกรณีที่เราแกไฟลหลาย

ครั้ง) เลยจะเห็นวา มี Commit ใหมโผลขึ้นมา 2 ตัว คือ ca764a3 กับ 4e8849b และในคำสั่งผมใส ­­no­edit

เพราะตองการใชขอความ Comment ใน Commit เปนคาตั้งตนของระบบ คือ Revert แลวตามดวย Comment

ที่อยูใน Commit ตัวตนแบบ ถาสังเกตจะเห็นวาเวลา Revert มันยอนกลับจาก Commit ใหมกวาไปหาเกากวา

(Add line two ใหมกวา Add line one)

จะเห็นวาคำสั่งบางคำสั่งที่ผมยกตัวอยางมาหลายๆ ตัวเราสามารถใชแทนกันได และบางตัวมีการใช

พารามิเตอรเพื่อความงายในการใชงาน หากอานการใชงานคำสั่งขางบนแลวยังรูสึกงงก็ไมแปลกเพราะบางคำส่ังเกี่ยว

เนื่องกันเปน Flow ตอกัน หรือใชงานรวมกัน การลองใชงาน Git และการอานเนื้อหาเพิ่มเติมจะทำใหทานมีบารมีแก

กลาขึ้น จากนั้นคอยกลับมาอานอีกก็จะเขาใจไดไมยาก

Page 32: Git ฉบับอนุบาล 2

หนา 29

Chapter 3 : Installation

หลังจากที่เรารูขอมูลเบ้ืองตนเกี่ยวกับ Version control, ประวัติของ Git และคำสั่งพื้นฐานของ Git ไปแลว

ก็ถึงข้ันตอนที่ยากที่สุดในการที่จะใชงาน Git ก็คือขั้นตอนการติดตั้งเนี่ยแหละฮะทานผูชม

========================================================================

3.1 Windows

========================================================================

1) ไปที่ http://git­scm.com/downloads

กด Download ของ Windows แลวรอโหลด

2) ติดตั้ง Git ลงในเครื่อง

ถามีการเตือนก็กดตามภาพดานลางเลย ถาไมมีก็ผานไปไดเลย

Page 33: Git ฉบับอนุบาล 2

หนา 30

ตัว Installer จะเดงขึ้นมา กด Next ไปเลย

Page 34: Git ฉบับอนุบาล 2

หนา 31

ตัวนี้เปนคำอธิบายลิขสิทธิ์การใชงาน กด Next ไป

เลือก Directory ปลายทางที่จะเอาไฟลของ Git ไปเก็บไว จากนั้นกด Next

Page 35: Git ฉบับอนุบาล 2

หนา 32

เลือก Component วาจะเอาอะไรไว เอาอะไรออก กด Next ไดเลย

กำหนดชื่อของ Shortcut กด Next

Page 36: Git ฉบับอนุบาล 2

หนา 33

ตัวเลือกแรก : ใชคำส่ัง Git ไดเฉพาะใน Git Bash

ตัวเลือกที่สอง : แกไข Windows Command Prompt ใหสามารถใชคำส่ัง Git ไดดวย แนะนำใหเลือกตัวนี ้

ตัวเลือกสุดทาย : แกไข Windows Command Prompt ใหสามารถใชคำสั่ง Git และติดต้ังคำสั่งที่คลายของ UNIX

ลงไปดวย (มีคำเตือนวาบางคำส่ังอาจจะทับกัน ซึ่งอาจจะทำใหการใชงาน Command ใน CMD เปล่ียนไป)

จากนั้น กด Next

Page 37: Git ฉบับอนุบาล 2

หนา 34

เปนตัวเลือกในการจบบรรทัด ใหเลือกตัวเลือกแรก เพราะการจบบรรทัดของ Windows กับของตระกูล UNIX เน่ีย

จะไมเหมือนกัน การเลือกตัวเลือกนี้จะทำใหสามารถทำงานขาม Platform ไดโดยไมติดปญหานี้ จากน้ันกด Next

Page 38: Git ฉบับอนุบาล 2

หนา 35

เมื่อติดตั้งเสร็จแลวกด View ReleaseNotes.rtf ถาตองการอานไฟลขอมูลประวัติการแกไข จากน้ัน Finish ไป

ลองเขา Git bash ดูโดยไปที่ Start menu > All

Programs > Git > Git bash จากนั้นลองใชคำ

สั่ง git version ลองวาทำงานไดจริงไหม

ถาขึ้นเลข Version ของ Git ก็เปนอันใชได

Page 39: Git ฉบับอนุบาล 2

หนา 36

========================================================================

3.2 Mac OS X

========================================================================

1) ไปที่ http://git­scm.com/downloads แลวก็ Download ตัวติดตั้งใน Mac OS X มา

2) ติดตั้ง Git ลงในเครื่อง

Page 40: Git ฉบับอนุบาล 2

หนา 37

กด Continue รัวๆไดเลย

Page 41: Git ฉบับอนุบาล 2

หนา 38

หลังจากติดตั้งเสร็จแลวใหเปด Terminal แลวลองพิมพ git version แลวแสดงผลออกมาแบบนี้เปนใชได

========================================================================

3.3 Others operating system

========================================================================

ในระบบปฏิบัติการอื่นก็สารมารถ Donwload และติดตั้งไดตามลิงก http://git­scm.com/downloads วิธีการติด

ตั้งก็คลายๆกัน

Page 42: Git ฉบับอนุบาล 2

หนา 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@i­aor.com ใชตั้งคา Email

$ git config ­­global color.ui true

$ git config ­­global user.ui true

ขอมูลขางบนเปน 2 คำส่ังแรกเปนขอมูลของผมนะ อยาลืมเปลี่ยนเปนของตัวเอง ไมงั้นผิดมหันตยังกะลอกการบาน

แลวลอกชื่อเพื่อนมาดวยยังไงยังงั้น

จากนั้นมาดูตัว Git ซึ่งมี flow แบบที่งายที่สุดในการที่เราจะเก็บโคดดังนี้ครับ

สำหรับมือใหมไมมีอะไรที่จะดีไปกวาการพิมพตามตัวอยางแลวหละครับ ดังน้ันก็จัดการเลยครับสรางโฟลเดอรขึ้นมา

สักที่หน่ึงแลว ส่ังไปเลย $ git init เริ่มสรางระบบ Repository ของ Git ขึ้นมาใชงาน

Page 43: Git ฉบับอนุบาล 2

หนา 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 ชื่อไฟล

Page 44: Git ฉบับอนุบาล 2

หนา 41

แตถาเราแกไขไฟลจะมีคำส่ัง 2 แบบที่ทำได คือการเพิ่มไฟลเขาใน Commit แบบปกติ ($ git add ชื่อไฟล) และไม

เก็บไฟลเวอรชั่นนั้นไวใน Commit น้ัน แตเอาไว Commit หลังตอนหลังก็ได ($ git checkout ­­ ชื่อไฟล)

การลบไฟล สั่ง $ git rm ชื่อไฟล ไดเลย แตถาเปน โฟลเดอรตองใสพารามิเตอร ­r ให recursive ไฟลในโฟลเดอร

สั่ง $ git rm ­r ชื่อโฟลเดอร มันตางจากการลบปกติตรงที่นอกจากไฟลจะหายไปจากโฟลเดอรแบบปกติแลว Git ยัง

รูดวยวาเราลบไฟลออกไปจาก Working directory ของเรา

การเปลี่ยนชื่อ ก็ใช $ git mv ช่ือไฟลปจจุบัน ชื่อไฟลที่จะเปลี่ยน

Page 45: Git ฉบับอนุบาล 2

หนา 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)

Page 46: Git ฉบับอนุบาล 2

หนา 43

ถาจะดูประวัติการทำงานก็ดูไดจากคำสั่ง $ git log ก็จะมีประวัติการ Commit โผลขึ้นมา

และนั่นคือ Flow ปกติที่เราใช Git เริ่มเก็บประวัติการแกไขไฟลครับ ถาหากเรามี Repo อยูแลวหรือตองการจะ

Clone มาจากที่อื่นเชน Github ก็แคเปล่ียนคำสั่ง $ git init เปน $ git clone แลวตามดวยที่อยู Repo

$ git clone https://github.com/chanwit/spock­report­html.git ใช Clone ขอมูลจาก Remote Repo

โคดที่ไดมาจะเปนโคดที่ตนทางมีการสรางไวแลว สวนการทำงานก็เหมือนกับการเริ่มโปรเจกใหมดวยตัวเองครับ ตาง

กันที่จะมีโคดและ Remote repo ติดมาแลว

Page 47: Git ฉบับอนุบาล 2

หนา 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 เขาหละ >__<”) เอาเปนวาเร่ิมตนแบบ

Step­by­Step กันเลยนะ

(1) ไปที่ https://www.github.com แลวก็สมัครสมาชิก

กรอกขอมูล

กด Sign up for GitHub

(2) เลือกแผนการใชและแนนอนผมเลือกตัวสุดทายเพราะใชฟรี (แตถาใครยังเรียนอยูก็ขอเขาใช Micro Plan

ไดนะครับฟรีผมเคยขอมาแลว) ขอดีของ Provate repo คือมันสามารถใหเฉพาะคนที่สิทธ์ิถึงจะดูโคดได

Page 48: Git ฉบับอนุบาล 2

หนา 45

(3) กด Finish sign up ไปไดเลยจากนั้นก็ไปเช็ค Email ที่เรากรอกไปจะเห็นเมลที่สงมาจาก Github เพ่ือขอ

ยืนยันตัวตน ก็ใหเรากด link มา แลวกด Confirm เปนอันจบพิธีการสมัคร แตยังเหลือการเพิ่มใบรับรองผู

ใชกับสราง Repo

(4) เพิ่มใบรับรองผูใช ตอนที่เรา Connect เขามาเพื่อ Pull หรือ Push ขอมูลเขามาที่ Github แลว Github

จะรูไดไงวาคุณเปนตัวจริง ลำพังชื่อกับ Email มันก็ปลอมกันไดงายๆ ดังน้ัน Github จึงใชการรับรอง SSH

key (Secure Shell key) ยืนยันตัวผูใชซึ่งเปนแบบ Public­key cryptography เวลาสรางจะไดไฟลสอง

ไฟลคือ Public key (นามสกุล .pub) กับ Private Key (ไมมีนามสกุล) คียทั้งสองสามารถใชเขารหัสขอมูล

ได แตถาจะเปดอานตองใชอีกใบที่เปนคูกัน ถาใช Public key ในการเขารหัสตองถอดรหัสดวย Private

Key เทานั้น และในทางกลับกันถาเขารหัสดวย Private Key ตองถอดรหัสดวย Public key เทานั้น จะใช

ตัวที่เขารหัสตัวมันเองถอดรหัสตัวมันเองไมได ดังนั้นวิธีการน้ีทำใหรับรองสิทธิ์วาผูรับและผูสงเปนคนที่เรา

ตองการจริงๆ เพราะจะมีแคผูรับและผูสงเทานั้นที่มีคียเปดอานของกันและกันได

เราจะสง Public key ไปเก็บไวที่ Github และเก็บ Private key ไวที่เครื่องเรา วิธีการสราง SSH key ใหสั่ง

$ ssh­keygen ­t rsa ­C "aorjoa@i­aor.com"

­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

Page 49: Git ฉบับอนุบาล 2

หนา 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

Page 50: Git ฉบับอนุบาล 2

หนา 47

จากนั้นก็ไปที่หนาเว็บของ github.com เพื่อเพิ่ม Public key ของเราที่สรางเมื่อก้ีให github รูจัก กดปุม Setting

> SSH Keys > กรอก Title (ปกติจะใสชื่อเครื่องคอม) > วางคียที่กอปปมาจากในชอง Key > กด Add key

เปนอันเรียบรอย

(5) สราง Repository

> กด New repository

> ตั้งชื่อ Repo

Page 51: Git ฉบับอนุบาล 2

หนา 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 ขึ้นมาถาม

Page 52: Git ฉบับอนุบาล 2

หนา 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 เหมือนยังกะกอปกันมา)

Page 53: Git ฉบับอนุบาล 2

หนา 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 ดูประวัติอีกที

Page 54: Git ฉบับอนุบาล 2

หนา 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 ­­no­edit 8ba8bb9..HEAD

Page 55: Git ฉบับอนุบาล 2

หนา 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) ขอมูลเปลี่ยนไปแลว

Page 56: Git ฉบับอนุบาล 2

หนา 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 เกิดขึ้น เพราะแกไฟลที่ตำแหนงเดียวกัน

Page 57: Git ฉบับอนุบาล 2

หนา 54

(3) ลองเปดดูที่ Editor

จะเห็นวามี 2 Commit ที่ Conflict กันครับ คือ จาก HEAD ในเครื่องเรา และ Commit ที่มีเลข 9a570f… ใน

ตัวอยางนี้ผมจะเก็บ HEAD ไว

จากนั้นก็ส่ัง Commit เก็บไว

(4) ลองดู Log

อันที่จริงแลว Git มี Tools ที่เอาไวชวย Merge conflict ไดในกรณีที่มี Conflict เกิดข้ึนสามารถเลือกไดวาจะเอา

อันไหน และถามี Conflict หลายๆอันมันก็จะเลื่อนๆมาใหเราดูไดดวย แตปกติแลวใช Editor ปกติก็เอาอยู

Page 58: Git ฉบับอนุบาล 2

หนา 55

สถานการณที่ 5 : เพิ่ม Alias ยอคำสั่งใหใชงายๆ

Alias หรือนามแฝง เปนการยอคำส่ังที่ใชบอยๆ ใหใชงายๆ ดูตัวอยางเลยแลวกัน

ถามี $ git log ­­graph ­­decorate ­­pretty=oneline ­­abbrev­commit ­­all สราง alias ช่ือ lol โดยส่ัง $ git

config ­­global ­­add alias.lol "log ­­graph ­­decorate ­­pretty=oneline ­­abbrev­commit ­­all"

คำสั่ง $ git log ­­graph ชวยใหเห็นการเขาออกของ Commit

(cc : http://uberblo.gs/2010/12/git­lol­the­other­git­log)

สถานการณที่ 6 : Fast Forward กับ 3­way Merge

> Fast forward เกิดขึ้นเวลาเราใชคำ

สั่ง Merge แลว Git พบวามันมีประวัติ

มาจากที่เดียวกัน มันก็จะพยายาม

ทำใหเปนเสนตรงแนวเดียวกัน

> 3­way Merge เปนการ Merge มี

ประวัติรวมกัน แลวสราง Commit

ใหมขึ้นมา จากรูปจะเห็นวงสีแดง 3

จุด ไดวงสีฟาเปนที่มาของ 3­way

Merge

เนื่องจาก 3­way Merge แบบนี้เห็น

ภาพการเขาออกไดดี จึงแนะนำใหใช

โดยเราสามารถบังคับใหเปน 3­way

Merge โดยสั่ง $ git merge ­­no­ff

ตามดวยชื่อ branch

Page 59: Git ฉบับอนุบาล 2

หนา 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 แตถาช่ือเหมือน

กันรวบมาเขียนตัวเดียวได

Page 60: Git ฉบับอนุบาล 2

หนา 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 ก็คือการลบนั่นเอง)

Page 61: Git ฉบับอนุบาล 2

หนา 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

Page 62: Git ฉบับอนุบาล 2

หนา 59

(2) สั่ง $ git rebase ­i 8ba8bb9

จะเดงหนาจอใหเราเลือก Commit จาก base ที่ตองการคือ 8ba8bb9 (สังเกตุวาไมมี Commit 8456e87 เพราะ

มันคนละ base)

โดยผมจะลบ Commit af13edd ออก ก็เอา Cursor ไปชี้ที่มัน กดปุม dd บนคียบอรด (กด d สองคร้ัง)

จากนั้นก็กดปุม :wq เพื่อบันทึกและออก

Git ก็จะพยายาม Rebase ถาผานก็แลวไป ก็กรณีผมทำบุญมานอย มี Conflict ติดมา

ผมเลยสั่ง $ git status ดูวาไฟลไหนที่มันติด Conflict

Page 63: Git ฉบับอนุบาล 2

หนา 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

Page 64: Git ฉบับอนุบาล 2

หนา 61

เทียบระหวาง Branch $ git diff master dev

จากดานบนจะเห็นวาถามองจาก dev ไป master จะเห็นบรรทัดหายไป (สีแดง) แตมุมมองของ master ไป dev

จะเห็นบรรทัดเพิ่มข้ึนมาในไฟล

เทียบระหวาง Commit $ git diff 2e78857 9a570f6

Page 65: Git ฉบับอนุบาล 2

หนา 62

ที่เจงกวานั้นคือ$ git whatchanged ­­since="2 day ago" ­­oneline หรือ $ git whatchanged ­­since="2

weeks ago" ­­oneline ถามกันตรงๆแบบนี้เลย

สถานการณที่ 10 : งานหาย แกไดดวย Reflog

ขณะที่ผมกำลังทำงานอยู สั่ง Git 2­3 คำสั่ง ทันใดขอมูลทั้งหมดหายไปตอหนาตอตา ไมตองจับมือแมวตัว

ไหนดม ผมเองแหละที่ทำมันเจง!! แตยังชิวๆอยูเพราะรูวาส่ัง $ git reset ขอมูลก็กลับมาได แตมือก็ดันเลือก

Commit ผิดซะงั้น Holy Sh**t นี่มันวันอะไรของผม นอกจากขอมูลหายเกลี้ยงแลว ประวัติยังหายไปดวย!

โชคยังดีที่ผมใช Git ซึ่งระบบของ Git ยังคงเก็บประวัติทุกอยางไวยอนหลังไปเปนเดือนๆ แถมยังบอกวา

เปนการกระทำอะไร Commit, Checkout บลาๆ บอกไดหมด ฟเจอรนี้เรียกวา Reflog เราก็จะสั่ง $ git reflog

….

จากนั้นผมก็จะส่ัง $ git reset ­­hard 2e78857

Page 66: Git ฉบับอนุบาล 2

หนา 63

จากนั้นผมจะสั่ง $ git cherry­pick 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 เพื่อดึงขอมูลที่เก็บไวออกมา

Page 67: Git ฉบับอนุบาล 2

หนา 64

ผมลองแกขอมูล เพิ่มบรรทัดที่ 2 เขาไป

ถาสั่ง $ git status ดูจะเห็นการเปล่ียนแปลง

ใช $ git stash ซอนขอมูลไว

ถาสั่ง Git status ดูจะเห็นวา Working directory มันวางแลว (เห็นการเปลี่ยนแปลงขอมูล เพราะซอนไวแลว)

ไฟลก็จะกลับไปเหมือนเดิม

ถัดจากนั้นจะ Pull , Merge หรือ Rebase ก็ตามสบาย และเมื่อเสร็จแลวก็ใช $ git stash pop ดึงขอมูลกลับคืนมา

Page 68: Git ฉบับอนุบาล 2

หนา 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 แลว

Page 69: Git ฉบับอนุบาล 2

หนา 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

Page 70: Git ฉบับอนุบาล 2

หนา 67

Merge ฟเจอร(สีชมพู) มาที่ Dev (สีเหลือง) และเขา Release (สีเขียว)

มี Checkout dev และไปพัฒนาฟเจอรตอ สวนใน Release มีการแกบั๊ค

จากนั้นก็ Merge Branch Dev ดวย Release (สีเขียว) จากนั้นก็ Merge เขา Master

มีการ Merge ฟเจอรกลับ มาที่ Dev และ Dev ก็ Merge กลับมาที่ Release และ Release ก็ Merge เขา Master

Page 72: Git ฉบับอนุบาล 2

หนา 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 มา

Page 73: Git ฉบับอนุบาล 2

หนา 70

Repo ที่ Fork มาแลว ผมแก็โคดเพิ่ม

(2) เมื่อเขาไปใน Repo แลวเลือก Pull Requests

(3) สราง New pull request

ลองดูประวัต ิ

ถาโอเคแลวก็กด Create pull request

เขียน Comment แลวก็กด Create pull request อีกรอบ

Page 74: Git ฉบับอนุบาล 2

หนา 71

ตอนนี้ Pull Request ก็ถูกเปดแลว

ฝงของเจาของ Repo ตนฉบับ

(1) เช็ค inbox message

เมื่อกดเขาไปเจะเห็นวสามีคนขอ Update readme.txt

(2) กด Merge pull request ขอมูล

(3) Confirm merge

(4) สถานะของ Request ก็จะเปลี่ยนไป

จะเห็นวาขอมูลมีการเปล่ียนไปแลว

Page 75: Git ฉบับอนุบาล 2

หนา 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 เขาไป

Page 76: Git ฉบับอนุบาล 2

หนา 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 หรือ เอาตัวเลือกออกแลวตั้งคาเอง

Page 77: Git ฉบับอนุบาล 2

หนา 74

(13) ประวัติการแกไข

(14) ลองแกไขไฟลที่อยูใน Folder ของ Repo จะเห็น Uncommitted changes

(15) ตรง Unstaged files ติ๊กเลือก แลวมันจะเดงไป Staged files ให

(16) Commit

(17) เพิ่ม Comment จากนั้นก็กด Commit

(18) หลังจาก Commit ก็จะเห็นการอัพเดท Master ก็จะยายไปแลว และ Origin ยังอยูที่เดิม

Page 78: Git ฉบับอนุบาล 2

หนา 75

(19) Push ไปที่ Origin (Github) เลือก Branch master

(20) สังเกตวา master และ origin/master อัพเดทแลว

(21) ลองเขาไปดูใน Gitghub

การใชงาน Git GUI ก็ชวยอำนวยความสะดวกไดดี แตฟงกชันการทำงานก็คลายๆกับในแบบ Command

line ตัวอยางดานบนผมแสดงแควิธีการ Commit ไฟลที่แกไข แตสวนฟงกชันการทำงานอยางอ่ืนก็ไมยากเกินไปที่

จะเรียนรูดวยตัวเอง

Page 79: Git ฉบับอนุบาล 2

หนา 76

Chapter 6 : บรรณานุกรม  

(1) Pro Git, [Scott Chacon, Ben Straub], ISBN­13: 978­1484200773

(2) Pro Git Grean Edition, https://github.com/opendream/progit

(3) อยาก commit รวมกับ commit กอนหนานั้น,

http://pphetra.blogspot.com/2011/02/git­commit­commit.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/se­56­2

(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/git­lol­the­other­git­log

(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://www­cs­students.stanford.edu/~blynn/gitmagic/book.pdf

(12) สราง Git Alias สำหรับคำส่ังที่ใชงานบอย, http://armno.in.th/2012/10/25/creating­git­alias

(13) version control Delta Storage,

http://version­control.net/version­control­howto/version­control­delta­storage

Thanks Wikipedia, Google, StackOverflow, Github and another source. :)

Page 80: Git ฉบับอนุบาล 2

หนา 77

คนเขียน

ปกติผมเขียน Blog เพื่อทบทวนและเผยแพรขอมูลพวกนี้แตผมพบวาปญหาของการเขียน Blog คือขอมูลไม

คอยจัดเรียงเปนระเบียบเวลาจะอานหาอานยาก(ถึงจะมีติด Tag ก็เถอะ) เลยกะจะเขียนเร่ือง Git ใหเปนเรื่องเปน

ราวเลยนาจะดีกวา พอเริ่มเขียนไปก็พบวามีหลายคำสั่งและขอมูลหลายสวนที่ผมก็ไมเคยรู แตจำเปนตองรู หรือรูไว

จะมีประโยชนผมก็ไปหาขอมูลแลวก็เอามาเพ่ิมเปนเอกสาร เพ่ิมไปเพิ่มมามันก็เยอะไปเร่ือยเลยทำเปนหนังสือมันซะ

เลย ดังนั้นหากผิดพลาดสวนไหนก็ขอใหแจงผมมาดวยจะดีมากครับ

ขอสารภาพมา ณ ที่นี้วาตอนเรียนนี่แอบลักไกกันเปนประจำ พอใชๆไปแลว

มีปญหา มึนตึ๊บ ก็ลบ Git ทั้งโฟลเดอรออก แลว Clone ลงมาใหมประจำ (>.<)” แต

ก็ยังดีที่มี Community ที่พอจะเปนที่พึ่งที่อาศัยไดถาใครมีคำถามขอสงสัยก็ลอง

เขาไปดูกันไดที่กลุม “Gitฮับ” :

https://www.facebook.com/groups/440497309296387

สุดทายหนังสือเลมนี้ใชสัญญาอนุญาต Creative Common 4.0 ซึ่งสามารถทำ

ซ้ำ ทำสำเนา เผยแพรตอ แกไข และใชไดสำหรับงานทุกวัตถุประสงคแมแตทำการคาก็

ใชได แตจำเปนตองแสดงแหลงที่มาของเอกสารน้ี

สามารถติดตอผมไดทาง

E­mail : [email protected]

Website : www.i­aor.com

WebBlog : aorjoa.blogspot.com

GitHub : https://github.com/Aorjoa

“ขอ Source code จงสถิตอยูแดทาน”