ฉันจะกระทบยอด HEAD ที่แยกออกมากับ Master / Origin ได้อย่างไร


1558

ฉันใหม่ที่ความซับซ้อนในการแตกแขนงของ Git ฉันมักจะทำงานในสาขาเดียวและยอมรับการเปลี่ยนแปลงและจากนั้นผลักดันให้ต้นกำเนิดระยะไกลของฉันเป็นระยะ

ที่ไหนสักแห่งเมื่อเร็ว ๆ นี้ฉันได้ทำการรีเซ็ตไฟล์บางไฟล์เพื่อให้พวกเขาหลุดพ้นจากการแสดงละครและต่อมาก็ a rebase -iเพื่อกำจัดคอมมิชชันล่าสุดในท้องถิ่น ตอนนี้ฉันอยู่ในสถานะที่ฉันไม่ค่อยเข้าใจ

ในพื้นที่ทำงานของฉันgit logแสดงสิ่งที่ฉันคาดหวัง - ฉันอยู่บนรถไฟที่ถูกต้องพร้อมกับความมุ่งมั่นที่ฉันไม่ต้องการจากไปและสิ่งใหม่ ๆ ที่นั่น ฯลฯ

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

ฉันคิดว่า "master / origin" แยกออกจาก HEAD แต่ฉันไม่ชัดเจน 100% ในสิ่งที่หมายถึงวิธีดูภาพด้วยเครื่องมือบรรทัดคำสั่งและวิธีแก้ไข


คุณเคยผลักภาระก่อนที่จะทำการรีบูตไหม?
manojlds

@manojlds: ไม่แน่ใจว่าคุณหมายถึงอะไร ฉันผลักบางครั้งก่อนที่จะทำการ rebase แต่ไม่ใช่ก่อนหน้านี้ทันที
Ben Zotto

เช่นเดียวกับที่คุณทำก่อนหน้านี้มุ่งมั่นที่คุณลบใน rebase -i .. จากคำตอบของคุณฉันคิดว่าไม่
manojlds

@manojlds: ถูกต้อง ฉันฆ่าเพียงแค่การกระทำที่ล่าสุดกว่าการผลักดันล่าสุด (แม้ว่าที่ผมกล่าวถึงผมมีตั้งแต่ผลักดันเพราะผมคิดว่าทุกอย่างก็ OK)
เบน Zotto

คุณช่วยอธิบายสิ่งที่คุณทำไปได้I did a reset of some files to get them out of commit stagingไหม? ขออภัยสำหรับคำถาม :)
manojlds

คำตอบ:


2521

ก่อนอื่นมาอธิบายให้ชัดเจนว่า HEAD คืออะไรและหมายความว่าอย่างไรเมื่อถอดออก

HEAD เป็นชื่อที่เป็นสัญลักษณ์สำหรับการกระทำที่ได้ชำระเงินแล้ว เมื่อ HEAD ไม่ได้ถูกแยกออก (สถานการณ์“ ปกติ” 1 : คุณมีสาขาที่เช็คเอาท์แล้ว) HEAD จะชี้ไปที่“ ref” ของสาขาและชี้ไปที่การกระทำ หัวจึง "แนบ" กับสาขา เมื่อคุณทำการคอมมิชชันใหม่สาขาที่ HEAD ชี้ไปจะถูกอัพเดตเพื่อชี้ไปที่การคอมมิทใหม่ HEAD ติดตามโดยอัตโนมัติเนื่องจากเพิ่งชี้ไปที่สาขา

  • git symbolic-ref HEADถัวrefs/heads/master
    เฉลี่ยที่สาขาที่ชื่อว่า“ ต้นแบบ” ได้รับการชำระ
  • git rev-parse refs/heads/masterอัตราผลตอบแทน17a02998078923f2d62811326d130de991d1a95a
    ที่กระทำคือเคล็ดลับปัจจุบันหรือ "หัว" ของสาขาหลัก
  • git rev-parse HEADยังให้ผล17a02998078923f2d62811326d130de991d1a95a
    นี่คือความหมายของการเป็น“ การอ้างอิงเชิงสัญลักษณ์” มันชี้ไปที่วัตถุผ่านการอ้างอิงอื่น
    (แต่เดิม refs สัญลักษณ์ถูกนำไปใช้เป็นลิงค์สัญลักษณ์ แต่ภายหลังเปลี่ยนเป็นไฟล์ธรรมดาที่มีการตีความเพิ่มเติมเพื่อให้สามารถใช้บนแพลตฟอร์มที่ไม่มี symlink ได้)

