ทำความเข้าใจความแตกต่างของสาขาระหว่าง SVN และ Git


44

ฉันเป็นผู้ใช้ของ SVN และตอนนี้ฉันกำลังเรียนรู้ Git

ใน SVN ฉันมักจะเช็คเอาต์ repo บนเครื่องของฉันซึ่งรวมถึงสาขาทั้งหมดในโครงการของฉันและฉันเคยเลือกโฟลเดอร์สำหรับสาขาที่ฉันสนใจและทำงานที่นั่น

ฉันเห็นความแตกต่างโดยใช้ Git

ขณะนี้ฉันกำลังโคลน repo และโคลนสาขาเฉพาะโดยใช้ gitk

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

ฉันไม่สามารถหาวิธีง่าย ๆ ในการดูสาขาทั้งหมดในที่เก็บในพื้นที่ของฉันโดยใช้ Git

  • ฉันต้องการทราบว่ากระบวนการ Git ที่ฉันอธิบายนั้นเป็น "มาตรฐาน" หรือไม่และถูกต้องหรือไม่

  • นอกจากนี้ฉันต้องการทราบวิธีจัดการกับกระบวนการที่ฉันต้องการทำงานในสองสาขาในเวลาเดียวกันในกรณีเช่นฉันต้องสร้างโปรแกรมแก้ไขด่วนบนต้นแบบ แต่เก็บเนื้อหาของสาขาอื่นด้วย

  • ข้อตกลงการใช้ชื่อที่แนะนำในการสร้างโฟลเดอร์ซึ่งรวมถึงการโคลนสาขาจาก repo ใน Git myproject-branchnameคืออะไร?


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

20
คุณได้ทำลายเวิร์กโฟลว์ใน SVN ตอนนี้คุณลองมิเรอร์ลงใน Git (ในขณะที่ SVN- เวิร์กโฟลว์ที่ใช้งานได้ดีสำหรับ Git เพียงบางส่วนเท่านั้น) ทางออกที่ดีที่สุด - ลืมนิสัย SVN ทั้งหมดและเริ่มต้นใน Git ตั้งแต่เริ่มต้น
Lazy Badger

6
git cloneเป็นเหมือนsvnadmin hotcopyหรือsvnrdump+ กว่าที่มันเป็นเหมือนsvnadmin load svn checkoutด้วยgitคุณไม่ขอบิตและชิ้นส่วนจากพื้นที่เก็บข้อมูล; คุณคัดลอกพื้นที่เก็บข้อมูลทั้งหมดและทำงานกับมันแบบโลคัลผลักดันการเปลี่ยนแปลงกลับไปยังพื้นที่เก็บข้อมูล "แหล่งที่มา" เมื่อใดและถ้าคุณรู้สึกว่ามัน Git และการโค่นล้มใช้สองรุ่นที่แตกต่างกันอย่างสิ้นเชิงสำหรับการควบคุมแหล่งที่มา
chepner

1
เกี่ยวกับสิ่งที่แก้ไขด่วนพิจารณาใช้git-flow
Bakuriu

5
@ LazyBadger จะไม่ทำลายเวิร์กโฟลว์ถ้ามันช่วยในการพัฒนาและให้คุณค่า ไม่มีวิธีที่ถูกต้องในการใช้สาขา
dietbuddha

คำตอบ:


67

ฉันเป็นผู้ใช้ของ SVN และตอนนี้ฉันกำลังเรียนรู้ GIT

ยินดีต้อนรับสู่แก๊งค์!

SVN การศึกษาอีกครั้ง

ใน SVN ฉันมักจะ [... ]

รอสักครู่ ในขณะที่ CVS และ SVN และระบบควบคุมเวอร์ชันแบบดั้งเดิม (เช่นส่วนกลาง) เป็นไปตาม (ส่วนใหญ่) มีจุดประสงค์เดียวกันกับระบบการควบคุมเวอร์ชันที่ทันสมัย ​​(เช่นกระจาย) เช่น Mercurial และ Git คุณจะเรียนรู้ Git ได้ดีขึ้นตั้งแต่ต้นแทนที่จะเป็น พยายามโอนเวิร์กโฟลว์ SVN ของคุณไปยัง Git

