การรวม: Hg / Git vs. SVN


144

ฉันมักจะอ่านว่า Hg (และ Git และ ... ) นั้นสามารถผสานได้ดีกว่า SVN แต่ฉันไม่เคยเห็นตัวอย่างการใช้งานจริงที่ Hg / Git สามารถผสานบางสิ่งที่ SVN ล้มเหลว (หรือที่ SVN ต้องการการแทรกแซงด้วยตนเอง) คุณสามารถโพสต์รายชื่อทีละขั้นตอนของการดำเนินการของสาขา / แก้ไข / กระทำ /...- ที่แสดงว่า SVN จะล้มเหลวในขณะที่ Hg / Git เคลื่อนไหวอย่างมีความสุขหรือไม่ ในทางปฏิบัติไม่ได้เป็นกรณีพิเศษอย่างยิ่งโปรด ...

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

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


2
ฉันคิดว่าคุณควรใส่ใจกับรายการที่ซ้ำกัน: stackoverflow.com/questions/43995/… stackoverflow.com/questions/459891//
P Shved

11
ฉันได้อ่านอันแรกแล้วอันอื่นก็ใหม่ แต่พวกเขามีอายุ 1-2 ปีแล้วและส่วนใหญ่จะเกี่ยวกับปัญหา pre-svn-1.5 (ที่ svn ยังไม่ได้รวมการติดตาม)
stmax

2
เพียงแค่ความคิดเห็นที่คุณยังสามารถก้อนบาซ่าด้วย git / hg เป็น DVCS อื่นที่จะจัดการกับปัญหาด้านล่างได้อย่างถูกต้อง และเนื่องจากคุณพูดถึงการพยายามหาข้อได้เปรียบ: ข้อดีด้านโลจิสติกส์อย่างง่ายของ git / hg / bzr คือสาขานั้นไม่ได้อยู่ในระดับโลกเหมือนกับ svn คุณไม่จำเป็นต้องเห็นสาขา 67 เมื่อมีเพียงคู่เท่านั้นที่ใช้กับคุณ ทุกคนทำงานในสาขา "ส่วนตัว" จากนั้นใช้ความสามารถในการผสานที่ยอดเยี่ยมเพื่อผสานกลับเข้ามาโดยไม่ต้องเหงื่อออกไม่ว่าการผสานจะทำงานใน 99% ของคดีหรือไม่
wadesworld

5
@wade: คุณเห็นสาขา "ส่วนตัว" เป็นข้อได้เปรียบในสภาพแวดล้อมขององค์กรหรือไม่ ฉันกังวลเกี่ยวกับการสำรองข้อมูล ฉันมักจะมีสาขาฟีเจอร์ที่มีชีวิตอยู่ประมาณ 1-2 เดือนก่อนคืนสู่สังคม ..
stmax

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

คำตอบ:


91

