อะไรคือความแตกต่างระหว่างสาขา git, fork, fetch, merge, rebase และ clone?


502

ฉันต้องการเข้าใจความแตกต่างระหว่างกิ่งส้อมและโคลนใน Git หรือไม่?

ในทำนองเดียวกันมันหมายความว่าอย่างไรเมื่อฉันทำ a git fetchตรงข้ามกับ a git pull?

นอกจากนี้สิ่งที่rebaseหมายความว่าเมื่อเทียบกับmerge?

ฉันจะสควอชแต่ละคนผูกมัดตัวเองได้อย่างไร?

พวกเขาจะใช้อย่างไรทำไมพวกเขาใช้และสิ่งที่พวกเขาเป็นตัวแทน?

GitHub คิดอย่างไร


19
คุณสามารถเปลี่ยนคำตอบที่ยอมรับให้เป็นคำตอบของ Michael Durrant ได้หรือไม่
siride

11
แน่นอนว่าเขาสามารถทำได้แต่สิ่งนี้จะต้องเป็นทางเลือกของเขาและคนส่วนใหญ่ที่มาถึงที่นี่ (เช่นฉัน) ต้องการบางสิ่งที่กระชับมากกว่าเช่นคำตอบที่เขาเลือกซึ่งในเวลานี้คือตัวคุณเอง =)
user1271772

คำตอบ:


366

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

สาขาเป็นสิ่งที่อยู่ในที่เก็บ แนวคิดมันแสดงถึงด้ายของการพัฒนา คุณมักจะมีสาขาหลัก แต่คุณอาจมีสาขาที่คุณกำลังทำงานกับฟีเจอร์ xyz และสาขาอื่นเพื่อแก้ไขข้อผิดพลาด abc เมื่อคุณตรวจสอบสาขาการกระทำใด ๆ ที่คุณทำจะอยู่ในสาขานั้นและจะไม่ถูกแชร์กับสาขาอื่นจนกว่าคุณจะรวมสาขาหรือรีบูทสาขาเหล่านั้นลงในสาขาที่มีปัญหา แน่นอนว่า Git ดูแปลก ๆ เล็กน้อยเมื่อพูดถึงสาขาจนกว่าคุณจะดูรูปแบบพื้นฐานของการใช้สาขา แทนที่จะอธิบายด้วยตัวเอง (ฉันได้พูดไปแล้วเยอะมาก) ฉันจะเชื่อมโยงไปยังคำอธิบาย "วิทยาการคอมพิวเตอร์" ว่า Git จำลองสาขาและคอมมิชชันได้อย่างไรนำมาจากเว็บไซต์ Git:

http://eagain.net/articles/git-for-computer-scientists/

ทางแยกไม่ใช่แนวคิดของ Git แต่เป็นแนวคิดทางการเมือง / สังคม นั่นคือถ้าบางคนไม่พอใจกับวิธีการดำเนินโครงการพวกเขาสามารถใช้ซอร์สโค้ดและทำงานด้วยตนเองแยกจากนักพัฒนาดั้งเดิม ที่จะถือว่าเป็นทางแยก Git ทำให้การฟอร์กเป็นเรื่องง่ายเพราะทุกคนมีสำเนาซอร์สโค้ดของตัวเองอยู่แล้วดังนั้นจึงเป็นเรื่องง่ายเหมือนการตัดความสัมพันธ์กับนักพัฒนาโครงการดั้งเดิมและไม่ต้องการส่งออกประวัติจากที่เก็บที่แชร์แบบที่คุณอาจต้องทำกับ SVN .

แก้ไข: เนื่องจากฉันไม่ทราบคำจำกัดความที่ทันสมัยของ "fork" ที่ใช้โดยไซต์เช่น GitHub โปรดดูความคิดเห็นและคำตอบของ Michael Durrantด้านล่างของฉันสำหรับข้อมูลเพิ่มเติม


125
ทางแยกไม่ได้แปลว่านักพัฒนาไม่พอใจกับ repo หลัก โดยทั่วไปแล้วหมายความว่าผู้พัฒนารายอื่นได้อ่าน แต่ไม่สามารถเขียนเข้าถึงการซื้อคืนได้ นักพัฒนาสามารถแยก repo ทำการเปลี่ยนแปลง แต่เนื่องจากเขาไม่สามารถเขียนไปยัง repo หลักเขาจะต้องส่งการเปลี่ยนแปลงของเขาเป็นแพทช์ ดังนั้นการฟอร์กจึงเป็นวิธีการสนับสนุนการทำงานร่วมกันโดยไม่ต้องให้สิทธิ์การเขียน
brycemcd

5
ฉันคิดว่ามันเป็นเรื่องจริง ฉันเคยเห็น "fork" ที่ใช้ในบริบทของการสร้างโครงการเวอร์ชันใหม่ที่อาจแข่งขันกัน
siride

32
คุณสามารถพูดได้ว่าส้อมเป็นสาขาที่ไม่คาดว่าจะถูกรวมเข้าด้วยกัน
masonk