http://hginit.com ( ดูที่ archive.org ) โดย Joel Spolsky (หนึ่งในผู้ก่อตั้ง Stack Exchange) เป็นบทเรียนสำหรับ Mercurial ไม่ใช่ Git แต่เป็นบทที่ศูนย์"Subversion Re-education"คือ ประโยชน์สำหรับคนเปลี่ยนห่างจาก SVN การใด ๆระบบการควบคุมเวอร์ชันกระจายตามที่มันบอกคุณว่าแนวคิด SVN คุณต้อง (ชั่วคราว) ยกเลิก -learn (หรือจะstashออกไปเป็นผู้ใช้ Git อาจจะบอกว่า) จะเป็นห่อสามารถที่หัวของรอบกระจาย แนวคิดของระบบการควบคุมเวอร์ชันและเวิร์กโฟลว์ที่เป็นสำนวนที่จัดตั้งขึ้นเพื่อทำงานกับมัน

ดังนั้นคุณสามารถอ่านบทที่ศูนย์และส่วนใหญ่เพียงแค่แทนที่คำว่า "mercurial" ด้วย "Git" และดังนั้นจึงต้องเตรียมตัวเองและความคิดของคุณสำหรับ Git

การพิมพ์ที่ดี

(คุณอาจข้ามนี้ได้ในขณะนี้.)ในขณะที่ปรอทและ Git มีมากคล้าย ๆ กันมากกว่าที่จะ SVN มีมีความแตกต่างทางความคิดระหว่างพวกเขาดังนั้นบางส่วนของงบและให้คำแนะนำในการ "โค่นล้มเรื่องการศึกษา" จะกลายเป็นที่ไม่ถูกต้องในทางเทคนิค เมื่อแทนที่ "mercurial" ด้วย "Git":

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

ใน SVN ทุกอย่างเป็นไดเรกทอรี (แต่คุณไม่ควรถือไว้เช่นนั้น)

แต่ฉันขัดจังหวะคุณ คุณกำลังพูด?

ใน SVN ฉันมักจะเช็คเอาต์ repo บนเครื่องของฉันซึ่งรวมถึงสาขาทั้งหมดในโครงการของฉันและฉันเคยเลือกโฟลเดอร์สำหรับสาขาที่ฉันสนใจและทำงานที่นั่น

หากคุณหมายความว่าคุณได้ตรวจสอบโฟลเดอร์รูทของที่เก็บ SVN (หรือโฟลเดอร์อื่น ๆ ที่เกี่ยวข้องมากกว่าtrunkหรือไปยังสาขาเดียวเช่นในเค้าโครง SVN repo แบบเดิมbranchesโฟลเดอร์ที่มีสาขาที่ไม่ใช่ลำต้นทั้งหมด) จากนั้น ฉันกล้าพูดได้ว่าคุณอาจใช้ SVN ผิด (ish) หรืออย่างน้อยก็มีความจริงที่ว่าลำตัวกิ่งก้านและแท็กทั้งหมดถูกพับเป็นเนมสเปซเดียว (แม้ว่าเป็นลำดับชั้น) พร้อมกับไดเรกทอรีภายในการแก้ไข / codebase

แม้ว่ามันอาจเป็นการล่อลวงให้เปลี่ยนสาขา SVN หลายสาขาพร้อมกัน แต่ AFAIK ไม่ใช่วิธีที่ SVN ตั้งใจจะใช้ (แม้ว่าฉันไม่แน่ใจเกี่ยวกับข้อเสียเฉพาะที่ทำงานเช่นนั้น)

ใน Git เฉพาะไดเรกทอรีเท่านั้นที่เป็นไดเรกทอรี

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

แต่ไฟล์ที่ไม่ซ่อนอยู่ที่คุณเห็นในโฟลเดอร์ที่เก็บคืออะไร?

