利用 Git fixup 和 autosquash 整理 commit

更新於 發佈於 閱讀時間約 4 分鐘
本文同步刊載於筆者個人網站:https://hhming.moe/post/git-fixup-and-autosquash/

最近在找資料的時候,偶然發現了兩個有趣的 git 指令:git commit --fixupgit rebase -i <sha> --autosquash

研究了下發現對於像我這種每次 commit 都要斤斤計較,盡可能完美的人來說非常好用,因此寫一篇筆記記錄一下用法。

說明

簡單來說,之前的我如果在 commit 之後,發現有問題的話,通常會採取下面幾種做法之一:

  1. 直接修改、add、commit,然後使用 rebase 來 squash commit
  2. git reset HEAD~ --soft 修改後重新 commit

上述兩種做法都可以在 local 整理好 commit log 再推出去,就會乾淨漂亮。缺點就是會比較麻煩,尤其是在改完其他東西 commit 後才發現,就要在 rebase 的時候調換順序來 squash,有時一個不小心可能會出現意外情況(我自己是沒碰過,畢竟 rebase 本身就有風險,使用時都要特別小心)。

而本文這次重點的 fixup 和 autosquash 就可以避免這個問題:在進行修補的時候,直接按照一般方式修改後,使用 git commit --fixup <被修補的 commit sha>,然後 push 之前使用 git rebase -i <本次操作之前沒問題的 commit sha> --autosquash 就可以了。

聽起來好像非常美好,實際使用如何呢?接著就是動手嘗試的時間了!

動手試試看

連續提交

首先開一個資料夾,然後初始化一下:

接著新增一個文字檔 a.txt:

root commit

root commit

讓我們來寫一下裡面的內容:

git fixup
raw-image

此時我們完成了 commit 但是發現打錯了,並沒有 git fixup 這個指令,因此要修正一下內容:

- git fixup

+ git commit --fixup

不過 commit 之前,先看一下我們 patch 對象 commit sha,並且加在這次 commit 指令上:

git commit --fixup=5df42ec
raw-image

如果有實際動手操作的話,應該會發現當執行 fixup commit 的時候,不會跳出編輯器,commit message 直接帶入 fixup! <patch 對象的 commit message>

接著來試試 autosquash 吧:

git rebase -i 0e5bfc8 --autosquash

此時會跳出編輯器,就和一般的互動式 rebase 一樣,唯一不同的是他在 fixup commit 那邊自動改為 fixup

互動式 rebase 畫面

互動式 rebase 畫面

直接儲存,來看看差異:

rebase fixup 後

rebase fixup 後

看起來不錯,commit log 整理的乾乾淨淨,而且還少了一次寫多餘的 commit message 的工。

跨提交

那如果是跨越一個或以上的提交,也能這樣玩嗎?我們用現在這個測試用的 repo 繼續試試看!

首先把剛剛 rebase 的指令也加上去:

加上 rebase 指令到文字檔

加上 rebase 指令到文字檔

接著回頭再修正一開始 fixup 指令中少的 =

- git commit --fixup

+ git commit --fixup=
raw-image

OK 現在我們再來執行一次相同的 rebase 指令試試看:

raw-image

可以發現 commit 的順序被自動的調換了!所以我們也不需要做什麼變更,直接儲存並執行 rebase:

raw-image

居然有衝突?原先預期應該是直接完成變基才對啊?好吧來看看發生什麼事:

raw-image

微妙……反正修一下就好對吧,還算簡單……

結果還是衝突= =

總之依樣畫葫蘆,再改一下就對了。

但是注意一點,雖然對後面 fixup! commit 來說,rebase 那行已經存在(文字檔第二行),可是在第一次解衝突的時候,那行是不該存在的!因為後面才會由第三個 commit 新增,所以記得只保留第一行(fixup 那行)就好。

跨提交一樣能完成

跨提交一樣能完成

結語

如果問我的話,因為常常使用 rebase 來壓縮 commit 或直接 reset 來整理 commit history,所以理解這項功能的使用並不難。不過如果是跨提交的情況下,對 rebase 操作不熟悉的人,使用上就比較危險一點。但這個東西確實能加快速度,省掉 patch commit message 的時間,之後有機會再來用用(但希望仍是可以盡量確認後再提交是最好的)。

最後提醒大家一點,這東西很明顯的就是 rebase 的應用,代表 commit sha 是會被變更的。如果已經推出去了,除非是只有自己在使用的分支,否則建議還是走一般的 commit 方式修正,避免其他人 pull 下來整個亂七八糟。

