如何修改现有的、未推送的提交?描述一种修改尚未推送到上游的先前提交消息的方法。新消息继承原始提交的时间戳。这似乎合乎逻辑,但有没有办法也重新设定时间呢?
当前回答
将最近5次提交的日期更新到当前日期(此方法不允许更新初始提交):
git rebase HEAD~5 --exec "git commit --amend --no-edit --date 'now'"
对于提交95f5074…15074db2后的所有提交:
git rebase 95f5074…15074db2 --exec "git commit --amend --no-edit --date 'now'"
对于所有的提交(包括初始提交):
git rebase --root --exec "git commit --amend --no-edit --date 'now'"
为交互模式添加-i。
执行git log——format=fuller——show-signature命令验证修改。
运行git push -f更新远程存储库(⚠️危险区域)
这是有影响的。例如:
提交id将会改变,因此您必须重新创建标记 您将失去原始签名 这将使用您的.gitconfig,这意味着您的密钥将用于签名提交(如果Git被配置为签名提交)
其他回答
TL;DR:匹配日期+重新创建GPG签名
(如果你知道一个可以保留原始签名的方法,请评论/编辑。)
我将碰到这个旧线程,因为签名提交的特性已经引入,所有这些git过滤器分支和喜欢基本上剥离了文档中指定的签名:
... 如果标签附加了签名,则签名将被剥离。根据定义,不可能保存签名. ...(来源:——tag-name-filter)
但它也会破坏GitHub提交上漂亮的验证徽章(如果以同样的方式实现,在其他Git托管位置也会如此),所以这也会修复这个问题。部分。
Afaik,不可能通过git命令来破坏一个(GPG)签名,它也包含了提交的日期,而不是简单的签名日期,因此即使编辑和提交的日期被移动了,它仍然是当前的日期,例如:
commit <hash>
gpg: Signature made Sun 25 Jul 2021 00:00:00 PM TZ
gpg: using TYPE key KEY
gpg: Good signature from "Signer <email@domain.tld>"
Author: Author <email@domain.tld>
AuthorDate: Sat Jan 1 00:00:00 2000 +0000
Commit: Author <email@domain.tld>
CommitDate: Sat Jan 1 00:00:00 2000 +0000
假设你有一个回购,你想从某个commit(我用根commit;如果其他人负责回购,则不建议使用)。git提交的文档说,如果存在,它也会从env vars中提取数据,因此我们有一个地方可以输入。
要检索数据(可以使用git commit——date=…设置),我们可以查看git show——format=%ad,因此对于原始日期字符串,它将是:
git show --format=%ad --no-patch
# Sat Jan 1 00:00:00 2000 +0000
所以我们有:
起点 每次提交的原始日期字符串 GIT_COMMITTER_DATE来匹配日期(author -> committer)
对于重基,我们这样做:
git rebase --root <branch-name> --keep-empty --interactive
这将用于一个分支<branch-name>的根提交,保留任何用git commit -m "empty"——allow-empty创建的空提交,并询问你要修改哪个提交。在这里,您可以将所需的提交从pick更改为edit(对于我的情况,将所有这些都标记为edit),然后您将被放入一个分离的HEAD提交,从这里开始乐趣。
# or "while :"
while true
do
GIT_COMMITTER_DATE=$(git show --format=%ad --no-patch) \
git commit --amend --gpg-sign --no-edit --allow-empty
git rebase --continue
done
(如果您没有用户名。指定签名密钥,使用——gpg-sign=<指纹>)
这将遍历每个编辑标记的提交,将提交者的日期设置为与作者的日期匹配,保留任何空提交,不会触及整个补丁体,并将添加带有命令执行日期的签名。
一旦你看到致命:没有调整进度?按Ctrl-C停止循环,检查日志,确认日期匹配,签名无处不在:
git log --pretty=fuller --show-signature
如果日志中一切正常,只需发出git push——force,就完成了。现在您应该看到每个提交的Verified徽章。
一个真实历史树的例子。GitHub似乎并不关心签名的日期(在任何地方都没有引用),但它仍然会出现在git日志中。
下面的bash函数将更改当前分支上任何提交的时间。
如果您已经推送了提交,或者在另一个分支中使用提交,请注意不要使用。
# rewrite_commit_date(commit, date_timestamp)
#
# !! Commit has to be on the current branch, and only on the current branch !!
#
# Usage example:
#
# 1. Set commit 0c935403 date to now:
#
# rewrite_commit_date 0c935403
#
# 2. Set commit 0c935403 date to 1402221655:
#
# rewrite_commit_date 0c935403 1402221655
#
rewrite_commit_date () {
local commit="$1" date_timestamp="$2"
local date temp_branch="temp-rebasing-branch"
local current_branch="$(git rev-parse --abbrev-ref HEAD)"
if [[ -z "$date_timestamp" ]]; then
date="$(date -R)"
else
date="$(date -R --date "@$date_timestamp")"
fi
git checkout -b "$temp_branch" "$commit"
GIT_COMMITTER_DATE="$date" git commit --amend --date "$date"
git checkout "$current_branch"
git rebase "$commit" --onto "$temp_branch"
git branch -d "$temp_branch"
}
我为此写了一个脚本和Homebrew包。超级容易安装,你可以在GitHub PotatoLabs/git-redate页面上找到它。
语法:
git redate -c 3
你只需要运行git redate,你就可以在vim中编辑最近5次提交的所有日期(还有一个-c选项来决定你想要返回多少次提交,它默认是5)。如果你有任何问题,评论或建议,请告诉我!
git commit --amend --date="now"
将最后一次提交的日期设置为当前日期
GIT_COMMITTER_DATE="$(date)" git commit --amend --no-edit --date "$(date)"
将最后一次提交的日期设置为任意日期
GIT_COMMITTER_DATE="Mon 20 Aug 2018 20:19:19 BST" git commit --amend --no-edit --date "Mon 20 Aug 2018 20:19:19 BST"
将任意提交的日期设置为任意或当前日期
还原到之前所述的提交和停止修改:
Git rebase <commit-hash>^ -i 将pick替换为e (edit)并提交(第一个) 退出编辑器(在VIM中,ESC后跟:wq) :
GIT_COMMITTER_DATE="$(date)" git commit - modify -no-edit -date "$(date)" GIT_COMMITTER_DATE="Mon 20 Aug 2018 20:19:19 BST" git commit - modify -no-edit -date "Mon 20 Aug 2018 20:19:19 BST"
来源: https://codewithhugo.com/change-the-date-of-a-git-commit/
推荐文章
- “git restore”命令是什么?“git restore”和“git reset”之间有什么区别?
- Git合并与强制覆盖
- Git拉另一个分支
- 在Bash命令提示符上添加git分支
- 如何更改Git日志日期格式
- git pull -rebase和git pull -ff-only之间的区别
- GitHub -致命:无法读取用户名https://github.com':没有这样的文件或目录
- 撤消git平分错误
- 使用.gitconfig配置diff工具
- 如何配置Mac OS X术语,使git有颜色?
- Visual Studio Code: .git文件夹/文件隐藏
- 如何使用yyyyMMddHHmmss格式格式化当前时间?
- “node_modules”文件夹应该包含在git存储库中吗
- 为什么git-rebase给了我合并冲突,而我所做的只是压缩提交?
- 当我试图推到原点时,为什么Git告诉我“没有这样的远程‘原点’”?