ฉันไม่ได้ใช้การโค่นล้มด้วยตัวเอง แต่จากบันทึกย่อประจำรุ่นสำหรับ Subversion 1.5: การติดตามการผสาน (พื้นฐาน)ดูเหมือนว่ามีความแตกต่างดังต่อไปนี้จากวิธีการผสานการติดตามในระบบควบคุมเวอร์ชันเต็มDAGเช่น Git หรือ Mercurial

  • ผสานลำต้นสาขาจะแตกต่างจากการควบรวมสาขาที่ลำต้น: เหตุผลผสานลำต้นสาขาบางต้องมีตัวเลือกในการ--reintegratesvn merge

    ในระบบควบคุมเวอร์ชันกระจายเช่น Git หรือ Mercurial ไม่มีความแตกต่างทางเทคนิคระหว่าง trunk และ Branch: ทุกสาขาถูกสร้างเท่ากัน (อาจมีความแตกต่างทางสังคม ) การผสานในทิศทางใดก็ทำได้เหมือนกัน

  • คุณต้องระบุตัวเลือก-g( --use-merge-history) ใหม่เพื่อsvn logและsvn blameรวมการติดตามเข้าบัญชี

    ในการติดตามการรวม Git และ Mercurial จะนำมาพิจารณาโดยอัตโนมัติเมื่อแสดงประวัติ (บันทึก) และการตำหนิ ใน Git คุณสามารถขอที่จะปฏิบัติตามผู้ปกครองครั้งแรกเท่านั้นที่มี--first-parent(ฉันเดาตัวเลือกที่คล้ายกันอยู่ยัง Mercurial) ไป "ทิ้ง" git logข้อมูลการติดตามผสานใน

  • จากสิ่งที่ฉันเข้าใจsvn:mergeinfoเก็บข้อมูลต่อเส้นทางเกี่ยวกับความขัดแย้ง (การโค่นล้มคือการเปลี่ยนแปลงตามเซ็ต) ในขณะที่ใน Git และ Mercurial มันเป็นเพียงการยอมรับวัตถุที่มีพ่อหรือแม่มากกว่าหนึ่งคน

  • ส่วนย่อย"ปัญหาที่ทราบ"สำหรับการติดตามการผสานในการโค่นล้มแสดงให้เห็นว่าการผสานซ้ำ / วนซ้ำ / ไตร่ตรองอาจทำงานไม่ถูกต้อง หมายความว่าด้วยการผสานประวัติที่สองต่อไปนี้อาจไม่ทำสิ่งที่ถูกต้อง ('A' อาจเป็นลำตัวหรือกิ่งไม้และ 'B' อาจเป็นกิ่งไม้หรือลำตัวตามลำดับ):

    * --- * --- x --- * --- y --- * --- * --- --- --- M2 <-
             \ \ /
              - * ---- M1 --- * --- * --- / <- B
    

    ในกรณีที่ ASCII-art ข้างต้นแตกหัก: สาขา 'B' ถูกสร้างขึ้น (แยก) จากสาขา 'A' เมื่อมีการแก้ไข 'x' จากนั้นสาขา 'A' จะถูกรวมเข้าด้วยกันที่การแก้ไข 'y' เป็นสาขา 'B' เป็น ผสาน 'M1' และในที่สุดก็รวมสาขา 'B' เข้าด้วยกันเป็นสาขา 'A' ในฐานะผสาน 'M2'

    * --- * --- x --- * ----- M1 - * --- * --- M2 <- A
             \ / / 
              \ - * --- y --- * --- * --- / <- B
    

    ในกรณีที่ ASCII-art ข้างต้นแตกหัก: สาขา 'B' ถูกสร้างขึ้น (แยก) จากสาขา 'A' เมื่อมีการแก้ไข 'x' จะถูกรวมเข้ากับสาขา 'A' ที่ 'y' เป็น 'M1' และใหม่กว่า รวมกันอีกครั้งในสาขา 'A' เป็น 'M2'

  • การโค่นล้มอาจไม่สนับสนุนกรณีขั้นสูงของการผสานกากบาด

    * --- ข ----- B1 - M1 - * --- M3
         \ \ / /
          \ X /
           \ / \ /
            \ - B2 - M2 - *
    

    Git จัดการกับสถานการณ์นี้ได้ดีในทางปฏิบัติโดยใช้กลยุทธ์การผสาน "แบบเรียกซ้ำ" ฉันไม่แน่ใจเกี่ยวกับ Mercurial

  • ใน"ปัญหาที่ทราบ"มีคำเตือนว่าการรวมการติดตามอาจไม่ทำงานกับการเปลี่ยนชื่อไฟล์เช่นเมื่อไฟล์ด้านหนึ่งเปลี่ยนชื่อ (และอาจแก้ไขได้) และด้านที่สองจะแก้ไขไฟล์โดยไม่เปลี่ยนชื่อ (ภายใต้ชื่อเก่า)

    ทั้งสอง Git และ Mercurial จัดการกับกรณีดังกล่าวเพียงแค่ปรับในการปฏิบัติ: Git โดยใช้การตรวจสอบการเปลี่ยนชื่อ , Mercurial ใช้ติดตามการเปลี่ยนชื่อ

HTH


อย่างใด (ข้อผิดพลาดใน Markdown parser?) ส่วนหลัง<pre>...</pre>บล็อกไม่ได้เยื้องตามที่ควรจะเป็น ...
Jakub Narębski