6
Git hub ใช้ "fork" ตามที่ตั้งใจไว้ มันเป็นพื้นที่เก็บข้อมูลใหม่ที่เก็บไว้ใน GitHub แยกจากเดิม อย่างไรก็ตาม GitHub ยังทำให้การดึงคำขอนั้นง่ายมาก คำขอดึงเป็นหลักขอให้เจ้าของที่เก็บต้นฉบับเพื่อ "ดึง" การเปลี่ยนแปลงจากทางแยกของ repo กลับสู่ต้นกำเนิด ด้วยวิธีนี้ทุกคนสามารถใช้การควบคุมแหล่งที่มาและมีประวัติของการเปลี่ยนแปลงทั้งหมดรวมถึงของพวกเขา แต่ไม่ใช่ทุกคนที่ต้องการเข้าถึงการเขียนไปยัง repo ดั้งเดิม
mklauber

4
ฉันได้อัปเดตคำตอบของฉันเพื่อบอกให้คนดูคำตอบของ Michael Durrant สำหรับข้อมูลเพิ่มเติมเกี่ยวกับแบบจำลองของ Github
siride

531

Git

คำตอบนี้รวมถึง GitHub เช่นเดียวกับคนจำนวนมากที่ถามถึงเรื่องนี้เช่นกัน

ที่เก็บในเครื่อง

Git (ในเครื่อง) มีไดเรกทอรี ( .git) ซึ่งคุณส่งไฟล์ไปให้และนี่คือ 'พื้นที่เก็บข้อมูลในเครื่อง' ของคุณ สิ่งนี้แตกต่างจากระบบเช่น SVN ที่คุณเพิ่มและกระทำกับที่เก็บข้อมูลระยะไกลทันที

Git เก็บไฟล์แต่ละเวอร์ชันที่เปลี่ยนแปลงโดยการบันทึกไฟล์ทั้งหมด นอกจากนี้ยังแตกต่างจาก SVN ในส่วนนี้เนื่องจากคุณสามารถไปที่เวอร์ชันใดก็ได้โดยไม่ต้อง 'สร้าง' ใหม่ผ่านการเปลี่ยนแปลงเดลต้า

Git ไม่ได้ 'ล็อค' ไฟล์เลยและหลีกเลี่ยงการใช้งาน 'การล็อคแบบเอกสิทธิ์' สำหรับการแก้ไข (ระบบเก่าเช่น pvcs คำนึงถึง) ดังนั้นไฟล์ทั้งหมดจึงสามารถแก้ไขได้แม้ในขณะออฟไลน์ จริง ๆ แล้วมันเป็นงานที่ยอดเยี่ยมในการผสานการเปลี่ยนแปลงไฟล์ (ภายในไฟล์เดียวกัน!) เข้าด้วยกันระหว่างการดึงหรือดึง / ดันไปยังพื้นที่เก็บข้อมูลระยะไกลเช่น GitHub ครั้งเดียวที่คุณต้องทำการเปลี่ยนแปลงด้วยตนเอง (จริง ๆ แล้วการแก้ไขไฟล์) คือถ้าการเปลี่ยนแปลงสองรายการเกี่ยวข้องกับรหัสบรรทัดเดียวกัน


สาขา

สาขาช่วยให้คุณรักษารหัสหลัก (สาขา 'ต้นแบบ') ทำสำเนา (สาขาใหม่) จากนั้นทำงานภายในสาขาใหม่นั้น หากงานใช้เวลาสักครู่หรือต้นแบบได้รับการอัปเดตจำนวนมากตั้งแต่มีการสร้างสาขาแล้วควรรวมหรือทำการรีบูท (มักจะต้องการประวัติที่ดีกว่าและง่ายต่อการแก้ไขข้อขัดแย้ง) กับสาขาหลักควรจะทำ เมื่อเสร็จแล้วคุณจะรวมการเปลี่ยนแปลงที่เกิดขึ้นในสาขากลับไปยังที่เก็บข้อมูลหลัก หลายองค์กรใช้สาขาสำหรับงานแต่ละชิ้นไม่ว่าจะเป็นฟีเจอร์บั๊กหรืองานบ้าน องค์กรอื่น ๆ ใช้สาขาสำหรับการเปลี่ยนแปลงที่สำคัญเช่นการอัปเกรดเวอร์ชันเท่านั้น

ทางแยก: ด้วยสาขาคุณสามารถควบคุมและจัดการสาขาได้ในขณะที่คนอื่น ๆ จะควบคุมการรับรหัสกลับเข้ามา

การพูดอย่างกว้างขวางมีสองวิธีหลักในการทำสาขา ประการแรกคือการเปลี่ยนแปลงส่วนใหญ่ในสาขาหลักเพียงใช้สาขาสำหรับสิ่งที่มีขนาดใหญ่และยาวกว่าเช่นการเปลี่ยนแปลงรุ่นที่คุณต้องการให้มีสองสาขาสำหรับความต้องการที่แตกต่างกัน ข้อที่สองคือโดยที่คุณสร้างสาขาสำหรับการร้องขอคุณสมบัติทุกครั้งการแก้ไขข้อบกพร่องหรืองานที่น่าเบื่อแล้วตัดสินใจด้วยตนเองว่าเมื่อใดที่จะรวมสาขาเหล่านั้นเข้ากับสาขาหลักหลักด้วยตนเอง แม้ว่านี่จะฟังดูน่าเบื่อ แต่นี่เป็นวิธีการทั่วไปและเป็นวิธีที่ฉันใช้และแนะนำอยู่ในขณะนี้เพราะสิ่งนี้ช่วยรักษาความสะอาดของสาขาหลักและเป็นหลักที่เราส่งเสริมการผลิตดังนั้นเราจึงต้องการโค้ดทดสอบที่สมบูรณ์ผ่านการรีบูตและ การรวมสาขา

