如何修改已存在但未推送的提交信息?的答案描述了一种方式,可以修改尚未向上游推送的先前提交的消息。 新消息继承原始提交的时间戳。这似乎很合理,但是否有一种方法也可以重新设置时间?
如何修改已存在但未推送的提交信息?的答案描述了一种方式,可以修改尚未向上游推送的先前提交的消息。 新消息继承原始提交的时间戳。这似乎很合理,但是否有一种方法也可以重新设置时间?
如果您想在标准的Windows命令行中执行被接受的答案(https://dev59.com/T3RB5IYBdhLWcg3w9b19#454750),您需要使用以下命令:
git filter-branch -f --env-filter "if [ $GIT_COMMIT = 578e6a450ff5318981367fe1f6f2390ce60ee045 ]; then export GIT_AUTHOR_DATE='2009-10-16T16:00+03:00'; export GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; fi"
注:
^
进行换行), 但我没有成功。特别感谢 Colin Svingen 的博客文章。尽管他的代码对我没用,但它确实帮助我找到了正确的解决方案。
GIT_COMMITTER_DATE="Sun Nov 20 21:02 2022 +0530" git commit --amend --no-edit --date="Sun Nov 20 21:02 2022 +0530"
git push -f
每次都有效。
要将最近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
更新远程存储库(⚠️危险区域)
这会有一些影响,例如:
.gitconfig
,这意味着如果Git配置为签署提交,则将使用您的密钥来签署提交。对于使用Powershell的人
git rebase DESIRED_REF^ -i
$commitDateString = "2020-01-22T22:22:22"
$env:GIT_COMMITTER_DATE = $commitDateString
git commit --amend --date $commitDateString
$env:GIT_COMMITTER_DATE = ""
git rebase --continue
感谢https://mnaoumov.wordpress.com/2012/09/23/git-change-date-of-commit/提供的帮助。
编辑最近三个提交的作者日期和提交日期:
git rebase -i HEAD~3 --committer-date-is-author-date --exec "git commit --amend --no-edit --date=now"
--exec
命令会在重新提交的每一行后面添加,你可以使用 --date=...
来选择作者日期,提交者日期将与作者日期相同。
除了Matt Montag的回答之外:
如果您需要在rebase命令后将时间戳重置为当前时间
git rebase -i HEAD~2
你可以使用以下其中一种选项
pick 4ca564e Do something
exec git commit --amend --no-edit --date=now
pick 1670583 Add another thing
exec git commit --amend --no-edit --reset-author
两种方法都可以使用
已经有很多好的答案了,但是当我想要在同一天或同一个月更改多个提交的日期时,我找不到合适的答案。因此,我创建了一个新的脚本来解决这个问题,并希望能帮助到某些人:
#!/bin/bash
# change GIT_AUTHOR_DATE for commit at Thu Sep 14 13:39:41 2017 +0800
# you can change the data_match to change all commits at any date, one day or one month
# you can also do the same for GIT_COMMITTER_DATE
git filter-branch --force --env-filter '
date_match="^Thu, 14 Sep 2017 13+"
# GIT_AUTHOR_DATE will be @1505367581 +0800, Git internal format
author_data=$GIT_AUTHOR_DATE;
author_data=${author_data#@}
author_data=${author_data% +0800} # author_data is 1505367581
oneday=$((24*60*60))
# author_data_str will be "Thu, 14 Sep 2017 13:39:41 +0800", RFC2822 format
author_data_str=`date -R -d @$author_data`
if [[ $author_data_str =~ $date_match ]];
then
# remove one day from author_data
new_data_sec=$(($author_data-$oneday))
# change to git internal format based on new_data_sec
new_data="@$new_data_sec +0800"
export GIT_AUTHOR_DATE="$new_data"
fi
' --tag-name-filter cat -- --branches --tags
AuthorDate: Wed Sep 13 13:39:41 2017 +0800
if [ "$GIT_COMMIT" = "$com_hash" ]; # com is commit
then
export GIT_AUTHOR_DATE="$com_date";
export GIT_COMMITTER_DATE="$com_date";
fi;
if [ true = false ]; # impossible
then
: # pass
elif [ "$GIT_COMMIT" = "$com_hash" ];
then
sed 's/.*/$com_msg_esc/g' # replace content with new content
else
cat - # returns previous content
fi;
我们使用以下方式推送所有更新:
git filter-branch -f \
--env-filter "$UPDATES" \
--msg-filter "$MESSAGES" \
-- "$REV"
(doc is here filter-branch man)
概述:日期匹配 + 重新生成 GPG 签名
(如果您知道保留原始签名的解决方法,请在评论/编辑中提出。)
我会顶起这个旧帖子,因为引入了签署提交的功能,所有这些git filter-branch
和类似的基本上都按照文档中指定的方式剥离了签名:
... 如果标签附带有签名,则将剥离签名。根据定义,无法保留签名。...(来源:--tag-name-filter)
但它也会破坏GitHub提交上漂亮的已验证
徽章(如果以相同的方式在其他Git托管位置实现),因此这也将修复它。部分地。
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
假设你有一个 repo,你想要从某个提交签名(我会选择根提交;如果其他人在该 repo 上工作,则不建议这样做)。git commit
文档说它也从环境变量中提取数据,如果存在的话,因此我们有一个放置输入的地方。
要检索数据(可以使用 git commit --date=...
设置),我们可以查看 git show --format=%ad
,因此对于原始日期字符串,它应该是:
git show --format=%ad --no-patch
# Sat Jan 1 00:00:00 2000 +0000
所以我们有:
GIT_COMMITTER_DATE
用于匹配日期(作者 -> 提交者)对于变基,让我们这样做:
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
(如果您没有指定user.signingkey
,请使用--gpg-sign=<fingerprint>
)
这将遍历每个标记为edit
的提交,将提交者的日期设置为与作者的日期相匹配,保留任何空提交,不会触及整体补丁内容,并在执行命令时添加带有日期的签名。
一旦您看到fatal: No rebase in progress?
,请按Ctrl-C
停止循环并检查日志以确认日期匹配并且签名已经存在于所有地方:
git log --pretty=fuller --show-signature
git push --force
即可完成。现在您应该看到每个提交的Verified
徽章。
具有真实历史树的示例。GitHub似乎不关心签名的日期(没有任何参考),但它仍将出现在git log
中。
git commit --amend --reset-author
- Erick M. Sprengel