修改最新Commit
如果只要修改最新提交,可以直接使用命令git commit --amend
,在文本编辑器中编辑并保存。如果提交已经推送,需要用git push --force
强制推送。
修改历史Commit
如果要修改历史提交,需要用到命令git rebase
。假设一共有三条提交信息:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18❯ git log
commit a42c6e958969a9e86fa3ef6a1f4116cbc6ce8226 (HEAD -> master, origin/master)
Author: Luckyfuy <abcxlxcba@sina.com>
Date: Tue Jan 31 16:55:20 2023 +0800
commit 3
commit f7918f949a80ca74c6ec0c9dd18a8d9fff5c120e
Author: Luckyfuy <abcxlxcba@sina.com>
Date: Tue Aug 24 12:17:29 2021 +0800
commit 2
commit 242c177f16ef0fb05dcaab3f1633268e2a3067a9
Author: Luckyfuy <abcxlxcba@sina.com>
Date: Sun Apr 4 11:29:49 2021 +0800
commit 1
如果要修改第二次提交,执行命令1
git rebase -i HEAD~2
但是如果要修改最早的提交,也就是第三次提交,不能用git rebase -i HEAD~3
,而是要用1
git rebase -i --root
假设我们要修改第三次提交,执行命令后会打开文件git-rebase-todo
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33pick 242c177 commit 1
pick f7918f9 commit 2
pick a42c6e9 commit 3
# Rebase a42c6e9 onto 6bb1aac (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 [-C | -c] <commit> = like "squash" but keep only the previous
# commit's log message, unless -C is used, in which case
# keep only this commit's message; -c is same as -C but
# opens the editor
# 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
# u, update-ref <ref> = track a placeholder for the <ref> to be updated
# to this position in the new commits. The <ref> is
# updated at the end of the rebase
#
# 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.
将第一行的pick
改为edit
,保存并退出,会得到如下信息:1
2
3
4
5
6
7
8Stopped at 242c177... add 22 files
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
执行git commit --amend
,修改文件,保存并退出。然后执行git rebase --continue
,就完成了本地修改。1
2
3
4
5
6
7❯ git commit --amend
[detached HEAD c04c450] commit 114514
Date: Sun Apr 4 11:29:49 2021 +0800
1 files changed, 27 insertions(+)
create mode 100644 README.md
❯ git rebase --continue
Successfully rebased and updated refs/heads/master.
再用git log
检查一遍:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18❯ git log
commit c376ae5c4cf6f3db1ce916d494094fe620fb0edf (HEAD -> master)
Author: Luckyfuy <abcxlxcba@sina.com>
Date: Tue Jan 31 16:55:20 2023 +0800
commit 3
commit dd92a12db7d0d0f0948d09e98575f7bf83754229
Author: Luckyfuy <abcxlxcba@sina.com>
Date: Tue Aug 24 12:17:29 2021 +0800
commit 2
commit c04c4500ecbe466808032f4f0337188de7d33bcb
Author: Luckyfuy <abcxlxcba@sina.com>
Date: Sun Apr 4 11:29:49 2021 +0800
commit 114514
最后推送到远程仓库,用--force
强制推送:1
git push --force
将CommitDate修改为AuthorDate
如果推送到GitHub,会发现一个问题:所有提交的时间都变成了git rebase
执行完成的时间。这是因为Git对提交有两套时间记录,分别是CommitDate和AuthorDate。执行完成git rebase
后,CommitDate会被修改为当前时间,而GitHub只会识别CommitDate。即便使用git commit --amend
修改提交时间,修改的也只是AuthorDate。于是我们需要将CommitDate修改为AuthorDate。
执行git log --format="%H %ci %ai %s"
可以查看CommitDate和AuthorDate:1
2
3
4❯ git log --format="%H %ci %ai %s"
c376ae5c4cf6f3db1ce916d494094fe620fb0edf 2023-06-24 11:43:51 +0800 2023-01-31 16:55:20 +0800 commit 3
dd92a12db7d0d0f0948d09e98575f7bf83754229 2023-06-24 11:43:51 +0800 2021-08-24 12:17:29 +0800 commit 2
c04c4500ecbe466808032f4f0337188de7d33bcb 2023-06-24 11:43:09 +0800 2021-04-04 11:29:49 +0800 commit 114514
可以看到,CommitDate和AuthorDate是不一致的。执行以下命令即可将CommitDate修改为AuthorDate:1
git filter-branch --env-filter 'export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"'
再检查一遍,可以看到CommitDate和AuthorDate已经一致:1
2
3
4❯ git log --format="%H %ci %ai %s"
20e42c0504a02c423d2fd8f7eec0d4df41d364f2 2023-01-31 16:55:20 +0800 2023-01-31 16:55:20 +0800 commit 3
65dc5ab4a8300d4449bf79f71e7382cb319c83e9 2021-08-24 12:17:29 +0800 2021-08-24 12:17:29 +0800 commit 2
fc1ce0d35a797a76d25fa0354b5434eae6957f98 2021-04-04 11:29:49 +0800 2021-04-04 11:29:49 +0800 commit 114514
最后再次强制推送即可:1
git push --force