Differences between revisions 3 and 4
Revision 3 as of 2008-11-21 05:55:34
Size: 18400
Comment: Translate remaining text to Thai
Revision 4 as of 2008-11-21 07:22:05
Size: 22260
Comment: Editing to make reading easier. Standardize hg "vocabs" (e.g. push, pull, ...)
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
รูปแบบการทำงานแบบกระจายอำนาจ (decentralized) ของ Mercurial อาจทำให้ผู้ใช้ใหม่หลายๆคนงง หน้านี้พยายามที่จะอธิบายคอนเซ็ปต์พื้นฐานต่างๆเพื่อให้ผู้ใช้เข้าใจได้ง่ายขึ้น
ดู[:ThaiTutorial:บทเรียน]สำหรับขั้นตอนแบบละเอียด
ผู้ใช้ใหม่ๆอาจงงกับรูปแบบการทำงานแบบแยกศูนย์ (decentralized) ของ Mercurial  หน้านี้จึงพยายามที่จะอธิบายหลักการพื้นฐานต่างๆเพื่อให้ผู้ใช้เข้าใจ Mercurial ได้ดีขึ้น
ดู[:ThaiTutorial:บทเรียนการใช้งาน Mercurial]สำหรับขั้นตอนอย่างการใช้งานอย่างละเอียด
Line 19: Line 19:
== อะไรอยู่ใน Repository ==

[:Repository:repository] ของ Mercurial ประกอบไปด้วย[:WorkingDirectory:ไดเร็คทอรี่ทำงาน]กั store:
== มีอะไรอยู่ใน Repository บ้าง ==

[:Repository:repository] ของ Mercurial ประกอบไปด้วยสองส่วนคือ[:WorkingDirectory:ไดเร็คทอรี่สำหรับใช้ทำงาน] (working directory) และที่จัดเ็บประวติ (store):
Line 48: Line 48:
store คือที่เก็บประวัติ'''ทั้งหมด'''ของโปรเจค ความแตกต่างของ Mercurial จาก [:SCM:SCMs] ทั่วไปก็คือปกติแล้ว SCM อื่นๆจะเก็บประวัติทั้งหมดไว้ที่ศูนย์กลางที่เดียว แต่ใน Mercurial ทุกๆไดเร็คทอรี่ทำงาน (working directory) จะมีประวัติเหล่านี้พ่วงมาด้วยเหมือนเป็นสำเนาส่วนตัว การทำแบบนี้จะทำให้สามารถทำงานขนานกันไปได้

ไดเร็คทอรี่ทำงานจะถือสำเนาของไฟล์ต่างๆ ณ เวลาใดเวลาหนึ่ง (เช่น การแก้ไขหรือที่เรียกว่า rev ครั้งที่ 2 เป็นต้น) ซึ่งคุณก็สามารถแก้ไขไฟล์ในไดเร็คทอรี่ได้ และเนื่องจากว่า[:Tag:ป้ายกำกับ (tags)]และ[:.hgignore:ไฟล์ที่ถูกเพิกเฉย (ignored files)]ก็ถูกเก็บประวัติด้วย ทั้งสองก็ถูกเก็บอยู่ใน repository เช่นกัน
ที่จัดเก็บประวัติจะทำหน้าที่เก็บประวัติการแก้ไข'''ทั้งหมด'''ของโปรเจค

รูปแบบ repository แบบนี้เป็นจุดที่ทำให้ Mercurial ต่างจาก [:SCM:SCM] ทั่วไป เพราะปกติ SCM จะเก็บประวัติการแก้ไขทั้งหมดไว้ในศูนย์กลางเพียงที่เดียว แต่ใน Mercurial ทุกๆ repository จะมีประวัติเหล่านี้ติดมาด้วยเหมือนเป็นสำเนาส่วนตัว การทำแบบนี้จะทำให้ผู้ใช้แต่ละคนสามารถทำงานขนานกันไปได้ง่ายดายกว่า