เรามีHEAD→การrefs/heads/master→การ17a02998078923f2d62811326d130de991d1a95a

เมื่อ HEAD ถูกถอดออกมันจะชี้ไปยังการกระทำโดยตรงแทนที่จะชี้ไปทางหนึ่งผ่านทางสาขา คุณสามารถนึกถึงเฮดเดอร์เดี่ยวที่อยู่ในสาขาที่ไม่มีชื่อ

  • git symbolic-ref HEAD ล้มเหลวด้วย fatal: ref HEAD is not a symbolic ref
  • git rev-parse HEADถัวเฉลี่ย17a02998078923f2d62811326d130de991d1a95a
    เนื่องจากมันไม่ใช่การอ้างอิงเชิงสัญลักษณ์มันจะต้องชี้ไปที่การยอมรับโดยตรง

เรามีHEAD17a02998078923f2d62811326d130de991d1a95a

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

1 การทำงานแบบ“ ปกติ” อย่างสมบูรณ์แบบด้วยหัวเดี่ยวคุณต้องติดตามสิ่งที่คุณกำลังทำเพื่อหลีกเลี่ยงการตกปลาที่หลุดออกจากการอ้างอิง


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

ในการกู้คืนจากสถานการณ์ของคุณคุณควรสร้างสาขาที่ชี้ไปที่การกระทำที่ชี้ไปในขณะนี้โดยหัวหน้าของคุณ:

git branch temp
git checkout temp

(ทั้งสองคำสั่งนี้สามารถย่อเป็นgit checkout -b temp)

สิ่งนี้จะแนบหัวของคุณไปยังtempสาขาใหม่

ถัดไปคุณควรเปรียบเทียบการกระทำปัจจุบัน (และประวัติ) กับสาขาปกติที่คุณคาดว่าจะทำงาน:

git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
git diff master temp
git diff origin/master temp

(คุณอาจต้องการทดลองใช้ตัวเลือกบันทึก: เพิ่ม-pออกไป--pretty=…เพื่อดูข้อความบันทึกทั้งหมด ฯลฯ )

หากtempสาขาใหม่ของคุณดูดีคุณอาจต้องการอัปเดต (เช่น) masterเพื่อชี้ไปที่:

git branch -f master temp
git checkout master

(ทั้งสองคำสั่งนี้สามารถย่อเป็นgit checkout -B master temp)

จากนั้นคุณสามารถลบสาขาชั่วคราว:

git branch -d temp

ในที่สุดคุณอาจต้องการที่จะผลักดันประวัติศาสตร์ที่ตีพิมพ์ซ้ำ:

git push origin master

คุณอาจจำเป็นต้องเพิ่ม--forceที่ส่วนท้ายของคำสั่งนี้เพื่อผลักดันหากสาขาระยะไกลไม่สามารถ“ ส่งต่ออย่างรวดเร็ว” ไปยังการส่งมอบใหม่ (เช่นคุณทิ้งหรือเขียนใหม่การกระทำที่มีอยู่หรือเขียนประวัติเล็กน้อย)

หากคุณอยู่ระหว่างการดำเนินการรีบูตคุณควรทำความสะอาด คุณสามารถตรวจสอบว่ามี rebase .git/rebase-merge/อยู่ในขั้นตอนโดยการมองหาไดเรกทอรี คุณสามารถล้างข้อมูล rebase ที่กำลังดำเนินการได้ด้วยตนเองโดยเพียงแค่ลบไดเรกทอรีนั้น (เช่นหากคุณไม่จำวัตถุประสงค์และบริบทของการดำเนินการ rebase ที่ใช้งานอยู่) โดยปกติแล้วคุณจะใช้งานgit rebase --abortแต่นั่นเป็นการตั้งค่าพิเศษบางอย่างที่คุณอาจต้องการหลีกเลี่ยง (จะย้าย HEAD กลับไปที่สาขาดั้งเดิมและรีเซ็ตกลับไปเป็นการกระทำดั้งเดิมซึ่งจะยกเลิกการทำงานบางอย่างที่เราทำด้านบน)