วิธีมาตรฐานที่จะนำมาเป็นสาขาใน merge'ที่จะโทคือการทำ สาขาสามารถเป็น "rebased" เพื่อล้างประวัติ ไม่ส่งผลกระทบต่อสถานะปัจจุบันและดำเนินการเพื่อให้ประวัติ 'สะอาด'

โดยพื้นฐานแล้วความคิดคือคุณแยกจากจุดหนึ่ง (โดยปกติมาจากต้นแบบ) เมื่อคุณแยกสาขาแล้ว 'อาจารย์' เองก็ก้าวไปข้างหน้าจากจุดแยกสาขานั้น จะเป็น 'สะอาดกว่า' (ง่ายต่อการแก้ไขปัญหาและประวัติจะเข้าใจได้ง่ายขึ้น) หากการเปลี่ยนแปลงทั้งหมดที่คุณทำในสาขานั้นเทียบกับสถานะปัจจุบันของต้นแบบด้วยการเปลี่ยนแปลงล่าสุดทั้งหมด ดังนั้นกระบวนการคือ: บันทึกการเปลี่ยนแปลง; รับต้นแบบ 'ใหม่' แล้วนำไปใช้ใหม่ (นี่คือส่วนที่รีบูต) การเปลี่ยนแปลงอีกครั้งกับสิ่งนั้น โปรดทราบว่าการรีบูตเช่นเดียวกับการผสานอาจทำให้เกิดข้อขัดแย้งที่คุณต้องแก้ไขด้วยตนเอง (เช่นแก้ไขและแก้ไข)

แนวทางหนึ่งที่ควรทราบ: รี
บูทเฉพาะในกรณีที่สาขาอยู่ในพื้นที่และคุณยังไม่ได้ผลักดันให้รีโมต!
นี่เป็นส่วนใหญ่เนื่องจากการรีบูตสามารถเปลี่ยนแปลงประวัติศาสตร์ที่คนอื่นเห็นซึ่งอาจรวมถึงการกระทำของตนเอง

ติดตามสาขา

เหล่านี้เป็นสาขาที่มีชื่อorigin/branch_name(ตรงข้ามกับเพียงbranch_name) เมื่อคุณกดและดึงรหัสไปยัง / จากที่เก็บข้อมูลระยะไกลนี่เป็นกลไกที่เกิดขึ้นจริง ตัวอย่างเช่นเมื่อคุณgit pushสาขาที่เรียกว่าสาขาbuilding_groupsของคุณไปก่อนorigin/building_groupsแล้วจึงไปที่ที่เก็บระยะไกล ในทำนองเดียวกันถ้าคุณทำgit fetch building_groupsไฟล์ที่ถูกเรียกคืนจะถูกวางไว้ในorigin/building_groupsสาขาของคุณ จากนั้นคุณสามารถเลือกที่จะรวมสาขานี้ลงในสำเนาในเครื่องของคุณ การปฏิบัติของเราคือการทำgit fetchและผสานแบบแมนนวลไม่ใช่แค่ a git pull(ซึ่งทำทั้งสองอย่างข้างต้นในขั้นตอนเดียว)

กำลังดึงสาขาใหม่

รับสาขาใหม่: ที่จุดเริ่มต้นของการโคลนคุณจะมีสาขาทั้งหมด อย่างไรก็ตามหากผู้พัฒนารายอื่นเพิ่มสาขาและผลักพวกเขาไปที่รีโมตจำเป็นต้องมีวิธีที่จะ 'รู้' เกี่ยวกับสาขาเหล่านั้นและชื่อของพวกเขาเพื่อให้สามารถดึงพวกเขาลงในเครื่องได้ ซึ่งจะดำเนินการผ่านทางgit fetchซึ่งจะได้รับสาขาใหม่และการเปลี่ยนแปลงทั้งหมดลงในพื้นที่เก็บข้อมูลในท้องถิ่นโดยใช้สาขาการติดตาม (เช่นorigin/) เมื่อfetchแก้ไขแล้วเราสามารถgit branch --remoteแสดงรายการสาขาการติดตามและgit checkout [branch]เปลี่ยนเป็นสาขาที่กำหนดได้

การผสม