ในไดเร็คทอรี่สำหรับใช้ทำงานจะมีสำเนาของไฟล์ต่างๆ ณ เวลาใดเวลาหนึ่ง (เช่นเวอร์ชั่นจากการแก้ไขครั้งที่สองหรือ rev 2 เป็นต้น) คุณสามารถแก้ไขไฟล์ในไดเร็คทอรี่สำหรับใช้ทำงานได้ตามปกติ และเนื่องจากว่า[:Tag:ป้ายกำกับ (tags)]และ[:.hgignore:ไฟล์ที่ไม่ถูกเก็บประวัติ (ignored files)]ก็เป็นส่วนหนึ่งของ repository ด้วยข้อมูลทั้งสองจึงถูกเก็บอยู่ใน repository เช่นกัน
Line 54: Line 56:
เมื่อคุณ[:Commit:คอมมิท]การแก้ไข ไฟล์ที่อยู่ในไดเร็คทอรี่ทำงานของคุณจะถูกเก็บเป็น [:ChangeSet:changeset] ใหม่ (หรือจะเรียกว่า "[:Revision:revision]" ใหม่ก็ได้) โดยมี[:Parent:บรรพบุรุษ]เป็นบรรพบุรุษของไดเร็คทอรี่ทำงานในขณะนั้น: เมื่อคุณ[:Commit:คอมมิท]การแก้ไข ไฟล์ต่างๆที่อยู่ในไดเร็คทอรี่สำหรับใช้ทำงานของคุณจะถูกเก็บเป็น[:ChangeSet:เซ็ตของการแก้ไข (changeset)] เซ็ตใหม่ (หรือจะเรียกสั้นๆว่า"[:Revision:การแก้ไข (revision)]"ใหม่ก็ได้) โดย[:Parent:บรรพบุรุษ (parent)]ของเซ็ตของการแก้ไขตัวใหม่นี้ก็คือบรรพบุรุษของไดเร็คทอรี่สำหรับใช้ทำงานในขณะนั้น:
Line 83: Line 85:
สังเกตุว่าในรูปภาพ revision 4 เป็น '''[:Branch:branch]''' ของ revision 2 ซึ่งเป็น revision นไดเร็คทอรี่ทำงาน หลังจากคอมมิท revision 4 จะกลายเป็น '''บรรพบุรุษ''' ของไดเร็คทอรี่ทำงานแทน

== Revisions, Changesets, Heads, และ Tip ==

Mercurial รวมการแก้ไขในหลายไฟล์ไว้ด้วยกันเป็นกลุ่มเพื่อที่จะคอมมิทเป็น [:ChangeSet:changeset] หรือเรียกอีกชื่อนึงได้ว่า revision ของโปรเจค
แต่ละ revision ก็จะมีตัวเลขเป็นตัวแทนเรียกว่า [:RevisionNumber:revision number] ซึ่งจะเพิ่มขึ้นตามลำดับ และเนื่องจากว่า Mercurial อนุญาติให้ผู้ใช้หลายคนทำงานขนานกันในหลายๆ repository ตัวเลข revision number ของผู้ใช้แต่ละคนอาจไม่ตรงกัน Mercurial จึงให้ตัวเลขอีกตัวเลขนึงเป็นตัวแทนของแต่ละ changset ในทุกๆ repository  ตัวเลขนี้เป็นตัวเลขฐานสิบหกยาว 40 หลักเรียกว่า [:ChangeSetID:changeset ID] และสามารถถูกย่อได้ตราบใดที่บ่งบอกึง changeset ที่ไม่กำกวมเช่น "e38487"
ในรูปภาพคุณจะเห็นว่าการแก้ไขครั้งที่ 4 เป็น '''[:Branch:กิ่ง]''' ของการแก้ไขครั้งที่ 2 ซึ่งเป็นเวอร์ชั่นเดิมของไดเร็คทอรี่สำหรับช้ทำงาน หลังจากการคอมมิท การแก้ไขครั้งที่ 4 จะกลายเป็น'''บรรพบุรุษ'''ใหม่ของไดเร็คทอรี่ทำงานแทน

== การแก้ไข (revision), เซ็ตของการแก้ไข (changeset), ส่วนยอด (head), และส่วนปลาย (tip) ==

Mercurial จะรวบรวมไฟล์ที่ถูกแก้ไขทั้งหมดไว้ด้วยกันเป็นกลุ่มเดียวสำหรับคอมมิท เราจะเรียกกลุ่มนี้ว่า[:ChangeSet:เซ็ตของการแก้ไข] หรือสั้นๆว่าการแก้ไข (revision)
การแก้ไขแต่ละครั้งจะมีตัวเลขกำกับเพื่อง่ายต่อการระบุ ตัวเลขนี้เรียกว่า[:RevisionNumber:ครั้งที่แก้ไข]ซึ่งจะเพิ่มขึ้นตามลำดับ เนื่องจากว่า Mercurial อนุญาติให้ผู้ใช้หลายคนทำงานขนานกันในหลายๆ repository ตัวเลขครั้งที่แก้ไขของผู้ใช้แต่ละคนอาจไม่ตรงกันได้ เพราะฉะนั้น Mercurial จึงมีตัวเลขกำกับอีกเลขนึงเพื่อระบุการแก้ไขเดียวกันในทุกๆ repository เป็นตัวเลขฐานสิบหก ยาว 40 หลัก ที่มีชื่อว่า [:ChangeSetID:รหัสประจำเซ็ตการแก้ไข] (changeset ID) คุณสามารถใช้รหัสแบบย่อได้้าเป็นรหัสที่สามารระบุเซ็ตการแก้ไขเจาะจงได้โดยไม่กำกวม เช่น "e38487"
Line 114: Line 116:
การ branch และ[:Merge:รวมการแก้ไข]สามารถเกิดขึ้นตรงจุดใดก็ได้ในประวัติการแก้ไข แต่ละ branch ที่ยังไม่ได้ถูกรวมจะสร้างสิ่งที่เรียกว่า [:Head:head] ใหม่ในประวัติการแก้ไข
ในรูปภาพด้านบน revisions 5 และ 6 คือ head แต่ Mercurial ให้ความหมายของ revision 6 ว่าเป็น[:Tip:ปลาย]ของ repository ด้วยเพราะว่าเป็น head ที่มีตัวเลข revision number สูงที่สุด
Revision 4 เรียกว่า [:MergeChangeset:merge changeset] เพราะว่าเป็น changeset ที่เกิดจากการรวมของ changeset ''สอง'' อันทีเป็นบรรพบุรุษ (คือ revisions 2 และ 3)

