DEV Community

Cover image for Git Rebase คอมมิทที่ push ขึ้นไปแล้ว
Atthaphon Urairat
Atthaphon Urairat

Posted on

Git Rebase คอมมิทที่ push ขึ้นไปแล้ว

วิธีง่ายๆ ในการกรุ๊ปรวมคอมมิทหลายๆ ตัวให้เป็นตัวเดียว และยังสามารถทำได้แม้ในกรณีที่เรา push คอมมิทเหล่านั้นขึ้นไปยัง git server เรียบร้อยแล้วด้วย

Git สามารถที่จะกรุ๊ปรวมคอมมิทให้กลายเป็นคอมมิทเดียวได้ด้วยคำสั่ง git rebase --interactive HEAD~[N] หรือสั้นๆ git rebase -i HEAD~[N] โดยที่ [N] คือจำนนวนคอมมิทก่อนหน้านี้

อธิบายเพิ่มเติมในส่วนของ HEAD~[N] ยกตัวอย่างง่ายๆ ในกรณีที่ตอนนี้เราอยู่ที่คอมมิทล่าสุด และถ้าหากเราต้องการกรุ๊ปรวมคอมมิทก่อนหน้านี้ 3 คอมมิท เราสามารถที่จะเพิ่มอาร์กิวเมนต์ต่อท้าย git rebase -i เพื่อที่จะนำคอมมิทก่อนหน้านี้มา 3 ตัวเพื่อนำมากรุ๊ปรวมให้เป็นคอมมิทเดียว ซึ่งเราสามารถเพิ่มอากิวเมนต์ได้โดยเพิ่มคำสั่ง HEAD~4 ต่อท้าย แต่เมื่อนับรวมกับคอมมิทล่าสุดของเราด้วยแล้วก็จะกลายเป็นว่าเราจะมีคอมมิทที่จะนำไปแก้ไขทั้งหมด 4 ตัว เพื่อให้เข้าใจได้ง่ายขึ้นเดี๋ยวเรามาลองดูโค้ดตัวอย่างกัน

ขั้นตอน 👩‍🏫

ก่อนที่เราจะทำ rebase เรามาดูคอมมิทที่เรามีกันก่อน เราสามารถเช็คคอมมิทได้จากหน้าต่างเครื่องมือช่วยอย่าง Sourcetree หรือจะใช้ command line อย่าง git log

commit 1e3399... (HEAD -> master, origin/master)
Author: Atthaphon Urairat <xxx@xxxxx.com>
Date:   Wed Jun 26 09:27:07 2019 +0700

    Completed B

commit 729dad...
Author: Atthaphon Urairat <xxx@xxxxx.com>
Date:   Wed Jun 26 09:21:11 2019 +0700

    add more option for header

commit f7375b...
Author: Atthaphon Urairat <xxx@xxxxx.com>
Date:   Wed Jun 26 09:06:29 2019 +0700

    disable cache

commit 256bbc...
Author: Atthaphon Urairat <xxx@xxxxx.com>
Date:   Wed Jun 26 08:54:46 2019 +0700

    corrected method

commit f62f5f...
Author: Atthaphon Urairat <xxx@xxxxx.com>
Date:   Tue Jun 25 18:42:33 2019 +0700

    Completed A

...

หรือถ้าหากว่าเราต้องการดู log แต่ละคอมมิทในบรรทัดเดียว เราก็สามารถเพิ่มอาร์กิวเมนต์ git log --pretty=oneline

1e3399... (HEAD -> master, origin/master) Completed B    <<< คอมมิทล่าสุด
729dad... add more option for header
f7375b... disable cache
256bbc... corrected method
f62f5f... Completed A                                    <<< คอมมิทเก่ากว่า
...

จากตัวอย่างข้างต้น ตอนนี้เราอยู่ที่คอมมิทแรก 1e3399... (HEAD -> master, origin/master) Completed B
และต้องการที่จะกรุ๊ปคอมมิทก่อนหน้านี้สามตัวถึงคอมมิทที่ชื่อ 256bbc... corrected method

ผลลัพธ์ที่เราคาดหวังไว้คือการกรุ๊ปรวมคอมมิทให้เป็นดังนี้

1e3399... (HEAD -> master, origin/master) Completed B
f62f5f... Completed A
...

นั่นคือการกรุ๊ปรวมคอมมิททั้งหมดที่อยู่ระหว่าง Completed B และ Completed A ให้เหลือเพียงคอมมิทดังตัวอย่างก่อนหน้านี้ ต่อไปเราก็มารันคำสั่งกันเลย