6
สิ่งที่น่าสนใจจากman git-symbolic-ref: "ในอดีต.git/HEADเป็นลิงค์สัญลักษณ์ที่ชี้ไปrefs/heads/masterเมื่อเราต้องการเปลี่ยนไปใช้สาขาอื่นเราทำln -sf refs/heads/newbranch .git/HEADและเมื่อเราต้องการค้นหาสาขาที่เราเปิดเราทำได้readlink .git/HEADแต่ลิงก์สัญลักษณ์ไม่สามารถเคลื่อนย้ายได้ทั้งหมด ดังนั้นค่าเหล่านี้จะถูกคัดค้านและการอ้างอิงเชิงสัญลักษณ์ (ตามที่อธิบายข้างต้น) จะถูกใช้โดยปริยาย "
Dmitry Minkovsky

10
ฉันเห็นด้วยกับ @AntonioSesto: สำหรับโครงการส่วนใหญ่ (แม้แต่โครงการที่ค่อนข้างใหญ่) คุณไม่จำเป็นต้องมีความซับซ้อนที่เหลือเชื่อซึ่งก็คือ Git สมองของฉันก่อกบฏด้วยสิ่งที่ชัดเจนเกินกว่าที่กำหนดไว้ ฉันไม่ต้องการมันและฉันไม่ต้องการมัน
Jasper Sprengers

36
นี่เป็นคำตอบที่ดี แต่ฉันคิดว่าไม่จำเป็นสำหรับสาขาชั่วคราว (แม้ว่าฉันมักจะใช้ตัวเอง) git branch -f master HEAD && git checkout masterคือพอ - สมมติว่าเป้าหมายของคุณคือการเก็บหัวปัจจุบันของคุณ masterแต่จะกำหนดให้เป็น เป้าหมายอื่น ๆ ก็สมเหตุสมผลและต้องขอสูตรอาหารอื่น ๆ
Adrian Ratnapala

38
ฮ่า ๆ ที่ความคิดเห็น gurning เกี่ยวกับความยาว ในขณะที่พวกเราที่เหลือเพียงแค่สแกนผ่านจนกว่าเราจะถึงบรรทัดที่ระบุว่า "การกู้คืนจากสถานการณ์ของคุณ [... ]" และไปจากที่นั่น - ในขณะที่ทำบันทึกจิตว่ามี backstory ที่มีประโยชน์อธิบายดีว่าเราสามารถอ่าน ในวันที่ฝนตก ตัวเลือกในการอ่านมากขึ้นไม่ได้ทำร้ายคุณ แต่มันไม่ยืนที่จะได้รับประโยชน์อื่น ๆ
underscore_d

5
นี่คือเหตุผลที่ฉันเกลียดคอมไพล์
โมนิก้า Heddneck

626

แค่ทำสิ่งนี้:

git checkout master

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

git checkout -b temp
git checkout -B master temp

57
นี่คือการตอบสนองที่เป็นอันตราย ผู้ที่มาถึงคำตอบนี้มีสถานะต่างกันและการตอบสนองแบบ "ทำแค่นี้เพื่อแก้ไข" ไม่ตอบคำถาม อันนี้สามารถทำลายงานได้อย่างง่ายดาย
Archonic

15
! "ปรมาจารย์ชำระเงิน git" จะทำให้การเปลี่ยนแปลงทั้งหมดสูญหายไปหากหัวหน้าที่ถอดออกไม่ได้เป็นส่วนหนึ่งของต้นแบบ !!
Tony

3
@Blauhirn คุณอาจมีการกระทำที่เช็คเอาท์ไม่ใช่สาขา สาขายังคงชี้ไปที่การกระทำแบบเดียวกัน แต่คุณอยู่ใน 'โหมด' ที่แตกต่างกัน
Daniel Alexiuc

1
git resetควรมาพร้อมกับคำเตือน "ถ้าคุณไม่รู้ว่าคุณกำลังทำอะไรให้หยุด" เพิ่งหายจากชั่วโมงแห่งความหวาดกลัวที่คิดว่าฉันต้องทำงานสัปดาห์สุดท้าย ขอบคุณ!
Opus1217

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

132

ฉันพบปัญหานี้และเมื่อฉันอ่านคำตอบที่ได้รับการโหวตสูงสุด:

HEAD เป็นชื่อที่เป็นสัญลักษณ์สำหรับการกระทำที่ได้ชำระเงินแล้ว