1
+1 สำหรับตัวอย่างที่มีรายละเอียดมากมาย ฉันยังไม่เข้าใจว่าทำไมตัวอย่างใน ASCII แรกอาจทำให้เกิดปัญหา ดูเหมือนว่าวิธีมาตรฐานในการจัดการกิ่งคุณลักษณะ: สมมติว่า A คือ trunk, B เป็นสาขาคุณลักษณะ คุณรวมทุกสัปดาห์จาก A ถึง B และเมื่อคุณทำเสร็จกับคุณสมบัติคุณรวมทุกอย่างจาก B ถึง A แล้วลบ B ที่ได้ผลสำหรับฉันเสมอ ฉันเข้าใจผิดแผนภาพหรือไม่
stmax

1
โปรดทราบว่าผมไม่ทราบว่า (ผมยังไม่ได้ตรวจสอบ) ว่าตัวอย่างดังกล่าวข้างต้นจริงๆให้ปัญหาในการโค่นล้ม ฉันคิดว่าการเปลี่ยนชื่อและการผสานข้ามเป็นปัญหาจริงใน SVN
Jakub Narębski

2
reintegrate ผสานเป็นตัวเลือกพิเศษเพื่อช่วยคุณในกรณีที่พบบ่อยที่สุดเมื่อรวม - ไม่มีความแตกต่างทางเทคนิคระหว่างกิ่งและลำตัวใน svn ฉันมักจะไม่ใช้และยึดติดกับตัวเลือกการผสานมาตรฐาน ยังคงปัญหาเดียวที่มี svn ผสานคือมันถือว่าการย้าย / เปลี่ยนชื่อเป็นลบ + นอกจากนี้
gbjbaanb

--reintegrateเลิกใช้แล้ว
naught101

120

ฉันก็กำลังมองหากรณีที่การโค่นล้มล้มเหลวในการรวมสาขาและ Mercurial (และ Git, Bazaar, ... ) ทำสิ่งที่ถูกต้อง

SVN หนังสืออธิบายวิธีการเปลี่ยนชื่อแฟ้มจะถูกผสานอย่างไม่ถูกต้อง สิ่งนี้ใช้กับการโค่นล้ม1.5 , 1.6 , 1.7และ1.8 ! ฉันพยายามสร้างสถานการณ์ด้านล่างใหม่:

cd / tmp/ tmp
rm -rf svn-repo svn-checkout- rf svn - repo svn - checkout
svnadmin สร้าง svn-repo- ซื้อคืน
ไฟล์ชำระเงิน svn: /// tmp / svn-repo svn-checkout: /// tmp / svn - repo svn - checkout
cd svn-checkout- ชำระเงิน
mkdir ลำต้นกิ่ง
echo 'Goodbye, World!' > trunk / hello.txt'ลาก่อนโลก!' > ลำต้น/ สวัสดี txt 
svn เพิ่มกิ่งลำต้น
svn commit -m 'การนำเข้าเริ่มต้น'- m 'นำเข้าเริ่มต้น'
svn copy '^ / trunk' '^ / branch / เปลี่ยนชื่อ' -m 'สร้าง branch''^ / trunk' '^ / branch / เปลี่ยนชื่อ' - m 'สร้างสาขา'  
svn switch '^ / trunk''^ / ลำต้น' 
echo 'Hello, World!' > hello.txt'สวัสดีชาวโลก!' > สวัสดี txt 
svn คอมมิท -m 'อัพเดทที่ท้ายรถ'- m 'อัปเดตที่ท้ายรถ'
svn switch '^ / branch / rename''^ / สาขา / เปลี่ยนชื่อ' 
svn เปลี่ยนชื่อ hello.txt hello.en.txt. สวัสดีครับ en . txt
svn commit -m 'เปลี่ยนชื่อในสาขา'- m 'เปลี่ยนชื่อในสาขา'
svn switch '^ / trunk''^ / ลำต้น' 
svn ผสาน - รวม '^ / branch / rename'- รวม'^ / สาขา / เปลี่ยนชื่อ' อีกครั้ง

