การอัปเดตถูกปฏิเสธเนื่องจากส่วนปลายของสาขาปัจจุบันของคุณอยู่เบื้องหลัง


158

ฉันเพิ่งเริ่มใช้ Git ดังนั้นอย่าลังเลที่จะปฏิบัติต่อฉันเหมือนมือใหม่

ขั้นตอนการทำงานของเราเป็นเช่นนั้น เรามีสาขาที่เรียกว่าที่ฉันสามารถเข้าถึงที่dev origin/devเมื่อเราทำการเปลี่ยนแปลงเราจะสร้าง branch จาก dev:

git checkout -b FixForBug origin / dev

ตอนนี้ผมได้เรียกว่าเป็นสาขาFixForBugที่ติดตามไป origin/dev(ผมคิดว่าเป็นคำที่เหมาะสม) ดังนั้นถ้าฉันทำgit pullมันจะทำให้เกิดการเปลี่ยนแปลงใหม่origin/devซึ่งดีมาก ตอนนี้เมื่อฉันแก้ไขเสร็จแล้วฉันก็กดไปที่สาขาระยะไกลที่เรียกว่าสิ่งเดียวกัน

ก่อนอื่นฉันดึงการเปลี่ยนแปลงใด ๆ จากorigin/devและทำการ rebase:

git ดึง --rebase

จากนั้นฉันจะผลักดันการเปลี่ยนแปลงไปยังสาขาระยะไกลที่มีชื่อเดียวกัน:

git push origin FixForBug

ตอนนี้มีสาขาบนเซิร์ฟเวอร์ระยะไกลและฉันสามารถสร้างคำขอดึงเพื่อให้การเปลี่ยนแปลงนั้นได้รับการอนุมัติและรวมกลับไปที่สาขา dev ฉันไม่เคยผลักดันอะไรให้กับorigin/devตัวเอง ฉันเดาว่านี่เป็นขั้นตอนการทำงานทั่วไป

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

ข้อผิดพลาด: ล้มเหลวในการส่งการอ้างอิงบางส่วนไปที่คำใบ้ ' https://github.limeade.info/Limeade/product.git ': การอัปเดตถูกปฏิเสธเนื่องจากส่วนปลายของสาขาปัจจุบันของคุณอยู่หลังคำใบ้: คู่ระยะไกล รวมการเปลี่ยนแปลงระยะไกล (เช่น hint: 'git pull ... ') ก่อนที่จะกดอีกครั้ง คำแนะนำ: ดู 'หมายเหตุเกี่ยวกับกรอไปข้างหน้า' ใน 'git push --help' สำหรับรายละเอียด

อย่างไรก็ตามถ้าฉันทำgit statusมันบอกว่าฉันนำหน้าorigin/dev1 คอมมิต (ซึ่งก็สมเหตุสมผลดี) และถ้าฉันทำตามคำใบ้และเรียกใช้git pullมันก็บอกว่าทุกอย่างเป็นปัจจุบัน ฉันคิดว่านี่เป็นเพราะฉันกำลังผลักดันไปยังสาขาอื่นที่ไม่ใช่สาขาต้นน้ำของฉัน ฉันสามารถแก้ไขปัญหานี้ได้โดยเรียกใช้:

git push -f origin FixForBug

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

คำถามของฉัน:

เหตุใดจึง-fจำเป็นต้องมีในสถานการณ์นี้ โดยปกติเมื่อคุณบังคับบางอย่างนั่นเป็นเพราะคุณทำอะไรผิดพลาดหรืออย่างน้อยก็ขัดต่อการปฏิบัติตามมาตรฐาน ฉันสามารถทำสิ่งนี้ได้หรือไม่หรือจะทำให้บางสิ่งในสาขาระยะไกลยุ่งหรือสร้างความยุ่งยากให้ใครก็ตามที่ต้องรวมเนื้อหาของฉันเป็น dev ในที่สุด?


2
ดูเหมือนว่าข้อความที่คุณได้รับคือการบอกว่า FixForBug สาขาระยะไกลอยู่ข้างหน้า FixForBug สาขาในพื้นที่ของคุณ คุณควรดึงการเปลี่ยนแปลงจากสาขาระยะไกลนั้นและรวมเข้ากับสาขาในพื้นที่ของคุณก่อนที่จะผลักดัน
mhatch

4
@mhatch - โดยพื้นฐานแล้ววิ่งgit pull origin FixForBugก่อนที่ฉันจะผลักไปที่? โอเคที่สมเหตุสมผล อย่าลังเลที่จะเพิ่มเป็นคำตอบ!
Mike Christensen

คำตอบ:


205

