是这样,最近两次提交的 commit message 写的有些问题,所以想改一下,查了一下是用git commit -amend
命令,于是进行了下面一系列操作(两次 commit 在下面分别称为最近一次和上一次吧,最近一次就是刚才即 22 日下午,上一次是 20 日晚上):
1 、运行git commit -amend
后打开了 vim,编辑了最近一次的 message,保存退出后运行git log
查看发现一切 OK
2 、想修改上一次的 message,查了下上次 commit id 开头是 6b2c8b16,于是运行git commit --amend 6b2c8b16
,报错提示error: 路径规格 '6b2c8b16' 未匹配任何 git 已知文件
,简单搜了下尝试运行了git commit -c 6b2c8b16 --amend
,打开了 vim,没仔细看后面#开头的文件变动列表(后来再次运行确认了是最近一次的文件变动列表),改完了保存退出
3 、运行git log
确认修改结果,发现悲剧了,最近一次的 commit message 没有了,取而代之的是刚修改的上一次的 message,诡异的是 Date 行显示的也是上一次的提交日期,可是git status
并查看代码发现最近一次的修改没有回滚,疑惑到底发生了什么
4 、安装了 sourcetree 打开项目,发现 commit 列表显示的最近一次的日期是刚才 vim 修改 message 的时间,即它跟 git log 中 Date 行显示的并不一样。而 source tree 的概况窗口显示如下:
提交:8882c410631f5418b0b7ed14c8bc7777fca9f312 [8882c41]
父级:6b2c8b16d5
日期:2021 年 8 月 20 日 23:05:02
提交时间:2021 年 8 月 22 日 15:05:21
我的问题是:
1 、步骤 3 中描述的问题该如何解决呢? git log 显示的日期不是实际 commit 的时间太别扭了。
2 、我运行的git commit -c 6b2c8b16 --amend
导致的结果是设计中的吗,还是误用命令触发了 bug 什么的?
3 、修改之前的 commit message 的正确命令是什么?
1
ampedee 2021-08-22 17:10:31 +08:00 via Android
用 rebase
|
2
nowheretoseek OP @ampedee 谢谢,参考 https://www.jianshu.com/p/0f1fbd50b4be 解决了问题,不过还是不大明白为什么会在步骤 3 中看到错误的 commit 时间,git 太深奥了……
|
3
secondwtq 2021-08-22 21:57:11 +08:00 1
> 发现 commit 列表显示的最近一次的日期是刚才 vim 修改 message 的时间,即它跟 git log 中 Date 行显示的并不一样。
根据发帖时间推算,你这个 “提交时间:2021 年 8 月 22 日 15:05:21” 对应的应该是你说的“刚才 vim 修改 message 的时间”,而“git log 中 Date 行”显示的应该是“日期:2021 年 8 月 20 日 23:05:02”,即“上一次的提交日期”。 Git 每个 commit 有两个日期,一个 AuthorDate,一个 CommitDate,git log 默认只显示 AuthorDate,用 git log --pretty=fuller 可以全部显示。你可能把这两个搞混了。 我没用过 git commit -c,但是 man 中对 git commit -c 的描述是: > -C <commit>, --reuse-message=<commit> > Take an existing commit object, and reuse the log message and the authorship information (including the timestamp) when creating the commit. > -c <commit>, --reedit-message=<commit> > Like -C, but with -c the editor is invoked, so that the user can further edit the commit message. 不知道你是怎么查到的,这个意思应该是你运行 git commit -c --amend 时,其实改的依然是 HEAD,只不过把 HEAD~1 的部分元数据搬了过来。 Git 和区块链一样都是类 Merkle Tree,也就是一个 commit 会递归地依赖于之前的所有 commit 。要想在 branch tip 之后的地方动刀子就必须重新生成中间的所有 commit ( commit message,author 和 commit 的元数据都会被放在一起做 hash )。所以直接改后面的 commit message 应该不太靠谱。 |
4
johnsona 2021-08-23 02:32:44 +08:00 via iPhone
git reflog
|
5
nowheretoseek OP @secondwtq 谢谢!关于 Merkle Tree 的解释很有启发性,我当时简单 Google 怎么改之前的 commit message,看到一个条目预览里有-c 参数的用法,没点进去细看,想当然地认为-c 是指定 commit id 的;认为可以直接改前面 commit 的 message 也是因为不了解这个类区块链的存储机制(其实现在也不了解,不过知道跟常见的存储不一样,有很强的前向依赖)。
我运行`git commit -c 6b2c8b16 --amend`时应该是重用了上一次的 message,对最近一次的 message 进行了编辑,这样一来最近一次就记录了上一次的 author date,然后我又不知道 git log 默认显示的是 author date,以为是 commit date,所以会有上面的疑惑。 现在疑惑解开了,再次感谢! |
6
nowheretoseek OP @johnsona 用到了,上面贴的链接了介绍了 rebase 和 reflog 的用法,都上用了,对这俩命令大致有了点了解。
|