ฉันจะบังคับให้ git pull เขียนทับทุกอย่างบน pull ทุกครั้งได้อย่างไร


203

ฉันมีที่เก็บข้อมูลส่วนกลาง CENTRAL ที่มีที่เก็บนักพัฒนาซอฟต์แวร์สามแห่งที่ดึงและผลักดันตามปกติ

ฉันยังมีที่เก็บอื่นอีกสองแห่งที่ดึงมาจาก CENTRAL bare repo: หนึ่งคือเซิร์ฟเวอร์สดและอีกอันคือเซิร์ฟเวอร์ทดสอบ / สเตจ - แต่ละอันดึงจากสาขาของตนเอง

สถานการณ์นี้คือ: ฉันมีpost-updateเบ็ดสคริปต์บน repo CENTRAL ที่เข้าถึงการทดสอบและ repos สดโดยอัตโนมัติและเรียกใช้คำสั่งดึงในแต่ละ การอัปเดตนี้จะทดสอบทั้งเซิร์ฟเวอร์ทดสอบและเซิร์ฟเวอร์จริงทั้งนี้ขึ้นอยู่กับว่าสาขาใดมีคอมมิทใหม่ ทั้งหมดนี้ใช้งานได้ดี

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

สิ่งที่ฉันต้องการที่จะมีเกิดขึ้นคือ: ฉันต้องการดึงจากเว็บไซต์ที่อยู่อาศัยและการทดสอบเพื่อเสมอเขียนทับ / ผสานดึง เสมอ. repos เหล่านี้จะถูกดึงอย่างเดียวเนื่องจากไม่ใช่เพื่อการพัฒนา

ในการวิจัยทั้งหมดของฉันฉันไม่สามารถหาทางออกที่ดีในการดึงเสมอบังคับให้เขียนทับไฟล์ท้องถิ่น เป็นไปได้ไหม? มันจะทำให้สถานการณ์การพัฒนาที่ดีถ้าเป็นเช่นนั้น


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

1
@Novelocrat ใช่ฉันเข้าใจสิ่งที่คุณพูด น่าเสียดายที่มีหลายสถานการณ์ที่บางคนสามารถอัปโหลดไฟล์ไปยังเซิร์ฟเวอร์ได้โดยตรง ในกรณีนั้นฉันจะต้องเรียกใช้คำสั่งจำนวนมากเพื่อซิงค์ repos อีกครั้ง ก่อนหน้านี้เราใช้สคริปต์ FTP เพื่อย้ายไฟล์จาก repo ไปยังเซิร์ฟเวอร์ วิธีการที่นำเสนอข้างต้นจะเป็นการกำจัดขั้นตอน FTP ซึ่งได้ผลดีมากในอดีต
bmilesp

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

คำตอบ:


510

จริงๆแล้ววิธีที่เหมาะในการทำเช่นนี้คือไม่ควรใช้pullเลย แต่แทนfetchและreset:

git fetch origin master
git reset --hard FETCH_HEAD
git clean -df

(แก้ไขmasterสาขาที่คุณต้องการติดตาม)

pullถูกออกแบบมาเพื่อผสานการเปลี่ยนแปลงเข้าด้วยกันในบางวิธีในขณะที่resetออกแบบมาเพื่อทำให้สำเนาในเครื่องของคุณตรงกับคำสั่งเฉพาะ

คุณอาจต้องการพิจารณาตัวเลือกที่แตกต่างกันเล็กน้อยcleanขึ้นอยู่กับความต้องการของระบบของคุณ


3
@ user730569 reset --hardเป็นคำสั่งที่ใช้ในการบังคับให้สถานะของไดเรกทอรีทำงาน (และสาขาปัจจุบัน) ไปยังสถานะที่ตรงกับการกระทำที่เฉพาะเจาะจง
แอมเบอร์

