วิธีการลบคอมมิทแรกในคอมไพล์?


179

ฉันอยากรู้เกี่ยวกับวิธีการลบความมุ่งมั่นแรกในคอมไพล์

การแก้ไขก่อนที่จะกระทำอะไร? การแก้ไขนี้มีชื่อหรือแท็กหรือไม่?


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

@Shahbaz ใช่นั่นเป็นวิธีที่ดีที่สุดลองดูตัวอย่าง: ariejan.net/2011/07/05/git-squash-your-latests-commits-into-one
timaschew

5
git rebase -i --rootคุณสามารถใช้ ดูคำตอบ SO ต่อไปนี้สำหรับรายละเอียด: stackoverflow.com/questions/2246208/…
MKroehnert


คำตอบนี้มีทางออกที่ถูกต้องในการลบการกระทำของสาขาปัจจุบัน:git filter-branch --parent-filter "sed 's/-p <the_commit>//'" HEAD
Jody Bruchon

คำตอบ:


320

สำหรับฉันวิธีที่ปลอดภัยที่สุดคือการใช้update-refคำสั่ง:

git update-ref -d HEAD

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

หากสิ่งที่คุณต้องการคือการรวมการคอมมิทครั้งแรกกับคอมมิชชันที่สองคุณสามารถใช้rebaseคำสั่ง:

git rebase -i --root

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

git checkout --orphan <new-branch-name>

7
มันแย่มากที่นี่ไม่ใช่คำตอบที่ยอมรับ มันก็แย่เกินไปที่ความนิยมสูงสุดบน google มากขึ้นหรือน้อยลงก็พูดว่า "คุณไม่สามารถยกเลิกการกระทำแรกได้" นี้ได้เคล็ดลับสำหรับฉัน. ขอบคุณ!
danielpops

1
ขอบคุณ @danielpops สำหรับการสนับสนุนของคุณ! เป็นการดีที่จะสังเกตว่าฉันตอบคำถามนี้ 3 ปีต่อมา Git ได้วิวัฒนาการในระหว่างนี้
59

ฉันใช้การ rebase ทำเครื่องหมายการกระทำที่สองว่า "สควอช" จากนั้นจึงกด --force เพื่อเริ่มต้น ขอบคุณ!
Philip Atz

1
git update-ref -d HEAD เป็นวิธีที่ปลอดภัยที่สุดในการลบประวัติทั้งหมดไม่ใช่แค่การคอมมิทเริ่มต้น
user1767316

ฉันทำและลบไฟล์ทั้งหมดที่ฉันเพิ่มไปในการส่งครั้งแรก เสียใจ อย่างน้อยก็ไม่มากนัก
Vyacheslav Tsivina

42

ไม่มีอะไรเกิดขึ้นก่อนการคอมมิชชันแรกเนื่องจากการคอมมิชชันทุกครั้งจะอ้างถึงการคอมมิชชันหลัก สิ่งนี้ทำให้การกระทำพิเศษครั้งแรก (การให้กำเนิดเด็กกำพร้า) ดังนั้นจึงไม่มีวิธีการอ้างถึง "รัฐ" ก่อนหน้านี้

ดังนั้นหากคุณต้องการแก้ไขการคอมมิชชันคุณสามารถทำได้ง่ายๆgit commit --amend: สิ่งนี้จะแก้ไขการคอมมิทโดยไม่ต้องสร้างคอมมิท

หากคุณต้องการเริ่มต้นใหม่ให้ลบที่.gitเก็บและสร้างที่เก็บอื่นgit init


7
คำตอบนี้ไม่ถูกต้อง: มีวิธีการกลับสู่สถานะก่อนที่จะยอมรับครั้งแรก ดูคำตอบของ tziด้านล่าง
เดวิดเนลสัน

2
และ--amendจะไม่อัปเดตผู้แต่งอย่างถูกต้องหากเริ่มมีการกำหนดค่าผิดพลาด นั่นคือสิ่งที่ฉันต้องการดังนั้นฉันจึงใช้คำตอบที่ได้รับการยอมรับจากนั้นก็ใช้คำสั่งใหม่แทน
Mark Edington

11
# Check out to a temporary branch:
git checkout --orphan TEMP_BRANCH

# Add all the files:
git add -A

# Commit the changes:
git commit -am "Initial commit"

# Delete the old branch:
git branch -D master

# Rename the temporary branch to master:
git branch -m master

# Finally, force update to our repository:
git push -f origin master