เมื่อคุณgit cloneเป็นที่เก็บ Git จะทำหลายสิ่ง ประมาณ:

  1. มันสร้างโฟลเดอร์เป้าหมายและในนั้น.git/โฟลเดอร์ย่อยที่มี "ฐานข้อมูล"
  2. มันถ่ายโอนการอ้างอิง (แท็กสาขา ฯลฯ ) ของฐานข้อมูลของที่เก็บต้นฉบับและทำสำเนาของพวกเขาในฐานข้อมูลใหม่ให้พวกเขามีชื่อปรับเปลี่ยนเล็กน้อยที่ทำเครื่องหมายพวกเขาเป็นการอ้างอิง "ระยะไกล"
  3. มันโอนการแก้ไขทั้งหมด(เช่นชื่อไฟล์ต้นไม้) ที่การอ้างอิงเหล่านี้ชี้ไปเช่นเดียวกับการแก้ไขทั้งหมดที่การแก้ไขเหล่านี้ชี้ไปยังโดยตรงหรือผ่านการขนส่ง (ผู้ปกครองและบรรพบุรุษ) ไปยังฐานข้อมูลใหม่และเก็บไว้เพื่อให้การอ้างอิงระยะไกลใหม่ ชี้ไปที่สิ่งที่มีอยู่ในที่เก็บใหม่
  4. มันสร้างสาขาท้องถิ่นติดตามการแก้ไขระยะไกลที่สอดคล้องกับสาขาเริ่มต้นของที่เก็บต้นกำเนิด (ปกติmaster)
  5. มันตรวจสอบสาขาท้องถิ่นที่

ขั้นตอนสุดท้ายนั้นหมายความว่า Git ค้นหาการแก้ไขที่สาขานี้ชี้และคลายไฟล์ทรีที่เก็บไว้ที่นั่น (ฐานข้อมูลใช้วิธีการบีบอัดและการทำซ้ำ) ลงในโฟลเดอร์รูทของที่เก็บ โฟลเดอร์รูทนั้นและโฟลเดอร์ย่อยทั้งหมด (ไม่รวม.gitโฟลเดอร์ย่อยพิเศษ) เรียกว่า "working copy" ของที่เก็บของคุณ นั่นคือสิ่งที่คุณโต้ตอบกับเนื้อหาของการตรวจสอบแก้ไข / สาขาในปัจจุบัน มันเป็นแค่โฟลเดอร์และไฟล์ปกติ อย่างไรก็ตามในการโต้ตอบกับพื้นที่เก็บข้อมูลต่อ se ("ฐานข้อมูล" ของการแก้ไขและการอ้างอิง) คุณใช้gitคำสั่ง

เห็นสาขา Git และโต้ตอบกับสาขา Git

ขณะนี้ฉันกำลังโคลน repo และโคลนสาขาเฉพาะโดยใช้ gitk

รุ่นของgitkฉันได้ไม่สามารถโคลนที่เก็บ มันสามารถดูประวัติ repo และสร้างสาขาและตรวจสอบสาขา นอกจากนี้ยังไม่มี "โคลน" สาขา คุณสามารถโคลนที่เก็บได้เท่านั้น

คุณไม่ได้หมายความว่าคุณโคลน repo ที่ใช้git clone ...แล้วโดยใช้gitk, ตรวจสอบสาขา?

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

[ ... ]

  • ฉันต้องการทราบว่ากระบวนการคอมไพล์ที่ฉันอธิบายไว้เป็น "มาตรฐาน" และมีวิธีการที่ถูกต้อง [... ]

ใช่นั่นเป็นมาตรฐานที่ค่อนข้างดี:

  • โคลนที่เก็บโดยใช้ git clone ...
  • ลองดูสาขาที่คุณต้องการใช้งานgit checkout ...หรือใช้เครื่องมือกราฟิกเช่นgikt

ฉันไม่สามารถหาวิธีง่าย ๆ ในการดูสาขาทั้งหมดในที่เก็บในพื้นที่ของฉันโดยใช้ GIT

  • [... ] หรือฉันพลาด smt