git rebase -i HEAD~4

คำเตือน เมื่อเรารันคำสั่งไปแล้ว ต่อจากนั้นหน้าจอก็จะเปลี่ยนเป็นตัว editor เพื่อโชว์คอมมิทที่เราต้องการจะทำการกรุ๊ปรวม แต่!! มันจะถูกแสดงออกมาในลำดับการจัดเรียงกลับหลัง ซึ่งต่างจากการรันคำสั่ง git log ของเราก่อนหน้านี้

TIP 💡 ในกรณีที่เรามีคอมมิทที่ต้องการจะกรุ๊ปรวมเยอะ และการนับคอมมิทเพื่อเอาเลขมาใส่ท้าย HEAD~ มีความยุ่งยากหรืออาจเกิดข้อผิดพลาดได้ง่าย เราก็สามารถที่จะใช้เลขคอมมิทแทนการใช้ HEAD~[N] ได้ดังนี้ git rebase -i [commit-number]

git rebase -i f62f5fd

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

pick f62f5fd corrected method            <<< คอมมิทเก่ากว่า
pick f7375bf disable cache
pick 729dad4 add more option for header
pick 1e3399c Completed B                 <<< คอมมิทล่าสุด

# Rebase f62f5fd..1e3399c onto f62f5fd (3 commands)

จากนั้นเราก็ทำการ เปลี่ยน pick เป็น squash หรือสามารถเขียนสั้นๆ s ก็ได้เพื่อทำการกรุ๊ปรวมคอมมิทจากเก่าสุดเพื่อให้รวมกับคอมมมิทล่าสุด

pick f62f5fd corrected method            <<< คอมมิทเก่ากว่า
s f7375bf disable cache
s 729dad4 add more option for header
s 1e3399c Completed B                    <<< คอมมิทล่าสุด

# Rebase f62f5fd..1e3399c onto f62f5fd (4 commands)

จากนั้นเมื่อเราทำการเซฟไฟล์แล้ว editor ก็จะพาเราไปอีกหน้าซึ่งเป็นหน้าสำหรับ commit msg ใหม่ แต่จะมีข้อความเริ่มต้นให้เราแบบด้านล่างนี้ แต่เราสามารถลบและใส่ข้อความใหม่ได้ หรือจะใช้ข้อความที่มีมาให้ก็ได้

# This is a combination of 3 commits.
# This is the 1st commit message:

corrected method

# This is the 1st commit message #2:

disable cache

# This is the 1st commit message #3:

add more option for header

# This is the 1st commit message #4:

Completed B

...

ผมจะทำการลบข้อความทั้งหมดให้เหลือเพียงคำว่า Completed B

Complete B

หลังจากทำการเซฟและออกจาก editor แล้วก็จะปรากฏข้อความแสดงความยินดี ซึ่งแสดงว่าเราทำการรวมคอมมิทให้กลายเป็นคอมมิทเดียวได้สำเร็จแล้ว 🥳🥳 ❤️🎉 (หรืออาจเป็นข้อความ ตอกย้ำก็ได้ในกรณีที่เราทำผิดพลาด 😫😫)

[detached HEAD 1bc71e4] Completed B
 Date: Wed Jun 26 08:54:46 2019 +0700
 4 files changed, 11 insertions(+), 21 deletions(-)
Successfully rebased and updated refs/heads/master

จากนั้นเราก็จะได้ คอมมิทใหม่มาซึ่งกรุ๊ปรวมคอมมิททั้งหมดที่เราได้ทำไปก่อนหน้านี้มาเป็นที่เรียบร้อยแล้ว

สุดท้ายนี้ ก็ทำการ push ขึ้นไปยัง git server ของเราอีกครั้งแบบ force push ด้วยคำสี่ง git push origin master --force

เตือน ❗️ ตั้งสติก่อนสตาร์ท เอ้ย!! โทด โทด ตั้งสติก่อน push ครับ 🤣🤣 เพราะการทำ force push มันถือว่าเป็นความเสี่ยง ดังนั้นเราควรแน่ใจกับ commit ของเรา หรืออาจสร้าง branch ไว้เป็น backup ก่อน ทำการ force push ไว้ดีกว่าครับ

วันนี้จบแล้วครับ ขอบคุณที่ติดตามอ่านจนจบครับ หวังว่าจะเป็นประโยชน์กับใครบ้างสักคนบ้างนะครับ

Discussion (1)

Collapse
reloadsweety profile image
reloadsweety

ขอบคุณครับ