3
ไม่ใช่คำตอบ:คำถามนี้คือ "วิธีลบการส่งครั้งแรก" และไม่ใช่ "วิธีลบทุกอย่างยกเว้นการส่งครั้งสุดท้าย"
peterh - Reinstate Monica

1
ฉันกำลังมองหาสิ่งนี้อย่างแน่นอน ขอบคุณ!
Krzysztof Tomaszewski

6

คุณอาจต้องการแก้ไขการมอบหมายครั้งแรกของคุณ (เนื่องจากมีการกระทำครั้งแรกใน repo คอมไพล์) พิจารณาใช้แทนปกติgit commit --amend --reset-authorgit commit --amend


1
ไม่ใช่คำตอบ:คำถามต้องการลบการส่งครั้งแรกและไม่แก้ไขคุณสมบัติของรายการสุดท้าย
peterh - Reinstate Monica

@ peterh-ReinstateMonica เพื่อความกระจ่าง: การมอบหมายสามารถแก้ไขได้ในระหว่างการรีบูตแบบโต้ตอบเพื่อเปลี่ยนเนื้อหาของพวกเขาอย่างสมบูรณ์ แต่ - ต้องมีการตั้งค่าผู้เขียนเพื่อเปลี่ยนแปลงผู้เขียนเช่นกัน ด้วยสิ่งนี้คุณสามารถแทนที่การกระทำแรกที่คุณชอบได้อย่างสมบูรณ์ ดูคำตอบของ CharlesB
Max Beikirch

3

ฉันกำลังมองหาวิธีที่จะเลิกคอมไพล์ทั้งหมดจาก repo เหมือนที่พวกเขาไม่เคยเกิดขึ้น

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

ไม่มีคำตอบใดที่แก้ไขได้สำหรับฉัน แต่หลังจากการค้นหาและลองผิดลองถูกมากมายฉันพบว่ามันใช้งานได้!

git update-ref -d HEAD
git push origin master -f

หวังว่านี่จะช่วยคุณได้ ขอให้มีความสุขมาก ๆ ในวันนี้นะ


1
เพื่อความชัดเจนสำหรับทุกคนที่อ่านคำตอบนี้:เป็นการลบทุกการกระทำ แต่ OP ต้องการลบการส่งคำสั่งแรกที่ทำกับ repo เท่านั้น อย่าเรียกใช้สิ่งนี้เพื่อลบคอมมิชชันแรกเพราะมันจะลบคอมมิททั้งหมด
Jody Bruchon

2

อีกวิธีที่คุณสามารถทำได้คือ:

  1. ชำระเงินไปยังสาขาที่คุณต้องการเก็บไว้ (พูด dev) git checkout dev
  2. ตอนนี้ลบสาขาที่คุณต้องการรีเซ็ต git branch -D master
  3. ตอนนี้สร้างสาขาที่ว่างเปล่าที่มีชื่อเดียวกัน git checkout --orphan master

แน่นอนทั้งหมดนี้จะขึ้นอยู่กับกรณีของคุณ แต่ถ้าคุณมีสาขามากกว่าหนึ่งการลบ.gitไดเรกทอรีจะไม่สมเหตุสมผล


3
หลังจากทำเช่นนี้คุณจะต้องลบสาขาในระยะไกลก่อนที่จะผลักดัน มิฉะนั้นเมื่อพยายามผลักคุณจะได้รับข้อผิดพลาดนี้:! [ปฏิเสธ] master -> master (ไม่ใช่ไปข้างหน้าอย่างรวดเร็ว) - ข้อผิดพลาด: ล้มเหลวในการผลักดันการอ้างอิงถึง 'git@github.com: r1 / r2.git' - คำใบ้: อัปเดตถูกปฏิเสธเนื่องจากส่วนท้ายของสาขาปัจจุบันของคุณคือ เบื้องหลัง - คำใบ้: คู่หูที่ห่างไกล รวมการเปลี่ยนแปลงระยะไกล (เช่นคำใบ้: 'git pull ... ') ก่อนที่จะผลักอีกครั้ง ... - ถ้าคุณทำการดึง git ทั้งหมดที่คอมมิทจะกลับมา
dxvargas

2

หากคุณต้องการเก็บสาขาอื่น แต่ให้ทำให้masterสาขาเริ่มต้นใหม่โดยไม่มีประวัติทั่วไปไปยังสาขาอื่นวิธีที่ปลอดภัยอย่างหนึ่งในการบรรลุเป้าหมายคือสร้างพื้นที่เก็บข้อมูลใหม่และผลักดันเนื้อหาของสาขาเดิม:

cd ..
git init newrepo
cd newrepo
# make some initial commits
git push ../oldrepo master:newmaster

สิ่งนี้จะสร้างnewmasterสาขาในที่เก็บเก่าโดยมีประวัติที่ไม่เหมือนสาขาอื่น ๆ แน่นอนคุณสามารถเขียนทับได้masterเช่นกันด้วยgit push -fเป็นอย่างดีกับ

หากคุณต้องการทำลายทุกสาขาและเนื้อหาที่มีอยู่ทั้งหมดจากนั้นเพียงแค่เรียกใช้

rm -rf .git/

1
ไม่ใช่คำตอบ: OP ต้องการลบการคอมมิทครั้งแรกและไม่เริ่ม repo คอมไพล์ใหม่ด้วยแผนผังการทำงานปัจจุบันเป็นคอมมิทเริ่มต้น
peterh - Reinstate Monica

@ peterh ฉันเห็นด้วยgit rebase --rootน่าจะเป็นสิ่งที่ OP ต้องการ แต่การพิจารณาคำตอบนี้มีสอง upvotes ฉันจะละเว้นจากการลบในกรณีที่บางคนยังพบว่ามีความเกี่ยวข้อง
user1338062

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

0

หากคุณเพิ่งส่งไปแล้ว แต่ไม่ได้ผลักมันก็แค่ลบไดเรกทอรี. gitและgit initอีกครั้ง ...


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

@ MikeBeaton คุณพูดถูก ฉันลบความคิดเห็นของฉัน แต่แล้วฉันต้องลงคะแนนเพื่อปิดคำถามไม่ชัดเจน หมายเหตุแม้ว่ามีเพียงฉันเท่านั้นที่แสดงความคิดเห็น แต่ข้างหลังฉันมีผู้เข้าชม 40000 คนและส่วนสำคัญของพวกเขาพบคำถามนี้ด้วย google - และพวกเขาไม่ได้สิ่งที่ต้องการ
peterh - Reinstate Monica

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

0

คำตอบของคำถามขึ้นอยู่กับว่า:

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

  • คุณต้องการลบการส่งมอบครั้งแรกในบางสาขาในขณะที่ 'ออกไปแทน' การกระทำที่ตามมา (และสาขาอื่น ๆ )

ที่สองของเหล่านี้ค่อนข้างง่าย คุณจำเป็นต้องลดระดับราก - คำตอบส่วนใหญ่เกี่ยวกับวิธีการทำเช่นนี้

ในการทำสิ่งที่สอง (การลบสิ่งแรกและสิ่งเดียวที่กระทำได้จากสาขาในขณะที่ออกจากสาขาอื่น ๆ เพียงอย่างเดียว) นั้นยากกว่า หรืออย่างน้อยโดยเฉพาะอย่างยิ่งยากขึ้นหากคุณต้องการให้มันเกิดขึ้นและเพื่อให้การเปลี่ยนแปลงสะท้อนกลับใน GitHub หรือ Bitbucket มี (เท่าที่ฉันสามารถบอกได้) ไม่มีทางเลยใน Git ที่จะผลักดันหรือบังคับให้ดันสาขาที่ไม่มีข้อผูกมัด และยังมีอีก (เท่าที่ฉันเห็น) ไม่มีทางที่จะสร้างสาขาใหม่ที่ว่างเปล่าโดยไม่มีข้อผูกมัดใน GitHub หรือ Bitbucket ดังนั้นคุณจำเป็นต้องสร้างพื้นที่เก็บข้อมูลใหม่เพื่อสร้างสาขาที่ว่างเปล่าโดยสมบูรณ์แล้วเพิ่มสาขาที่คุณต้องการ (รวมถึงคอมมิทที่คุณต้องการ) - ตามคำตอบของ @ user1338062

ดังนั้นฉันหวังว่าคำตอบนี้จะอธิบายสิ่งที่อาจไม่ชัดเจน - ว่ามีสองวิธีที่แตกต่างกันที่ต้องดำเนินการสำหรับสถานการณ์ที่แตกต่างกัน (มากหรือน้อยกว่านั้น) สองสถานการณ์ซึ่งเป็นทั้งสองสิ่งที่คุณอาจต้องการทำตามลำดับ เพื่อทำสิ่งที่ OP ต้องการอย่างเต็มที่

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