在 Git 中修改指定的提交
一、概述
在本文中,我們將探索修改 Git 提交的不同方法。
2. 使用amend
我們可以通過簡單地使用amend選項來修改最新的 Git 提交。它替換了最近的提交。我們也可以修改提交消息並更新提交中包含的文件。 Git 將修改後的提交視為新提交。
讓我們用一個例子來試試修改選項。為簡單起見,讓我們更新一個文件並使用消息“Commit 1”提交。現在,讓我們嘗試使用amend選項更新提交:
git commit --amend
執行上述命令會打開一個編輯器以包含更改。讓我們更新提交消息並保存更改。關閉編輯器後,我們可以看到更新後的提交如下:
[master c0bc5d3] Amended Commit 1
Date: Wed Jun 29 22:41:08 2022 +0530
1 file changed, 1 insertion(+), 1 deletion(-)
我們還可以在修改提交時包含階段性更改。讓我們創建額外的更改並使用amend選項將它們包含在最新的提交中,再次更改提交消息:
[master 0a1d571] Amended Commit 1 - Added new file
Date: Wed Jun 29 22:41:08 2022 +0530
2 files changed, 2 insertions(+), 1 deletion(-)
create mode 100644 README2
如果我們只想添加分階段的更改而不更新提交消息,我們可以使用no-edit選項:
git commit --amend --no-edit
因此,我們可以看到修改選項是向最近提交添加更改的便捷方式。現在,讓我們探索更新 Git 歷史中舊提交的不同方法。
3. 使用rebase
我們可以使用rebase命令將一系列提交移動到新的基礎上。 Git 在內部為每個舊提交創建一個新提交並移動到指定的新庫。
將-i選項與rebase命令一起使用會啟動交互式會話。在此會話期間,如果需要,我們可以使用以下命令修改每個提交:
- *選擇(p)* -> 包含特定的提交
- *squash (s)* -> 將提交與前一個提交合併
- *drop (d)* -> 刪除特定的提交
- *reword (r)* -> 包含提交並更新提交消息
- *編輯(e)* -> 包含提交並帶有更新包含的文件的選項
讓我們嘗試使用上述命令更新示例中的提交歷史記錄。在這一步, git log顯示以下提交:
commit 5742fcbe1cb14a9c4f1425eea9032ffb4c6191e5 (HEAD -> master)
Author: #####
Date: Fri Jul 1 08:11:52 2022 +0530
commit 5
commit e9ed266b84dd29095577ddd8f6dc7fcf5cf9db0d
Author: #####
Date: Fri Jul 1 08:11:37 2022 +0530
commit 4
commit 080e3ecc041b7be1757af67bf03db982135b9093
Author: #####
Date: Fri Jul 1 08:11:18 2022 +0530
commit 3
commit d5923e0ced1caff5874d8d41f39d197b5e1e2468
Author: #####
Date: Fri Jul 1 08:10:58 2022 +0530
commit 2
commit 1376dc1182a798b16dc85239ec7382e8340d5267
Author: #####
Date: Wed Jun 29 22:41:08 2022 +0530
Amended Commit 1 - Added new file
假設我們要更改提交“ Amended Commit 1 – Added new file
”之後提交的修改。
讓我們將上面的提交設置為新的基礎:
git rebase -i 1376dc1182a798b16dc85239ec7382e8340d5267
這將打開一個編輯器,我們可以在其中根據需要進行更改:
pick d5923e0 commit 2
pick 080e3ec commit 3
pick e9ed266 commit 4
pick 5742fcb commit 5
# Rebase #####..### onto #### (4 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
現在,讓我們嘗試一些命令來更新 Git 歷史記錄:
reword d5923e0 commit 2-updated
edit 080e3ec commit 3
squash e9ed266 commit 4
drop 5742fcb commit 5
在第一個命令之後,我們將看到輸出:
[detached HEAD 178e8eb] commit 2-alter
Date: Fri Jul 1 08:10:58 2022 +0530
1 file changed, 1 insertion(+)
Stopped at ######... commit 3
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
現在,按照 Git 輸出中的說明,我們執行git commit –amend命令並進行一些更改:
commit 3
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Fri Jul 1 08:11:18 2022 +0530
#
# interactive rebase in progress; onto 1376dc1
# Last commands done (2 commands done):
# reword d5923e0 commit 2-updated
# edit 080e3ec commit 3
# Next commands to do (2 remaining commands):
# squash e9ed266 commit 4
# drop 5742fcb commit 5
# You are currently splitting a commit while rebasing branch 'master' on '1376dc1'.
#
# Changes to be committed:
# modified: README
# modified: README2
關閉編輯器後,我們得到以下輸出:
[detached HEAD 9433120] commit 3 - updated
Date: Fri Jul 1 08:11:18 2022 +0530
2 files changed, 3 insertions(+), 1 deletion(-)
我們可以在這裡看到,我們不僅更新了提交消息,而且還包含了一個文件作為提交的一部分。
接下來,我們需要執行git rebase –continue命令移動到下一次更新。
我們的下一步涉及提交 4和提交 3的壓縮,它打開到下面的編輯器:
# This is a combination of 2 commits.
# This is the 1st commit message:
commit 3 - updated
# This is the commit message #2:
commit 4
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Date: Fri Jul 1 08:11:18 2022 +0530
# interactive rebase in progress; onto 1376dc1
# Last commands done (3 commands done):
# edit 080e3ec commit 3
# squash e9ed266 commit 4
# Next command to do (1 remaining command):
# drop 5742fcb commit 5
# You are currently rebasing branch 'master' on '1376dc1'.
#
# Changes to be committed:
# modified: README
# modified: README2
對上述編輯器添加修改後,我們得到以下輸出:
[detached HEAD 917c583] commit 3 - squashed with commit 4
Date: Fri Jul 1 08:11:18 2022 +0530
2 files changed, 3 insertions(+), 1 deletion(-)
Successfully rebased and updated refs/heads/master.
最後,我們要求刪除**提交 5 ,這不需要我們進行任何進一步的修改。
4. 分析日誌
執行上述步驟後,我們可以看到git log
的輸出為:
commit 917c583d5bb02803ee43cf87a2143f201c97bbe8 (HEAD -> master)
Author: #######
Date: Fri Jul 1 08:11:18 2022 +0530
commit 3 - squashed with commit 4
commit 4
commit 178e8ebec178c166d1c9def2d680f41933eba29b
Author: #######
Date: Fri Jul 1 08:10:58 2022 +0530
commit 2-alter
commit 1376dc1182a798b16dc85239ec7382e8340d5267
Author: #######
Date: Wed Jun 29 22:41:08 2022 +0530
Amended Commit 1 - Added new file
在這裡,我們可以做一些觀察:
- 提交 5被刪除
- 提交 4與提交 3合併
- 提交 2消息已更新
在最終日誌中,我們可以看到提交的 id 現在已更改。這是因為 Git 已經替換了以前的提交並創建了帶有修改的新提交。
我們可以使用reflog
命令查看當前HEAD
相關的引用日誌。它包括與 Git 提交相關的所有更新的歷史記錄。
讓我們使用reflog命令來觀察我們示例的 git 歷史記錄:
917c583 (HEAD -> master) [email protected]{0}: rebase -i (finish): returning to refs/heads/master
917c583 (HEAD -> master) [email protected]{1}: rebase -i (squash): commit 3 - squashed with commit 4
9433120 [email protected]{2}: commit (amend): commit 3 - updated
f4e8340 [email protected]{3}: commit (amend): commit 3 - updated
fd048e1 [email protected]{4}: commit (amend): commit 3 - updated
39b2f1b [email protected]{5}: commit (amend): commit 3 - updated
f79cbfb [email protected]{6}: rebase -i (edit): commit 3
178e8eb [email protected]{7}: rebase -i (reword): commit 2-alter
d5923e0 [email protected]{8}: rebase -i: fast-forward
1376dc1 [email protected]{9}: rebase -i (start): checkout 1376dc1182a798b16dc85239ec7382e8340d5267
5742fcb [email protected]{10}: commit: commit 5
e9ed266 [email protected]{11}: commit: commit 4
080e3ec [email protected]{12}: commit: commit 3
d5923e0 [email protected]{13}: commit: commit 2
1376dc1 [email protected]{14}: commit (amend): Amended Commit 1 - Added new file
5. 結論
在本文中,我們探索了改變 Git 歷史的不同方法。但是,我們在使用這些選項時應謹慎行事,因為它也可能導致內容丟失。