avatar-img
4會員
19內容數
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
hms5232的沙龍 的其他內容
本文介紹了作者使用 Rust 重寫的一個專案,目的是為了在樹梅派上取得 LAN IP,並透過 Telegram 機器人發送訊息。作者首先提到在樹梅派上使用 Python 版本時遇到的問題,之後才開始討論為什麼選擇了 Rust 重寫的理由。
最近和同事在聊天時,因為手邊剛好在操作 MySQL,無聊間想到,不知道能不能輸入 bye 來結束連線呢?實際測試了下,沒有。於是開啟了我的第一個 Rust 練習作品之路。
在開發 Rust 或是使用 Rust 編寫的 CLI 工具時,常會看見類似下方的錯誤訊息: note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace 簡單寫一下該怎麼做。
本教學文章目標為使用 GitLab Pages 來協助達成隨機分配問卷或網址入口等需求
最近在幫家裡弄網站,規畫都好了,也買了 domain。結果過幾天被女友慫恿(他還自己身先士卒的也買了一個自己喜歡的 domain)下,也買了一個自己的網域名稱,開啟個人網站之路!
轉眼間又到了 10 月,說起 10 月除了國慶連假,當然還有不可錯過的開源界活動 Hacktoberfest! 什麼是 Hacktoberfest? Hacktoberfest 是由 Hack、 October、 Festival 組合而成的單字,為 DigitalOcean 每年舉辦的全球性活動,
本文介紹了作者使用 Rust 重寫的一個專案,目的是為了在樹梅派上取得 LAN IP,並透過 Telegram 機器人發送訊息。作者首先提到在樹梅派上使用 Python 版本時遇到的問題,之後才開始討論為什麼選擇了 Rust 重寫的理由。
最近和同事在聊天時,因為手邊剛好在操作 MySQL,無聊間想到,不知道能不能輸入 bye 來結束連線呢?實際測試了下,沒有。於是開啟了我的第一個 Rust 練習作品之路。
在開發 Rust 或是使用 Rust 編寫的 CLI 工具時,常會看見類似下方的錯誤訊息: note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace 簡單寫一下該怎麼做。
本教學文章目標為使用 GitLab Pages 來協助達成隨機分配問卷或網址入口等需求
最近在幫家裡弄網站,規畫都好了,也買了 domain。結果過幾天被女友慫恿(他還自己身先士卒的也買了一個自己喜歡的 domain)下,也買了一個自己的網域名稱,開啟個人網站之路!
轉眼間又到了 10 月,說起 10 月除了國慶連假,當然還有不可錯過的開源界活動 Hacktoberfest! 什麼是 Hacktoberfest? Hacktoberfest 是由 Hack、 October、 Festival 組合而成的單字,為 DigitalOcean 每年舉辦的全球性活動,
你可能也想看
Google News 追蹤
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
更新專案的指令有: 01 `git fetch` 來對專案做「更新 Update」。 02 `git push` 來分享你對專案的「變更 Change」[3]。 03 `git remote` 來管理遠端的儲存庫。 有趣的是,fetch 這個字源於古英語的"fetan", 表示拿來,取回來的意思。
分支與合併 Branching and Merging[1] 。 這裡提供一個很有趣的說法, 就是理解「分支 Branching」最好的方式, 就是把它理解成「上下文 Context」。
今天學習Git的第二步: 基礎快照 Basic Snapshotting [1] 。 之前提到,快照在Git的意思, 是Git 會紀錄 Git 儲存庫裡面每一個檔案在提交時刻的狀態。 可以說,Git 本身就是製作與組織這些「快照」的最強工具。 透過使用快照,你可以記錄你
今天學習Git Command-Line Syntax [1] 。 Git command的 convention 為: `git [switches] <command> [<args>]` 而每一個部分的基本解釋是: - `git` 是 Git 命令的開頭 - `[s
Windows : 下載Git (git-scm.com)並按照指示安裝。 安裝完成後,你可以通過運行以下命令來確認安裝是否成功: git --version 初次設定GIT 接下來就是按照初次設定git,會需要配置你的用戶名和電子郵件地址,這些信息將被記錄在您提交的每個變更中。 git
Thumbnail
本篇文章介紹如何使用Git Bash進行版本控制操作,包括創建repository、查看狀態、歷程以及加入暫存和提交暫存等操作。透過基本的Git指令,您可以更深入地瞭解Git工具的使用方法。
※ 需要做版本備份時: git init:初始化此資料夾,由git 開始追蹤版本控制。 git add:將檔案加入到暫存區。 git commit:把暫存區的內容提交到儲存庫。 git status:查看目前所有檔案的狀態。 git log:查看過去所有commit的記錄。 ※ 需要做修
※ 簡短說明Git 和 Git Flow 是什麼?如何應用? Git 是什麼? Git是一個分散式版本控制軟體,能夠紀錄檔案的狀態變化,以及協調多個開發者之間的工作。它允許團隊成員協作編輯和管理項目的代碼庫,並且能夠追蹤文件的歷史變更、恢復到以前的版本、合併不同版本的代碼,以及解決代碼衝突等。
※ Git(四) 空的資料夾無法被加入 Git 進行版本控制,但這個資料夾如果又是很重要的資料夾,你會怎麼處理? 當空的目錄無法被加入 Git 進行版本控制時,有以下的做法可以解決: 在那個空目錄裡隨便放一個檔案就行了。 在這個資料夾中添加一個名為 .gitkeep 的空檔案,讓 Git 能
※ 關於Git (二) 請寫下從 Github 上複製一個專案下來,做一次遞交,然後推上去會用到的所有 git 指令。 複製專案(Clone) markdown-here: git clone https://github.com/adam-p/markdown-here.git 如果在訊息
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
更新專案的指令有: 01 `git fetch` 來對專案做「更新 Update」。 02 `git push` 來分享你對專案的「變更 Change」[3]。 03 `git remote` 來管理遠端的儲存庫。 有趣的是,fetch 這個字源於古英語的"fetan", 表示拿來,取回來的意思。
分支與合併 Branching and Merging[1] 。 這裡提供一個很有趣的說法, 就是理解「分支 Branching」最好的方式, 就是把它理解成「上下文 Context」。
今天學習Git的第二步: 基礎快照 Basic Snapshotting [1] 。 之前提到,快照在Git的意思, 是Git 會紀錄 Git 儲存庫裡面每一個檔案在提交時刻的狀態。 可以說,Git 本身就是製作與組織這些「快照」的最強工具。 透過使用快照,你可以記錄你
今天學習Git Command-Line Syntax [1] 。 Git command的 convention 為: `git [switches] <command> [<args>]` 而每一個部分的基本解釋是: - `git` 是 Git 命令的開頭 - `[s
Windows : 下載Git (git-scm.com)並按照指示安裝。 安裝完成後,你可以通過運行以下命令來確認安裝是否成功: git --version 初次設定GIT 接下來就是按照初次設定git,會需要配置你的用戶名和電子郵件地址,這些信息將被記錄在您提交的每個變更中。 git
Thumbnail
本篇文章介紹如何使用Git Bash進行版本控制操作,包括創建repository、查看狀態、歷程以及加入暫存和提交暫存等操作。透過基本的Git指令,您可以更深入地瞭解Git工具的使用方法。
※ 需要做版本備份時: git init:初始化此資料夾,由git 開始追蹤版本控制。 git add:將檔案加入到暫存區。 git commit:把暫存區的內容提交到儲存庫。 git status:查看目前所有檔案的狀態。 git log:查看過去所有commit的記錄。 ※ 需要做修
※ 簡短說明Git 和 Git Flow 是什麼?如何應用? Git 是什麼? Git是一個分散式版本控制軟體,能夠紀錄檔案的狀態變化,以及協調多個開發者之間的工作。它允許團隊成員協作編輯和管理項目的代碼庫,並且能夠追蹤文件的歷史變更、恢復到以前的版本、合併不同版本的代碼,以及解決代碼衝突等。
※ Git(四) 空的資料夾無法被加入 Git 進行版本控制,但這個資料夾如果又是很重要的資料夾,你會怎麼處理? 當空的目錄無法被加入 Git 進行版本控制時,有以下的做法可以解決: 在那個空目錄裡隨便放一個檔案就行了。 在這個資料夾中添加一個名為 .gitkeep 的空檔案,讓 Git 能
※ 關於Git (二) 請寫下從 Github 上複製一個專案下來,做一次遞交,然後推上去會用到的所有 git 指令。 複製專案(Clone) markdown-here: git clone https://github.com/adam-p/markdown-here.git 如果在訊息