ฉันคิดว่า: Ah-ha! หากHEADเป็นชื่อที่เป็นสัญลักษณ์ของการชำระเงินแบบ currenlty ฉันสามารถตกลงกันได้masterโดยรีบูตโดยเทียบกับmaster:

git rebase HEAD master

คำสั่งนี้:

  1. ตรวจสอบ master
  2. ระบุพาเรนต์ของการHEADย้อนกลับไปยังจุดที่HEADแยกจากmaster
  3. เล่นการกระทำเหล่านั้นด้านบนของ master

ผลลัพธ์ที่ได้คือการกระทำทั้งหมดที่เกิดขึ้นHEADแต่ไม่ได้masterอยู่ในmasterนั้นด้วย masterยังคงเช็คเอาต์


เกี่ยวกับรีโมท:

สองคอมมิชชันที่ฉันฆ่าในการรีบูตได้รับการผลักดันและใหม่ที่คอมมิชชันภายในไม่ได้อยู่ที่นั่น

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

หลังจากที่คุณผลักดันmasterระยะไกลoriginสาขาการติดตามระยะไกลของคุณจะได้รับการปรับปรุงเพื่อให้ชี้ไปที่เดียวกันกระทำเป็นorigin/mastermaster


3
git: "ก่อนอื่นกรอกหัวเพื่อเล่นซ้ำงานของคุณทับ ... เจ้านายที่ส่งต่ออย่างรวดเร็วไปยัง HEAD" ฉัน: "ดี!"
เบนจามิน

81

ดูที่นี่สำหรับคำอธิบายพื้นฐานของการถอดหัว:

http://git-scm.com/docs/git-checkout

บรรทัดคำสั่งเพื่อให้เห็นภาพ:

git branch

หรือ

git branch -a

คุณจะได้รับผลลัพธ์เช่นด้านล่าง:

* (no branch)
master
branch1

* (no branch)แสดงให้เห็นว่าคุณอยู่ในหัวเดี่ยว

คุณอาจมาที่สถานะนี้ด้วยการทำgit checkout somecommitฯลฯ และมันจะเตือนคุณด้วยสิ่งต่อไปนี้:

คุณอยู่ในสถานะ 'ถอดหัว' คุณสามารถดูรอบ ๆ ทำการเปลี่ยนแปลงทดสอบและส่งมอบและคุณสามารถละทิ้งการกระทำใด ๆ ที่คุณทำในสถานะนี้โดยไม่กระทบสาขาใด ๆ โดยดำเนินการชำระเงินอีกครั้ง

หากคุณต้องการที่จะสร้างสาขาใหม่เพื่อรักษาความมุ่งมั่นที่คุณสร้างคุณสามารถทำได้ (ตอนนี้หรือภายหลัง) โดยใช้ -b กับคำสั่งเช็คเอาต์อีกครั้ง ตัวอย่าง:

git checkout -b new_branch_name

ตอนนี้เพื่อนำพวกเขาเข้าสู่ปรมาจารย์:

ทำgit reflogหรือเพียงแค่git logและจดบันทึกการกระทำของคุณ ตอนนี้git checkout masterและgit mergeความมุ่งมั่น

git merge HEAD@{1}

แก้ไข:

ในการเพิ่มให้ใช้git rebase -iไม่เพียง แต่สำหรับการลบ / การฆ่ายอมรับว่าคุณไม่ต้องการ แต่สำหรับการแก้ไข เพียงแค่พูดถึง "แก้ไข" ในรายการกระทำและคุณจะสามารถแก้ไขการกระทำของคุณแล้วออกgit rebase --continueไปข้างหน้า สิ่งนี้จะทำให้มั่นใจได้ว่าคุณไม่เคยมาที่ HEAD เดี่ยว


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

6
"@ {1}" ทำอะไร
ebi

35

ดึงความมุ่งมั่นของคุณออกสู่สาขาของตัวเอง

git checkout -b mynewbranchทำงานเพียงแค่

จากนั้นเรียกใช้แล้วgit logคุณจะเห็นว่าการกระทำอยู่HEADในสาขาใหม่นี้


ถ้าฉันทำสิ่งนี้จะmynewbranchแนบกับอะไรไหม
Benjohn

1
ใช่มันยึดติดกับส่วนหัวที่แยกออกจากกันซึ่งเป็นสิ่งที่ฉันต้องการ ขอบคุณ!
Benjohn

22