-f จะจำเป็นจริงๆเพราะ rebase เมื่อใดก็ตามที่คุณทำ rebase คุณจะต้องทำการบังคับเนื่องจากสาขาระยะไกลไม่สามารถส่งต่อไปยังคอมมิตของคุณได้อย่างรวดเร็ว คุณต้องการตรวจสอบให้แน่ใจเสมอว่าคุณดึงก่อนที่จะผลักดัน แต่ถ้าคุณไม่ต้องการบังคับให้ push ไปที่ master หรือ dev สำหรับเรื่องนั้นคุณสามารถสร้าง branch ใหม่เพื่อผลักดันและรวมหรือทำการประชาสัมพันธ์ .


2
ขอบคุณสำหรับคำตอบที่เป็นประโยชน์นี้! :)
AIM_BLB

1
คุณช่วยชี้แจงประเด็น "คุณต้องการให้แน่ใจเสมอว่าคุณดึงก่อนผลัก"? เป็นที่ชัดเจนว่าเหตุใดจึงต้องใช้ "push -f" หลังจาก rebase ของสาขาในพื้นที่ ในกรณีนี้การ rebase ของโลคัลจะไม่ถูกยกเลิกโดยการดึงรีโมตก่อนที่จะกดหรือไม่?
haripkannan

51

เพื่อให้แน่ใจว่า FixForBug สาขาในพื้นที่ของคุณไม่ได้นำหน้า FixForBug สาขาระยะไกลดึงและรวมการเปลี่ยนแปลงก่อนที่จะผลักดัน

git pull origin FixForBug
git push origin FixForBug

2
OP ระบุว่าพวกเขาได้ทำการดึงคอมไพล์แล้วและพยายามผลักดัน คำตอบของคุณใช้ไม่ได้กับคำถามของ OP
Patrick

1
การหลีกเลี่ยงแรงผลักจะดีกว่าเสมอ ขอบคุณสำหรับการแบ่งปัน!
Ann Kilzer

19

the tip of your current branch is behind its remote counterpartหมายความว่ามีการเปลี่ยนแปลงในสาขาระยะไกลที่คุณไม่มีในเครื่อง และคอมไพล์จะบอกให้คุณนำเข้าการเปลี่ยนแปลงใหม่จากREMOTEและรวมเข้ากับโค้ดของคุณจากนั้นpushไปยังรีโมต

คุณสามารถใช้คำสั่งนี้เพื่อบังคับให้เปลี่ยนแปลงเซิร์ฟเวอร์ด้วย local repo ()

git push -f origin master

ด้วย-fแท็กคุณจะแทนที่Remote Brach codeด้วยรหัสของคุณ


16

หากคุณต้องการหลีกเลี่ยงการใช้งาน-fคุณสามารถใช้เพียงแค่

git pull

แทน

git pull --rebase

non-rebase จะดึงการเปลี่ยนแปลงจากorigin/devและรวมเข้ากับFixForBugสาขาของคุณ จากนั้นคุณจะสามารถเรียกใช้

git push origin FixForBug

-fโดยไม่ต้องใช้


3
Rebase เป็นส่วนหนึ่งของขั้นตอนการทำงานของเราที่นี่ ฉันจะโดนตะโกนใส่ถ้าไม่ทำ
Mike Christensen

1
@MikeChristensen: โอเคดีแล้วทำตามขั้นตอนที่บันทึกไว้แน่นอน จากสิ่งที่คุณอธิบายคุณจะต้องใช้-fเนื่องจากคุณกำลังแทนที่การกระทำบนที่เก็บต้นน้ำด้วยที่เก็บข้อมูลอื่นที่มีประวัติ (rebased) ที่แตกต่างกัน หากคุณจะใช้ผลิตภัณฑ์เช่นGerritก็จะสนับสนุนขั้นตอนการตรวจสอบโค้ดใหม่โดยไม่ต้องใช้-fเมื่อกด เราใช้ Gerrit ในที่ทำงานด้วยวิธีนี้และได้ผลดีมาก
Greg Hewgill

6

คำสั่งที่ฉันใช้กับ Azure DevOps เมื่อฉันพบข้อความ "การอัปเดตถูกปฏิเสธเนื่องจากส่วนปลายของสาขาปัจจุบันของคุณอยู่ข้างหลัง" คือ / คือคำสั่งนี้:

git ดึงต้นแบบต้นทาง

(หรือจะเริ่มด้วยโฟลเดอร์ใหม่แล้วทำการ Clone ก็ได้) ..

คำตอบนี้ไม่ได้ตอบคำถามที่วางไว้โดยเฉพาะ Keif ได้ตอบคำถามข้างต้นนี้ แต่ตอบคำถามชื่อเรื่อง / ข้อความส่วนหัวและนี่จะเป็นคำถามทั่วไปสำหรับผู้ใช้ Azure DevOps