การรวมเป็นกระบวนการของการรวมการเปลี่ยนแปลงรหัสจากสาขาที่แตกต่างกันหรือจากสาขาที่ต่างกันในสาขาเดียวกัน (ตัวอย่างเช่นเมื่อสาขาในท้องถิ่นและระยะไกลไม่ซิงค์กัน) หากมีการพัฒนางานในสาขาและงานเสร็จสมบูรณ์พร้อมและทดสอบแล้วจะสามารถรวมเข้ากับmasterสาขา นี้จะกระทำโดยgit checkout masterการสลับไปยังสาขาแล้วmaster git merge your_branchการผสานจะนำไฟล์ต่าง ๆ ทั้งหมดและแม้แต่การเปลี่ยนแปลงที่แตกต่างกันไปยังไฟล์เดียวกันเข้าด้วยกัน ซึ่งหมายความว่ามันจะเปลี่ยนรหัสภายในไฟล์เพื่อรวมการเปลี่ยนแปลงทั้งหมด

เมื่อทำcheckoutของmasterมันเป็นยังแนะนำให้ทำgit pull origin masterจะได้รับรุ่นใหม่ล่าสุดของต้นแบบระยะไกลรวมเข้าเป็นหลักในท้องถิ่นของคุณ ถ้าต้นแบบระยะไกลการเปลี่ยนแปลงกล่าวคือคุณจะเห็นข้อมูลที่สะท้อนให้เห็นว่าในช่วงที่moved forward git pullหากเป็นกรณีนี้ (มีการเปลี่ยนแปลงข้อมูลหลัก) คุณจะได้รับคำแนะนำให้ทำตามgit checkout your_branchนั้นrebaseเพื่อให้การเปลี่ยนแปลงของคุณได้รับ 'เล่นซ้ำ' จริง ๆ จากด้านบนของต้นแบบ 'ใหม่' จากนั้นคุณจะได้รับข้อมูลล่าสุดตามที่แสดงในย่อหน้าถัดไป

หากไม่มีข้อขัดแย้งมาสเตอร์จะมีการเปลี่ยนแปลงใหม่ที่เพิ่มเข้ามาหากมีข้อขัดแย้งหมายความว่าไฟล์เดียวกันมีการเปลี่ยนแปลงรอบ ๆ บรรทัดของรหัสที่คล้ายกันซึ่งไม่สามารถผสานได้โดยอัตโนมัติ ในกรณีนี้git merge new_branchจะรายงานว่ามีข้อขัดแย้งที่จะแก้ไข คุณ 'แก้ไข' พวกเขาด้วยการแก้ไขไฟล์ (ซึ่งจะมีการเปลี่ยนแปลงทั้งสองอย่าง) เลือกการเปลี่ยนแปลงที่คุณต้องการลบบรรทัดของการเปลี่ยนแปลงที่คุณไม่ต้องการแล้วบันทึกไฟล์ การเปลี่ยนแปลงที่มีเครื่องหมายคั่นเช่นและ========<<<<<<<<

เมื่อคุณแก้ไขข้อขัดแย้งใด ๆ แล้วคุณจะได้อีกครั้งgit addและgit commitการเปลี่ยนแปลงเหล่านั้นเพื่อดำเนินการต่อการผสาน (คุณจะได้รับข้อเสนอแนะจากคอมไพล์ในระหว่างกระบวนการนี้เพื่อแนะนำคุณ)

เมื่อกระบวนการไม่ทำงานคุณจะพบว่าgit merge --abortมีประโยชน์มากในการรีเซ็ตสิ่งต่าง ๆ

การรีบูตแบบโต้ตอบและการแบน / การเรียงลำดับใหม่ / ลบการกระทำ

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

ปัจจัยสำคัญในการประเมินเมื่อพิจารณาว่าจะทำสิ่งนี้หรือไม่ว่าการกระทำหลายรายการนั้นขัดแย้งกับไฟล์เดียวกันหรือไฟล์มากกว่าหนึ่งครั้ง (ดีกว่าการสควอชที่ตกลงไว้ในกรณีนั้น) สิ่งนี้ทำด้วยเครื่องมือการรีบูตแบบโต้ตอบ เครื่องมือนี้ช่วยให้คุณสควอชคอมมิทลบคอมมิทข้อความ reword เป็นต้นgit rebase -i HEAD~10( หมายเหตุ: นั่นคือ~ไม่ใช่ไม่ใช่ก- ) จะแสดงสิ่งต่อไปนี้:

การรีบูตแบบโต้ตอบใน Git

ระวังและใช้เครื่องมือนี้อย่างระมัดระวัง ทำหนึ่งสควอช / ลบ / สั่งซื้อใหม่ในเวลาออกและบันทึกการกระทำนั้นแล้วใส่เครื่องมืออีกครั้ง หากการคอมมิชชันไม่ต่อเนื่องคุณสามารถจัดลำดับใหม่ได้ (จากนั้นสควอชตามต้องการ) คุณสามารถลบคอมมิทที่นี่ได้เช่นกัน แต่คุณต้องแน่ใจในสิ่งที่คุณทำเมื่อคุณทำเช่นนั้น!

งา