== การทำสำเนา, แก้ไข, รวมการแก้ไข, ดึงการแก้ไข และอัพเดท ==

สมมุติว่าเรามีผู้ใช้คนนึงชื่ออลิซ ซึ่งมี repository แบบนี้:
การแตกกิ่งและ[:Merge:การรวมประวัติ]อาจเกิดขึ้นตรงจุดใดก็ได้ใน repository แต่ละกิ่งที่ยังไม่ได้ถูกรวมกับกิ่งอื่นมีชื่อเรียกว่า[:Head:ส่วนยอด]ของ repository
ในรูปภาพด้านบนการแก้ไขครั้งที่ 5 และ 6 คือส่วนยอด แต่การแก้ไขครั้งที่ 6 มีความหมายพิเศษกว่าคือเป็น[:Tip:ส่วนปลาย]ของ repository ด้วย ส่วนปลายของ repository คือส่วนยอดที่เป็นการแก้ไขครั้งล่าสุด (ตัวเลขครั้งที่แก้ไขสูงที่สุด)
การแก้ไขครั้งที่ 4 มีชื่อเรียกว่า[:MergeChangeset:เซ็ตการแก้ไขรวม] เพราะว่าเป็นเซ็ตการแก้ไขที่เกิดจากการรวมของกันของบรรพบุรุษอีก''สอง''เซ็ต (คือการแก้ไขครั้งที่ 2 และ 3)

== การทำสำเนา (clone), แก้ไข, รวมประวัติการแก้ไข (merge), การดึงประวัติการแก้ไข (pull) และการอัพเดทไดเร็คทอรี่สำหรับใช้ทำงาน (update) ==

สมมุติว่าอลิซมี repository ดังนี้:
Line 131: Line 133:
บ๊อบ[:Clone:ทำสำเนา] repository ของอลิซเป็น repository ส่วนตัวของตัวเองที่เป็นเอกเทศจากตัวต้นแบบของอลิซ และก็มีไฟล์ของเวอร์ชั่นปลายซึ่งก็คือ revision d ในไดเร็คทอรี่ทำงานของเขา: บ๊อบ[:Clone:ทำสำเนา] (clone) repository จากอลิซเป็น repository ส่วนตัวของตัวเองและในไดเร็คทอรี่สำหรับใช้ทำงานของเขามีไฟล์เวอร์ชั่น d ซึ่งก็คือส่วนปลายของ repository:
Line 142: Line 144:
ตอนี้บ๊อบสามารถทำงาน้เป็นอิสระจากอลิซ บ๊อบทำการแก้ไขและ[:Commit:คอมมิท]การแก้ไขสองครั้งคือ e และ f: หลังจากทำสำเบ๊อบสามารถทำงานอิสระจากอลิซ บ๊อบแก้ไขไฟล์และ[:Commit:คอมมิท]สองครั้งทำให้เกิดเวร์ชั่น e และ f:
Line 155: Line 157:
ในขณะเดียวกันอลิซก็ทำการแก้ไข g เช่นกัน ทำให้ประวัติการแก้ไขใน repository ของเธอแตกแขนงออกไปจากของบ๊อบและทำให้เกิด [:Branch:branch] ขึ้น: ในขณะเดียวกันอลิซก็ทำการแก้ไขและคอมมิทเวอร์ชั่น g เช่นกัน ทำให้ประวัติการแก้ไขใน repository ของอลิซแตกแขนงออกไปจากประวัติการแก้ไขใน repository ของบ๊อบ จึงเกิด[:Branch:การแตกกิ่ง]ขึ้น:
Line 167: Line 169:
บ๊อบจึง[:Pull:ดึงการแก้ไข]จาก repository ของอลิซเพื่อทำให้ประวัติการแก้ไขตรงกัน การทำเช่นน้จะคัดลอกการแก้ไขที่อลิซทำทั้งหมดมาไว้ใน repository ของบ๊อบ (ในตัวอย่างนี้คือแค่การแก้ไข g) สังเกตุว่าไดเร็คทอรี่ำงานของบ๊อบจะ'''ไม่'''ถูกเปลี่นแปลงจากการดึงการแก้ไขครั้งนี้: บ๊อบจึง[:Pull:ดึงประวัติการแก้ไข]จาก repository ของอลิซเพื่อทำให้ประวัติการแก้ไขสอดคล้องกัน การดึงประวัติการแก้ไขจะคัดลอกการแก้ไขทั้งหมดทที่อลิซคอมมิทมาไว้ใน repository ของบ๊อบ (ในตัวอย่างนี้คือแค่การแก้ไขเวอร์ชั่น g) สังเกตุว่าการดึงประวัติจะ'''ไม่'''แก้ไขไฟล์ใดๆในไดเร็คทอรี่หรับใช้ทำงานของบ๊อบเลแม้แต่น้อย:
Line 182: Line 184:
และเนื่องจากว่าการแก้ไข '''g''' ของอลิซกลายเป็น head ใหม่ใน repository ของบ๊อบมันเลยกลายเป็น '''ปลาย''' ของ repository ด้วย

