อะไรคือความแตกต่างระหว่าง "squash" และ "fixup" ใน Git / Git Extension


112

ฉันใช้Git Extensions มาระยะหนึ่งแล้ว (มันยอดเยี่ยมมาก!) แต่ฉันไม่พบคำตอบง่ายๆสำหรับสิ่งต่อไปนี้:

บางครั้งเมื่อพิมพ์ข้อความคอมมิตจะพิมพ์ผิด เพื่อนของฉันแสดงวิธีแก้ไขด้วยวิธีต่อไปนี้ (ใน Git Extentions):

คลิกขวาที่คอมมิต> ขั้นสูง> Fixup คอมมิต

ใส่คำอธิบายภาพที่นี่

จากนั้นฉันก็ทำเครื่องหมายในช่อง "แก้ไข" และเขียนข้อความของฉันและ voila ใหม่! ข้อความยืนยันของฉันได้รับการแก้ไข

อย่างไรก็ตามตัวเลือกอื่น "สควอชกระทำ" ... ฉันสงสัยมาตลอดว่ามันทำอะไร?!

คำถามของฉันคือ:

หากว่าใครบางคนเพียงแค่อธิบายให้ฉันสิ่งที่เป็นความแตกต่างที่แน่นอนระหว่างสควอชกระทำและFixup กระทำในGit / Git Extentions ? พวกเขาดู ... "คล้าย"กับฉัน: ใส่คำอธิบายภาพที่นี่ ใส่คำอธิบายภาพที่นี่

คำตอบ:


153

ฉันไม่รู้ว่า Git Extensions ทำอะไรกับมันโดยเฉพาะ แต่git rebaseมีตัวเลือกในการสควอชหรือแก้ไขโดยอัตโนมัติด้วยสควอช! หรือแก้ไข! คำนำหน้าตามลำดับ:

   --autosquash, --no-autosquash
       When the commit log message begins with "squash! ..." (or "fixup!
       ..."), and there is a commit whose title begins with the same ...,
       automatically modify the todo list of rebase -i so that the commit
       marked for squashing comes right after the commit to be modified,
       and change the action of the moved commit from pick to squash (or
       fixup).

ความแตกต่างระหว่างสควอชและฟิกซ์อัพคือในระหว่างการรีเบสการsquashดำเนินการจะแจ้งให้คุณรวมข้อความของสควอชต้นฉบับและสควอชคอมมิตในขณะที่การfixupดำเนินการจะเก็บข้อความเดิมไว้และทิ้งข้อความจากฟิกซ์อัพคอมมิต


6
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับrebaseสควอช / fixup ที่เอกสาร Git

นี่คือคำตอบที่ยอดเยี่ยม สงสัยเสมอว่าทำไมฉันถึงได้รับข้อความคอมมิตแบบผสม
jedd.ahyoung

67

พูดง่ายๆก็คือเมื่อ rebasing ชุดของคอมมิตแต่ละคอมมิตที่ทำเครื่องหมายเป็น a squashจะเปิดโอกาสให้คุณใช้ข้อความนั้นเป็นส่วนหนึ่งของข้อความpickหรือคอมrewordมิต

เมื่อคุณใช้fixupข้อความจากคอมมิตนั้นจะถูกละทิ้ง


ข้อความใดถูกเก็บไว้ในfixupตอนนั้น?
IgorGanapolsky

2
@IgorGanapolsky ข้อความจากการกระทำต่อไปในแผนผังคอมไพล์ โดยพื้นฐานแล้วคุณ "รวม" การกระทำของคุณเข้ากับมัน
Alexander Haroldo da Rocha

15

จากgit-rebase doc ส่วน "โหมดโต้ตอบ" :

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


13

ถ้าคำถามคือสิ่งที่แตกต่างระหว่างsquashและfixupในคอมไพล์เมื่อทำคอมไพล์ rebase --interactiveแล้วคำตอบคือกระทำข้อความ

s, squash <commit> = ใช้การกระทำ แต่รวมเข้ากับการกระทำก่อนหน้านี้

f, fixup <commit>= เช่น "สควอช" แต่ทิ้งข้อความบันทึกของคอมมิตนี้


ตัวอย่างเช่น:

pick 22a4667 father commit message
squash 46d7c0d child commit message # case 1
# fixup 46d7c0d child commit message # case 2

กระทำข้อความหลังจาก rebasing ในกรณีที่ 1จะเป็น:

father commit message

child commit message

ในขณะที่ข้อความคอมมิตในกรณีที่ 2 คือ:

father commit message
# no sub messages

1

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

git rebase -i Head~2

นี่คือ rebase แบบโต้ตอบและโปรดสังเกตสิ่งต่อไปนี้:

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

โพสต์ที่คุณลิงก์เป็นคำอธิบายที่ชัดเจนที่สุดที่ฉันเคยเห็นเกี่ยวกับสควอชและฟิกซ์อัพ ขอบคุณ!
Simon Tewsi

0

ทำไมไม่ถาม git ตัวเอง? เมื่อคุณตั้งฐานgit-bashใหม่มันจะบอกว่า:

pick 512b1d7 (some comment)
# Rebase 621b2e4..512b1d7 onto 621b2e4 (1 command)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
D:/code/fenixito-legacy-api/.git/rebase-merge/git-rebase-todo [unix] (11:57 23/10/2019)                                         1,1 start
"D:/code/xxx/.git/rebase-merge/git-rebase-todo" [UNIX] 27L, 1170C

คุณจะเห็น:

s, squash = ใช้การกระทำ แต่รวมเข้ากับการกระทำก่อนหน้านี้

f, fixup = like "squash" แต่ทิ้งข้อความบันทึกของการกระทำนี้

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