มีสองวิธีหลักในการทำงานร่วมกันในที่เก็บ Git รายละเอียดข้างต้นโดยตรงผ่านสาขาที่ผู้คนดึงและดันจาก / ถึง ผู้ทำงานร่วมกันเหล่านี้มีคีย์ SSH ของพวกเขาที่ลงทะเบียนกับที่เก็บระยะไกล นี่จะช่วยให้พวกเขาส่งตรงไปยังที่เก็บนั้น ข้อเสียคือคุณต้องรักษารายชื่อผู้ใช้ วิธีการอื่น - การฟอร์ก - อนุญาตให้ใครก็ตาม 'แยก' พื้นที่เก็บข้อมูลโดยทั่วไปแล้วการทำสำเนาโลคัลในบัญชีพื้นที่เก็บข้อมูล Git ของพวกเขาเอง จากนั้นพวกเขาสามารถทำการเปลี่ยนแปลงและเมื่อเสร็จสิ้นการส่ง 'คำขอดึง' (จริงๆแล้วมันเป็น 'ผลักดัน' จากพวกเขาและคำขอ 'ดึง' สำหรับผู้ดูแลพื้นที่เก็บข้อมูลจริง) เพื่อรับรหัสที่ยอมรับ

วิธีที่สองนี้ใช้ forks ไม่ต้องการให้ใครดูแลรายการของผู้ใช้สำหรับที่เก็บ


GitHub

GitHub (พื้นที่เก็บข้อมูลระยะไกล) เป็นแหล่งข้อมูลระยะไกลที่โดยปกติแล้วคุณจะผลักดันและดึงการเปลี่ยนแปลงที่กระทำไปหากคุณมี (หรือเพิ่ม) พื้นที่เก็บข้อมูลดังกล่าวดังนั้นภายในและระยะไกลจึงค่อนข้างชัดเจน อีกวิธีในการคิดถึงที่เก็บระยะไกลก็คือมันเป็น.gitโครงสร้างไดเรกทอรีที่อาศัยอยู่บนเซิร์ฟเวอร์ระยะไกล

เมื่อคุณ 'ส้อม - ใน GitHub เว็บเบราเซอร์ GUI คุณสามารถคลิกที่ปุ่มนี้ภาพของปุ่มแยก- คุณสร้างสำเนา (โคลน) ของรหัสในของคุณบัญชี GitHub อาจเป็นเรื่องละเอียดเล็กน้อยในครั้งแรกที่คุณทำดังนั้นโปรดตรวจสอบให้แน่ใจว่าคุณได้ดูที่เก็บรหัสฐานข้อมูลไว้ที่ใด - เจ้าของเดิมหรือ 'แยกจาก' และคุณเช่นนี้

ภาพของชื่อพื้นที่เก็บข้อมูลที่แยกแล้ว

เมื่อคุณมีสำเนาโลคัลคุณสามารถทำการเปลี่ยนแปลงได้ตามต้องการ (โดยการดึงและผลักดันพวกเขาไปยังเครื่องท้องถิ่น) เมื่อเสร็จแล้วคุณส่ง 'คำขอดึง' ให้กับเจ้าของพื้นที่เก็บข้อมูลเดิม / ผู้ดูแลระบบ (ฟังดูแปลก แต่จริงๆแล้วคุณแค่คลิกที่นี่ภาพของปุ่มคำขอดึง:) และพวกเขา 'ดึง' มันมา

สิ่งที่พบได้ทั่วไปสำหรับทีมที่ทำงานกับโค้ดด้วยกันคือ 'โคลน' พื้นที่เก็บข้อมูล (คลิกที่ไอคอน 'คัดลอก' บนหน้าจอหลักของที่เก็บ) จากนั้นพิมพ์โลคัลgit cloneและวาง นี่จะเป็นการตั้งค่าของคุณในเครื่องและคุณยังสามารถผลักและดึงไปยังตำแหน่ง GitHub (แบ่งปัน)

โคลนนิ่ง

ตามที่ระบุในส่วนบน GitHub โคลนคือสำเนาของที่เก็บ เมื่อคุณมีพื้นที่เก็บข้อมูลระยะไกลคุณออกgit cloneคำสั่งกับ URL ของมันแล้วคุณจบลงด้วยการคัดลอกท้องถิ่นหรือโคลนของพื้นที่เก็บข้อมูล โคลนนี้มีทุกสิ่ง , ไฟล์, สาขาหลัก, สาขาอื่น ๆ , ความมุ่งมั่นที่มีอยู่ทั้งหมด, shebang ทั้งหมด เป็นโคลนที่คุณเพิ่มและกระทำของคุณจากนั้นพื้นที่เก็บข้อมูลระยะไกลตัวเองเป็นสิ่งที่คุณผลักดันความมุ่งมั่นเหล่านั้น นี่เป็นแนวคิดในท้องถิ่น / ระยะไกลที่ทำให้ Git (และระบบที่คล้ายคลึงกับมันเช่น Mercurial) เป็น DVCS ( Distributed Version Control System) ซึ่งตรงข้ามกับ CVS แบบดั้งเดิม (ระบบการกำหนดรหัส) เช่น SVN, PVCS, CVS เป็นต้น คุณกระทำโดยตรงกับที่เก็บระยะไกล

การแสดง

การแสดงแนวคิดหลักสามารถดูได้ที่
http://marklodato.github.com/visual-git-guide/index-en.htmlและ
http://ndpsoftware.com/git-cheatsheet.html#loc=index