จากนั้นบ๊อบก็ทำการ[:Merge:รวมการแก้ไข]ซึ่งก็คือการรวมการแก้ไขล่าสุดของเขา (f) กับปลายของ repository หลังจากการรวม ไดเร็คทอรี่ทำงานของเค้าก็จะมีบรรพบุรุษ 2 revisions คือ f และ g:
การแก้ไขเวอร์ชั่น '''g''' ของอลิซกลายเป็นส่วนยอดใหม่ใน repository ของบ๊อบ และก็เป็น'''ส่วนปลาย'''ของ repository อีกด้วยเนื่องจากเป็นการแก้ไขครั้งล่าสุด (ที่มีเลขครั้งที่แก้ไขมากที่สุดใน repository ของบ๊อบ)

จากนั้นบ๊อบจึงทำการ[:Merge:รวมประวัติการแก้ไข]ของส่วนยอดทั้งสองเข้าด้วยกัน นั่นก็คือการรวมการแก้ไขล่าสุดของเขา (เวอร์ชั่น f) เข้ากับส่วนปลายของ repository (เวอร์ชั่น g) ผลลัพธ์ของการรวมก็คือไดเร็คทอรี่สำหรับใช้ทำงานของบ๊อบจะมีบรรพบุรุษ 2 เวอร์ชั่นคือ f และ g นั่นเอง:
Line 201: Line 203:
หลังจากตรวจสอบดูว่าการรวมการแก้ไขในไดเร็คทอรี่ำงานของเขาเป็นไปด้วยดีไม่มีอะไรผิดพลาด บ๊อบก็คอมมิทและสร้าง [:MergeChangeset:merge changeset] ใหม่คือ h ใน store ของ repository เขา: หลังจากตรวจสอบดูว่าการรวมประวัติการแก้ไขในไดเร็คทอรี่หรับใช้ทำงานของเขาเป็นไปด้วยดี บ๊อบก็คอมมิทและสร้าง[:MergeChangeset:เซ็ตการแก้ไขรวม]ใหม่ ซึ่งก็คือเวอร์ชั่น h ในที่จัดเก็บประวัติ (store) ของ repository เขา:
Line 220: Line 222:
ตอนนี้ถ้าอลิซ'''ดึงการแก้ไข'''จากบ๊อบ เธอจะเห็นประวัติการแก้ไขจากบ๊อบคือ e, f, และ h ใน store ของเธอด้วย: ตอนนี้ถ้าอลิซ'''ดึงประวัติการแก้ไข'''จากบ๊อบ เธอจะเห็นประวัติการแก้ไขจากบ๊อบคือ e, f, และ h ในที่จัดเก็บประวัติใน repository ของเธอด้วย:
Line 239: Line 241:
สังเกตุว่าไดเร็คทอรี่ทำงานของอลิซไม่ถูกเปลี่ยนเนื่องจากการดึงการแก้ไข เธอจะต้องทำการ[:Update:อัพเดท]เพื่อทำให้ไดเร็คทอรี่ทำงานมีเนื้อหาตรงกับ changset h การอัพเดทจะทำให้บรรพบุรุษของไดเร็คทอรี่ทำงานเปลี่ยนเป็น changeset h และทำให้เนื้อหาของไฟล์ในไดเร็คทอรี่ทำงานตรงกับเนื้อหาของ revision h. สังเกตุว่าไดเร็คทอรี่ทำงานของอลิซก็ไม่ถูกเปลี่ยนแปลงเนื่องจากการดึงประวัติการการแก้ไขเช่นกัน อลิซจะต้อง[:Update:อัพเดทไดเร็คทอรี่สำหรับใช้ทำงาน]ของเธอให้มีเนื้อหาตรงกับเซ็ตการแก้ไขในเวอร์ชั่น h เอง การอัพเดทนี้จะทำให้บรรพบุรุษของไดเร็คทอรี่สำหรับใช้ทำงานเปลี่ยนเป็นเวอร์ชั่น h และทำให้เนื้อหาของไฟล์ในไดเร็คทอรี่ตรงกับเนื้อหาในเวอร์ชั่น h เช่นกัน
Line 258: Line 260:
ถึงตอนนี้ทั้งอลิซและบ๊อบมีทั้งประวัติการแก้ไขและเนื้อหาในไดเร็คทอรี่ทำงานตรงกันอีกครั้ง ณ จุดนี้ทั้งอลิซและบ๊อบจะมีประวัติการแก้ไขและเนื้อหาในไดเร็คทอรี่สำหรับใช้ทำงานตรงกันอีกครั้ง
Line 263: Line 265:
Mercurial เป็นระบบที่ทำงานแบบแยกศูนย์ จึงไม่มีการกำหนดความหมายพิเศษสำหรับ repository กลาง ผู้ใช้มีสิทธิ์เลือกโครงสร้างของ repository ต่างๆได้ตามต้องการ (ดู CommunicatingChanges): Mercurial เป็นระบบที่ทำงานแบบแยกศูนย์ จึงไม่มีการกำหนดความหมายพิเศษสำหรับ repository กลาง ผู้ใช้มีสิทธิ์เลือกโครงสร้างของ repository ได้ตามต้องการ (ลองดู CommunicatingChanges):
Line 283: Line 285:
ต่างจากระบบเวอร์ชั่นคอนโทรลแบบรวมศูนย์อื่นๆซึ่งการแก้ไขเพื่อทดลองอะไรๆ อาจก่อให้เกิดปัญหา ระบบ DVCS อย่าง Mercurial สามารถทำให้คุณทดลองได้อย่างง่ายดายโดยการทำสำเนาของ repository และก็เริ่มแก้ไขได้เลย ถ้าการแก้ไขเป็นไปได้ด้วยดี คุณก็แค่ push ไปที่ repository อื่น แต่ถ้าคุณไม่ชอบก็ลบ repository ทิ้งและลองวิธีอื่นแทน


