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

uatthaphon

Atthaphon Urairat

Posted on July 2, 2019

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 ไว้ดีกว่าครับ

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

💖 💪 🙅 🚩
uatthaphon
Atthaphon Urairat

Posted on July 2, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related