หากคุณมีเพียงสาขาหลักและต้องการกลับไปที่ "พัฒนา" หรือคุณลักษณะเพียงทำเช่นนี้:

git checkout origin/develop

หมายเหตุ: การตรวจสอบจากแหล่งกำเนิด / พัฒนา

คุณอยู่ในสถานะHEAD เดี่ยว คุณสามารถดูรอบ ๆ ทำการเปลี่ยนแปลงทดสอบและส่งมอบและคุณสามารถละทิ้งการกระทำใด ๆ ที่คุณทำในสถานะนี้โดยไม่กระทบสาขาใด ๆ โดยดำเนินการชำระเงินอีกครั้ง ...

แล้วก็

git checkout -b develop

มันได้ผล :)


7
สิ่งที่ได้ผลสำหรับฉันไม่ใช่ 'ต้นกำเนิดการชำระเงิน git / พัฒนา' แต่ 'การชำระเงิน git พัฒนา' การใช้ 'ต้นทาง / พัฒนา' ส่งผลให้ไม่มีการเปลี่ยนแปลงดังนั้นจึงยังคงอยู่ใน "ส่วนหัวแยกที่จุดเริ่มต้น / พัฒนา" การข้ามส่วน 'ต้นกำเนิด' แก้ไขทุกอย่าง
DrStrangepork

18

หากคุณต้องการผลักดัน HEAD ที่ดึงออกมาปัจจุบันของคุณ (ตรวจสอบgit logก่อนหน้า) ลอง:

git push origin HEAD:master

เพื่อส่ง HEAD ที่แยกออกมาของคุณไปยังสาขาหลักที่จุดเริ่มต้น หากการกดของคุณถูกปฏิเสธให้ลองgit pull origin masterก่อนเพื่อรับการเปลี่ยนแปลงจากจุดเริ่มต้น หากคุณไม่สนใจเกี่ยวกับการเปลี่ยนแปลงจากต้นกำเนิดและถูกปฏิเสธเนื่องจากคุณทำการรีบูทโดยเจตนาและคุณต้องการแทนที่ต้นกำเนิด / มาสเตอร์ด้วยสาขาที่แยกออกในปัจจุบันของคุณ - คุณอาจบังคับให้มัน ( -f) ในกรณีที่คุณสูญเสียสิทธิ์การเข้าถึงก่อนหน้านี้คุณสามารถเรียกใช้git reflogเพื่อดูประวัติจากสาขาทั้งหมด


หากต้องการกลับสู่สาขาหลักในขณะที่ทำการเปลี่ยนแปลงให้ลองคำสั่งต่อไปนี้:

git rebase HEAD master
git checkout master

ดู: Git: "ไม่ได้อยู่ที่สาขาใดในปัจจุบัน" มีวิธีง่าย ๆ ในการกลับไปที่สาขาในขณะที่รักษาการเปลี่ยนแปลงหรือไม่


2
นี่เป็นการส่งข้อผูกมัดที่แยกออกไปยังจุดเริ่มต้น / ต้นแบบ หากต้องการแนบหัวเข้ากับสาขาในพื้นที่ให้ทำดังนี้: stackoverflow.com/a/17667057/776345
Paschalis

เมื่อฉันทำสิ่งนี้ฉันจะได้รับที่เก็บนี้ถูกกำหนดค่าสำหรับ Git LFS แต่ไม่พบ 'git-lfs' บนเส้นทางของคุณ หากคุณไม่ต้องการใช้ Git LFS อีกต่อไปให้นำ hook นี้ออกโดยลบ. git / hooks / post-checkout
2568374

16

ฉันพบคำถามนี้เมื่อค้นหา You are in 'detached HEAD' state.

หลังจากวิเคราะห์สิ่งที่ฉันได้ทำเพื่อมาที่นี่เมื่อเทียบกับสิ่งที่ฉันทำในอดีตฉันค้นพบว่าฉันทำผิด

การไหลปกติของฉันคือ:

git checkout master
git fetch
git checkout my-cool-branch
git pull

ครั้งนี้ฉันทำ:

git checkout master
git fetch
git checkout origin/my-cool-branch
# You are in 'detached HEAD' state.

ปัญหาคือว่าฉันไม่ได้ตั้งใจ:

git checkout origin/my-cool-branch

ค่อนข้างมากกว่า:

git checkout my-cool-branch