== Mercurial ทำอะไรไม่ได้บ้าง? ==

ผู้ใช้ SVN/CVS หลายคนคาดหวังว่าจะเก็บหลายๆโปรเจคไว้ใน repository เดียว แต่ Mercurial ไม่ได้ถูกออกแบบมาเพื่อสนับสนุนการใช้แบบนี้ซักเท่าไร เพราะฉะนั้นคุณอาจจะอยากลองเปลี่ยนวิธีการทำงานของคุณดู เหตุผลก็คือคุณไม่สามารถดึงแค่ไดเร็คทอรี่ใดไดเร็คทอรี่หนึ่งมาจาก repository ของ Mercurial ได้ แต่ถ้าคุณต้องการเก็บหลายๆโปรเจคในจริงๆคุณอาจจะอยากลองศึกษาดู ForestExtension



ำหรับการแนะนำเกี่ยวกับวิธีการใช้งาน Mercurial แบบมีตัวอย่างลองดู[:ThaiTutorial:บทเรียนการใช้งาน Mercurial]
Mercurial ต่างจากระบบเวอร์ชั่นคอนโทรลแบบรวมศูนย์อื่นๆ  ในระบบแบบรวมศูนย์การแก้ไขเพื่อทำการทดลองบางอย่างอาจก่อให้เกิดปัญหาได้ถ้าผู้ใช้ไม่ระมัดระวัง แต่ระบบ DVCS อย่าง Mercurial ทำให้การทำการทดลองง่ายและปลอดภัยขึ้นเพราะคุณแค่ต้องทำำเนาของ repository และก็เริ่มแก้ไขได้เลย repository ต้นฉบับของคุณจะเป็นอิสระจาก repository ทดลองจึงทำให้การทำงานขนานไปได้พร้อมๆกัน ถ้าการทดลองเป็นไปได้ด้วยดี คุณก็แค่ผลักประวัติการแก้ไข (push) กลับไปที่ repository ต้นฉบับ แต่ถ้าคุณไม่ชอบก็แค่ลบ repository ทดลองทิ้งและสร้างสำเนาขึ้นมาทำงานใหม่


== Mercurial ไม่เหมาะกับการใช้งานแบบไหนบ้าง? ==

ผู้ใช้ SVN/CVS หลายคนคิดว่าจะเก็บหลายๆโปรเจคไว้ใน repository เดียว จริงๆแล้ว Mercurial ไม่ได้ถูกออกแบบมาเพื่อสนับสนุนการใช้แบบนี้ซักเท่าไรเพราะฉะนั้นคุณอาจจะอยากลองเปลี่ยนวิธีการทำงานของคุณดู  เหตุผลก็คือคุณไม่สามารถดึงแค่ไดเร็คทอรี่ใดไดเร็คทอรี่หนึ่งมาจาก repository ของ Mercurial ได้ (การทำสำเนาจะทำสำเนาของทุกๆไดเร็คทอรี่ใน repository) แต่ถ้าคุณต้องการเก็บหลายๆโปรเจคในหนึ่ง repository จริงๆคุณอาจจะอยากลองดู ForestExtension



