git-svn dcommit หลังจากรวมเข้ากับ git เป็นอันตรายหรือไม่?


135

แรงจูงใจของฉันในการลองใช้ git-svn คือการผสานและการแตกแขนงได้อย่างง่ายดาย จากนั้นฉันสังเกตเห็นว่า man git-svn (1) พูดว่า:

ไม่แนะนำให้ใช้ git-merge หรือ git-pull ในสาขาที่คุณวางแผนจะ dcommit การโค่นล้มไม่ได้แสดงถึงการรวมเข้าด้วยกันในรูปแบบที่สมเหตุสมผลหรือเป็นประโยชน์ ดังนั้นผู้ใช้ที่ใช้ Subversion จะไม่เห็นการผสานใด ๆ ที่คุณทำ นอกจากนี้หากคุณรวมหรือดึงจาก git branch ที่เป็นมิเรอร์ของสาขา SVN dcommit อาจส่งไปยังสาขาที่ไม่ถูกต้อง

หมายความว่าฉันไม่สามารถสร้างสาขาในพื้นที่จาก svn / trunk (หรือสาขา) แฮ็คออกไปรวมกลับเป็น svn / trunk แล้ว dcommit หรือไม่ ฉันเข้าใจว่าผู้ใช้ svn จะเห็นความยุ่งเหยิงแบบเดียวกับที่รวมใน svn ก่อน 1.5.x มาโดยตลอด แต่มีข้อเสียอื่น ๆ หรือไม่? ประโยคสุดท้ายนั้นทำให้ฉันกังวลเช่นกัน ผู้คนทำสิ่งเหล่านี้เป็นประจำหรือไม่?


14
นี่เป็นสิ่งที่ผิด: การโค่นล้มไม่ได้แสดงถึงการผสานในรูปแบบที่สมเหตุสมผลหรือเป็นประโยชน์ใด ๆ ดังนั้นผู้ใช้ที่ใช้ Subversion จะไม่เห็นการผสานใด ๆ ที่คุณได้สร้างขึ้น นอกจากนี้หากคุณรวมหรือดึงจาก git branch ที่เป็นมิเรอร์ของสาขา SVN dcommit อาจส่งไปยังสาขาที่ไม่ถูกต้อง การโค่นล้มไม่เพียงแสดงถึงข้อมูลการติดตามการผสานคอมไพล์เท่านั้น แต่ยังมีข้อมูลที่ละเอียดมากขึ้นอีกด้วย เป็น git-svn ที่ไม่สามารถสร้าง svn: mergeinfo ที่เหมาะสมหรือสร้าง dcommit ไปยังสาขาที่เหมาะสม
Alexander Kitaev

2
@AlexanderKitaev: เอกสารgit-svnมีการเปลี่ยนแปลงตั้งแต่นั้นมาและนอกจากนี้ยังมี--mergeinfo=<mergeinfo>ตัวเลือกที่อาจสามารถส่งข้อมูลการผสานไปยัง SVN ได้ ไม่แน่ใจว่าควรใช้อย่างไร
Mr_and_Mrs_D

คำตอบ:


175

อันที่จริงฉันพบวิธีที่ดีกว่านี้ด้วย--no-ffตัวเลือกในการผสานคอมไพล์ เทคนิคสควอชทั้งหมดที่ฉันเคยใช้มาก่อนไม่จำเป็นอีกต่อไป

เวิร์กโฟลว์ใหม่ของฉันตอนนี้เป็นดังนี้:

  • ฉันมี "ต้นแบบ" ที่สาขาเป็นสาขาเดียวที่ฉัน dcommit จากโคลนและว่าพื้นที่เก็บข้อมูล SVN ( -sสมมติว่าคุณมีรูปแบบ SVN มาตรฐานในพื้นที่เก็บข้อมูลtrunk/, branches/และtags/):

    git svn clone [-s] <svn-url>
    
  • ฉันทำงานในสาขาท้องถิ่น "งาน" ( -bสร้างสาขา "งาน")

    git checkout -b work
    
  • เข้าสู่สาขา "งาน" ในเครื่อง ( -sเพื่อลงชื่อออกจากข้อความคอมมิตของคุณ) ในภาคต่อฉันคิดว่าคุณได้กระทำ 3 ครั้งในท้องถิ่น

    ...
    (work)$> git commit -s -m "msg 1"
    ...
    (work)$> git commit -s -m "msg 2"
    ...
    (work)$> git commit -s -m "msg 3"
    

