1. Overview
1.概述
In this article, we’ll explore different ways to modify a Git commit.
在这篇文章中,我们将探讨修改Git提交的不同方法。
2. Using amend
2.使用amend。
We can modify the latest Git commit by simply using the amend option. It replaces the most recent commit. We can modify the commit message and update the files included in the commit as well. Git considers the amended commit as a new commit.
我们可以通过简单地使用amend选项来修改最新的 Git 提交。它取代了最新的提交。我们可以修改提交信息,也可以更新提交中包含的文件。Git认为修改后的提交是一个新的提交。
Let’s try the amend option using an example. For simplicity, let’s update a file and commit with the message “Commit 1”. Now, let’s try to update the commit using the amend option:
让我们用一个例子试试amend选项。为了简单起见,让我们更新一个文件并提交,信息为 “Commit 1″。现在,让我们尝试用amend选项来更新该提交。
git commit --amend
Executing the above command opens up an editor to include changes. Let’s update the commit message and save the changes. After closing the editor, we can see the updated commit as:
执行上述命令可以打开一个编辑器,将修改内容纳入其中。让我们更新提交信息并保存修改。关闭编辑器后,我们可以看到更新后的提交信息为。
[master c0bc5d3] Amended Commit 1
Date: Wed Jun 29 22:41:08 2022 +0530
1 file changed, 1 insertion(+), 1 deletion(-)
We can also include staged changes while amending the commit. Let’s create additional changes and use the amend option to include them in the latest commit, again changing the commit message:
我们也可以在修改提交的同时包括阶段性的修改。让我们创建更多的修改,并使用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
In case we just want to add the staged changes without updating the commit message, we can use the no-edit option:
如果我们只想添加阶段性修改而不更新提交信息,我们可以使用no-edit选项。
git commit --amend --no-edit
Hence, we can see that the amend option is a convenient way to add changes to the most recent commit. Now, let’s explore different ways to update older commits in our Git history.
因此,我们可以看到,amend选项是为最近的提交添加修改的一种便捷方式。现在,让我们来探讨一下在Git历史中更新旧提交的不同方法。
3. Using rebase
3.使用rebase。
We can move a sequence of commits to a new base using the rebase command. Git internally creates a new commit for each old commit and moves to the specified new base.
我们可以使用rebase命令将一连串的提交转移到一个新的基数。Git在内部为每个旧的提交创建一个新的提交,并移动到指定的新基地。
Using the -i option with the rebase command starts an interactive session. During this session, we can modify each commit if required using the below commands:
使用-i选项和rebase命令可以启动一个互动会话。在这个会话中,如果需要,我们可以使用下面的命令来修改每个提交。
- pick (p) -> include the specific commit
- squash (s) -> merge the commit with the previous commit
- drop (d) -> remove the specific commit
- reword (r) -> include the commit and update the commit message
- edit (e) -> include the commit with an option to update the files included as well
Let’s try updating the commit history in our example using the above commands. At this step, git log shows the following commits:
让我们试试用上述命令更新我们例子中的提交历史。在这一步,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
Suppose we want to change the modifications committed after the commit “Amended Commit 1 – Added new file”.
假设我们想改变提交”Amended Commit 1 – Added new file“之后的修改。
Let’s set the above commit as the new base:
让我们把上面的提交作为新的基础。
git rebase -i 1376dc1182a798b16dc85239ec7382e8340d5267
This opens an editor, where we can make changes as required:
这将打开一个编辑器,我们可以根据需要进行修改。
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
Now, let’s try a few commands to update the Git history:
现在,让我们尝试用几个命令来更新Git历史。
reword d5923e0 commit 2-updated
edit 080e3ec commit 3
squash e9ed266 commit 4
drop 5742fcb commit 5
After the first command, we’ll see the output:
在第一个命令之后,我们会看到输出。
[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
Now, as specified in the Git output, we execute the git commit –amend command and make a few changes:
现在,按照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
After closing the editor, we get the following output:
关闭编辑器后,我们得到以下输出。
[detached HEAD 9433120] commit 3 - updated
Date: Fri Jul 1 08:11:18 2022 +0530
2 files changed, 3 insertions(+), 1 deletion(-)
We can see here that we’ve not only updated the commit message but also included one more file as part of the commit.
我们在这里可以看到,我们不仅更新了提交信息,而且还把一个文件作为提交的一部分。
Next, we need to execute the git rebase –continue command to move to the next update.
接下来,我们需要执行git rebase -continue命令,进入下一个更新。
Our next step involves the squash of commit 4 with commit 3, and it opens up to the below editor:
我们的下一步涉及commit 4与commit 3的squash,它打开了下面的编辑器。
# 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
After adding modifications to the above editor, we get the below output:
在上述编辑器中添加修改后,我们得到以下输出。
[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.
Finally, we had requested to drop the commit 5, which doesn’t require any further modification from our end.
最后,我们要求撤销commit 5,这不需要我们再做任何修改。
4. Analyzing Logs
4.分析日志
After performing the above steps, we can see the output from git log as:
执行上述步骤后,我们可以看到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
Here, we can make a few observations:
在这里,我们可以做一些观察。
- commit 5 is removed
- commit 4 is merged with commit 3
- commit 2 message is updated
In the final log, we can see that the ids for commits are changed now. This is because Git has replaced the previous commits and created new commits with modifications.
在最后的日志中,我们可以看到,现在提交的id已经改变。这是因为 Git 替换了之前的提交,并创建了带有修改内容的新提交。
We can use the reflog command to view the reference logs related to the current HEAD. It includes the history of all updates related to Git commits.
我们可以使用reflog命令来查看与当前HEAD相关的参考日志。它包括所有与Git提交相关的更新历史。
Let’s use the reflog command to observe the git history for our example:
让我们使用reflog命令来观察我们例子的git历史。
917c583 (HEAD -> master) HEAD@{0}: rebase -i (finish): returning to refs/heads/master
917c583 (HEAD -> master) HEAD@{1}: rebase -i (squash): commit 3 - squashed with commit 4
9433120 HEAD@{2}: commit (amend): commit 3 - updated
f4e8340 HEAD@{3}: commit (amend): commit 3 - updated
fd048e1 HEAD@{4}: commit (amend): commit 3 - updated
39b2f1b HEAD@{5}: commit (amend): commit 3 - updated
f79cbfb HEAD@{6}: rebase -i (edit): commit 3
178e8eb HEAD@{7}: rebase -i (reword): commit 2-alter
d5923e0 HEAD@{8}: rebase -i: fast-forward
1376dc1 HEAD@{9}: rebase -i (start): checkout 1376dc1182a798b16dc85239ec7382e8340d5267
5742fcb HEAD@{10}: commit: commit 5
e9ed266 HEAD@{11}: commit: commit 4
080e3ec HEAD@{12}: commit: commit 3
d5923e0 HEAD@{13}: commit: commit 2
1376dc1 HEAD@{14}: commit (amend): Amended Commit 1 - Added new file
5. Conclusion
5.总结
In this article, we’ve explored different ways to alter Git history. However, we should exercise caution while using these options, as it may lead to lost content as well.
在这篇文章中,我们探讨了改变 Git 历史的不同方法。然而,在使用这些选项时,我们应该谨慎,因为这也可能导致内容的丢失。