การเปลี่ยนสาขาระยะไกลใน Git


137

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

remote:
  master

local:
  master
  feature

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

remote:
  master
  feature

local:
  master
  feature

จากนั้นฉันตั้งค่าสาขาใหม่เพื่อติดตามรีโมท:

remote:
  master
  feature

local:
  master
  feature -> origin/feature

และทั้งหมดเป็นอย่างดี สิ่งที่ฉันต้องการจะทำต่อจากนี้คือการปรับฐานสาขาฟีเจอร์ใหม่เป็นสาขาหลักบนรีโมท แต่ฉันต้องการทำสิ่งนี้จากเครื่องในพื้นที่ของฉัน ฉันต้องการที่จะทำ:

git checkout master
git pull
git checkout feature
git rebase master
git push origin feature

เพื่อให้สาขาของคุณสมบัติระยะไกลเป็นปัจจุบันกับรีโมตมาสเตอร์ อย่างไรก็ตามวิธีนี้ทำให้ Git บ่น:

To <remote>
 ! [rejected]        feature -> feature (non-fast-forward)
error: failed to push some refs to '<remote>'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

git pullใช้กลอุบาย แต่ทำให้เกิดการผสานที่ฉันต้องการหลีกเลี่ยง ฉันกังวลว่าข้อความfeature -> featureจะระบุมากกว่าfeature -> origin/featureแต่นี่อาจเป็นเพียงการนำเสนอ

ฉันพลาดอะไรไปหรือไปเกี่ยวกับเรื่องนี้ผิดทาง? ไม่สำคัญที่จะหลีกเลี่ยงการทำ rebase บนเซิร์ฟเวอร์ระยะไกล แต่จะทำให้การแก้ไขข้อขัดแย้งในการผสานจาก rebase ทำได้ยากขึ้นมาก


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

คำตอบ:


187

ขึ้นอยู่กับว่าคุณลักษณะนั้นถูกใช้โดยบุคคลหนึ่งคนหรือหากผู้อื่นกำลังดำเนินการอยู่

คุณสามารถบังคับให้กดหลังจาก rebase หากเป็นเพียงคุณ:

git push origin feature -f

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

git merge master
git push origin feature

วิธีนี้จะช่วยให้มั่นใจได้ว่าคุณมีประวัติร่วมกันกับคนที่คุณทำงานร่วมด้วย

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

นี่คือเรื่องของฉันในเรื่องที่เรียกว่าสาขาต่อคุณลักษณะ

หวังว่านี่จะช่วยได้


29
+1 สำหรับif others are working on it, you should merge and not rebase off of masterrebase จะใช้ได้ดีกว่าในสาขาส่วนตัวเท่านั้น
Hendra Uzia

6
ทางเลือกในการคอมไพล์คุณลักษณะจุดเริ่มต้นของการพุช -f คุณยังสามารถลบคุณสมบัติระยะไกลของคุณและคุณสมบัติพุชอีกครั้ง
Markus

2
การรวมมาสเตอร์เข้ากับสาขาของคุณจะสร้างคอมมิตการผสานและจะทำให้เกิดความขัดแย้งกับสาขาฟีเจอร์เปิดอื่น ๆ จากมาสเตอร์หลังจากที่มีการผลักการเปลี่ยนแปลงของคุณ
สตีเวน

+1 สำหรับgit push origin feature -f. ในบางบริบทอาจจำเป็นต้องทำการ rebase แม้ว่าจะมีสาขาระยะไกลก็ตาม ปมคือการรู้ว่ากำลังทำอะไร และเราควรรับช่วงต่อว่าคุณอาจกำลังลบคอมมิตใน repo ระยะไกล
enagra

33

ยินดีที่คุณนำเรื่องนี้ขึ้นมา

นี่เป็นสิ่งสำคัญ / แนวคิดในคอมไพล์ที่ผู้ใช้คอมไพล์จำนวนมากจะได้รับประโยชน์จากการรู้ git rebase เป็นเครื่องมือที่ทรงพลังมากและช่วยให้คุณทำสควอชร่วมกันลบคอมมิท ฯลฯ แต่เช่นเดียวกับเครื่องมือที่มีประสิทธิภาพใด ๆ โดยพื้นฐานแล้วคุณต้องรู้ว่าคุณกำลังทำอะไรอยู่หรือบางสิ่งอาจผิดพลาดจริงๆ

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

นี่คือเหตุผลว่าทำไมสิ่งสำคัญคือต้องจำไว้ว่าเมื่อคุณผลักดันคอมมิชชันแล้วคุณไม่ควรตั้งฐานใหม่ในภายหลัง สาเหตุที่สิ่งนี้สำคัญคือคนอื่นอาจดึงความมุ่งมั่นของคุณและยึดผลงานของพวกเขาจากการมีส่วนร่วมของคุณไปยังฐานรหัสและหากคุณตัดสินใจที่จะย้ายเนื้อหานั้นจากที่หนึ่งไปยังอีกที่หนึ่ง (สร้างฐานใหม่) และผลักดันสิ่งเหล่านั้น การเปลี่ยนแปลงจากนั้นคนอื่นจะได้รับปัญหาและต้องสร้างรหัสใหม่ ลองนึกภาพคุณมีนักพัฒนา 1,000 คน :) มันทำให้เกิดการทำงานซ้ำที่ไม่จำเป็นมากมาย



1
อัปเดตภาษาของฉัน
ralphtheninja

6

เนื่องจากคุณได้รับการปรับปรุงfeatureใหม่masterในท้องถิ่นของคุณfeatureจึงไม่ใช่การเดินหน้าอย่างรวดเร็วorigin/featureอีกต่อไป git push origin +featureดังนั้นผมคิดว่ามันเป็นเรื่องดีอย่างสมบูรณ์แบบในกรณีนี้เพื่อแทนที่การตรวจสอบอย่างรวดเร็วไปข้างหน้าด้วยการทำ คุณยังสามารถระบุสิ่งนี้ในการกำหนดค่าของคุณ

git config remote.origin.push +refs/heads/feature:refs/heads/feature

หากคนอื่นทำงานด้านบนorigin/featureพวกเขาจะถูกรบกวนโดยการอัปเดตบังคับนี้ คุณสามารถหลีกเลี่ยงที่โดยการผสานในใหม่masterเข้าไปfeatureแทน rebasing ผลลัพธ์จะเป็นไปอย่างรวดเร็ว


1

คุณสามารถปิดการใช้งานการตรวจสอบ (ถ้าคุณจริงๆแน่ใจว่าคุณรู้ว่าสิ่งที่คุณกำลังทำ) โดยใช้ตัวเลือกในการ--forcegit push


16
ปัญหาคือฉันไม่แน่ใจว่าฉันรู้จริงๆว่าฉันกำลังทำอะไร :)
kfb

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