在实际工程中,有时我们在以往的提交中忘记提交部分代码,当想起来的时候已经提交过很多笔了。于是想要把当前的更改提交到历史 commit 中去。
假设当前我们提交了三次:
$ git log
commit 0e162000e27ba998d5a92cc04b489e3d3ec0e30d (HEAD -> master)
Author: cloxnu <[email protected]>
Date: Fri Nov 5 13:46:08 2021 +0800
3rd commit
commit f5f470406634bb255e4f19bf62780868afeed32d
Author: cloxnu <[email protected]>
Date: Fri Nov 5 13:45:21 2021 +0800
2nd commit
commit cf8c580d322e459fa1acf4ef1e6d08163aeb1a21
Author: cloxnu <[email protected]>
Date: Fri Nov 5 13:41:30 2021 +0800
1st commit
这几次提交就只涉及一个文件 1.txt
$ cat 1.txt
11111111
22222222
33333333
其中第一行为第一次提交,第二行为第二次提交,第三行为第三次提交。
此时如果想要将第二次提交增加一个新文件 2.txt
,该怎么操作呢?
步骤
- 首先新建
2.txt
$ cat 2.txt
22222222
- 将当前的更改 stash
$ git stash
Saved working directory and index state WIP on master: 0e16200 3rd commit
- 根据之前
git log
打印的 commit 信息确定将要更改的 commit hash 值。然后使用git rebase -i
(没错,这相当于一次 rebase)
$ git rebase -i f5f470406634bb255e4f19bf62780868afeed32d^
⚠️ 注意:这里输入的提交 hash 值后需要加上
^
1,代表这次 commit 的父提交。或者:$ git rebase -i cf8c580d322e459fa1acf4ef1e6d08163aeb1a21
或
$ git rebase -i HEAD~2
如果此时需要更改第一次提交,因为第一次提交没有父提交,所以应该输入命令
$ git rebase -i --root
- 此时会进入 vim,编辑对于这些 commit 需要执行怎样的操作
pick f5f4704 2nd commit
pick 0e16200 3rd commit
# Rebase cf8c580..0e16200 onto cf8c580 (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.
#
# 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.
#
我们当前需要变更第二次 commit,所以应该把第一行的 pick
改为 edit
,然后 :wq
保存。
- 此时进入这样的画面
Stopped at f5f4704... 2nd commit
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
这时可以将我们 stash 后的更改 pop 出来
$ git stash pop
interactive rebase in progress; onto cf8c580
Last command done (1 command done):
edit f5f4704 2nd commit
Next command to do (1 remaining command):
pick 0e16200 3rd commit
(use "git rebase --edit-todo" to view and edit)
You are currently editing a commit while rebasing branch 'master' on 'cf8c580'.
(use "git commit --amend" to amend the current commit)
(use "git rebase --continue" once you are satisfied with your changes)
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: 2.txt
Dropped refs/stash@{0} (15fa455ffa846f31167b311c3b7b9314f6c944db)
- 提交
$ git add .
$ git commit --amend
并确认提交信息。
- 继续进行 rebase
$ git rebase --continue
Successfully rebased and updated refs/heads/master.
结束。
验证
此时我们看到第二次和第三次的提交的 hash 值都被修改了
$ git log
commit 9522b421544a86b1fc7be32bac18e889fb57b096 (HEAD -> master)
Author: cloxnu <[email protected]>
Date: Fri Nov 5 13:46:08 2021 +0800
3rd commit
commit 903242f62a479417f1b3d759b0a64280ea43287b
Author: cloxnu <[email protected]>
Date: Fri Nov 5 13:45:21 2021 +0800
2nd commit
commit cf8c580d322e459fa1acf4ef1e6d08163aeb1a21
Author: cloxnu <[email protected]>
Date: Fri Nov 5 13:41:30 2021 +0800
1st commit
查看第二次提交:
$ git show HEAD^
commit 903242f62a479417f1b3d759b0a64280ea43287b
Author: cloxnu <[email protected]>
Date: Fri Nov 5 13:45:21 2021 +0800
2nd commit
diff --git a/1.txt b/1.txt
index ca028fb..71d9a24 100644
--- a/1.txt
+++ b/1.txt
@@ -1 +1,2 @@
11111111
+22222222
diff --git a/2.txt b/2.txt
new file mode 100644
index 0000000..75a1dd2
--- /dev/null
+++ b/2.txt
@@ -0,0 +1 @@
+22222222