天天看點

Git如何修改曆史的Commit資訊

作者:程式猿凱撒
Git如何修改曆史的Commit資訊

最近由于一行單元測試代碼沒有寫 Assert 斷言,導緻了項目在 CI 過程中沒有通過,于是遭到了某位同僚的吐槽,在修改我的代碼後寫上了一句送出資訊。

Git如何修改曆史的Commit資訊

我想,做為技術人,修改這條 Commit 資訊還是不難的,于是我通過本文介紹的技巧完成了修改,效果如下:

Git如何修改曆史的Commit資訊

其實修改曆史送出資訊很簡單。

一、找到該 Commit 前一條的 Commit ID

例如目前有 3 條送出,使用 git log 檢視。

yaml複制代碼commit 0a4549598e56b53395c562e784553d863ec597c1
Author: 張三 <[email protected]>
Date:   Fri Jun 16 12:25:34 2023 +0800
   fix: 正常的送出資訊1

commit e0871dfb91f6a0acc5298d9e1960291629479a46
Author: 李四 <[email protected]>
Date:   Fri Jun 16 12:20:08 2023 +0800
   fix: fucking the code

commit e7dc6e4d1001ecff3c1000f82ffffe06859fad61
Author: 張三 <[email protected]>
Date:   Thu Jun 15 14:32:49 2023 +0800
   fix: 正常的送出資訊2
           

我們要修改的 Commit 是第二條,于是我們要找的前一條 Commit ID 就是 e7dc6e4d1001ecff3c1000f82ffffe06859fad61。

二、git rebase -i 指令

然後執行 git rebase -i e7dc6e4d1001ecff3c1000f82ffffe06859fad61,會得到下面的内容:

yaml複制代碼pick e0871dfb91f6a0acc5298d9e1960291629479a46 fix: fucking the code
pick 0a4549598e56b53395c562e784553d863ec597c1 fix: 正常的送出資訊1

# ...
           

找到需要修改的 commit 記錄,把 pick 修改為 edit 或 e,:wq 儲存退出。也就是:

yaml複制代碼edit e0871dfb91f6a0acc5298d9e1960291629479a46 fix: fucking the code
pick 0a4549598e56b53395c562e784553d863ec597c1 fix: 正常的送出資訊1

# ...
           

三、修改 commit 的具體資訊

執行 git commit --amend,會得到下面的内容:

makefile複制代碼fix: fucking the code

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Fri Jun 16 12:20:08 2023 +0800
           

修改文本内容:

makefile複制代碼fix: fucking me

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Fri Jun 16 12:20:08 2023 +0800
           

儲存并繼續下一條git rebase --continue,直到全部完成。接着執行 git push -f 推到遠端,當然這需要有 Maintainer 權限。

接下來再檢視送出日志,git log:

yaml複制代碼commit 0a4549598e56b53395c562e784553d863ec597c1
Author: 張三 <[email protected]>
Date:   Fri Jun 16 12:25:34 2023 +0800
   fix: 正常的送出資訊1

commit e0871dfb91f6a0acc5298d9e1960291629479a46
Author: 李四 <[email protected]>
Date:   Fri Jun 16 12:20:08 2023 +0800
   fix: fucking me

commit e7dc6e4d1001ecff3c1000f82ffffe06859fad61
Author: 張三 <[email protected]>
Date:   Thu Jun 15 14:32:49 2023 +0800
   fix: 正常的送出資訊2
           

修改完成!不過要提醒的是:技巧慎用他途。

四、總結一下 git rebase 指令

對于 git rebase 指令,官方文檔 是這樣介紹的:允許你在另一個基礎分支的頭部重新應用送出。

git-rebase - Reapply commits on top of another base tip

使用方法:

Git如何修改曆史的Commit資訊

我們在執行 git rebase -i 之後,注釋裡已經給出了所有的用法:

ini複制代碼# Rebase 29fc076c..db0768e3 onto 29fc076c (3 commands)
#
# 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
# b, break = stop here (continue rebase later with 'git rebase --continue')
# 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.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
           

歸納一下:

指令 縮寫 含義
pick p 保留該commit
reword r 保留該commit,但需要修改該commit的注釋
edit e 保留該commit, 但我要停下來修改該送出(不僅僅修改注釋)
squash s 将該commit合并到前一個commit
fixup f 将該commit合并到前一個commit,但不要保留該送出的注釋資訊
exec x 執行shell指令
drop d 丢棄該commit

繼續閱讀