ตอนนี้คุณต้องการเข้าสู่เซิร์ฟเวอร์ SVN

  • [ในที่สุด] ซ่อนการแก้ไขที่คุณไม่ต้องการเห็นการกระทำบนเซิร์ฟเวอร์ SVN (บ่อยครั้งที่คุณแสดงความคิดเห็นโค้ดบางส่วนในไฟล์หลักเพียงเพราะคุณต้องการเร่งการรวบรวมและมุ่งเน้นไปที่คุณสมบัติที่กำหนด)

    (work)$> git stash
    
  • สร้างสาขาหลักใหม่ด้วยที่เก็บ SVN (เพื่ออัปเดตจากเซิร์ฟเวอร์ SVN)

    (work)$> git checkout master
    (master)$> git svn rebase
    
  • กลับไปที่สาขางานและสร้างฐานข้อมูลใหม่กับมาสเตอร์

    (master)$> git checkout work
    (work)$> git rebase master
    
  • ตรวจสอบให้แน่ใจว่าทุกอย่างเรียบร้อยดีโดยใช้ตัวอย่างเช่น:

    (work)$> git log --graph --oneline --decorate
    
  • ตอนนี้ถึงเวลารวมคำสั่งทั้งสามจากสาขา "งาน" เป็น "หลัก" โดยใช้--no-ffตัวเลือกที่ยอดเยี่ยม

    (work)$> git checkout master
    (master)$> git merge --no-ff work
    
  • คุณสามารถสังเกตสถานะของบันทึก:

    (master)$> git log --graph --oneline --decorate
    * 56a779b (work, master) Merge branch 'work'
    |\  
    | * af6f7ae msg 3
    | * 8750643 msg 2
    | * 08464ae msg 1
    |/  
    * 21e20fa (git-svn) last svn commit
    
  • ตอนนี้คุณอาจต้องการแก้ไข ( amend) คอมมิตสุดท้ายสำหรับ dudes SVN ของคุณ (มิฉะนั้นพวกเขาจะเห็นคอมมิตเดียวพร้อมข้อความ "ผสานสาขา 'งาน'"

    (master)$> git commit --amend
    
  • สุดท้ายยอมรับบนเซิร์ฟเวอร์ SVN

    (master)$> git svn dcommit
    
  • กลับไปทำงานและกู้คืนไฟล์ที่เก็บไว้ในที่สุด:

    (master)$> git checkout work
    (work)$> git stash pop
    

4
นี่คือขั้นตอนการทำงานที่ git n00b กำลังมองหา สร้างสาขาในพื้นที่เพื่อแก้ไขจุดบกพร่องทำทุกอย่างแล้วส่งขึ้นไปที่ svn ด้วยการคอมมิตเดียว การใช้คำตอบที่ได้รับคะแนนสูงสุดที่นี่ทำให้สิ่งที่ฉันกำลังทำอยู่ - ไม่สามารถ git svn rebase โดยไม่มีข้อผิดพลาด
JoãoBragança

19
นี่ไม่ใช่สิ่งที่เอกสาร git-svn ที่อ้างถึงใน op เตือน? การรันการผสานกับ--no-ffอ็อพชันแสดงว่าคุณกำลังสร้างคอมมิตการผสานอย่างชัดเจน (คอมมิตกับผู้ปกครองสองคน) แทนที่จะเป็นการกรอไปข้างหน้า เพื่อให้แน่ใจว่าการคอมมิตทั้งหมดในสาขาการติดตาม svn เป็นการคอมมิตแม่เดียวการผสานทั้งหมดต้องส่งต่ออย่างรวดเร็ว ( --ff-onlyสามารถช่วยในเรื่องนี้ได้) หรือถ้าหีบมีการเปลี่ยนแปลงด้านหลังของคุณ a --squashใช่ไหม
jemmons

4
สิ่งนี้ใช้ได้กับสาขาเดียวที่คุณลบทันที แต่git svn dcommitเขียนคอมมิตคอมมิตที่คุณให้ใหม่ ซึ่งหมายความว่าคุณสูญเสียผู้ปกครองคนอื่นไปและตอนนี้ git repo ของคุณไม่มีบันทึกว่าคุณเคยรวมสาขานั้นเข้าmasterด้วยกัน นอกจากนี้ยังสามารถปล่อยให้ไดเรกทอรีการทำงานของคุณอยู่ในสถานะที่ไม่สอดคล้องกัน
rescdsk

9
ใช้git merge --no-ff work -m "commit message"แทนการมีgit commit --amendขั้นตอนพิเศษ
tekumara

3
สำหรับฉันฉันต้องการใช้ "git merge --ff-only work" เนื่องจากฉันต้องการรักษาความมุ่งมั่นทั้งหมดของฉันไม่ใช่แค่ข้อสุดท้าย
Moataz Elmasry

49

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

ฉันมีสาขา "master" ที่ใช้ติดตามเซิร์ฟเวอร์ svn นี่เป็นสาขาเดียวที่ฉันแนะนำ ถ้าฉันกำลังทำงานบางอย่างฉันจะสร้างสาขาหัวข้อและดำเนินการต่อไป เมื่อฉันต้องการที่จะยอมรับฉันทำสิ่งต่อไปนี้:

  1. ให้คำมั่นสัญญาทุกอย่างกับสาขาหัวข้อ
  2. git svn rebase (แก้ไขข้อขัดแย้งระหว่างงานของคุณและ svn)
  3. git หลักชำระเงิน
  4. git svn rebase (ทำให้ขั้นตอนต่อไปคือการผสานไปข้างหน้าอย่างรวดเร็วดูความคิดเห็นของ Aaron ด้านล่าง)
  5. git ผสาน topic_branch
  6. แก้ไขข้อขัดแย้งในการผสาน(ไม่ควรมีในตอนนี้)
  7. git svn dcommit

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

ควรวิ่งgit svn dcommit -nก่อนเพื่อให้แน่ใจว่าคุณกำลังจะทำในสิ่งที่คุณตั้งใจจะกระทำ ไม่เหมือน git การเขียนประวัติใหม่ใน svn นั้นยาก!

ฉันรู้สึกว่าต้องมีวิธีที่ดีกว่าในการรวมการเปลี่ยนแปลงในสาขาหัวข้อในขณะที่ข้ามการเปลี่ยนแปลงในท้องถิ่นเหล่านั้นมากกว่าการใช้เชอร์รี่เลือกดังนั้นหากใครมีความคิดก็ยินดีต้อนรับ


ถ้าฉันเข้าใจสิ่งนี้ถูกต้องใน git การรวม git กับ svn ก็โอเค แต่ไม่ใช่ svn กับ svn? ดังนั้นฉันจึงไม่สามารถผสาน svn / branch กับ svn / trunk ใน git ได้?
Knut Eldhuset

1
การเขียนประวัติใหม่ใน SVN เป็นเรื่องยากหากคุณต้องการทำอะไรที่ไม่สำคัญ ในกรณีที่ไม่สำคัญมันเป็นไปไม่ได้ในทางปฏิบัติ
Aristotle Pagaltzis

19
คำตอบของ Greg Hewgill มีคนโหวตเยอะมาก แต่ฉันเชื่อว่ามันผิด การรวมจาก topic_branch เป็น Master จะปลอดภัยก็ต่อเมื่อเป็นการรวมแบบกรอไปข้างหน้าเท่านั้น หากเป็นการผสานจริงที่ต้องการการรวมคอมมิตการผสานจะหายไปเมื่อคุณ dcommit ครั้งต่อไปที่คุณพยายามรวม topic_branch เป็น master คอมไพล์คิดว่าการผสานครั้งแรกไม่เคยเกิดขึ้นและนรกทั้งหมดก็หลุดออกไป ดูคำถามทำไม git svn dcommit จึงสูญเสียประวัติการผสานคอมมิตสำหรับสาขาในพื้นที่
Aaron

1
@Greg Hewgill การแก้ไขไม่ชัดเจน คุณเขียนว่า rebase "ทำให้การคอมมิตต่อไปเป็นการรวมกรอไปข้างหน้า" ฉันไม่รู้ว่าหมายความว่าอย่างไรเพราะการผสานไปข้างหน้าอย่างรวดเร็วไม่ได้เกี่ยวข้องกับการคอมมิต แต่บางทีคุณอาจหมายถึง "ทำการผสานครั้งต่อไปเป็นการรวมแบบกรอไปข้างหน้า" แต่ถ้านั่นคือสิ่งที่คุณหมายถึงมันไม่ถูกต้อง การผสานจาก topic_branch เป็น master เป็นการผสานกรอไปข้างหน้าหรือไม่ขึ้นอยู่กับว่ามีการคอมมิตใด ๆ บนมาสเตอร์ตั้งแต่จุดสาขา เมื่อคุณ rebase master นั่นจะเป็นการสร้าง commits ใหม่กับ master ดังนั้นการผสานที่ตามมาจึงไม่จำเป็นต้องเป็นการผสานfast-forward
Aaron

1
@Aaron: ใช่ฉันไม่รู้ว่าฉันคิดอะไรอยู่ที่นั่น ฉันได้แก้ไขอีกครั้งหวังว่าจะสมเหตุสมผล ปัญหาอย่างหนึ่งคือมีหลายวิธีในการทำสิ่งต่างๆใน Git ซึ่งต้องใช้คำอธิบายค่อนข้างมากเพื่ออธิบายลำดับการกระทำที่เฉพาะเจาะจง
Greg Hewgill

33

วิธีแก้ปัญหาง่ายๆ: ลบสาขา 'งาน' ออกหลังจากรวมเข้าด้วยกัน

คำตอบสั้น ๆ :คุณสามารถใช้คอมไพล์ได้ตามต้องการ (ดูขั้นตอนการทำงานอย่างง่ายด้านล่าง) รวมถึงการผสาน เพียงตรวจสอบให้แน่ใจว่าทำตาม ' git merge work ' แต่ละรายการด้วย ' git branch -d work ' เพื่อลบสาขางานชั่วคราว

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

(หมายเหตุ: git-svn สามารถทำได้ไม่มากนัก: svn ไม่เข้าใจการผสาน git ที่ทรงพลังกว่ามากดังนั้นภายในที่เก็บ svn ข้อมูลการผสานนี้จึงไม่สามารถแสดงในลักษณะใดก็ได้)

แต่นี่คือทั้งหมดปัญหาหากคุณลบสาขา 'งาน' หลังจากที่รวมเข้ากับ 'สาขาหลัก' แล้วที่เก็บ git ของคุณจะสะอาด 100% และดูเหมือนที่เก็บ svn ของคุณ

ขั้นตอนการทำงานของฉัน: แน่นอนก่อนอื่นฉันโคลนที่เก็บ svn ระยะไกลลงในที่เก็บ git ในเครื่อง (อาจใช้เวลาสักครู่):

$> git svn clone <svn-repository-url> <local-directory>

จากนั้นงานทั้งหมดจะเกิดขึ้นภายใน "local-directory" เมื่อใดก็ตามที่ฉันต้องการรับการอัปเดตจากเซิร์ฟเวอร์ (เช่น 'svn update') ฉันจะ:

$> git checkout master
$> git svn rebase

ฉันทำงานพัฒนาทั้งหมดใน 'งาน' สาขาแยกต่างหากที่สร้างขึ้นในลักษณะนี้:

$> git checkout -b work

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

$> git commit -am '-- finished a little piece of work'

ขั้นตอนต่อไป (git rebase -i) เป็นทางเลือก --- เป็นเพียงการล้างประวัติก่อนที่จะเก็บใน svn: เมื่อฉันไปถึงศิลาไมล์ที่มั่นคงที่ฉันต้องการแบ่งปันกับคนอื่นฉันจะเขียนประวัติของ 'งาน' นี้ใหม่ แยกสาขาและล้างข้อความคอมมิต (นักพัฒนาคนอื่น ๆ ไม่จำเป็นต้องเห็นขั้นตอนและข้อผิดพลาดเล็ก ๆ น้อย ๆ ทั้งหมดที่ฉันทำระหว่างทาง --- แค่ผลลัพธ์) สำหรับสิ่งนี้ฉันทำ

$> git log

และคัดลอกแฮช sha-1 ของคอมมิตสุดท้ายที่อยู่ในที่เก็บ svn (ตามที่ระบุโดย git-svn-id) แล้วฉันก็โทร

$> git rebase -i 74e4068360e34b2ccf0c5869703af458cde0cdcb

เพียงวางแฮช sha-1 ของการกระทำ svn ล่าสุดของเราแทนของฉัน คุณอาจต้องการอ่านเอกสารเกี่ยวกับ 'git help rebase' สำหรับรายละเอียด กล่าวโดยย่อ: คำสั่งนี้จะเปิดตัวแก้ไขที่นำเสนอคอมมิตของคุณก่อน ---- เพียงแค่เปลี่ยน 'เลือก' เป็น 'สควอช' สำหรับการกระทำทั้งหมดที่คุณต้องการสควอชด้วยการกระทำก่อนหน้านี้ แน่นอนบรรทัดแรกควรอยู่ในฐานะ "เลือก" ด้วยวิธีนี้คุณสามารถรวมความมุ่งมั่นเล็ก ๆ น้อย ๆ ของคุณให้เป็นหน่วยที่มีความหมายอย่างน้อยหนึ่งหน่วย บันทึกและออกจากโปรแกรมแก้ไข คุณจะได้รับตัวแก้ไขอื่นเพื่อขอให้คุณเขียนข้อความบันทึกการคอมมิตใหม่

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

ในการพุชการเปลี่ยนแปลงไปยังที่เก็บ svn ฉันทำ:

$> git checkout master
$> git svn rebase

ตอนนี้เรากลับมาที่สาขา 'master' เก่าที่อัปเดตพร้อมกับการเปลี่ยนแปลงทั้งหมดที่เกิดขึ้นในเวลาเฉลี่ยในที่เก็บ svn (การเปลี่ยนแปลงใหม่ของคุณจะซ่อนอยู่ในสาขา 'งาน'

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

$> git checkout master
$> git merge work        # (1) merge your 'work' into 'master'
$> git branch -d work    # (2) remove the work branch immediately after merging
$> git svn dcommit       # (3) push your changes to the svn repository

หมายเหตุ 1: คำสั่ง 'git branch -d work' ค่อนข้างปลอดภัย: อนุญาตให้คุณลบสาขาที่คุณไม่ต้องการอีกต่อไปเท่านั้น (เนื่องจากรวมเข้ากับสาขาปัจจุบันของคุณแล้ว) หากคุณดำเนินการคำสั่งนี้โดยไม่ได้ตั้งใจก่อนที่จะรวมงานกับสาขา 'หลัก' คุณจะได้รับข้อความแสดงข้อผิดพลาด

หมายเหตุ 2: ตรวจสอบให้แน่ใจว่าได้ลบสาขาของคุณด้วย 'git branch -d work' ระหว่างการผสานและ dcommit: หากคุณพยายามลบ branch หลังจาก dcommit คุณจะได้รับข้อความแสดงข้อผิดพลาด: เมื่อคุณ 'git svn dcommit' git จะลืมสิ่งนั้น สาขาของคุณถูกรวมเข้ากับ "master" แล้ว คุณต้องลบออกด้วย 'git branch -D work' ซึ่งไม่ได้ทำการตรวจสอบความปลอดภัย

ตอนนี้ฉันสร้างสาขา 'งาน' ใหม่ทันทีเพื่อหลีกเลี่ยงการแฮ็กสาขา 'หลัก' โดยไม่ได้ตั้งใจ:

$> git checkout -b work
$> git branch            # show my branches:
  master
* work

การรวม 'งาน' ของคุณเข้ากับการเปลี่ยนแปลงบน svn: นี่คือสิ่งที่ฉันทำเมื่อ 'git svn rebase' เปิดเผยว่าคนอื่นเปลี่ยนที่เก็บ svn ในขณะที่ฉันทำงานในสาขา 'งาน' ของฉัน:

$> git checkout master
$> git svn rebase              # 'svn pull' changes
$> git checkout work           # go to my work
$> git checkout -b integration # make a copy of the branch
$> git merge master            # integrate my changes with theirs
$> ... check/fix/debug ...
$> ... rewrite history with rebase -i if needed

$> git checkout master         # try again to push my changes
$> git svn rebase              # hopefully no further changes to merge
$> git merge integration       # (1) merge your work with theirs
$> git branch -d work          # (2) remove branches that are merged
$> git branch -d integration   # (2) remove branches that are merged
$> git svn dcommit             # (3) push your changes to the svn repository

มีโซลูชันที่มีประสิทธิภาพมากขึ้น: เวิร์กโฟลว์ที่นำเสนอนั้นเรียบง่าย: ใช้พลังของคอมไพล์ภายใน 'การอัปเดต / แฮ็ค / dcommit' แต่ละรอบเท่านั้น - แต่จะทิ้งประวัติโครงการระยะยาวไว้เป็นเชิงเส้นเช่นเดียวกับที่เก็บ svn สิ่งนี้ใช้ได้หากคุณต้องการเริ่มใช้ git merges ในขั้นตอนแรกเล็ก ๆ ในโครงการ svn แบบเดิม

เมื่อคุณคุ้นเคยกับการผสานคอมไพล์รู้สึกอิสระที่จะสำรวจขั้นตอนการทำงานอื่น ๆ : ถ้าคุณรู้ว่าสิ่งที่คุณทำคุณสามารถผสมผสานคอมไพล์ด้วยการผสาน SVN ( ใช้ Git-SVN (หรือคล้ายกัน) เพียงเพื่อช่วยให้ออกมาพร้อมกับการผสาน SVN? )


สิ่งนี้ดูเหมือนซับซ้อนโดยไม่จำเป็น ฉันเคยได้ยินว่ามีคนทำgit merge --squash workทำไมไม่ทำแบบนี้? ฉันสามารถเห็นการทำสควอชคอมมิทในสาขาก่อนที่จะรวมกันหากคุณสร้าง 'การเลือก' มากกว่าหนึ่งรายการ (บอกว่าคุณมีคอมมิท 8 คอมมิตและคุณกำลังเปลี่ยนคอมมิต 4 คอมมิทให้เป็น 1 และรวมคอมมิต 2 คอมมิตเข้าด้วยกัน) นอกจากนี้เมื่ออัปเดตสาขา 'งาน' ของฉันฉันทำได้rebaseง่ายกว่าการสร้างสาขาอื่นสำหรับสาขาของฉันและทำการรวม ...
void.pointer

8

Greg Hewgill คำตอบด้านบนไม่ปลอดภัย! หากมีการคอมมิตใหม่ปรากฏขึ้นบน trunk ระหว่าง "git svn rebase" ทั้งสองการผสานจะไม่กรอไปข้างหน้า

สามารถมั่นใจได้โดยใช้แฟล็ก "--ff-only" กับ git-merge แต่โดยปกติฉันจะไม่เรียกใช้ "git svn rebase" ในสาขามีเพียง "git rebase master" เท่านั้น (สมมติว่าเป็นเฉพาะ local สาขา). หลังจากนั้นจะมีการรับประกัน "git merge thebranch" อย่างรวดเร็ว


6

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

สมมติว่าคุณมีหัวข้อ svn branch เรียกว่า svn-branch

git svn fetch
git checkout remotes/trunk -b big-merge
git merge --squash svn-branch

ณ จุดนี้คุณมีการเปลี่ยนแปลงทั้งหมดจาก svn-branch ที่ถูกบีบให้เป็นคอมมิตเดียวที่รออยู่ในดัชนี

git commit

อย่างไรก็ตามตามที่คนอื่น ๆ ชี้ให้เห็นสิ่งนี้จะสูญเสียความละเอียดของการกระทำไป
Kzqai

@Tchalvak: บางครั้งคุณก็ต้องการแค่นั้น ฉันมักจะทำในสาขาคุณลักษณะอีกทั้ง "ความยุ่งเหยิงคงที่จากการกระทำครั้งก่อน" และจุดจบเหล่านี้ฉันชอบซ่อนเพราะชื่อเสียงที่ดี :-)
schoetbi

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

1
@schoetbi ใช่บางครั้งคุณต้องล้างประวัติที่ยุ่งเหยิงก่อนเผยแพร่ นี่คือที่ที่ 'git rebase -i <trunk>' เป็นตัวช่วยที่ดี: คุณสามารถเข้าร่วม / จัดลำดับใหม่ / ลบและแม้แต่แยกคอมมิต (!)
inger

5

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

git rebase master topic

ซึ่งจะเล่นคอมมิตของคุณผ่านสาขาหลักพร้อมให้คุณ dcommit

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