การแก้ไข (ในสถานการณ์ของฉัน) เป็นเพียงการเรียกใช้คำสั่งข้างต้นแล้วดำเนินการต่อ:

git checkout my-cool-branch
git pull

11

ต่อไปนี้ใช้งานได้สำหรับฉัน (ใช้เฉพาะสาขาหลัก):

git push origin HEAD:master
git checkout master        
git pull

อันแรกผลักหัว HEAD ที่แยกออกไปยังแหล่งกำเนิดระยะไกล

คนที่สองย้ายไปที่อาจารย์สาขา

อันที่สามกู้ HEAD ที่แนบมากับหัวหน้าสาขา

ปัญหาอาจเกิดขึ้นที่คำสั่งแรกหากการกดถูกปฏิเสธ แต่สิ่งนี้จะไม่เป็นปัญหาของหัวหน้าเดี่ยวอีกต่อไป แต่เป็นเรื่องเกี่ยวกับความจริงที่ว่า HEAD เดี่ยวไม่ได้ตระหนักถึงการเปลี่ยนแปลงระยะไกล


ไม่ทำงานฉันได้: ที่เก็บนี้ถูกกำหนดค่าสำหรับ Git LFS แต่ไม่พบ 'git-lfs' บนเส้นทางของคุณ หากคุณไม่ต้องการใช้ Git LFS อีกต่อไปให้นำ hook นี้ออกโดยลบ. git / hooks / pre-push และคุณไม่ได้อยู่ในสาขา โปรดระบุสาขาที่คุณต้องการผสาน
user2568374

11

ฉันเพิ่งพบปัญหานี้ในวันนี้และฉันค่อนข้างแน่ใจว่าฉันแก้ไขมันด้วยการทำ:

git branch temp
git checkout master
git merge temp

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


@StarShine Kenorb ซ่อมมันแล้ว ตอนนี้มันจะช่วยประหยัดการแยกของคุณมุ่งมั่นที่จะสาขาใหม่, temp, สวิตช์เพื่อ master และผสาน temp เป็นหลัก
Cees Timmerman

ฉันไม่ทราบว่าเพราะเหตุใด ppl จึง downvoting สิ่งนี้จะแก้ไขสถิติปัญหาของฉัน แต่คุณอาจต้องการรวมคำสั่งสาขาลบ temp
GlassGhost

8

หากคุณแน่ใจว่า HEAD นั้นเป็นสถานะที่ดี:

git branch -f master HEAD
git checkout master

คุณอาจไม่สามารถเริ่มต้นกำเนิดได้เนื่องจากอาจารย์ของคุณแยกจากต้นกำเนิด หากคุณแน่ใจว่าไม่มีใครใช้ repo อยู่คุณสามารถบังคับให้กด:

git push -f

มีประโยชน์มากที่สุดหากคุณอยู่ในสาขาคุณลักษณะที่ไม่มีใครใช้


6

สิ่งที่คุณต้องทำคือ 'เช็คเอาต์ git [branch-name]' โดยที่ [branch-name] เป็นชื่อของสาขาเดิมที่คุณเข้าสู่สถานะผู้นำเดี่ยว (ที่แยกจาก asdfasdf) จะหายไป

ตัวอย่างเช่นในสาขา 'dev' คุณชำระเงินการกระทำ asdfasd14314 ->

'git checkout asdfasd14314'

ตอนนี้คุณอยู่ในสถานะผู้นำเดี่ยว

'git branch' จะแสดงรายการเหมือน ->

* (detached from asdfasdf)
  dev
  prod
  stage

แต่เพื่อออกจากสถานะหัวหน้าเดี่ยวและกลับไปที่ dev ->

'git checkout dev'

จากนั้น 'git branch' จะแสดงรายการ ->

* dev
  prod
  stage

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


6

ตามที่คริสชี้ฉันมีสถานการณ์ต่อไปนี้

git symbolic-ref HEAD ล้มเหลวด้วย fatal: ref HEAD is not a symbolic ref

