วิธีบังคับให้กดรีเซ็ตเป็นที่เก็บระยะไกล


96

สาขาหลักที่ห่างไกลของเราเกิดความสับสน รหัสการพัฒนาปัจจุบันอยู่ในสาขาหลักพร้อมกับคอมมิตล่าสุด เห็นได้ชัดว่ารหัสการพัฒนายังไม่พร้อมสำหรับสาขาหลัก

git reset --hard (Tag)ดังนั้นในพื้นที่เก็บข้อมูลท้องถิ่นของฉันฉันไม่ได้ตั้งค่าให้แท็กล่าสุด ตอนนี้สาขาหลักถูกต้องในที่เก็บในเครื่องของฉัน ตอนนี้เมื่อฉันพยายามพุชการเปลี่ยนแปลงไปยังที่เก็บระยะไกลgit push origin masterฉันได้รับข้อผิดพลาด:

To (REMOTE GIT REPOSITORY LOCATION)
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'
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.

หลังจากมองไปรอบ ๆ ฉันก็พบ--forceตัวเลือก ดังนั้นฉันจึงผลักดันไปยังที่เก็บระยะไกลgit push --force origin masterและฉันยังคงได้รับข้อผิดพลาด:

Total 0 (delta 0), reused 0 (delta 0)
remote: error: denying non-fast-forward refs/heads/master (you should pull first)
To (REMOTE GIT REPOSITORY LOCATION)
 ! [remote rejected] master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'

ฉันไม่สามารถดึงข้อมูลต้นแบบได้เนื่องจากมีรหัสการพัฒนาที่ไม่สามารถใช้กับต้นแบบได้


3
ฉันคิดว่าข้อความดังกล่าวหมายความว่าคุณไม่มีสิทธิ์ในการผลักดันแบบไม่กรอไปข้างหน้า
svick

3
คุณถูกต้องขอบคุณ ในไฟล์กำหนดค่าสำหรับที่เก็บบนรีโมต, denyNonFastforwards = true. ฉันเปลี่ยนเป็นเท็จผลักการเปลี่ยนแปลงของฉันแล้วเปลี่ยนกลับเป็นจริง ขอบคุณทุกคนอีกครั้งสำหรับความช่วยเหลือ
samwell

2
@samwell โปรดทำเครื่องหมายคำตอบของ svick ว่ายอมรับ
hultqvist

@samwell คำตอบของ svick เหมาะกับคุณหรือไม่?
Songo

สำหรับผู้ที่ต้องการรายละเอียดเกี่ยวกับการปิดการใช้งาน denonFastForwards เช่น samwell สามารถดูคำแนะนำเพิ่มเติมได้ที่นี่: stackoverflow.com/a/43721579/2073804
ron190

คำตอบ:


154

ข้อความนี้หมายความว่าคุณไม่ได้รับอนุญาตให้ทำการกดแบบไม่กรอไปข้างหน้า

ที่เก็บระยะไกลของคุณมีแนวโน้มมากที่สุดdenyNonFastforwards = trueในการกำหนดค่า หากคุณเปลี่ยนสิ่งนั้นgit push --forceควรใช้งานได้

ในการเปลี่ยนการตั้งค่าคุณต้องเข้าถึงเครื่องด้วยที่เก็บระยะไกล git config receive.denynonfastforwards falseจากนั้นทำ


1
คุณสามารถทำgit configเซิร์ฟเวอร์ได้หรือไม่? หรือบางทีคุณอาจใช้คำนั้นในเชิงเปรียบเทียบ ในการเล่นกับแนวคิดเหล่านี้ฉันได้สร้าง repo ทดสอบใน/opt/git(พื้นที่เซิร์ฟเวอร์ git ของฉัน) จากนั้นฉันแก้ไขการตั้งค่านี้ใน/opt/git/the_repo/the_repo.git/config. แต่เมื่อทำแล้วได้ผลgit push --force origin SHA:branchตามที่กำหนด
HankCa

4
ข้อความแสดงข้อผิดพลาดจะมีบรรทัดที่ขึ้นต้นด้วย "error: failed to push some refs to <your repository>" โดยที่ <your repository> คือพา ธ ที่ลงท้ายด้วย. git ซึ่งเป็นไดเร็กทอรีที่มีไฟล์ชื่อ "config" นี้ "การตั้งค่า" ไฟล์ที่คุณสามารถตั้ง denyNonFastforwards = false
กากกะรุน