อาจจะ:

  • คุณสามารถแสดงรายการสาขาท้องถิ่นด้วย git branch
  • คุณสามารถแสดงรายการสาขาระยะไกลด้วยgit branch -rหรือทุกสาขาด้วยgit branch -a
  • คุณสามารถใช้gitkเพื่อดูประวัติทั้งหมด (แท็กสาขาทั้งหมด ฯลฯ ที่ repo ในพื้นที่ของคุณรู้) โดยเรียกใช้ด้วย

    gitk --all
    

วิธีการทำงานกับหลายสาขาพร้อมกัน

  • นอกจากนี้ฉันต้องการทราบวิธีจัดการกับกระบวนการที่ฉันต้องการทำงานในสองสาขาในเวลาเดียวกันในกรณีเช่นฉันต้องสร้างโปรแกรมแก้ไขด่วนบนต้นแบบ แต่เก็บเนื้อหาของสาขาอื่นด้วย

มีสถานการณ์ที่แตกต่างกันที่นี่:

การเปลี่ยนแปลงใหม่ (ยังไม่ได้สร้าง) จะต้องนำไปใช้กับหลายสาขา

ใช้เวิร์กโฟลว์นี้:

  1. สร้างสาขาใหม่cจากการแก้ไขที่มีอยู่แล้วในบรรพบุรุษของสาขาเหล่านี้ทั้งหมด (เช่นการแก้ไขที่นำข้อบกพร่องเมื่อการเปลี่ยนแปลงจะเป็นข้อผิดพลาด) หรือจากการแก้ไขที่ (รวมถึงบรรพบุรุษทั้งหมด) ยอมรับได้ใน สาขาทั้งหมดเหล่านี้
  2. สร้างและกระทำการเปลี่ยนแปลงในสาขาใหม่cนั้น
  3. สำหรับแต่ละสาขาbที่ต้องการการเปลี่ยนแปลง:

    1. ตรวจสอบb:

      git checkout b
      
    2. รวมcเข้ากับb:

      git merge c
      
  4. ลบสาขาc:

    git branch --delete c
    

จำเป็นต้องทำการเปลี่ยนแปลงที่มีอยู่ในสาขาอื่น

(... แต่ไม่มีการเปลี่ยนแปลงอื่น ๆ ในที่ที่การเปลี่ยนแปลงนั้นอยู่)

  1. ตรวจสอบสาขาที่ต้องการเปลี่ยนแปลง
  2. เชอร์รี่เลือกการแก้ไขที่ทำให้เกิดการเปลี่ยนแปลงตามลำดับ

ในสาขาหนึ่งaคุณต้องการเปลี่ยนไฟล์หนึ่งไฟล์หรือบางไฟล์เป็นสถานะที่แน่นอนที่พวกเขามีในสาขาอื่นb

  1. เช็คเอาท์ a
  2. รับเนื้อหาไฟล์จากสาขาb:

    git checkout b -- path/to/a/file.txt path/to/another/file.cpp or/even/a/complete/directory/ ...
    

    (นอกเหนือจากที่git checkoutไม่มีเส้นทางผ่านสิ่งนี้จะไม่สลับไปที่สาขาbเพียงรับเนื้อหาไฟล์ที่ร้องขอจากที่นั่นไฟล์เหล่านี้อาจมีอยู่หรืออาจไม่มีอยู่aถ้าทำได้ไฟล์เหล่านั้นจะถูกเขียนทับด้วยเนื้อหาบนb)

ในขณะที่ทำงานในสาขาหนึ่งคุณต้องการดูว่าสิ่งต่าง ๆ ในสาขาอื่น

ลองดูสาขาที่คุณต้องการทำงาน