หากคุณต้องการให้ภาพแสดงการเปลี่ยนแปลงที่เกิดขึ้นคุณไม่สามารถเอาชนะเครื่องมือแสดงผลgitg( gitxสำหรับ macOS) ด้วย GUI ที่ฉันเรียกว่า 'แผนที่รถไฟใต้ดิน' (โดยเฉพาะรถไฟใต้ดินลอนดอน) เหมาะสำหรับการแสดงว่าใครทำอะไร การเปลี่ยนแปลงของสิ่งต่าง ๆ แยกและรวม ฯลฯ

นอกจากนี้คุณยังสามารถใช้เพื่อเพิ่มกระทำและจัดการการเปลี่ยนแปลงของคุณ!

รูปภาพของอินเตอร์เฟส gitg / gitx

แม้ว่า gitg / gitx ค่อนข้างน้อย แต่จำนวนของเครื่องมือ GUI ยังคงขยายตัวอย่างต่อเนื่อง ผู้ใช้ Mac หลายคนใช้ gitx ทางแยกของ Brotherbard และสำหรับ Linux ตัวเลือกที่ยอดเยี่ยมคือ smart-git พร้อมอินเทอร์เฟซที่ใช้งานง่าย แต่ทรงพลัง:

รูปภาพของ smart-git GUI

โปรดทราบว่าแม้มีเครื่องมือ GUI คุณอาจทำคำสั่งมากมายที่บรรทัดคำสั่ง

สำหรับสิ่งนี้ฉันมีนามแฝงต่อไปนี้ใน~/.bash_aliasesไฟล์ของฉัน(ซึ่งถูกเรียกจาก~/.bashrcไฟล์ของฉันสำหรับแต่ละเซสชันเทอร์มินัล):

# git
alias g='git status'
alias gcob='git checkout -b '
alias gcom='git checkout master'
alias gd='git diff'
alias gf='git fetch'
alias gfrm='git fetch; git reset --hard origin/master'
alias gg='git grep '
alias gits='alias | grep "^alias g.*git.*$"'
alias gl='git log'
alias gl1='git log --oneline'
alias glf='git log --name-status'
alias glp='git log -p'
alias gpull='git pull '
alias gpush='git push '

และฉันมี "นามแฝง git" ต่อไปนี้ใน~/.gitconfigไฟล์ของฉัน- ทำไมจึงมีสิ่งเหล่านี้
ดังนั้นการทำให้สาขาเสร็จสมบูรณ์ (ด้วยปุ่ม TAB) ทำงานได้!

ดังนั้นเหล่านี้คือ:

[alias]
  co = checkout
  cob = checkout -b

ตัวอย่างการใช้งาน: git co [branch]<- การเติมแท็บให้เสร็จสมบูรณ์สำหรับสาขาจะใช้งานได้

เครื่องมือการเรียนรู้ GUI

คุณอาจพบว่าhttps://learngitbranching.js.org/มีประโยชน์ในการเรียนรู้แนวคิดพื้นฐานบางอย่าง สกรีนช็อต: วิดีโอ: https://youtu.be/23JqqcLPss0ป้อนคำอธิบายรูปภาพที่นี่

ในที่สุด 7 ผู้ช่วยชีวิตที่สำคัญ!

  1. คุณทำการเปลี่ยนแปลงเพิ่มและคอมมิชชันพวกเขา (แต่อย่าดัน) แล้วโอ้! คุณรู้ว่าคุณอยู่ในระดับต้นแบบ!

    git reset [filename(s)]
    git checkout -b [name_for_a_new_branch]
    git add [file(s)]
    git commit -m "A useful message"
    
    Voila!  You've moved that 'master' commit to its own branch !
  2. คุณเลอะไฟล์บางไฟล์ในขณะที่ทำงานในสาขาท้องถิ่นและเพียงต้องการกลับไปที่สิ่งที่คุณมีครั้งล่าสุดที่คุณทำgit pull:

    git reset --hard origin/master  # You will need to be comfortable doing this!
  3. คุณเริ่มทำการเปลี่ยนแปลงแบบโลคัลแก้ไขไฟล์ครึ่งโหลจากนั้นโอ้อึคุณยังอยู่ในสาขาหลัก (หรือสาขาอื่น):

    git checkout -b new_branch_name  # just create a new branch
    git add .                      # add the changes files
    git commit -m"your message"    # and commit them
  4. คุณทำหนึ่งไฟล์โดยเฉพาะในสาขาปัจจุบันของคุณและต้องการ 'รีเซ็ต' ไฟล์นั้น (สูญเสียการเปลี่ยนแปลง) โดยทั่วไปว่ามันเป็นครั้งสุดท้ายที่คุณดึงมันจากพื้นที่เก็บข้อมูลระยะไกล:

    git checkout your/directories/filename

    นี่เป็นการรีเซ็ตไฟล์ (เช่นคำสั่ง Git จำนวนมากซึ่งไม่ได้ตั้งชื่ออย่างดีสำหรับสิ่งที่ทำที่นี่)

  5. คุณทำการเปลี่ยนแปลงบางอย่างในเครื่องคุณต้องการให้แน่ใจว่าคุณจะไม่สูญเสียมันในขณะที่คุณทำgit resetหรือrebase: ฉันมักจะทำสำเนาคู่มือของโครงการทั้งหมด ( cp -r ../my_project ~/) เมื่อฉันไม่แน่ใจว่าฉันอาจสับสนใน Git หรือไม่สำคัญ การเปลี่ยนแปลง

  6. คุณกำลังรีบูต แต่สิ่งต่าง ๆ เกิดความสับสน:

    git rebase --abort # To abandon interactive rebase and merge issues
  7. เพิ่มสาขา Git ของคุณในPS1พรอมต์ของคุณ(ดูhttps://unix.stackexchange.com/a/127800/10043 ) เช่น

    รูปภาพของพรอมต์

    selenium_rspec_conversionสาขาคือ


1
2/20/12 เพิ่มข้อมูลเกี่ยวกับการรวมกับการรีบูต
Michael Durrant

1
6/16/12 เพิ่มเติมส่วนในโคลนเพื่อให้สมบูรณ์ยิ่งขึ้น
Michael Durrant

4
ข้อความเยอะมาก !! ฉันจะยึดติดกับการโค่นล้มง่าย ๆ ของฉัน :-)
จอนนี่