ตามหนังสือเล่มนี้การผสานควรเสร็จสิ้นอย่างเรียบร้อย แต่มีข้อมูลที่ไม่ถูกต้องในไฟล์ที่ถูกเปลี่ยนชื่อเนื่องจากการอัพเดทtrunkถูกลืม แต่ฉันได้รับข้อขัดแย้งของทรี (นี่คือ Subversion 1.6.17 ซึ่งเป็นเวอร์ชันใหม่ล่าสุดใน Debian ณ เวลาที่เขียน):

--- การรวมความแตกต่างระหว่างที่เก็บข้อมูล URL เป็น '.':
สวัสดี. en.txt
   C hello.txt
สรุปความขัดแย้ง:
  ความขัดแย้งของต้นไม้: 1

ไม่ควรมีข้อขัดแย้งใด ๆ เลย - การอัปเดตควรรวมเข้ากับชื่อใหม่ของไฟล์ ในขณะที่การโค่นล้มล้มเหลว Mercurial จัดการสิ่งนี้ได้อย่างถูกต้อง:

rm -rf /tmp/hg-repo
hg init /tmp/hg-repo
cd /tmp/hg-repo
echo 'Goodbye, World!' > hello.txt
hg add hello.txt
hg commit -m 'Initial import.'
echo 'Hello, World!' > hello.txt
hg commit -m 'Update.'
hg update 0
hg rename hello.txt hello.en.txt
hg commit -m 'Rename.'
hg merge

ก่อนทำการผสานที่เก็บจะมีลักษณะดังนี้ (จากhg glog):

@ changeset: 2: 6502899164cc
| แท็ก: เคล็ดลับ
| parent: 0: d08bcebadd9e
| ผู้ใช้: Martin Geisler
| วันที่: Thu Apr 01 12:29:19 2010 +0200
| สรุป: เปลี่ยนชื่อ
|
| o เซ็ตการแก้ไข: 1: 9d06fa155634
| / ผู้ใช้: Martin Geisler 
| วันที่: Thu Apr 01 12:29:18 2010 +0200
| สรุป: อัปเดต
|
o เซ็ตการแก้ไข: 0: d08bcebadd9e
   ผู้ใช้: Martin Geisler 
   วันที่: Thu Apr 01 12:29:18 2010 +0200
   สรุป: การนำเข้าเริ่มต้น

ผลลัพธ์ของการผสานคือ:

การรวม hello.en.txt และ hello.txt ไปยัง hello.en.txt
อัพเดต 0 ไฟล์, รวม 1 ไฟล์, ลบไฟล์ 0 ไฟล์, ไม่ได้แก้ไข 0 ไฟล์
(รวมสาขาอย่าลืมผูกมัด)

กล่าวอีกนัยหนึ่ง: Mercurial นำการเปลี่ยนแปลงจากการแก้ไข 1 และรวมเข้าไว้ในชื่อไฟล์ใหม่จากการแก้ไข 2 ( hello.en.txt) การจัดการกรณีนี้เป็นสิ่งจำเป็นของหลักสูตรเพื่อ refactoring สนับสนุนและ refactoring คือว่าชนิดของสิ่งที่คุณต้องการจะทำในสาขา


+1 สำหรับตัวอย่างโดยละเอียดเราสามารถแตะลงบนแป้นพิมพ์และดูตัวเองว่าเกิดอะไรขึ้น ในฐานะ Mercurial noob ฉันสงสัยว่ารุ่น hg ของตัวอย่างนี้มีการติดตามในลักษณะที่ชัดเจนทีละบรรทัดหรือไม่?
DarenW

4
@ DarenW: ฉันได้เพิ่มคำสั่ง Mercurial ที่สอดคล้องกันฉันหวังว่ามันจะทำให้ทุกอย่างชัดเจนขึ้น!
Martin Geisler

17

โดยไม่ต้องพูดเกี่ยวกับข้อได้เปรียบปกติ (ยอมรับแบบออฟไลน์กระบวนการเผยแพร่ ... ) นี่คือตัวอย่าง "ผสาน" ที่ฉันชอบ:

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