จากนั้นเพื่อดูสาขาอื่น

  • ใช้เครื่องมือกราฟิกที่อนุญาตให้คุณดูเนื้อหาที่ยังไม่ได้ตรวจสอบการแก้ไข (เช่นgitkพยายามเปลี่ยนปุ่มตัวเลือกจาก "patch" เป็น "tree")
  • หรือโคลนที่เก็บข้อมูลไปยังไดเรกทอรีชั่วคราวและตรวจสอบสาขาอื่น ๆ ที่นั่น
  • หรือใช้git worktreeเพื่อสร้างไดเรกทอรีการทำงานแยกต่างหากของพื้นที่เก็บข้อมูลเดียวกัน (เช่นใช้ฐานข้อมูลใน.git/ไดเรกทอรีของพื้นที่เก็บข้อมูลปัจจุบันของคุณ) ซึ่งคุณสามารถตรวจสอบสาขาอื่น ๆ

สำหรับเวิร์กโฟลว์สุดท้ายstashนั้นเหมาะอย่างยิ่ง
CAD97

@ CAD97 ไม่ได้ถ้าคุณต้องการที่จะยังคงทำงานในสาขาแรกในขณะที่กำลังมองหาที่ที่สองสำหรับการอ้างอิงในแบบคู่ขนาน git stashเป็นการดีที่จะย้ายงานที่ยังไม่เสร็จออกไปให้พ้นทางเช่นเปลี่ยนกิ่งไม้แล้วกลับมาใหม่ในภายหลัง
das-g

1
"Mercurial เวิร์กโฟลว์มักจะทำงานโดยการโคลนพื้นที่เก็บข้อมูลที่สมบูรณ์เพื่อการพัฒนาที่แตกต่าง" - เอ๊ะฉันเคยได้ยินเรื่องนี้ แต่คนส่วนใหญ่ที่ต้องการกิ่ง Git ก็ใช้บุ๊กมาร์กแทนการทำซ้ำ repo ทั้งหมด มันง่ายกว่ามาก
Kevin

@ เควินนั่นอาจจะเป็น เมื่อไม่นานมานี้ฉันได้ใช้ Mercurial ครั้งล่าสุดดังนั้นบางทีมันอาจจะแตกต่างกันไปในตอนนั้น (หรือบางทีมันอาจจะเป็นเพียงแค่ขั้นตอนการทำงานของชุมชนที่ฉันใช้มันกับที่เป็นเช่นนี้.)
das-G

บางทีข้อความ Hg Init "[... ] เพราะคุณควรแยก Mercurial ด้วยการโคลนที่เก็บ [... ]" ควรได้รับการอัปเดตในเรื่องนั้นด้วย
das-g

31

ใน SVN ฉันมักจะเช็คเอาต์ repo บนเครื่องของฉันซึ่งรวมถึงสาขาทั้งหมดในโครงการของฉันและฉันเคยเลือกโฟลเดอร์สำหรับสาขาที่ฉันสนใจและทำงานที่นั่น

ยกเว้นว่าคุณตรวจสอบไดเรกทอรีด้านบนลำตัวในการโค่นล้มคุณโดยทั่วไปไม่ได้มีสาขาทั้งหมดในประเทศ ใน Git เนื้อหาทั้งหมด (กระทำข้อความสาขา ฯลฯ ) จะถูกโคลนทุกสำเนา

ขณะนี้ฉันกำลังโคลน repo และโคลนสาขาเฉพาะโดยใช้ gitk

เป็นไปไม่ได้ดูด้านบน คุณสามารถแต่คุณไม่สามารถgit checkout branch-name git clone something branch-nameในการโค่นล้มกิ่งไม้คือโฟลเดอร์ ใน Git สาขาเป็นตัวชี้ไปยังกระทำ

ฉันไม่สามารถหาวิธีง่าย ๆ ในการดูสาขาทั้งหมดในที่เก็บในพื้นที่ของฉันโดยใช้ GIT

git branchวิ่ง โดยค่าเริ่มต้นจะแสดงเฉพาะสาขาในท้องถิ่น ใช้git branch --remoteเพื่อดูสาขาระยะไกล


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

