Git pull หลังจากการอัพเดทแบบบังคับ


332

ฉันแค่บีบบางอย่างที่ทำgit rebaseและทำgit push --force(ซึ่งฉันรู้ว่าชั่ว)

ตอนนี้วิศวกรซอฟต์แวร์รายอื่นมีประวัติแตกต่างกันและเมื่อพวกเขาทำgit pullGit จะรวมเข้าด้วยกัน มีวิธีในการแก้ไขปัญหานี้rm my-repo; git clone git@example.org:my-repo.gitหรือไม่?

ฉันต้องการสิ่งที่ตรงกันข้ามgit push --forceแต่git pull --forceไม่ได้ให้ผลลัพธ์ที่ต้องการ


16
พวกเขาสามารถลบสาขาและสร้างมันใหม่โดยไม่ต้องลบ repo ทั้งหมด:git checkout master && git branch -D test && git checkout -b test origin/test
Florian Klein

1
สำเนาซ้ำที่เป็นไปได้ของForce Git เพื่อเขียนทับไฟล์ในเครื่องที่ pull
gpoo

คำตอบ:


510

เพื่อรับข้อผูกพันใหม่

git fetch

ตั้งค่าใหม่

git resetคุณสามารถรีเซ็ตกระทำสำหรับสาขาในประเทศโดยใช้

หากต้องการเปลี่ยนการกระทำของสาขาในพื้นที่:

git reset origin/master --hard

ระวังให้ดีเนื่องจากเอกสารประกอบมีดังนี้:

รีเซ็ตดัชนีและแผนผังการทำงาน การเปลี่ยนแปลงใด ๆ กับไฟล์ที่ถูกติดตามในแผนผังการทำงานตั้งแต่ <commit> ถูกยกเลิก

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

rebase

คุณสามารถเล่นซ้ำกระทำในพื้นที่ของคุณด้านบนของการกระทำอื่น ๆ / สาขาโดยใช้git rebase:

git rebase -i origin/master

สิ่งนี้จะเรียกใช้ rebase ในโหมดอินเทอร์แอคทีฟซึ่งคุณสามารถเลือกวิธีการใช้แต่ละการคอมมิตที่ไม่ได้อยู่ในประวัติที่คุณกำลังรีบูตอยู่ด้านบน

หากคอมมิชชันที่คุณลบ (พร้อมgit push -f) ถูกดึงเข้าสู่ประวัติศาสตร์ท้องถิ่นแล้วพวกเขาจะถูกระบุว่าเป็นคอมมิชชันที่จะนำมาใช้ใหม่ - พวกเขาจะต้องถูกลบออกเป็นส่วนหนึ่งของการรีบูตมิเช่นนั้นจะถูกรวมเข้าไปในประวัติศาสตร์ สำหรับสาขา - และปรากฏขึ้นอีกครั้งในประวัติระยะไกลในการผลักดันครั้งต่อไป

ใช้วิธีใช้git command --helpสำหรับรายละเอียดเพิ่มเติมและตัวอย่างในคำสั่งใด ๆ ข้างต้น (หรืออื่น ๆ )


2
@iblue เลือกระหว่างการสูญเสียการเปลี่ยนแปลงทั้งหมดลบประวัติการกระทำ แต่เก็บการเปลี่ยนแปลงไฟล์หรือพยายามที่จะใช้แต่ละการกระทำที่ด้านบนของหัวใหม่ ตัวเลือกที่ง่ายที่สุดอาจเป็นซอฟต์รีเซ็ต
AD7six

1
@iblue เมื่อเพื่อนร่วมงานของคุณใช้ `git reabse origin / master 'และหมายความว่าในขณะที่พวกเขามีความมุ่งมั่นมาแล้ว git จะเขียนคำสั่งของคุณไปยังด้านหลังของคอมมิท
ทิม

6
อาจจะคุ้มค่าที่จะกล่าวถึงหากเป็นสาขาอื่น:git reset origin/otherbranch --hard
bmaupin

ดังนั้นเพื่อชี้แจงนี้เป็นอย่างใดอย่างหนึ่ง : ตัวเลือกที่ 1: reset --hard, หรือตัวเลือกที่ 2: reset --soft+ rebaseใช่มั้ย?
PlasmaBinturong

2
@PlasmaBinturong ฉบับที่git reset --soft origin/masterจะเปลี่ยนประวัติศาสตร์กระทำเพื่อให้ตรงกับระยะไกลและขั้นตอนที่แตกต่างไปจากระยะไกลซึ่งจากนั้นจะมุ่งมั่น ไม่จำเป็นต้องรีบาวด์ในสถานการณ์นั้น (และคุณจะได้รับการป้องกันไม่ให้ทำเช่นนั้นเนื่องจากการเปลี่ยนแปลงที่ไม่มีข้อผูกมัด) เนื่องจากไม่มีประวัติการกระทำที่แตกต่างกัน ตัวเลือกทั้งสองถูกรีเซ็ตหรือรีบูต - ไม่ใช่ทั้งสองอย่างรวมกัน โปรดถามคำถามว่าสถานการณ์ของคุณแตกต่างจากที่ฉันเคยตอบไว้ที่นี่หรือไม่
AD7six

16

สิ่งนี้จะไม่แก้ไขสาขาที่มีรหัสที่คุณไม่ต้องการ (ดูด้านล่างสำหรับวิธีการทำ) แต่ถ้าพวกเขาดึงบางสาขาและตอนนี้ต้องการให้มันสะอาด (และไม่ "ล่วงหน้า" ของ แหล่งกำเนิด / บางสาขา) จากนั้นคุณก็:

git checkout some-branch   # where some-branch can be replaced by any other branch
git branch base-branch -D  # where base-branch is the one with the squashed commits
git checkout -b base-branch origin/base-branch  # recreating branch with correct commits

หมายเหตุ: คุณสามารถรวมสิ่งเหล่านี้ทั้งหมดโดยใส่ && ระหว่างพวกเขา

Note2: Florian พูดถึงสิ่งนี้ในความคิดเห็น แต่ใครเป็นคนอ่านความคิดเห็นเมื่อมองหาคำตอบ?

Note3: หากคุณมีกิ่งที่ปนเปื้อนคุณสามารถสร้างสาขาใหม่โดยอิงจาก "สาขาใบ้" ใหม่และเพียงเลือกเชอร์รี่

Ex:

git checkout feature-old  # some branch with the extra commits
git log                   # gives commits (write down the id of the ones you want)
git checkout base-branch  # after you have already cleaned your local copy of it as above
git checkout -b feature-new # make a new branch for your feature
git cherry-pick asdfasd   # where asdfasd is one of the commit ids you want
# repeat previous step for each commit id
git branch feature-old -D # delete the old branch

ตอนนี้ฟีเจอร์ใหม่คือสาขาของคุณที่ไม่มีข้อผูกพันพิเศษ


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

@ peter-mortensen การแก้ไขควรเป็นเรื่องสำคัญตามstackoverflow.com/help/editing
Tom Prats

สำหรับขั้นตอนสุดท้ายคุณสามารถใช้git checkout -b base-branch origin/base-branchกับgit checkout --track origin/base-branch
bluesmonk

2

ดึงด้วย rebase

การดึงแบบปกติคือการดึงข้อมูล + ผสาน แต่สิ่งที่คุณต้องการคือการดึงข้อมูล + การรีบูต นี่คือตัวเลือกที่มีpullคำสั่ง:

git pull --rebase

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