6
ฮะ? ผู้ใช้โค่นล้มยังสามารถเขียนหนังสือเกี่ยวกับการใช้การโค่นล้ม ฉันคิดว่าการโค่นล้มเป็นเทคโนโลยีรุ่นเก่าที่มีฟังก์ชั่นน้อยลง ส่วนตัวแล้วฉันพบว่าคอมไพล์ใช้งานง่ายมาก ymmv
Michael Durrant

3
ว้าว Micheal! ดังนั้นทั้งหมดเกี่ยวกับการแบ่งปันความรู้ ขอขอบคุณสำหรับการทำงานที่ดีแน่นอน 1
Michiel

143

นี่คือภาพลักษณ์ของโอลิเวอร์สตีลว่ามันเข้ากันได้อย่างไร:

ป้อนคำอธิบายรูปภาพที่นี่


6
ภาพนี้สามารถอัปเดตเพื่อเพิ่ม "git clone" ซึ่งฉันมั่นใจว่าคนส่วนใหญ่คุ้นเคยในทุกกรณี
Contango

3
@ Gravitas ฉันรักกราฟิกนี้จริงๆ แต่มันไม่ได้บอกฉันเมื่อไฟล์ถูกเขียนทับและเมื่อรวมเข้าด้วยกัน คุณช่วยให้ฉันรู้ว่าคำสั่งเหล่านี้คืออะไร บางทีคำสั่งเขียนทับด้านบนและคำสั่งผสานด้านล่างไดรฟ์? ขอบคุณ
zylstra

จากสิ่งที่ฉันเข้าใจดึง git จะดึงลงมาจากระยะไกลสิ่งที่คุณถาม (ดังนั้นสิ่งใดก็ตามที่คุณขอ) และรวมทันทีเข้าไปในสาขาที่คุณอยู่ในเมื่อคุณทำคำขอ ดึงเป็นคำขอระดับสูงที่เรียกใช้ 'ดึงข้อมูล' แล้ว 'รวม' โดยค่าเริ่มต้นหรือ rebase ด้วย '–rebase' คุณสามารถทำได้โดยปราศจากมันเป็นเพียงความสะดวกสบาย
Contango

โคลนคอมไพล์จะไปตรงไหนในแผนภาพนี้ นอกจากนี้คอมไพล์ผสาน? ฉันใหม่มากกับคอมไพล์ แต่ฉันชอบรูปนี้
Mishelle

2
ฉันจะดูว่าฉันสามารถทำแผนภาพรุ่นปรับปรุง
Contango

8

ส้อมกับ Clone - สองคำที่ทั้งคู่หมายถึงการคัดลอก