2
@pipe เมื่อคุณยอมรับการเปลี่ยนแปลงคุณทำได้โดยการสร้างการกระทำในท้องถิ่นซึ่งการเปลี่ยนแปลงการกระทำที่สาขาจะชี้ไป หากคุณต้องการให้ผู้อื่นรับการเปลี่ยนแปลงเหล่านี้คุณต้องผลักดันการเปลี่ยนแปลงเหล่านี้ไปยังที่เก็บข้อมูลระยะไกล ซึ่งส่งผลให้สาขาระยะไกลชี้ไปที่การกระทำใหม่นี้ ตอนนี้ทุกคนสามารถดึงการเปลี่ยนแปลงเหล่านี้ได้จากที่นั่นและในที่สุดทุกคนก็จะได้รับสำเนาของพื้นที่เก็บข้อมูลทั้งหมด
Frozn

9
@pipe แรกคุณสามารถในความเป็นจริงโคลนเพียงสาขาโดยใช้--single-branch(แม้เพียงปลายด้วย--depth 1) ความแตกต่างระหว่างสาขาในพื้นที่และสาขาที่ห่างไกลที่รู้จักกันในชื่อคอมไพล์เป็นเพียงประเภทของฉลาก สาขาระยะไกลจะนำหน้าด้วยชื่อของแหล่งที่มาระยะไกล (บ่อยครั้งorigin) สาขาในท้องที่ไม่มีคำนำหน้าดังกล่าว แต่ในท้ายที่สุดข้อมูลจะพร้อมใช้งานในเครื่อง (เว้นแต่คุณจะทำ--single-branchหรือสิ่งที่คล้ายกัน) เมื่อคุณเรียกใช้git checkout $branchnameด้วยสาขาที่ไม่มีสาขา แต่มีสาขาระยะไกลอยู่ git จะตั้งค่าสาขาในพื้นที่โดยอัตโนมัติ "ติดตาม" รีโมต
Jonas Schäfer

"ถ้าคุณไม่ตรวจสอบไดเรกทอรีด้านบนลำตัว" - ประสบการณ์ของฉันคือสิ่งนี้เป็นเรื่องธรรมดาเพราะมันทำให้การรวมง่ายขึ้นมาก (แม้ว่าเราจะใช้สาขา "สด" เพียงอย่างเดียวแทนที่จะเป็นแท็กเวอร์ชันดังนั้นโดยปกติจะมีจำนวนเพียง 2-3 สำเนาของรหัส)
Izkata

1
@Izkata "มันทำให้การรวมง่ายขึ้นมาก" ใช่ไหม
HorusKol

3

เช่นนี้จะติดแท็กด้วยผมหวังว่าขาดความรู้ SVN เป็น neglectable

ขณะนี้ฉันกำลังโคลน repo และโคลนสาขาเฉพาะโดยใช้ gitk

คุณกำลังโคลนพื้นที่เก็บข้อมูลระยะไกลทั้งหมดไม่เพียง แต่สาขาที่เฉพาะเจาะจง

ที่เก็บจะถูกจินตนาการว่าเป็นฐานข้อมูลที่ดีที่สุดดังนั้นคุณจึงทำการโคลนสถานะปัจจุบันของฐานข้อมูลระยะไกล แต่หลังจากนั้นคุณกำลังทำงานกับสำเนาของฐานข้อมูลนั้นเอง ถ้าคุณกระทำคุณจะแก้ไขฐานข้อมูลท้องถิ่นของคุณ

fetchคำสั่งที่ใช้ในการเก็บฐานข้อมูลท้องถิ่นในการซิงค์กับรีโมทหนึ่งเดียว

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

สมมติว่าคุณกำลังทำงานในที่เก็บง่าย ๆ ที่ไม่มีสาขานอกจากmasterคุณสามารถเข้าไปดูใน.gitโฟลเดอร์เพื่อเผย "magic":

สมมติสุดท้ายของการกระทำ (บนmaster) คือคุณจะพบว่าที่อยู่ภายใต้182e8220b404437b9e43eb78149d31af79040c66cat .git/refs/heads/master