คุณามารถศึกษาวิธีการใช้งาน Mercurial จากตัวอย่างได้จาก[:ThaiTutorial:บทเรียนการใช้งาน Mercurial]

ผู้ใช้ใหม่ๆอาจงงกับรูปแบบการทำงานแบบแยกศูนย์ (decentralized) ของ Mercurial หน้านี้จึงพยายามที่จะอธิบายหลักการพื้นฐานต่างๆเพื่อให้ผู้ใช้เข้าใจ Mercurial ได้ดีขึ้น ดู[:ThaiTutorial:บทเรียนการใช้งาน Mercurial]สำหรับขั้นตอนอย่างการใช้งานอย่างละเอียด

(คำแปล: [:BrazilianPortugueseUnderstandingMercurial:ภาษาโปรตุเกสบราซิล], [:ChineseUnderstandingMercurial:ภาษาจีน], [:FrenchUnderstandingMercurial:ภาษาฝรั่งเศษ], [:GermanUnderstandingMercurial:ภาษาเยอรมัน], [:ItalianUnderstandingMercurial:ภาษาอิตาลี], [:JapaneseUnderstandingMercurial:ภาษาญี่ปุ่น], [:KoreanUnderstandingMercurial:ภาษาเกาหลี], [:RussianUnderstandingMercurial:ภาษารัสเซีย], [:SpanishUnderstandingMercurial:ภาษาสเปน] )

สารบัญ

มีอะไรอยู่ใน Repository บ้าง

[:Repository:repository] ของ Mercurial ประกอบไปด้วยสองส่วนคือ[:WorkingDirectory:ไดเร็คทอรี่สำหรับใช้ทำงาน] (working directory) และที่จัดเก็บประวัติ (store):

ที่จัดเก็บประวัติจะทำหน้าที่เก็บประวัติการแก้ไขทั้งหมดของโปรเจค

รูปแบบ repository แบบนี้เป็นจุดที่ทำให้ Mercurial ต่างจาก [:SCM:SCM] ทั่วไป เพราะปกติ SCM จะเก็บประวัติการแก้ไขทั้งหมดไว้ในศูนย์กลางเพียงที่เดียว แต่ใน Mercurial ทุกๆ repository จะมีประวัติเหล่านี้ติดมาด้วยเหมือนเป็นสำเนาส่วนตัว การทำแบบนี้จะทำให้ผู้ใช้แต่ละคนสามารถทำงานขนานกันไปได้ง่ายดายกว่า

ในไดเร็คทอรี่สำหรับใช้ทำงานจะมีสำเนาของไฟล์ต่างๆ ณ เวลาใดเวลาหนึ่ง (เช่นเวอร์ชั่นจากการแก้ไขครั้งที่สองหรือ rev 2 เป็นต้น) คุณสามารถแก้ไขไฟล์ในไดเร็คทอรี่สำหรับใช้ทำงานได้ตามปกติ และเนื่องจากว่า[:Tag:ป้ายกำกับ (tags)]และ[:.hgignore:ไฟล์ที่ไม่ถูกเก็บประวัติ (ignored files)]ก็เป็นส่วนหนึ่งของ repository ด้วยข้อมูลทั้งสองจึงถูกเก็บอยู่ใน repository เช่นกัน

การคอมมิท(บันทึก) การแก้ไข

เมื่อคุณ[:Commit:คอมมิท]การแก้ไข ไฟล์ต่างๆที่อยู่ในไดเร็คทอรี่สำหรับใช้ทำงานของคุณจะถูกเก็บเป็น[:ChangeSet:เซ็ตของการแก้ไข (changeset)] เซ็ตใหม่ (หรือจะเรียกสั้นๆว่า"[:Revision:การแก้ไข (revision)]"ใหม่ก็ได้) โดย[:Parent:บรรพบุรุษ (parent)]ของเซ็ตของการแก้ไขตัวใหม่นี้ก็คือบรรพบุรุษของไดเร็คทอรี่สำหรับใช้ทำงานในขณะนั้น:

ในรูปภาพคุณจะเห็นว่าการแก้ไขครั้งที่ 4 เป็น [:Branch:กิ่ง] ของการแก้ไขครั้งที่ 2 ซึ่งเป็นเวอร์ชั่นเดิมของไดเร็คทอรี่สำหรับใช้ทำงาน หลังจากการคอมมิท การแก้ไขครั้งที่ 4 จะกลายเป็นบรรพบุรุษใหม่ของไดเร็คทอรี่ทำงานแทน

การแก้ไข (revision), เซ็ตของการแก้ไข (changeset), ส่วนยอด (head), และส่วนปลาย (tip)