โปรดดูแผนภาพนี้ (มีพื้นเพมาจากhttp://www.dataschool.io/content/images/2014/Mar/github1.png )

.-------------------------.     1. Fork     .-------------------------.
| Your GitHub repo        | <-------------- | Joe's GitHub repo       |
| github.com/you/coolgame |                 | github.com/joe/coolgame |
| ----------------------- | 7. Pull Request | ----------------------- |
| master -> c224ff7       | --------------> | master -> c224ff7 (c)   |
| anidea -> 884faa1 (a)   |                 | anidea -> 884faa1 (b)   |
'-------------------------'                 '-------------------------'
    |                 ^
    | 2. Clone        |
    |                 |
    |                 |
    |                 |
    |                 |
    |                 | 6. Push (anidea => origin/anidea)
    v                 |
.-------------------------.
| Your computer           |  3. Create branch 'anidea'
| $HOME/coolgame          |
| ----------------------- |  4. Update a file
| master -> c224ff7       |
| anidea -> 884faa1       |  5. Commit (to 'anidea')
'-------------------------'

(a) - after you have pushed it
(b) - after Joe has accepted it
(c) - eventually Joe might merge 'anidea' (make 'master -> 884faa1')

ส้อม

  • สำเนาไปยัง repo ระยะไกลของคุณ (คลาวด์) ที่เชื่อมโยงไปยัง Joe's
  • สำเนาที่คุณสามารถคัดลอกไปยัง repo ท้องถิ่นของคุณและ F *% $ - up
  • เมื่อเสร็จแล้วคุณสามารถกลับไปที่รีโมท
  • จากนั้นคุณสามารถถามโจว่าเขาต้องการใช้มันในโครงการของเขาหรือไม่โดยคลิกคำขอดึง

โคลน

  • สำเนาไปยัง repo ในพื้นที่ของคุณ (ฮาร์ดไดรฟ์)

โปรดทราบว่าข้อได้เปรียบที่แท้จริงของ DVCS คือคุณไม่จำเป็นต้องมีสิทธิ์การเข้าถึงใด ๆ กับ repo ของ Joe เพื่อทำสิ่งนี้ หากโจต้องการให้คุณมีส่วนร่วมบ่อยขึ้นเขาสามารถให้สิทธิ์การเข้าถึงแบบพุชให้กับคุณ: พวกเขาสามารถผลักไสanideaสิทธิ์ไปยัง repo ของเขาและช่วยงานบ้านของคุณให้เป็นปัจจุบัน OTOH ถ้าคุณไม่สามารถบรรลุข้อตกลงกับ Joe คุณสามารถพัฒนาต่อไปและใช้ส้อมของคุณ (และดูว่าคุณสามารถทำให้เขาเปลี่ยนใจในภายหลัง)
Alois Mahdal

6

เพียงเพื่อเพิ่มให้กับผู้อื่นโน้ตเฉพาะสำหรับการฟอร์ก

เป็นการดีที่ได้ทราบว่าในทางเทคนิคการโคลน repo และการฟอร์ก Repo นั้นเป็นสิ่งเดียวกัน ทำ:

git clone $some_other_repo

และคุณสามารถแตะตัวคุณเองที่ด้านหลัง --- คุณเพิ่งหักเงินซื้อคืนอื่น ๆ

Git ในฐานะ VCS นั้นแท้จริงแล้วทั้งหมดเกี่ยวกับการโคลนการฟอร์ก นอกเหนือจาก "เพียงแค่เรียกดู" โดยใช้ UI ระยะไกลเช่น cgit มีน้อยมากที่จะทำกับ git repo ที่ไม่เกี่ยวข้องกับการฟอร์คโคลน repo ในบางจุด

อย่างไรก็ตาม

  • เมื่อมีคนบอกว่าฉันแยก repo Xพวกเขาหมายความว่าพวกเขาได้สร้างโคลนของ repo ที่อื่นโดยมีเจตนาที่จะเปิดเผยให้ผู้อื่นตัวอย่างเช่นเพื่อแสดงการทดลองบางอย่างหรือเพื่อใช้กลไกการควบคุมการเข้าถึงที่แตกต่างกัน (เช่นเพื่อให้คนที่ไม่มี Github เข้าถึงได้ แต่ด้วยบัญชีภายในของ บริษัท เพื่อทำงานร่วมกัน)

    ข้อเท็จจริงที่ว่า: repo อาจถูกสร้างขึ้นด้วยคำสั่งอื่นมากกว่า git cloneที่ว่ามันน่าจะเป็นโฮสต์บนเซิร์ฟเวอร์แทนแล็ปท็อปของใครบางคนและส่วนใหญ่อาจมีรูปแบบที่แตกต่างกันเล็กน้อย (เป็น "repo เปลือย" คือไม่มีต้นไม้) ทั้งหมดเป็นเพียงรายละเอียดทางเทคนิค

    ความจริงที่ว่ามันอาจจะมีชุดของแท็กหรือการกระทำที่แตกต่างกันส่วนใหญ่น่าจะเป็นเหตุผลที่พวกเขาทำมันในตอนแรก

    (สิ่งที่ Github ทำเมื่อคุณคลิก "fork" เป็นเพียงการโคลนด้วยน้ำตาลเพิ่ม: มันโคลน repo ให้คุณวางไว้ในบัญชีของคุณบันทึก "forked จาก" ที่ไหนสักแห่งเพิ่มชื่อระยะไกล "upstream" และที่สำคัญที่สุดคือ เล่นภาพเคลื่อนไหวที่ดี)

  • เมื่อมีคนบอกว่าฉันโคลน repo Xพวกเขาหมายความว่าพวกเขาได้สร้างโคลนของ repo ในแล็ปท็อปหรือเดสก์ท็อปของพวกเขาด้วยความตั้งใจศึกษาเล่นกับมันสนับสนุนหรือสร้างบางอย่างจากซอร์สโค้ดในนั้น

ความสวยงามของ Git คือการที่มันทำให้สิ่งนี้เข้ากันได้อย่างสมบูรณ์แบบ: repos ทั้งหมดเหล่านี้มีส่วนร่วมของblock commit chain ดังนั้นจึงเป็นไปได้ที่จะปลอดภัย (ดูหมายเหตุด้านล่าง) ผสานการเปลี่ยนแปลงไปมาระหว่าง repos เหล่านี้ตามที่คุณเห็นสมควร


หมายเหตุ: "ปลอดภัย" ตราบใดที่คุณไม่ได้เขียนส่วนทั่วไปของโซ่และตราบใดที่การเปลี่ยนแปลงไม่ขัดแย้งกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.