คุณจะผสานรวมหนึ่งในสองคุณสมบัติในสาขาหลักได้อย่างไร
หรือคุณแยกคุณสมบัติทั้งสองในสาขาของตัวเองได้อย่างไร

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

  • คอมมิท (หรือการแก้ไขสำหรับ SVN) ที่ใช้ในแพทช์ของคุณ
  • คนอื่น ๆ ไม่ได้เป็นส่วนหนึ่งของโปรแกรมแก้ไข

Git (และ Mercurial ฉันก็เช่นกัน) เสนอตัวเลือก rebase --onto เพื่อ rebase (รีเซ็ตรากของสาขา) ส่วนหนึ่งของสาขา:

จากโพสต์ของ Jefromi

- x - x - x (v2) - x - x - x (v2.1)
           \
            x - x - x (v2-only) - x - x - x (wss)

คุณสามารถแก้ให้หายยุ่งสถานการณ์นี้ที่คุณมีแพทช์สำหรับ v2 เช่นเดียวกับคุณสมบัติ wss ใหม่เป็น:

- x - x - x (v2) - x - x - x (v2.1)
          |\
          |  x - x - x (v2-only)
           \
             x - x - x (wss)

ช่วยให้คุณ:

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

คุณสมบัติอื่น ๆ ที่ฉันชอบ (ซึ่งมีอิทธิพลต่อการรวม) คือความสามารถในการสควอชกระทำ (ในสาขาที่ยังไม่ได้ผลักไปยัง repo อื่น) เพื่อนำเสนอ:

  • ประวัติที่สะอาดกว่า
  • กระทำการที่สอดคล้องกันมากขึ้น (แทนที่จะกระทำ 1 สำหรับฟังก์ชั่น 1, ส่งมอบ 2 สำหรับฟังก์ชั่น 2 ส่งมอบอีกครั้งสำหรับฟังก์ชั่น 1 ... )

มั่นใจได้ว่าการผสานซึ่งง่ายกว่ามากและมีความขัดแย้งน้อย


svn ไม่ได้มีภาระผูกพันออฟไลน์? ROFL? ทุกคนสามารถพิจารณาใช้จากระยะไกลได้อย่างไรถ้าเป็นเช่นนั้น
o0 '

@Lohoris เมื่อ SVN ออกมาไม่มี DVCS โอเพนซอร์สที่ใช้กันอย่างแพร่หลาย; ณ จุดนี้ฉันคิดว่ามันเป็นแรงเฉื่อยส่วนใหญ่ที่ผู้คนยังคงใช้มัน
Max Nanasy

@ MaxNanasy ความเฉื่อยที่แย่มาก ๆ ... ยังคงเลือกที่ตอนนี้มันจะเป็นเรื่องงี่เง่า
o0 '

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

1
@ โลริสฉันคิดว่าคุณเข้าใจจุดผิดเกี่ยวกับ DB, ไฟร์วอลล์และอื่น ๆ : มีจุดเล็ก ๆ น้อย ๆ ที่ฉันสามารถส่งมอบเครื่องที่บ้านของฉันได้ถ้าฉันไม่สามารถเรียกใช้รหัสนั้นได้ก่อน ผมสามารถทำงานคนตาบอด แต่ความจริงที่ว่าฉันไม่สามารถกระทำสิ่งใดที่หนึ่งจะไม่เป็นสิ่งที่สำคัญการวางฉันลง
IMSoP

8

เมื่อเร็ว ๆ นี้เราย้ายจาก SVN ไปยัง GIT และเผชิญกับความไม่แน่นอนเช่นนี้ มีหลักฐานมากมายที่ GIT ดีกว่า แต่ก็ยากที่จะหาตัวอย่าง

ฉันสามารถบอกคุณได้ว่าGIT นั้นดีกว่าการรวมกันมากกว่า SVN นี่เป็นเรื่องเล็ก ๆ น้อย ๆ แต่มีตารางที่จะติดตาม

