git 修改倒数二个 commit
相信大家都知道 git 下面的這個命令了:
git commit --amend通過這個命令可以修改最新的 commit 提交。也就是指向當前 HEAD 的那次提交。但是,如果想修改的是倒數第二次 commit 提交而又不想驚動倒數第一次的 commit 提交,應該怎么辦呢?
git rebase 就像一塊臭豆腐,沒吃之前聞起來好臭,吃過以后發現“真香”。不過話說回來,git rebase 也算是 git 里邊的高級操作了,下來我們就來看看是怎么用它來修改倒數第二個 commit 的吧!
起因
任何東西都有個因果緣由,我寫這篇博客的原因也是。
某天,我修改了程序文件的某個功能,因為邏輯上是兩個東西,所以對這兩次修改分別提交了兩次 commit,然后 gmail 出去了,結果被 committer 指出我第一次的 commit 提交有問題,還需要進行修改,但是第二次提交應該是沒有問題的。
[root@master GitTest]# git log commit a892d9e31d85c2d37eb036d3ef89197a7bceaacb (HEAD -> master) Author: looking <looking@qq.com> Date: Mon Aug 31 21:29:24 2020 +0800nice to meet you toocommit 155cd2e87152c5f60a2421651a86690f7cd984c6 Author: looking <looking@qq.com> Date: Mon Aug 31 21:16:51 2020 +0800nice to meet youcommit 3f2061298d921378da14f4003753f1f277e67243 (origin/master) Author: looking <looking@qq.com> Date: Thu Aug 20 23:02:46 2020 +0800I am Lookingadd one line in hello.txtSigned-off-by: Lu Kaiyi <looking@qq.com>那么?現在該怎么辦?我有以下幾個選擇。
第一個選擇
git reset --hard HEAD^1
由于本地提交了兩次而且還沒有 Applied 到遠端,所以領先了遠端 2 個 commit。
[root@master GitTest]# git status On branch master Your branch is ahead of 'origin/master' by 2 commits.(use "git push" to publish your local commits)nothing to commit, working tree clean既然要修改倒數第二個 commit,那我就把 HEAD 切換過那去,修改文件,暫存文件,重新提交 commit:
[root@master GitTest]# git reset --hard HEAD^1 HEAD is now at 155cd2e nice to meet you [root@master GitTest]# vim hello.txt [root@master GitTest]# git add hello.txt [root@master GitTest]# git commit --amend這樣做似乎沒什么問題,畢竟倒數第二次 commit 的 bug 已經成功修復。但是,我倒數第一次的 commit 和對文件的修改都丟失了,現在不得不重新提交一遍,真 TMD * 蛋(心中暗暗罵了一句)。所以,這只能算是不怎么地的一個可選方案了。
第二個選擇
git reset HEAD~
你可能想,我只撤銷倒數第一次的 commit,不撤銷倒數第一次的文件修改,不還是能回到倒數第二次的 commit 去!
[root@master GitTest]# git reset HEAD~ Unstaged changes after reset: M hello.txt [root@master GitTest]# git log commit 3d879227e4fe5f1091ec431a767308edb3059e21 (HEAD -> master) Author: looking <looking@qq.com> Date: Mon Aug 31 21:16:51 2020 +0800nice to meet youcommit 3f2061298d921378da14f4003753f1f277e67243 (origin/master) Author: looking <looking@qq.com> Date: Thu Aug 20 23:02:46 2020 +0800I am Lookingadd one line in hello.txtSigned-off-by: Lu Kaiyi <looking@qq.com>但是你看下邊,commit 雖然已經撤銷了,但是文件還是被追蹤到為 modified,如果兩次是對不同文件 commit 的話其實還行(畢竟這種情況你至少可以使用 git add file 單獨添加文件到暫存區)。但是如果你倒數第二次和倒數第一次 commit 修改的是同一個文件的內容,豈不又 GG 了,畢竟現在可能沒辦法做到只 commit 文件的一部分修改(沒說太絕,怕打臉)。還有一點就是我倒數第一個 commit 提交寫的 comment 內容實在太多了,現在都沒了,我還得重新寫一遍 commit comment,還是有點不爽快:
[root@master GitTest]# git status On branch master Your branch is ahead of 'origin/master' by 1 commit.(use "git push" to publish your local commits)Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified: hello.txtno changes added to commit (use "git add" and/or "git commit -a")第三個選擇
git revert <commit-id>
git revert 是用于“反做”某一個版本,以達到撤銷該版本的修改的目的。?其特點是會新建一個 commit 來回滾之前 commit-id 的操作,可以看到?git revert <commit-id> 執行的操作是 commit-id 操作的逆操作,也就是 commit-id 做的動作,它都會反向操作一遍。這樣操作以后,你倒數第二個 commit 的提交就被撤銷了,這時候你就可以繼續修改再次提交了。
root@master ~/GitTest# git revert 72bfd90b8194b1d3537fc62a22d6776d32ae5b4b [master 780b3e0] Revert "add hello in hello.txt"1 file changed, 1 deletion(-) root@master ~/GitTest# git show commit 780b3e0044b10aa62a6459a44d4b657da76a501d (HEAD -> master) Author: looking <looking@qq.com> Date: Mon Jun 6 17:26:12 2022 +0800Revert "add hello in hello.txt"This reverts commit 72bfd90b8194b1d3537fc62a22d6776d32ae5b4b.diff --git a/hello.txt b/hello.txt index 25f7272..83585f1 100644 --- a/hello.txt +++ b/hello.txt @@ -1,4 +1,3 @@ -hellonicehello worldhello world. I am Looking當然, 如果倒數第一個 commit 的修改是基于倒數第二個 commit 基礎之上的修改,那么很可能也會沖突的,這時候就需要自己手動處理一下沖突了。?
修改沖突的文件 git add 沖突的文件 git revert --continue最好的選擇
git rebase -i HEAD~2 和 git rebase --continue
[root@master GitTest]# git log commit a892d9e31d85c2d37eb036d3ef89197a7bceaacb (HEAD -> master) Author: looking <looking@qq.com> Date: Mon Aug 31 21:29:24 2020 +0800nice to meet you toocommit 155cd2e87152c5f60a2421651a86690f7cd984c6 Author: looking <looking@qq.com> Date: Mon Aug 31 21:16:51 2020 +0800nice to meet youcommit 3f2061298d921378da14f4003753f1f277e67243 (origin/master) Author: looking <looking@qq.com> Date: Thu Aug 20 23:02:46 2020 +0800I am Lookingadd one line in hello.txtSigned-off-by: Lu Kaiyi <looking@qq.com>git rebase -i HEAD~2
git rebase -i HEAD~2 以后,git 會自動給你切換到下面這個界面,你將你需要修改的那個 commit 前邊的 pick 修改為 edit。
[root@master GitTest]# git rebase -i HEAD~2edit 3d87922 nice to meet you pick df5f952 nice to meet you too# Rebase 3f20612..df5f952 onto 3f20612 (2 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.然后保存退出,而且 git 也已經提醒你版本已經 stopped 在這個 commit 節點了,你可以開始你的表演(修改)了:
[root@master GitTest]# git rebase -i HEAD~2 Stopped at 3d87922... nice to meet you You can amend the commit now, withgit commit --amend Once you are satisfied with your changes, rungit rebase --continue假如我想把原來插入的 nice to meet you 修改為 nice。用 vim 修改后用 git commit --amend 重新提交 commit。
[root@master GitTest]# vim hello.txt [root@master GitTest]# git add hello.txt [root@master GitTest]# git commit --amendnice # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Date: Mon Aug 31 21:16:51 2020 +0800 # # interactive rebase in progress; onto 3f20612[detached HEAD bcbfd91] niceDate: Mon Aug 31 21:16:51 2020 +08001 file changed, 1 insertion(+)git rebase --continue
然后繼續 git rebase --continue 就好了(如果沒有沖突,直接 git rebase --continue 也是極好的)。
[root@master GitTest]# git add hello.txt [root@master GitTest]# git rebase --continue [detached HEAD 72017cd] nice to meet you too1 file changed, 1 insertion(+) Successfully rebased and updated refs/heads/master.如果是對同一個文件修改的話,還是需要自己處理沖突的,不過至少把你當前的提交和最后一次提交的沖突反映到了文件。處理完成以后,重新對沖突文件進行 git add file 來表示你已經處理好沖突了,然后再次執行 git rebase --continue 就大功告成(git 已經幫你把最后一次 commit comment 保存起來的,所以不用擔心重新寫提交 comment 的問題啦) 。
[root@master GitTest]# git rebase --continue Auto-merging hello.txt CONFLICT (content): Merge conflict in hello.txt error: could not apply df5f952... nice to meet you too Resolve all conflicts manually, mark them as resolved with "git add/rm <conflicted_files>", then run "git rebase --continue". You can instead skip this commit: run "git rebase --skip". To abort and get back to the state before "git rebase", run "git rebase --abort". Could not apply df5f952... nice to meet you too[root@master GitTest]# git add hello.txt [root@master GitTest]# git rebase --continue [detached HEAD 72017cd] nice to meet you too1 file changed, 1 insertion(+) Successfully rebased and updated refs/heads/master.?最后查看日志和文件內容,已經成功修改。
[root@master GitTest]# git log commit 72017cd6e0222ff5fb544ce460ad3f2b046952ed (HEAD -> master) Author: looking <looking@qq.com> Date: Mon Aug 31 21:59:19 2020 +0800nice to meet you toocommit 50a084c8cce985ba6b5ee9bb7bce7a950671bb8e Author: looking <looking@qq.com> Date: Mon Aug 31 21:16:51 2020 +0800nicecommit 3f2061298d921378da14f4003753f1f277e67243 (origin/master) Author: looking <looking@qq.com> Date: Thu Aug 20 23:02:46 2020 +0800I am Lookingadd one line in hello.txtgit rebase --abort
如果你在 rebase 的任何過程中想退出 rebase 過程,直接執行 git rebase --abort 就直接退出回到 rebase 之前的狀態啦。
總結
以上是生活随笔為你收集整理的git 修改倒数二个 commit的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 十年磨一剑:蚂蚁集团可观测性平台 Ant
- 下一篇: rebase interactive