จากที่คุณปิดสาขาสาขาใหม่ที่คุณจะได้พบกับตัวชี้เดียวกันแน่นอนในแฟ้มgit checkout -b mybranchcat .git/refs/heads/mybranch

สาขาไม่มีอะไรมากไปกว่า "ตัวชี้" "การทำงาน" HEADเครื่องหมายที่เรียกว่า

หากคุณต้องการทราบว่าคุณอยู่ที่ไหนHEAD:

cat .git/HEADซึ่งกล่าวว่าเช่นref: refs/heads/mybranchซึ่งจะเปลี่ยนจุด ( cat .git/refs/heads/mybranch) เพื่อแฮชกระทำ78a8a6eb6f82eae21b156b68d553dd143c6d3e6f

การกระทำที่เกิดขึ้นจริงจะถูกเก็บไว้ภายใต้objectsโฟลเดอร์ (วิธีเป็นหัวข้อของตัวเอง)

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

อย่าสับสนworking directoryกับ "ฐานข้อมูล git" โดยรวม ดังที่ฉันได้กล่าวไปแล้วไดเรกทอรีทำงานของคุณเป็นเพียงส่วนหนึ่งของ (อาจ) ส่วนย่อย

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

โดยปกติถ้าคุณต้องการดูว่าสาขาใดที่กำหนดไว้สำหรับโครงการคุณมีความเป็นไปได้

  • git branch สำหรับสาขาท้องถิ่น
  • git branch --remote สำหรับสาขาระยะไกล
  • git branch -a สำหรับทั้ง

(หรือgit branch -v)

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

เวิร์กโฟลว์ทั่วไปของฉันคือ:

  • แยกสาขาคุณลักษณะออก
  • แยกสาขา WIP (อยู่ระหว่างดำเนินการ) จากสาขานั้น
  • ทำงานได้ตามที่คุณต้องการ - แม้ว่าคุณจะมอบหมายงานหลังจากบรรทัดเดียว มันไม่สำคัญ

เมื่อคุณสมบัติเสร็จสมบูรณ์:

  • สควอช / ทำใหม่WIPสาขา (ด้วยการรีบูตแบบโต้ตอบ) = ทำให้การกระทำเดียวจากที่
  • รวมWIPสาขาเข้ากับสาขาฟีเจอร์และข้อเสนอที่ (ถ้าคุณทำงานกับ GitHub ข้อเสนอนั้นจะเรียกว่า "คำขอดึง") เพื่อรวมเข้ากับสาขาที่มั่นคง (มาสเตอร์)

นอกจากนี้ฉันต้องการทราบวิธีจัดการกับกระบวนการที่ฉันต้องการ wprl ในสองสาขาในเวลาเดียวกันในกรณีเช่นฉันต้องสร้างโปรแกรมแก้ไขด่วนบนต้นแบบ แต่เก็บเนื้อหาของสาขาอื่นด้วย

ขึ้นอยู่กับว่าโครงการของคุณมีโครงสร้างอย่างไร:

สมมติว่าคุณมีเจ้านายที่มั่นคง และฟีเจอร์นั้นได้รับการพัฒนาออกมาจากสาขาที่มีเสถียรภาพเท่านั้นดังนั้นโดยปกติแล้วจะอยู่หลังสาขาฟีเจอร์ จากนั้นคุณจะมีความมุ่งมั่นต่ออาจารย์ที่จะเป็นรากของสาขาคุณลักษณะ

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

หรือคุณสามารถทำการเปลี่ยนแปลงสาขา (เช่นmaster) และทำให้พวกเขาเปลี่ยนเป็นสาขาอื่นได้

อะไรคืออนุสัญญาชื่อที่แนะนำในการสร้างโฟลเดอร์ซึ่งรวมถึงสาขาที่โคลนจาก repo ใน GIT เช่น myproject-branchname

มันขึ้นอยู่กับคุณ.

โดยทั่วไปแล้วคุณจะได้ชื่อที่เก็บ

แต่มีโอกาสเมื่อไม่ต้องการ:

เช่นคุณคัดลอก oh-my-zsh ด้วยgit clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh Here .oh-my-zshถูกตั้งชื่ออย่างชัดเจนว่าเป็นเป้าหมาย


2

Git clone จริง ๆ แล้วโคลนที่เก็บข้อมูลทั้งหมด แต่ตั้งค่าไดเรกทอรีการทำงานของคุณเป็นค่าเริ่มต้น

คุณสามารถดูสาขาอื่น ๆ ที่ใช้git branchเพื่อดูสาขาท้องถิ่นหรือดูสาขาgit branch -rระยะไกลจากนั้นgit checkoutเปลี่ยนเป็นสาขาที่มีอยู่หรือสร้างสาขาใหม่ตามสาขาปัจจุบัน

คุณควรอ่านเอกสาร git สำหรับรายละเอียดเพิ่มเติมและ Atlassian ก็มีบทความดีๆอยู่บ้างเช่นกัน


0

สาขาในคอมไพล์และ svn เป็นสิ่งที่แตกต่างกันโดยพื้นฐาน

ใน svn สาขา (หรือแท็ก) เป็นไดเรกทอรีใน repo

ในคอมไพล์สาขา (หรือแท็ก) เป็นตัวชี้ไปยังกระทำ

ด้วย svn คุณสามารถถ้าคุณต้องการเช็คเอาท์รูทของ repo ซึ่งหมายความว่าคุณมีทุกสาขาและแท็กชำระเงินทันที การดำเนินการนี้ไม่ใช่วิธีปกติในการใช้ svn

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

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

โดยอาศัยอำนาจในการเป็นไดเรกทอรีและอาศัยอำนาจตามแบบจำลองประวัติศาสตร์เชิงเส้นอย่างง่ายของ svn สาขา svn มีประวัติที่แข็งแกร่ง หากคุณต้องการที่จะรู้ว่าสิ่งที่อยู่ในสาขา x ในวันที่คุณสามารถถามคำถามว่า

ในทางกลับกันกิ่งของ Git นั้นไม่มีประวัติจริงๆ มี "reflog" แต่มีไว้เพื่อเป็นกลไกการกู้คืนความเสียหายมากกว่าประวัติระยะยาว โดยเฉพาะการอ้างอิงไม่สามารถอ่านได้จากระยะไกลและถูกปิดใช้งานโดยค่าเริ่มต้นสำหรับ repos เปลือย

ความมุ่งมั่นของหลักสูตรมีประวัติ แต่ประวัติศาสตร์เหล่านั้นไม่เพียงพอที่จะตอบคำถามของ "สิ่งที่อยู่ในสาขา x ของ repo y ในวันที่ซี"

ฉันไม่สามารถหาวิธีง่าย ๆ ในการดูสาขาทั้งหมดในที่เก็บในพื้นที่ของฉันโดยใช้ Git

คุณสามารถแสดงรายการสาขาท้องถิ่นทั้งหมดโดยพิมพ์ "git branch"

คุณสามารถแสดงรายการทุกสาขาได้ทั้งในและนอกสถานที่โดยใช้ "git branch -a"

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

คู่ของตัวเลือก

คุณสามารถคอมมิชชันการเปลี่ยนแปลงของคุณใน "สาขาอื่น" สลับไปที่มาสเตอร์ทำงานที่นั่นแล้วสลับกลับ

คุณยังสามารถสร้างแผนผังการทำงานพิเศษ Google "git-worktree" สำหรับรายละเอียดเกี่ยวกับไวยากรณ์

ข้อตกลงการใช้ชื่อที่แนะนำในการสร้างโฟลเดอร์ซึ่งรวมถึงสาขาที่ถูกโคลนจาก repo ใน Git คือตัวอย่างเช่น myproject-branchname?

ฉันไม่คิดว่าจะมีการประชุมที่จัดตั้งขึ้น การมีต้นไม้ทำงานหลายรายการเช็คเอาต์พร้อมกันนั้นเป็นข้อยกเว้นไม่ใช่กฎ


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