อย่างไรก็ตามgit rev-parse refs/heads/masterชี้ไปที่การกระทำที่ดีจากที่ฉันสามารถกู้คืนได้ (ในกรณีของฉันการกระทำครั้งสุดท้ายและคุณสามารถเห็นการกระทำนั้นโดยใช้git show [SHA]

ฉันทำสิ่งที่ยุ่งมากหลังจากนั้น แต่สิ่งที่ดูเหมือนว่าจะได้รับการแก้ไขเป็นเพียง

git symbolic-ref HEAD refs/heads/master

และติดหัวอีกครั้ง!


1
ขอบคุณ! หัวของฉันหลุดออกมา ฉันสามารถจับมันได้ถึงต้นแบบ แต่พวกเขาเพิ่งจะชี้ไปที่ความมุ่งมั่นเดียวกันมากกว่าที่จะชี้ไปที่หัวหน้าที่ชี้ไปที่ความมุ่งมั่น คำแนะนำที่ดี = D
RagingRoosevelt


4

ฉันมีปัญหานี้ในวันนี้ที่ฉันได้อัปเดต submodule แต่ไม่มีในสาขาใด ๆ ฉันได้กระทำไปแล้วดังนั้นการชำระเงินการยกเลิกการเปิดใช้งานจึงไม่ทำงาน ฉันลงเอยด้วยการหยิบเชอร์รี่ที่ศีรษะแยก ดังนั้นทันทีที่ฉันทำสัญญา (เมื่อการผลักดันล้มเหลว) ฉันทำ:

git checkout master
git cherry-pick 99fe23ab

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


3

หากคุณทำข้อผูกมัดด้านบนของหลักและเพียงต้องการ "ย้อนกลับผสาน" ที่masterนั่น (เช่นคุณต้องการที่masterจะชี้ไปที่HEAD) ซับหนึ่งจะเป็น:

git checkout -B master HEAD
  1. ที่สร้างสาขาใหม่ชื่อmasterแม้ว่ามันจะมีอยู่แล้ว (ซึ่งก็เหมือนการย้ายmasterและนั่นคือสิ่งที่เราต้องการ)
  2. สาขาที่สร้างขึ้นใหม่ถูกตั้งค่าให้ชี้ไปHEADที่ซึ่งคุณอยู่ที่ไหน
  3. สาขาใหม่จะถูกเช็คเอาท์ดังนั้นคุณจะอยู่ในmasterภายหลัง

ฉันพบว่ามีประโยชน์อย่างยิ่งในกรณีของที่เก็บย่อยซึ่งเกิดขึ้นในสถานะที่แยกออกมาค่อนข้างบ่อย


3

ฉันมีปัญหาเดียวกันและฉันได้แก้ไขมันโดยทำตามขั้นตอนต่อไปนี้

หากคุณต้องการเปลี่ยนแปลง

  1. ก่อนอื่นคุณต้องเรียกใช้git checkout masterคำสั่งเพื่อนำคุณกลับไปที่สาขาหลัก
  2. หากคุณต้องการให้การเปลี่ยนแปลงของคุณดำเนินต่อไปgit checkout -b changesและ git checkout -B master changes

หากคุณไม่ต้องการการเปลี่ยนแปลง

  1. git clean -dfการลบไฟล์ที่ไม่ได้ติดตามทุกสาขาของคุณทำงานได้

  2. จากนั้นคุณต้องล้างข้อมูลการเปลี่ยนแปลงที่ไม่จัดเก็บทั้งหมดภายในที่เก็บข้อมูลของคุณ เพื่อที่จะทำเช่นนั้นคุณจะต้องเรียกใช้git checkout --

  3. ในที่สุดคุณต้องนำสาขาของคุณกลับไปที่สาขาหลักโดยใช้git checkout masterคำสั่ง


3

สำหรับฉันมันเป็นเรื่องง่ายเหมือนการลบสาขาในพื้นที่อีกครั้งเนื่องจากฉันไม่มีข้อผูกพันในท้องถิ่นที่ฉันต้องการผลักดัน:

ดังนั้นฉันจึง:

git branch -d branchname

จากนั้นตรวจสอบสาขาอีกครั้ง:

git checkout branchname

1

เมื่อฉันพบว่าตัวเองอยู่ในสถานการณ์เมื่อปรากฎว่าฉันได้ทำการเปลี่ยนแปลงบางอย่างในขณะที่ฉันไม่ได้อยู่ในmaster(เช่นHEADแยกออกไปอยู่ด้านบนmasterและไม่มีข้อผูกมัดระหว่าง) อาจช่วย:

git stash # HEAD has same content as master, but we are still not in master
git checkout master  # switch to master, okay because no changes and master
git stash apply  # apply changes we had between HEAD and master in the first place

1

ในคำง่ายเดี่ยว HEAD หมายถึงรัฐที่คุณจะไม่ได้รับการตรวจสอบออกไปยังส่วนหัว (หรือเคล็ดลับ) ของทุกสาขา

ทำความเข้าใจกับตัวอย่าง

สาขาในกรณีส่วนใหญ่เป็นลำดับของการกระทำหลายอย่างเช่น:

Commit 1: master -> branch_HEAD (123be6a76168aca712aea16076e971c23835f8ca)

กระทำ 2: หลัก -> 123be6a76168aca712aea16076e971c23835f8ca -> branch_HEAD (100644a76168aca712aea16076e971c23835f8ca)

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

คำอธิบายเชิงทฤษฎี

ในบล็อกนี้การระบุที่เก็บ Git อย่างชัดเจนนั้นเป็นแผนผังของการกระทำโดยแต่ละคอมมิชชันชี้ไปที่บรรพบุรุษของมันพร้อมกับพอยน์เตอร์แต่ละตัวได้รับการอัพเดตและพอยน์เตอร์เหล่านี้ไปยังแต่ละสาขาจะถูกเก็บไว้ในไดเรกทอรีย่อย. git / refs แท็กจะถูกเก็บไว้ใน. git / refs / แท็กและสาขาจะถูกเก็บไว้ใน. git / refs / heads หากคุณดูไฟล์ใด ๆ คุณจะพบว่าแต่ละแท็กสอดคล้องกับไฟล์เดียวโดยมีแฮชคอมมิท 40 ตัวอักษรและดังที่อธิบายไว้ข้างต้นโดย @Chris Johnsen และ @Yaroslav Nikitenko คุณสามารถตรวจสอบข้อมูลอ้างอิงเหล่านี้ได้


0

ฉันเข้าสู่สถานะที่โง่มากฉันสงสัยว่าคนอื่นจะพบว่าสิ่งนี้มีประโยชน์ .... แต่ในกรณี

git ls-remote origin
0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b        HEAD
6f96ad0f97ee832ee16007d865aac9af847c1ef6        refs/heads/HEAD
0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b        refs/heads/master

ซึ่งในที่สุดฉันก็แก้ไขด้วย

git push origin :HEAD

0

สิ่งนี้ใช้ได้กับฉันอย่างสมบูรณ์แบบ:

1. git stashเพื่อบันทึกการดัดแปลงในเครื่องของคุณ

หากคุณต้องการยกเลิกการเปลี่ยนแปลง
git clean -df
git checkout -- .
git clean จะลบไฟล์ที่ไม่ได้ติดตามทั้งหมด (คำเตือน: ในขณะที่มันจะไม่ลบไฟล์ที่ถูกกล่าวถึงโดยตรงใน. gitignore มันอาจลบไฟล์ที่ไม่สนใจที่อยู่ในโฟลเดอร์) และ git checkout ล้างการเปลี่ยนแปลงทั้งหมด

2. git checkout masterเพื่อสลับไปที่สาขาหลัก (สมมติว่าคุณต้องการใช้หลัก)
3. git pullเพื่อดึงการส่งข้อมูลล่าสุดจากสาขาหลัก
4. git statusเพื่อตรวจสอบทุกอย่างดูดี

On branch master
Your branch is up-to-date with 'origin/master'.

0

ในกรณีของฉันฉันวิ่งgit statusและฉันเห็นว่าฉันมีไฟล์ที่ไม่ได้ติดตามในไดเรกทอรีการทำงานของฉัน

เพื่อให้การรีบูตทำงานได้ฉันต้องทำความสะอาด (เนื่องจากฉันไม่ต้องการ)


0

หากคุณกำลังใช้EGitใน Eclipse: ถือว่าคุณเป็นหัวหน้าสาขาการพัฒนาหลักของคุณ

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

หลังจากนี้คุณควรจะสามารถกลับไปที่ต้นแบบดั้งเดิม


-1

ผมมีปัญหาเดียวกัน. ฉันซ่อนการเปลี่ยนแปลงของฉันด้วย git stashและฮาร์ดรีเซ็ตสาขาในท้องถิ่นเป็นคอมมิชชันก่อนหน้า (ฉันคิดว่ามันเป็นสาเหตุ) จากนั้นก็ทำgit pullและฉันไม่ได้รับการถอดหัวในตอนนี้ อย่าลืมที่git stash applyจะเปลี่ยนแปลงของคุณอีกครั้ง


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