Mercurial จะรวบรวมไฟล์ที่ถูกแก้ไขทั้งหมดไว้ด้วยกันเป็นกลุ่มเดียวสำหรับคอมมิท เราจะเรียกกลุ่มๆนี้ว่า[:ChangeSet:เซ็ตของการแก้ไข] หรือสั้นๆว่าการแก้ไข (revision) การแก้ไขแต่ละครั้งจะมีตัวเลขกำกับเพื่อง่ายต่อการระบุ ตัวเลขนี้เรียกว่า[:RevisionNumber:ครั้งที่แก้ไข]ซึ่งจะเพิ่มขึ้นตามลำดับ เนื่องจากว่า Mercurial อนุญาติให้ผู้ใช้หลายคนทำงานขนานกันในหลายๆ repository ตัวเลขครั้งที่แก้ไขของผู้ใช้แต่ละคนอาจไม่ตรงกันได้ เพราะฉะนั้น Mercurial จึงมีตัวเลขกำกับอีกเลขนึงเพื่อระบุการแก้ไขเดียวกันในทุกๆ repository เป็นตัวเลขฐานสิบหก ยาว 40 หลัก ที่มีชื่อว่า [:ChangeSetID:รหัสประจำเซ็ตการแก้ไข] (changeset ID) คุณสามารถใช้รหัสแบบย่อได้ถ้าเป็นรหัสที่สามารถระบุเซ็ตการแก้ไขเจาะจงได้โดยไม่กำกวม เช่น "e38487"

การแตกกิ่งและ[:Merge:การรวมประวัติ]อาจเกิดขึ้นตรงจุดใดก็ได้ใน repository แต่ละกิ่งที่ยังไม่ได้ถูกรวมกับกิ่งอื่นมีชื่อเรียกว่า[:Head:ส่วนยอด]ของ repository ในรูปภาพด้านบนการแก้ไขครั้งที่ 5 และ 6 คือส่วนยอด แต่การแก้ไขครั้งที่ 6 มีความหมายพิเศษกว่าคือเป็น[:Tip:ส่วนปลาย]ของ repository ด้วย ส่วนปลายของ repository คือส่วนยอดที่เป็นการแก้ไขครั้งล่าสุด (ตัวเลขครั้งที่แก้ไขสูงที่สุด) การแก้ไขครั้งที่ 4 มีชื่อเรียกว่า[:MergeChangeset:เซ็ตการแก้ไขรวม] เพราะว่าเป็นเซ็ตการแก้ไขที่เกิดจากการรวมของกันของบรรพบุรุษอีกสองเซ็ต (คือการแก้ไขครั้งที่ 2 และ 3)

การทำสำเนา (clone), แก้ไข, รวมประวัติการแก้ไข (merge), การดึงประวัติการแก้ไข (pull) และการอัพเดทไดเร็คทอรี่สำหรับใช้ทำงาน (update)

สมมุติว่าอลิซมี repository ดังนี้:

บ๊อบ[:Clone:ทำสำเนา] (clone) repository จากอลิซเป็น repository ส่วนตัวของตัวเองและในไดเร็คทอรี่สำหรับใช้ทำงานของเขามีไฟล์เวอร์ชั่น d ซึ่งก็คือส่วนปลายของ repository:

หลังจากทำสำเนาบ๊อบสามารถทำงานโดยอิสระจากอลิซ บ๊อบแก้ไขไฟล์และ[:Commit:คอมมิท]สองครั้งทำให้เกิดเวอร์ชั่น e และ f:

ในขณะเดียวกันอลิซก็ทำการแก้ไขและคอมมิทเวอร์ชั่น g เช่นกัน ทำให้ประวัติการแก้ไขใน repository ของอลิซแตกแขนงออกไปจากประวัติการแก้ไขใน repository ของบ๊อบ จึงเกิด[:Branch:การแตกกิ่ง]ขึ้น:

บ๊อบจึง[:Pull:ดึงประวัติการแก้ไข]จาก repository ของอลิซเพื่อทำให้ประวัติการแก้ไขสอดคล้องกัน การดึงประวัติการแก้ไขจะคัดลอกการแก้ไขทั้งหมดที่ที่อลิซคอมมิทมาไว้ใน repository ของบ๊อบ (ในตัวอย่างนี้คือแค่การแก้ไขเวอร์ชั่น g) สังเกตุว่าการดึงประวัติจะไม่แก้ไขไฟล์ใดๆในไดเร็คทอรี่สำหรับใช้ทำงานของบ๊อบเลยแม้แต่น้อย:

การแก้ไขเวอร์ชั่น g ของอลิซกลายเป็นส่วนยอดใหม่ใน repository ของบ๊อบ และก็เป็นส่วนปลายของ repository อีกด้วยเนื่องจากเป็นการแก้ไขครั้งล่าสุด (ที่มีเลขครั้งที่แก้ไขมากที่สุดใน repository ของบ๊อบ)