นี่คือบางสิ่งที่เราค้นพบ:

  • SVN เคยใช้ความขัดแย้งกับต้นไม้จำนวนมากในสถานการณ์ที่ดูเหมือนว่าไม่ควร เราไม่เคยไปถึงจุดต่ำสุดของเรื่องนี้ แต่ไม่ได้เกิดขึ้นใน GIT
  • ในขณะที่ดีขึ้น GIT นั้นซับซ้อนกว่ามาก ใช้เวลาในการฝึกฝน
  • เราเคยชินกับเต่า SVN ซึ่งเราชอบ GIT ของเต่านั้นไม่ดีเท่านี้และอาจทำให้คุณไม่พอใจ อย่างไรก็ตามตอนนี้ฉันใช้บรรทัดคำสั่ง GIT ซึ่งฉันชอบ Tortoise SVN หรือ GIT GUI ใด ๆ

เมื่อเราประเมิน GIT เราก็ทำการทดสอบต่อไปนี้ สิ่งเหล่านี้แสดงให้เห็นว่า GIT เป็นผู้ชนะเมื่อมีการรวมเข้าด้วยกัน แต่ไม่มาก ในทางปฏิบัติความแตกต่างนั้นใหญ่กว่ามาก แต่ฉันคิดว่าเราไม่สามารถจัดการกับสถานการณ์ที่ SVN จัดการได้ไม่ดี

GIT กับการประเมินผลการผสาน SVN


5

คนอื่น ๆ ได้ครอบคลุมแง่มุมทางทฤษฎีมากกว่านี้ บางทีฉันอาจให้มุมมองที่เป็นประโยชน์มากกว่านี้

ฉันกำลังทำงานให้กับ บริษัท ที่ใช้ SVN ในรูปแบบการพัฒนา "ฟีเจอร์สาขา" นั่นคือ:

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

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

  • ^/trunkเราเคยมีปัญหาค่อนข้างน้อยกับคนที่แตกแขนงจากจุดที่ต่ำกว่า สัตว์เลี้ยงลูกด้วยนมนี้รวมบันทึกข้อมูลทั่วทั้งต้นไม้และในที่สุดก็แบ่งการติดตามการผสาน ความขัดแย้งที่ผิดพลาดเริ่มปรากฏขึ้นและความสับสนก็ครอบงำ
  • การรับการเปลี่ยนแปลงจากลำตัวไปยังสาขานั้นจะค่อนข้างตรงไปข้างหน้า svn mergeทำในสิ่งที่คุณต้องการ การผสานการเปลี่ยนแปลงของคุณกลับมาจำเป็นต้องมี (เราได้รับการบอกกล่าว) --reintegrateในคำสั่งผสาน ฉันไม่เคยเข้าใจสวิตช์นี้จริง ๆ แต่ก็หมายความว่าสาขาจะไม่สามารถรวมเข้ากับลำต้นได้อีก นี่หมายความว่าเป็นสาขาที่ตายแล้วและคุณต้องสร้างสาขาใหม่เพื่อทำงานต่อไป (เห็นโน๊ต)
  • ธุรกิจทั้งหมดของการดำเนินการบนเซิร์ฟเวอร์ผ่าน URL เมื่อสร้างและลบสาขาทำให้เกิดความสับสนและทำให้ผู้คนกลัว ดังนั้นพวกเขาจึงหลีกเลี่ยง
  • การสลับไปมาระหว่างกิ่งนั้นเป็นเรื่องง่ายที่จะผิดปล่อยให้ส่วนหนึ่งของต้นไม้ดูที่สาขา A ในขณะที่ปล่อยให้อีกส่วนหนึ่งมองที่สาขา B ดังนั้นผู้คนจึงชอบทำงานทั้งหมดในสาขาเดียว

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

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

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

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

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

...แต่...

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

โชคดีที่ทีมเล็กพอที่จะรับมือ แต่มันก็ไม่ได้ขยาย สิ่งนี้ไม่มีปัญหาใด ๆ กับ CVCS แต่ยิ่งกว่านั้นเนื่องจากการรวมกันไม่สำคัญเท่ากับใน DVCS พวกเขาไม่ลื่น "การรวมแรงเสียดทาน" นั้นทำให้เกิดพฤติกรรมซึ่งหมายความว่าโมเดล "สาขาคุณลักษณะ" จะเริ่มพังทลายลง การรวมที่ดีต้องเป็นคุณสมบัติของ VCS ทั้งหมดไม่ใช่แค่ DVCS