25
FETCH_HEADคือการอ้างอิงที่สร้างขึ้นโดยอัตโนมัติfetchเพื่อแสดงการอ้างอิงที่ดึงมา มันไม่ได้ถูกรวมเพียงแค่เขียนทับตรงเมื่อใดก็ตามที่คุณทำการดึงข้อมูล cleanเป็นคำสั่งที่ลบไฟล์ที่ไม่ได้ติดตามโดยgitที่-dfธงบอกให้ลบไดเรกทอรี ( -d) และจริงจะกำจัด ( -f)
แอมเบอร์

4
เหตุใดจึงไม่มีคำหลักสำหรับสิ่งนี้ ฉันต้องการสิ่งนี้บ่อยกว่าการดึง
Wolfgang Fahl

14
คุณอาจต้องการใช้git clean -dnก่อนใช้git clean -dfดังนั้นคุณจะเห็นว่าไฟล์ / โฟลเดอร์ใดที่จะถูกลบ git clean -dfสามารถกลับรายการได้หากคุณมีข้อมูลสำรอง
Ibrahim Lawal

1
@NickMiddleweek ฉันเป็นห่วงgit clean -dfจะลบไฟล์ gitignored ด้วย แต่กลับกลายเป็นว่าจะไม่ git clean --helpกล่าวว่า "โดยปกติไฟล์ที่ไม่รู้จักกับ Git เท่านั้นที่จะถูกลบออก แต่ถ้าระบุตัวเลือก -x ไฟล์ที่ถูกละเว้นจะถูกลบด้วยเช่นนี้สามารถเป็นประโยชน์ในการลบผลิตภัณฑ์บิลด์ทั้งหมด"
nickang


6

ฉันไม่แน่ใจว่าจะทำอย่างไรในคำสั่งเดียว แต่คุณสามารถทำสิ่งที่ชอบ:

git reset --hard
git pull

หรือแม้กระทั่ง

git stash
git pull

ในการรันในคำสั่งเดียว: git reset --hard && git pull. อีกวิธีหนึ่ง แต่ไม่ดีกว่าgit reset --hard; git pull. การใช้&&จะเรียกใช้คำสั่งที่สองก็ต่อเมื่อคำสั่งแรกประสบความสำเร็จ ;จะเรียกใช้โดยไม่คำนึงถึงรหัสออกจากคำสั่งแรก
mazunki

5

ในการดึงสำเนาของสาขาและบังคับให้เขียนทับไฟล์ในเครื่องจากแหล่งกำเนิดให้ใช้:

git reset --hard origin/current_branch

งานปัจจุบันทั้งหมดจะสูญหายและจะเหมือนกันกับสาขาต้นทาง



2

คุณสามารถเปลี่ยนตะขอเพื่อล้างทุกอย่างให้สะอาด

# Danger! Wipes local data!

# Remove all local changes to tracked files
git reset --hard HEAD

# Remove all untracked files and directories
git clean -dfx

git pull ...

2
x ทำอะไร กรุณาอธิบายสวิตช์
Steve K

2
x ควรลบไฟล์ที่ไม่ได้ติดตามทั้งหมดฉันคิดว่า ยากที่จะบอกใน manpage พูดซึ่งเป็นเหตุผลที่เรามีดังนั้น
JosephK

2
@JosephK: ไม่ถูกต้อง วัตถุประสงค์เบื้องต้นของgit clean"การลบไฟล์ที่ไม่ได้ติดตามจากแผนผังการทำงาน" (ด้านบนของหน้า) ปกตินี้ไม่รวมถึงไฟล์ที่ไม่สนใจ แต่-xบอกว่าgit cleanจะรวมไฟล์ละเว้นเช่นกัน (ยกเว้นนี้ไม่ได้ส่งผลกระทบต่อไฟล์ละเว้นโดย-eตัวเลือก)
Dietrich Epp

2

หากคุณยังไม่ได้ทำการเปลี่ยนแปลงภายในเครื่องตั้งแต่การดึง / โคลนครั้งล่าสุดคุณสามารถใช้:

git checkout *
git pull

checkoutจะล้างการเปลี่ยนแปลงในท้องถิ่นของคุณด้วยการกระทำในท้องถิ่นครั้งสุดท้ายและ pullจะย่อไปยังที่เก็บระยะไกล

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