ฉันสังเกตความคิดเห็น: "คุณต้องการให้แน่ใจเสมอว่าคุณดึงก่อนที่จะผลักดัน" ในคำตอบจาก Keif ด้านบน!

ฉันยังใช้เครื่องมือ Git Gui นอกเหนือจากเครื่องมือบรรทัดคำสั่ง Git

(ฉันไม่แน่ใจว่าจะทำอย่างไรให้เทียบเท่ากับคำสั่งบรรทัดคำสั่ง "git pull origin master" ภายใน Git Gui ดังนั้นฉันจึงกลับไปที่บรรทัดคำสั่งเพื่อทำสิ่งนี้)

แผนภาพที่แสดงคำสั่ง git ต่างๆสำหรับการดำเนินการต่างๆที่คุณอาจต้องการดำเนินการคือ:

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


4

นี่เพิ่งเกิดขึ้นกับฉัน

  • เมื่อวานนี้ฉันขอดึงนายของเรา
  • เพื่อนร่วมงานของฉันกำลังตรวจสอบวันนี้และเห็นว่ามันไม่ตรงกันกับสาขาหลักของเราดังนั้นด้วยความตั้งใจที่จะช่วยฉันเขาจึงรวมอาจารย์เข้ากับสาขาของฉัน
  • ฉันไม่รู้ว่าเขาทำอย่างนั้น
  • จากนั้นฉันก็รวมต้นแบบไว้ในเครื่องพยายามผลักดัน แต่มันล้มเหลว ทำไม? เนื่องจากเพื่อนร่วมงานของฉันรวมกับอาจารย์ได้สร้างข้อผูกพันพิเศษที่ฉันไม่มีในเครื่อง !

วิธีแก้ปัญหา: ดึงสาขาของตัวเองลงเพื่อที่ฉันจะได้รับภาระพิเศษนั้น จากนั้นผลักดันกลับไปยังสาขาที่ห่างไกลของฉัน

แท้จริงสิ่งที่ฉันทำในสาขาของฉันคือ:

git pull
git push

3

นี่คือวิธีที่ฉันแก้ไขปัญหาของฉัน

สมมติว่าสาขาต้นน้ำคือสาขาที่คุณแยกมาและจุดเริ่มต้นคือ repo ของคุณและคุณต้องการส่ง MR / PR ไปยังสาขาต้นน้ำ

สมมติว่าคุณได้คอมมิต 4 ข้อแล้วคุณจะได้รับ Updates were rejected because the tip of your current branch is behind.

นี่คือสิ่งที่ฉันทำ

ขั้นแรกสควอชทั้งหมด 4 ข้อของคุณ

git rebase -i HEAD~4

คุณจะได้รับรายการการกระทำที่pickเขียนไว้ (เปิดในตัวแก้ไข)

ตัวอย่าง

pick fda59df commit 1
pick x536897 commit 2
pick c01a668 commit 3
pick c011a77 commit 4

ถึง

pick fda59df commit 1
squash x536897 commit 2
squash c01a668 commit 3
squash c011a77 commit 4

หลังจากนั้นคุณสามารถบันทึกคอมมิตรวมของคุณได้

ต่อไป

คุณจะต้องซ่อนการกระทำของคุณ

นี่คือวิธีการ

git reset --soft HEAD~1
git stash

ตอนนี้ rebase กับสาขาต้นน้ำของคุณ

git fetch upstream beta && git rebase upstream/beta

ตอนนี้ป๊อปคอมมิตที่ซ่อนอยู่ของคุณ

git stash pop

ยอมรับการเปลี่ยนแปลงเหล่านี้และผลักดัน

git add -A
git commit -m "[foo] - foobar commit"
git push origin fix/#123 -f

2

ต้องเป็นเพราะการกระทำอยู่ก่อนการผลักดันปัจจุบันของคุณ

1) git pull origin "ชื่อสาขาที่คุณต้องการพุช"

2) git rebase

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

3) git rebase - ดำเนินการต่อ


0

ฉันมีปัญหานี้เมื่อพยายามผลักดันหลังจาก rebase ผ่าน Visual Studio Code ปัญหาของฉันได้รับการแก้ไขโดยเพียงแค่คัดลอกคำสั่งจากหน้าต่าง git output และดำเนินการจากหน้าต่างเทอร์มินัลใน Visual Studio Code

ในกรณีของฉันคำสั่งเป็นดังนี้:

git push origin NameOfMyBranch:NameOfMyBranch


0

คุณต้องเพิ่มไฟล์ใหม่ในคอมมิตของคุณซึ่งยังไม่ถูกพุช ตรวจสอบไฟล์และดันไฟล์นั้นอีกครั้งจากนั้นลองดึง / ดันไฟล์จะได้ สิ่งนี้ได้ผลสำหรับฉัน ..

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