ตามนี้ขณะนี้มี--record-onlyสวิทช์ที่สามารถนำมาใช้ในการแก้--reintegrateปัญหาที่เกิดขึ้นและเห็นได้ชัดว่า v1.8 Chooses เมื่อจะทำ reintegrate โดยอัตโนมัติและจะไม่ก่อให้เกิดสาขาจะตายหลังจากนั้น


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

@IMSoP: อาจเป็นไปได้ว่ามีเหตุผลบางอย่าง มันไม่ได้อธิบายให้ฉันฟังว่าทำไมมันถึงมีความจำเป็นหรือทำไมมันทำให้การรวมสาขาจากสาขานั้นเป็นไปไม่ได้ ไม่ได้ช่วยตัวเลือกที่ไม่มีเอกสารส่วนใหญ่เช่นกัน
พอล S

ฉันเคยใช้มันผ่าน TortoiseSVN ซึ่งมีการอธิบายอย่างเด่นชัดใน UI รวม ฉันเชื่อว่า SVN 1.8 เลือกกลยุทธ์ที่ถูกต้องโดยอัตโนมัติและไม่ต้องการตัวเลือกแยกต่างหาก แต่ฉันไม่รู้ว่าพวกเขาได้แก้ไขอัลกอริทึมการผสานปกติเพื่อจัดการอย่างถูกต้องกับสาขาที่ถูกรีเซ็ตด้วยวิธีนี้หรือไม่
IMSoP

3

ก่อนการโค่นล้ม 1.5 (ถ้าฉันไม่เข้าใจผิด) การโค่นล้มมีข้อเสียอย่างมีนัยสำคัญในการที่จะไม่จำประวัติการรวม

ลองดูกรณีที่เค้าร่างโดย VonC:

- x - x - x (v2) - x - x - x (v2.1)
          |\
          |  x - A - x (v2-only)
           \
             x - B - x (wss)

ประกาศการแก้ไข A และ B สมมติว่าคุณรวมการเปลี่ยนแปลงจากการแก้ไข A ในสาขา "wss" กับสาขา "v2-only" ที่การแก้ไข B (ไม่ว่าจะด้วยเหตุผลใดก็ตาม) แต่ใช้ทั้งสองสาขาต่อไป หากคุณพยายามรวมสองกิ่งเข้าด้วยกันโดยใช้ Mercurial มันจะรวมการเปลี่ยนแปลงหลังจากการแก้ไข A และ B ด้วยการโค่นล้มคุณจะต้องรวมทุกอย่างเข้าด้วยกันราวกับว่าคุณไม่ได้ทำการผสานมาก่อน

นี่คือตัวอย่างจากประสบการณ์ของฉันเองที่การผสานจาก B ถึง A ใช้เวลาหลายชั่วโมงเนื่องจากปริมาณของรหัส: นั่นจะเป็นความเจ็บปวดที่แท้จริงที่จะต้องผ่านอีกครั้งซึ่งจะเป็นกรณีที่มีการโค่นล้ม pre-1.5

ข้อแตกต่างที่เกี่ยวข้องในพฤติกรรมการรวมจากHginit: การโค่นล้มการศึกษาใหม่ :

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

เมื่อเราต้องรวมการโค่นล้มพยายามที่จะตรวจสอบทั้งการแก้ไข - รหัสที่แก้ไขของฉันและรหัสที่คุณแก้ไข - และมันพยายามที่จะเดาว่าจะรวมมันเข้าด้วยกันได้อย่างไรในระเบียบที่ไม่บริสุทธิ์ มันมักจะล้มเหลวในการผลิตหน้าและหน้าของ "การรวมความขัดแย้ง" ที่ไม่ได้ขัดแย้งกันจริงๆเพียงแค่วางที่การโค่นล้มล้มเหลวในการคิดสิ่งที่เราทำ