จากนั้นบ๊อบจึงทำการ[:Merge:รวมประวัติการแก้ไข]ของส่วนยอดทั้งสองเข้าด้วยกัน นั่นก็คือการรวมการแก้ไขล่าสุดของเขา (เวอร์ชั่น f) เข้ากับส่วนปลายของ repository (เวอร์ชั่น g) ผลลัพธ์ของการรวมก็คือไดเร็คทอรี่สำหรับใช้ทำงานของบ๊อบจะมีบรรพบุรุษ 2 เวอร์ชั่นคือ f และ g นั่นเอง:

หลังจากตรวจสอบดูว่าการรวมประวัติการแก้ไขในไดเร็คทอรี่สำหรับใช้ทำงานของเขาเป็นไปด้วยดี บ๊อบก็คอมมิทและสร้าง[:MergeChangeset:เซ็ตการแก้ไขรวม]ใหม่ ซึ่งก็คือเวอร์ชั่น h ในที่จัดเก็บประวัติ (store) ของ repository เขา:

ตอนนี้ถ้าอลิซดึงประวัติการแก้ไขจากบ๊อบ เธอจะเห็นประวัติการแก้ไขจากบ๊อบคือ e, f, และ h ในที่จัดเก็บประวัติใน repository ของเธอด้วย:

สังเกตุว่าไดเร็คทอรี่ทำงานของอลิซก็ไม่ถูกเปลี่ยนแปลงเนื่องจากการดึงประวัติการการแก้ไขเช่นกัน อลิซจะต้อง[:Update:อัพเดทไดเร็คทอรี่สำหรับใช้ทำงาน]ของเธอให้มีเนื้อหาตรงกับเซ็ตการแก้ไขในเวอร์ชั่น h เอง การอัพเดทนี้จะทำให้บรรพบุรุษของไดเร็คทอรี่สำหรับใช้ทำงานเปลี่ยนเป็นเวอร์ชั่น h และทำให้เนื้อหาของไฟล์ในไดเร็คทอรี่ตรงกับเนื้อหาในเวอร์ชั่น h เช่นกัน

ณ จุดนี้ทั้งอลิซและบ๊อบจะมีประวัติการแก้ไขและเนื้อหาในไดเร็คทอรี่สำหรับใช้ทำงานตรงกันอีกครั้ง

ระบบการทำงานแบบแยกศูนย์

Mercurial เป็นระบบที่ทำงานแบบแยกศูนย์ จึงไม่มีการกำหนดความหมายพิเศษสำหรับ repository กลาง ผู้ใช้มีสิทธิ์เลือกโครงสร้างของ repository ได้ตามต้องการ (ลองดู CommunicatingChanges):

Mercurial ต่างจากระบบเวอร์ชั่นคอนโทรลแบบรวมศูนย์อื่นๆ ในระบบแบบรวมศูนย์การแก้ไขเพื่อทำการทดลองบางอย่างอาจก่อให้เกิดปัญหาได้ถ้าผู้ใช้ไม่ระมัดระวัง แต่ระบบ DVCS อย่าง Mercurial ทำให้การทำการทดลองง่ายและปลอดภัยขึ้นเพราะคุณแค่ต้องทำสำเนาของ repository และก็เริ่มแก้ไขได้เลย repository ต้นฉบับของคุณจะเป็นอิสระจาก repository ทดลองจึงทำให้การทำงานขนานไปได้พร้อมๆกัน ถ้าการทดลองเป็นไปได้ด้วยดี คุณก็แค่ผลักประวัติการแก้ไข (push) กลับไปที่ repository ต้นฉบับ แต่ถ้าคุณไม่ชอบก็แค่ลบ repository ทดลองทิ้งและสร้างสำเนาขึ้นมาทำงานใหม่

Mercurial ไม่เหมาะกับการใช้งานแบบไหนบ้าง?

ผู้ใช้ SVN/CVS หลายคนคิดว่าจะเก็บหลายๆโปรเจคไว้ใน repository เดียว จริงๆแล้ว Mercurial ไม่ได้ถูกออกแบบมาเพื่อสนับสนุนการใช้แบบนี้ซักเท่าไรเพราะฉะนั้นคุณอาจจะอยากลองเปลี่ยนวิธีการทำงานของคุณดู เหตุผลก็คือคุณไม่สามารถดึงแค่ไดเร็คทอรี่ใดไดเร็คทอรี่หนึ่งมาจาก repository ของ Mercurial ได้ (การทำสำเนาจะทำสำเนาของทุกๆไดเร็คทอรี่ใน repository) แต่ถ้าคุณต้องการเก็บหลายๆโปรเจคในหนึ่ง repository จริงๆคุณอาจจะอยากลองดู ForestExtension

คุณสามารถศึกษาวิธีการใช้งาน Mercurial จากตัวอย่างได้จาก[:ThaiTutorial:บทเรียนการใช้งาน Mercurial]

ThaiUnderstandingMercurial (last edited 2012-11-11 13:31:09 by abuehl)