1
ความคิดเห็นของ @ Emery มีค่า บางครั้งโฟลเดอร์บนเซิร์ฟเวอร์จะมีการตั้งค่าต้นทางเป็น /srv/git/repo.git นี่คือการกำหนดค่าที่มีการตั้งค่า denonFastForwards ไม่ใช่โฟลเดอร์แอปพลิเคชัน
Elijah Lynn

1
@hsalimi หากคุณไม่สามารถเข้าถึงเซิร์ฟเวอร์ได้คุณต้องติดต่อผู้ดูแลระบบเซิร์ฟเวอร์และให้ปิดเซิร์ฟเวอร์ชั่วคราวเพื่อให้คุณสามารถบังคับให้พุชแล้วเปิดอีกครั้ง ไม่น่าเป็นไปได้มากนักที่จะทำเช่นนี้ได้ อาจเป็นเรื่องปกติมากขึ้นในสภาพแวดล้อมภายในกับทีมโฮสติ้งของคุณเอง
Elijah Lynn

1
ในตอนแรกสิ่งนี้น่าหงุดหงิด แต่ความสวยงามของมันคือรีโมทได้รับการปกป้องโดยค่าเริ่มต้นโดยสิ้นเชิงและหากคุณในฐานะนักพัฒนามีเจตนาและทำ rebases อย่างถูกต้องคุณสามารถแทนที่การกำหนดค่านี้เพื่ออนุญาตให้เกิดพฤติกรรมที่เป็นอันตรายได้ การรีเบตเป็นสิ่งที่ผู้ใช้คอมไพล์ทุกคนควรรู้วิธีทำและรู้ว่าเมื่อใดที่ไม่ควรทำ doc1 doc2
moodboom

15

รีโมทไม่อนุญาตให้ส่งต่ออย่างรวดเร็ว

ทางเลือกที่ดีที่สุดของคุณคือgit revertการกระทำทั้งหมดที่ไม่ควรมีและระมัดระวังให้มากขึ้นในอนาคต

git revert [commit]จะสร้างคอมมิตใหม่ที่ยกเลิกสิ่งที่[commit]ทำ


เป็นการตั้งค่าบางอย่างบนที่เก็บระยะไกลที่บล็อกการเปลี่ยนแปลงที่ไม่ใช่กรอไปข้างหน้าทั้งหมด
samwell

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

12

ลองใช้-fแฟล็กและวางไว้หลังชื่อสาขาระยะไกล

git push origin master -f


1
ไม่นั่นก็ไม่ได้ผลเช่นกัน ฉันยังลองgit push -f origin masterและผลลัพธ์เดียวกัน ทั้งสองครั้งที่ฉันลองฉันได้รับข้อความแสดงข้อผิดพลาดรุ่นที่สอง
samwell

12

ขั้นตอนในการเปิดใช้งานการบังคับอย่างถาวรในลักษณะต่อไปนี้

git push -f myrepo my-branch

แก้ไขไฟล์ชื่อ "config" ในโฟลเดอร์ที่ลงท้ายด้วย ".git" บนที่เก็บระยะไกลของคุณ

ในเอาต์พุตบรรทัดคำสั่งของ git จากการพุชที่ล้มเหลวให้มองหาบรรทัดที่ระบุว่า:

error: failed to push some refs to 'ssh://user@some-remote-server.mycompany.com/srv/git/myrepo.git

แล้ว

ssh user@some-remote-server.mycompany.com
cd /srv/git/myrepo.git
vi config

ตั้งค่า "denonFastforwards" เป็นเท็จ

ใน "config" ให้ตั้งค่า

[receive]
        denyNonFastforwards = false

ตอนนี้คุณสามารถพุชจากเครื่องในพื้นที่ของคุณด้วย -f

git push -f myrepo my-branch

จะทำอย่างไรโดยไม่ต้องเข้าถึง SSH เพื่อ bare git repo?
Vladimir Vukanac

อาจใช้คำสั่ง git revert ตามที่ richo แนะนำ? หากคุณสำรองสถานะปัจจุบันของ repo ก่อนคุณยังสามารถรวมโค้ดของคุณเพื่อก้าวไปข้างหน้าได้
Emery

git revertเป็นเรื่องที่ซับซ้อนเมื่อคุณรวมเข้าด้วยกัน เพื่อให้ซับซ้อนยิ่งขึ้นกรณีของฉันมีการผสาน 3 ครั้งซึ่งอันหนึ่งมีอายุมาก ~ 20 คอมมิตที่แตกต่างจากการพัฒนาอันดับที่ 2 คือการผสานจากมาสเตอร์ - น่าเกลียดเหมือนนรก
Vladimir Vukanac