ในทางตรงกันข้ามในขณะที่เราทำงานแยกกันใน Mercurial Mercurial ไม่ว่างที่จะทำการเปลี่ยนแปลงหลายอย่าง ดังนั้นเมื่อเราต้องการรวมรหัสของเราเข้าด้วยกัน Mercurial มีข้อมูลมากขึ้นจริง ๆ : มันรู้ว่าเราแต่ละคนเปลี่ยนแปลงอะไรและสามารถนำการเปลี่ยนแปลงเหล่านั้นมาใช้ใหม่ได้แทนที่จะมองไปที่ผลิตภัณฑ์ขั้นสุดท้ายและพยายามเดาว่าจะใส่มันอย่างไร ด้วยกัน.

ในระยะสั้นวิธีการวิเคราะห์ความแตกต่างของ Mercurial นั้นเหนือกว่าการโค่นล้ม


5
ฉันอ่าน hginit แล้ว น่าเสียดายที่มันไม่แสดงตัวอย่างที่เป็นประโยชน์มากขึ้นว่าที่ hg ทำงานได้ดีกว่า svn .. โดยพื้นฐานแล้วมันบอกให้คุณ "trust joel" ว่า hg นั้นดีกว่า ตัวอย่างง่ายๆที่เขาแสดงให้เห็นอาจจะทำได้ด้วย svn เช่นกัน .. ที่จริงแล้วคือเหตุผลที่ฉันเปิดคำถามนี้
stmax

1
คำถามไร้เดียงสาอยู่ในใจ: จะเกิดอะไรขึ้นถ้าอัลกอริทึมการผสานของ Mercurial ถูกนำไปใช้ในการโค่นล้ม? svn จะดีเท่า hg หรือไม่? ไม่เพราะความได้เปรียบของ hg อยู่ในระดับองค์กรที่สูงกว่าไม่ใช่ข้อความคณิตศาสตร์ระดับต่ำของการรวมบรรทัดจากไฟล์ นั่นเป็นความคิดแปลกใหม่ที่ผู้ใช้งานเราต้องการ
DarenW

@stmax: ฉันเห็นสิ่งที่คุณหมายถึง อย่างไรก็ตามความคิดเห็นของ Joel หรือคนอื่น ๆ ไม่สำคัญ: เทคโนโลยีหนึ่งอาจดีกว่าเทคโนโลยีอื่น ๆ (สำหรับชุดของกรณีการใช้งาน) หรือไม่ @DarenW และ @stmax: จากประสบการณ์ส่วนตัวของฉัน Hg ได้รับรางวัลเนื่องจากการดำเนินการแบบกระจาย (ฉันไม่ได้เชื่อมต่อตลอดเวลา) ประสิทธิภาพ (การดำเนินงานในท้องถิ่นจำนวนมาก) การแยกสาขาที่ใช้งานง่ายอย่างยิ่งยวดโดยอัลกอริทึมผสานที่ยอดเยี่ยม การย้อนกลับ hg, เอาต์พุตบันทึก templated, hg glog, โฟลเดอร์. hg เดียว ... ฉันสามารถไปต่อไปเรื่อย ๆ ได้ ... ทุกอย่างนอกจาก git และ bazaar อาจจะรู้สึกว่าเป็นแจ็คเกต
Tomislav Nakic-Alfirevic

ความคิดเห็น hg ที่ยกมาเกี่ยวกับ "เซ็ตการแก้ไข" ดูเหมือนจะไม่ถูกต้องสำหรับฉัน SVN รู้ดีว่าการรวมกันของการเปลี่ยนแปลงนั้นเป็นอย่างไร (เซ็ตการแก้ไขนั้นเป็นความแตกต่างระหว่างสแน๊ปช็อตสองอันและในทางกลับกันใช่มั้ย) และสามารถนำมาใช้แต่ละอันได้ถ้าต้องการ แน่นอนไม่ต้อง "เดา" อะไร ถ้ามันทำให้ "หนึ่งในความไม่บริสุทธิ์ที่ยิ่งใหญ่" นั่นเป็นปัญหาการดำเนินการไม่ใช่สิ่งพื้นฐานสำหรับการออกแบบ ปัญหาหลักที่แก้ไขได้ยากบนการออกแบบสถาปัตยกรรมปัจจุบันคือการย้าย / คัดลอก / เปลี่ยนชื่อไฟล์
IMSoP
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.