1
บางทีวิธีแก้ปัญหาคือการรีเซ็ตเป็นสถานะที่ต้องการสำรองข้อมูล (ซ่อน) ดึงอีกครั้งและใช้การสำรองข้อมูล (ซ่อน)
Vladimir Vukanac

1
mrW คุณยังสามารถรวมฐานรหัสที่คุณต้องการไว้ด้านบนของฐานรหัสที่เปลี่ยนกลับ / ดึงออกมาได้
Emery


2

คุณไม่ได้รับอนุญาตให้ทำการ git push ที่ไม่ใช่กรอไปข้างหน้า

  1. หากรีโมตคือ GitHub ให้ไปที่https://github.com/$USER/$REPO/settings/branchesและยกเลิกการป้องกันสาขาที่เป็นปัญหา

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

    คุณต้องเป็นผู้ดูแลระบบของ repo จึงจะทำได้

  2. หากรีโมตเป็นเซิร์ฟเวอร์ git ของคุณเองให้เรียกใช้ที่git config receive.denynonfastforwards falseนั่น


โปรดทราบว่าสำหรับอินสแตนซ์ Git Hub Enterprise การพุชไปยังสาขาเริ่มต้น (โดยทั่วไปคือ "master") สามารถปิดใช้งานที่ระดับอินสแตนซ์ได้ ซึ่งหมายความว่าแม้ว่าคุณจะไม่ได้รับการปกป้อง "master" และแม้ว่าคุณจะเป็นผู้ดูแลเว็บไซต์คุณจะไม่สามารถบังคับให้ส่งไปยังสาขาเริ่มต้นได้ สมมติว่าคุณมีสิทธิ์คุณสามารถแก้ไขปัญหานี้ได้ชั่วคราวโดยการเปลี่ยนสาขาเริ่มต้นไปเป็นอย่างอื่นทำการบังคับของคุณแล้วเปลี่ยนกลับ
Christopher Hunter

0

ปัญหาเกิดขึ้นเป็นสาขาในปัจจุบันไม่ได้กำหนดค่าอย่างถูกต้องสำหรับPULL ตรวจสอบครั้งแรกไม่ว่าจะเป็นสาขาต้นน้ำมีการกำหนดค่าอย่างถูกต้องสำหรับการดึงใช้ git remote show origin- คุณสามารถค้นหาได้ภายใต้หัวข้อ - สาขาท้องถิ่นกำหนดค่าสำหรับ 'คอมไพล์ดึง': ถ้าไม่กำหนดค่าโดยใช้:

git config branch.MYBRANCH.merge refs/heads/MYBRANCH

ตั้งชื่อสาขาที่เหมาะสมสำหรับตัวยึดสถานที่ - MYBRANCH


0

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

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

ไปที่โฟลเดอร์ต้นทางจากนั้นเรียกใช้คำสั่ง: โปรดทราบว่านั่นhttps://github.com/*.gitคือลิงก์ repo ระยะไกลของคุณ

git init
git remote add origin https://github.com/*.git
git add .
git commit -m "initial commit"
git push origin master -f
git push --set-upstream origin master

**Note: this will clear all your git history on your master branch**


0

สำหรับฉันคำใบ้ของ @svick ชี้ไปในทิศทางที่ถูกต้อง เนื่องจากเซิร์ฟเวอร์ git ที่ฉันต้องการแก้ไขเป็นกล่องของฉันจริงๆฉันจึงลงชื่อเข้าใช้และgit config --global receive.denynonfastforwards falseทำการเปลี่ยน repos ทั้งหมดเพื่อยอมรับการกดที่ไม่ใช่ ff แบบบังคับ ไม่ได้ทำงานนอกกรอบ สิ่งที่ฉันพบคือใน config มีการreceive.denynonfastforwards=trueตั้งค่าไว้แล้วและไม่สามารถลบgit config --global --unset receive.denynonfastforwardsได้ ทำการแก้ไขใน repo ด้วยตนเอง ( vi config) ได้ผล


0

ฉันแก้ไขโดยการลบสาขาหลักออกจากการป้องกันและเป็นค่าเริ่มต้นซึ่งอยู่เหนือกฎสาขาที่ยื่นออกมาในการตั้งค่าที่เก็บ

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