【问题标题】:How can one change the timestamp of an old commit in Git?如何在 Git 中更改旧提交的时间戳?
【发布时间】:2010-10-02 01:39:11
【问题描述】:

How to modify existing, unpushed commits? 的答案描述了一种修改尚未推送到上游的先前提交消息的方法。新消息继承原始提交的时间戳。这似乎合乎逻辑,但有没有办法也重新设置时间?

【问题讨论】:

  • git commit --amend --reset-author
  • 上面的评论 ^^ (@ErickM.Sprengel) 应该是公认的答案。易于运行,尤其适用于最新的提交。

标签: git timestamp commit git-rewrite-history


【解决方案1】:

您可以进行交互式变基并选择edit 作为您想要更改其日期的提交。例如,当 rebase 进程停止以修改您输入的提交时:

git commit --amend --date="Wed Feb 16 14:00 2011 +0100" --no-edit

附: --date=now 将使用当前时间。

之后,你继续你的交互式变基。

更改提交日期而不是作者日期:

GIT_COMMITTER_DATE="Wed Feb 16 14:00 2011 +0100" git commit --amend --no-edit

上面几行设置了一个环境变量GIT_COMMITTER_DATE,用于修改提交。

一切都在 Git Bash 中测试。

【讨论】:

  • @nschum --date="" 和 --data"non-date-text" 都产生相同的结果,取现在的日期。
  • 在 git 版本 1.7.7.1 上使用 --date="now" 给出致命:无效日期格式:现在
  • 当您要更改日期的提交是最近的提交时,您不必执行rebase,您可以执行git commit --amend
  • 不要导出 GIT_COMMITTER_DATE="",尝试取消设置 GIT_COMMITTER_DATE。
  • 我正在使用 --no-edit 以便您可以在自动化脚本中使用! + var fixedDate = strftime(new Date(), "%c"); + var result = shelljs.exec("git commit --amend --date=\"" + fixedDate + "\" --no-edit");
【解决方案2】:

git filter-branch 与设置 GIT_AUTHOR_DATEGIT_COMMITTER_DATE 的 env 过滤器一起用于您要修复的提交的特定哈希。

这将使该哈希值和所有未来的哈希值无效。

示例:

如果您想更改提交 119f9ecf58069b265ab22f1f97d2b648faf932e0dates,您可以这样做:

git filter-branch --env-filter \
    'if [ $GIT_COMMIT = 119f9ecf58069b265ab22f1f97d2b648faf932e0 ]
     then
         export GIT_AUTHOR_DATE="Fri Jan 2 21:38:53 2009 -0800"
         export GIT_COMMITTER_DATE="Sat May 19 01:01:01 2007 -0700"
     fi'

【讨论】:

  • 找到正确的值,但只是设置这些变量实际上似乎并没有影响旧提交的日期。
  • 您所说的“这将使该哈希值和所有未来的哈希值无效”是什么意思?
  • EpicDavi:这意味着您将不得不强制推送到任何远程存储库,并且任何已拉取提交或任何未来提交的人都必须重置和拉取,或者从头开始删除和克隆。据我所知,没有办法解决这个问题。
  • 作为初学者的说明,短哈希在if语句中不起作用,使用长SHA-1
【解决方案3】:

在一个命令中处理所有这些建议的更好方法是

LC_ALL=C GIT_COMMITTER_DATE="$(date)" git commit --amend --no-edit --date "$(date)"

这会将最后一次提交的提交和作者日期设置为“现在”。

【讨论】:

  • 这非常适合在交互式变基期间编辑特定提交。
  • 你也可以给它的shell添加一个别名
  • 似乎 Git 不能识别日期格式,因此要完全正确,您必须将其设置为:LANG= GIT_COMMITTER_DATE="`date`" git commit --amend --date "`date`"
  • 你也可以只做--date "now"。 Git >= 2 将解释这一点。
  • LC_ALL=C 是做什么的?
【解决方案4】:

只需git commit --amend --reset-author --no-edit。对于较旧的提交,您可以进行交互式变基并为要修改其日期的提交选择 edit

git rebase -i <ref>

然后用--reset-author--no-edit 修改提交以将作者日期更改为当前日期:

git commit --amend --reset-author --no-edit

最后继续你的交互式变基:

git rebase --continue

【讨论】:

  • 使用 --reset-author 很好,它是 git 1.6.6 中的新功能(参考 gitlog.wordpress.com/2010/01/13/git-1-6-6
  • 这可以很好地使 Github 以正确的顺序显示重新定位的 PR 的提交,因为 they order them by timestamp 并且没有这个技巧,时间戳可能都是相同的。
  • note --reset-author 会将作者和作者日期重置为现在。
  • 这会同时改变“提交日期”吗?
  • @luochen1990 不,这不会改变提交者日期,这只会改变作者日期
【解决方案5】:

我为此编写了一个脚本和 Homebrew 包。超级容易安装,你可以在 GitHub PotatoLabs/git-redate 页面找到它。

语法:

git redate -c 3

您只需要运行git redate,您就可以在vim 中编辑最近5 次提交的所有日期(还有一个-c 选项可以让您返回多少次提交,它只是默认为 5)。如果您有任何问题、cmets 或建议,请告诉我!

【讨论】:

  • 好东西,尽管我不得不使用 vim 而不是 nano
  • 感谢@Edmund 提供了一个很棒的脚本。运行 git redate -c 后,我无法在 vi 中看到要编辑的日期。我看到的只是 %cI | XXXXXXXXXXXXXXXX |初始提交。能否请你帮忙?谢谢
  • @KiemNguyen 你能试试 git redate(不带 -c)吗?
  • 完全同意 Mina 和 @howdoyouturnthison 的观点,为什么不通过 EDITOR 环境变量使其与编辑器无关? (我也是在 linux 上,而不是 mac...)
  • 感谢@Edmund!以防万一,您的脚本在处理 COMMITS 的默认值时遇到问题。如果未设置,则以下代码仅将过滤器应用于(我猜/找到)最后一次提交。 "git filter-branch -f --env-filter "$ENVFILTER" HEAD~$COMMITS..HEAD >/dev/null"
【解决方案6】:

每个提交都与两个日期相关联,即提交者日期和作者日期。您可以通过以下方式查看这些日期:

git log --format=fuller

如果您想更改最近 6 次提交的作者日期和提交者日期,您可以简单地使用交互式变基:

git rebase -i HEAD~6

.

pick c95a4b7 Modification 1
pick 1bc0b44 Modification 2
pick de19ad3 Modification 3
pick c110e7e Modification 4
pick 342256c Modification 5
pick 5108205 Modification 6

# Rebase eadedca..5108205 onto eadedca (6 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit

对于您想要更改日期的所有提交,将 pick 替换为 edit(或只是 e),然后保存并退出您的编辑器。

您现在可以通过以ISO-8601 格式指定作者日期和提交者日期来修改每个提交:

GIT_COMMITTER_DATE="2017-10-08T09:51:07" git commit --amend --date="2017-10-08T09:51:07"

第一个日期是提交日期,第二个是作者日期。

然后使用 :

进入下一个提交
git rebase --continue

重复该过程,直到您修改所有提交。使用git status 检查您的进度。

【讨论】:

  • 我遵循了这个并最终陷入了“分离的头”!
  • 这是最好和最简单的答案。小提示:在git commit --amend --no-edit --date=2017-10-08T09:51:07 中使用--no-edit 来保留旧的提交信息。
  • 您可能还想更新GIT_COMMITTER_DATE,如此处所述eddmann.com/posts/…
  • @smihael 感谢您的链接。我已将您的建议包含在我的回答中。
  • 由于git log --format=fuller 以及在一个命令中更改两个日期的能力,得到了很好的答案。
【解决方案7】:
git commit --amend --date="now"

【讨论】:

    【解决方案8】:

    如何编辑多个提交日期

    其他答案对于编辑多个提交日期不是很方便。几年后我回到这个问题来分享一个技术。

    要更改最近 4 次提交的日期:

    git rebase -i HEAD~4
    

    如下编辑变基,插入exec 行以根据需要修改日期:

    pick 4ca564e Do something
    exec git commit --amend --no-edit --date "1 Oct 2019 12:00:00 PDT"
    pick 1670583 Add another thing
    exec git commit --amend --no-edit --date "2 Oct 2019 12:00:00 PDT"
    pick b54021c Add some tests
    exec git commit --amend --no-edit --date "3 Oct 2019 12:00:00 PDT"
    pick e8f6653 Fix the broken thing
    exec git commit --amend --no-edit --date "4 Oct 2019 12:00:00 PDT"
    

    更新(2021 年 9 月):

    如果你想在 rebase 指令列表 (Git 2.6+) 中查看原始提交日期:

    git config --add rebase.instructionFormat "[%ai] %s"
    

    然后你会看到类似的东西

    pick 4f5a371f [2021-09-08 02:56:50 -0700] Add npm events
    pick 67937227 [2021-09-09 03:05:42 -0700] Fixup
    

    【讨论】:

    • 很好地使用了--amend/--date 选项。比使用环境变量的my own answer 更简单。赞成。
    • 是否可以使用当前日期/时间作为参数?
    • 回复。 '是否可以使用当前日期/时间作为参数?':“现在”被理解为有效日期,因此上面的 exec 行将变为 exec git commit --amend --no-edit --date "now"
    • 作为补充,我编写了一个 bash 脚本,它将这个答案(多次提交)与接受的答案(过滤器)结合起来:gist.github.com/pixelbrackets/e2c2b451b77516e69377ecb4fd6f3a0d
    【解决方案9】:

    theospanswer 的基础上,我编写了一个名为git-cdc(用于更改日期提交)的脚本,并将其放入我的PATH

    名称很重要:git-xxx 在您的PATH 中的任何位置都允许您输入:

    git xxx
    # here
    git cdc ... 
    

    该脚本在 bash 中,即使在 Windows 上也是如此(因为 Git 会从其 msys environment 调用它)

    #!/bin/bash
    # commit
    # date YYYY-mm-dd HH:MM:SS
    
    commit="$1" datecal="$2"
    temp_branch="temp-rebasing-branch"
    current_branch="$(git rev-parse --abbrev-ref HEAD)"
    
    date_timestamp=$(date -d "$datecal" +%s)
    date_r=$(date -R -d "$datecal")
    
    if [[ -z "$commit" ]]; then
        exit 0
    fi
    
    git checkout -b "$temp_branch" "$commit"
    GIT_COMMITTER_DATE="$date_timestamp" GIT_AUTHOR_DATE="$date_timestamp" git commit --amend --no-edit --date "$date_r"
    git checkout "$current_branch"
    git rebase  --autostash --committer-date-is-author-date "$commit" --onto "$temp_branch"
    git branch -d "$temp_branch"
    

    这样,您可以输入:

    git cdc @~ "2014-07-04 20:32:45"
    

    这会将 HEAD (@~) 之前提交的作者/提交日期重置为指定日期。

    git cdc @~ "2 days ago"
    

    这会将 HEAD (@~) 之前提交的作者/提交日期重置为同一小时,但 2 天前。


    Ilya Semenov 提到in the comments

    对于 OS X,您还可以安装 GNU coreutils (brew install coreutils),将其添加到 PATH (PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"),然后使用“2 days ago”语法。

    【讨论】:

    • 对我来说,这只适用于将日期和时间引用到一个引号中:git cdc @~ "2014-07-04 20:32:45 否则它将无法识别时间并因此获得时间 00:00:00(它成为第三个参数) .
    • 对于 OS X,您还可以安装 GNU coreutils (brew install coreutils),将其添加到 PATH (PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"),然后使用“2 天前”语法。
    • @IlyaSemenov 很有趣。我已将您的评论包含在答案中以提高知名度。
    • 我正在尝试使用您的第一个示例,但我不断收到“致命:无效日期格式:”。 Mac OS X 期望的日期格式是什么?
    • @usbsnowcrash 在 mac 上不确定。第二个示例“2 days ago”有效吗?
    【解决方案10】:

    在阅读了所有答案后,我想出了一种更简洁方便的方式来一次编辑多个提交的日期,而无需交互地重新设置基准:

    git rebase HEAD~4 --exec "git commit --amend --no-edit --date 'now'"
    

    它同时改变了提交者和作者的日期。

    【讨论】:

    • 我喜欢你的回答,我需要所有本地提交,所以我做到了:git rebase origin/main --exec "git commit --amend --reset-author --no-edit"
    【解决方案11】:

    我创建了这个 npm 包来更改旧提交的日期。

    https://github.com/bitriddler/git-change-date

    示例用法:

    npm install -g git-change-date
    cd [your-directory]
    git-change-date
    

    系统将提示您选择要修改的提交,然后输入新日期。

    如果您想通过特定哈希更改提交,请运行此git-change-date --hash=[hash]

    【讨论】:

    • 我只想说这很棒而且效果很好。谢谢,您为我节省了大量时间!
    • @Kareem Elbahrawy 我收到以下错误:请帮助我(Git + Windows 10)命令失败:cd C:\D\Projects\Git\xx-xx && git filter-branch -f - -env-filter '如果 [ $GIT_COMMIT = xxxxxx ] 然后 export GIT_AUTHOR_DATE="Wed Jan 27 16:00:00 2021 +0530" export GIT_COMMITTER_DATE="Wed Jan 27 16:00:00 2021 +0530" fi' 致命:$ GIT_COMMIT:工作树中没有这样的路径。使用 'git -- ...' 指定本地不存在的路径。
    【解决方案12】:

    如果是之前的最后一次提交。

    git rebase  -i HEAD~2
    git commit --amend --date=now
    

    如果你已经推送到 orgin 并且可以强制使用:

    git push --force 
    

    如果你不能强制推送,如果它被推送,你就不能更改提交! .

    【讨论】:

      【解决方案13】:

      这是一个方便的别名,它将上次提交的提交时间和作者时间都更改为date --date 接受的时间:

      [alias]
          cd = "!d=\"$(date -d \"$1\")\" && shift && GIT_COMMITTER_DATE=\"$d\" \
                  git commit --amend --date \"$d\""
      

      用法:git cd &lt;date_arg&gt;

      例子:

      git cd now  # update the last commit time to current time
      git cd '1 hour ago'  # set time to 1 hour ago
      

      编辑: 这是一个更加自动化的版本,它检查索引是否干净(没有未提交的更改)并重用最后的提交消息,否则会失败(防傻瓜):

      [alias]
          cd = "!d=\"$(date -d \"$1\")\" && shift && \
              git diff-index --cached --quiet HEAD --ignore-submodules -- && \
              GIT_COMMITTER_DATE=\"$d\" git commit --amend -C HEAD --date \"$d\"" \
              || echo >&2 "error: date change failed: index not clean!"
      

      【讨论】:

      • 作者换了,@eold?
      【解决方案14】:

      更改作者日期和提交日期:

      GIT_COMMITTER_DATE="Wed Sep 23 9:40 2015 +0200" git commit --amend --date "Wed Sep 23 9:40 2015 +0200"
      

      【讨论】:

      • 我只需将--no-edit 添加到此命令中,以避免更改提交消息。干得好!
      【解决方案15】:

      以下 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"
      }
      

      【讨论】:

      • 你有一个错误:if [[ -z "$commit" ]] -> if [[ -z "$date_timestamp" ]]
      • 不错!我建议在方法末尾设置GIT_COMMITTER_DATE=,以防止任何进一步的手动提交以保持指定的日期。
      • @loopkin,GIT_COMMITTER_DATE 只是为“git commit”命令设置的,所以之后不需要清除它
      • @nimrodm,我刚刚再次测试,你是对的。感谢您指出这一点。
      【解决方案16】:

      修改最后一次提交的日期和时间的最简单方法

      git commit --amend --date="12/31/2021 @ 14:00"
      

      【讨论】:

      • 这只会改变AuthorDate,而不是CommitDate。你可以通过输入git log --format=fuller看到它不起作用。
      【解决方案17】:

      如果尚未推送提交,那么我可以使用类似的东西:

      git commit --amend --date=" Wed Mar 25 10:05:44 2020 +0300"
      

      之后 git bash 会打开带有已应用日期的编辑器,因此您只需通过在 VI 编辑器命令模式下键入“:wq”来保存它,然后就可以推送它了

      【讨论】:

      • 只是添加一个不错的答案:如果您不想编辑提交消息(如果您只想更改提交日期),请使用 --no-edit 选项。
      • 另外,如果提交已经被推送,您仍然可以使用git push -f(强制更新)推送更改的提交。不过,这可能会产生副作用。 (特别是如果很多人有存储库的本地克隆)
      【解决方案18】:

      如果您想获得另一个提交的确切日期(假设您对一个提交进行了变基编辑并希望它具有原始预变基版本的日期):

      git commit --amend --date="$(git show -s --format=%ai a383243)"
      

      这会将 HEAD 提交的日期更正为完全提交日期 a383243(如果有歧义,请包含更多数字)。它还会弹出一个编辑器窗口,以便您编辑提交消息。

      这是您通常关心的作者日期 - 请参阅提交者日期的其他答案。

      【讨论】:

        【解决方案19】:

        如果您想在标准 Windows 命令行中执行接受的答案 (https://stackoverflow.com/a/454750/72809),则需要以下命令:

        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"
        

        注意事项:

        • 可能可以将命令拆分为多行(Windows 支持使用尖括号符号^ 进行行拆分),但我没有成功。
        • 您可以编写 ISO 日期,从而节省大量时间来寻找正确的星期几,并避免对元素顺序的普遍困扰。
        • 如果您希望 Author 和 Committer 日期相同,则只需引用之前设置的变量即可。

        非常感谢blog post by Colin Svingen。尽管他的代码对我不起作用,但它帮助我找到了正确的解决方案。

        【讨论】:

          【解决方案20】:

          对于那些使用 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/

          【讨论】:

            【解决方案21】:

            将最后一次提交的日期设置为当前日期

            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"
            

            将任意提交的日期设置为任意日期或当前日期

            变基到之前的提交并停止修改:

            1. git rebase &lt;commit-hash&gt;^ -i
            2. pick 替换为e(编辑)与该提交(第一个)的行
            3. 退出编辑器(在 VIM 中,ESC 后跟 :wq
            4. 要么:
            • 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"

            来源: https://codewithhugo.com/change-the-date-of-a-git-commit/

            【讨论】:

              【解决方案22】:

              编辑最近 3 次提交的作者日期和提交日期:

              git rebase -i HEAD~3 --committer-date-is-author-date --exec "git commit --amend --no-edit --date=now"
              

              --exec 命令附加在变基中的每一行之后,您可以使用--date=... 选择作者日期,提交者日期将与作者日期相同。

              【讨论】:

                【解决方案23】:

                我想确保在午夜准确地更新我的代码的版权 cmets,并且我不想冒着使用 atcron 的微小延迟的风险。所以,我提交了代码,然后:

                GIT_COMMITTER_DATE="Fri Jan 1 00:00:00 2021 +1000" git commit --amend --no-edit --date="Fri Jan 1 00:00:00 2021 +1000"
                

                (或者甚至将 UTC 偏移量设置为 0?决定...)现在我可以推送了!

                大家新年快乐?

                【讨论】:

                  【解决方案24】:

                  已经有很多很好的答案,但是当我想在一天或一个月内更改多次提交的日期时,我找不到合适的答案。因此,我为此创建了一个新脚本并进行了解释,希望对某人有所帮助:

                  #!/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
                  

                  【讨论】:

                    【解决方案25】:

                    用于将最后 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 配置为签署提交)

                    【讨论】:

                      【解决方案26】:

                      TL;DR:匹配日期 + 重新创建 GPG 签名

                      (如果您知道剥离以保留 原始 签名的解决方法,请评论/编辑。)


                      我会碰到这个旧线程,因为已经引入了签名提交的功能,所有这些git filter-branch 和喜欢基本上都按照文档中的规定剥离签名:

                      ...如果标签附加了签名,则签名将被剥离。根据定义,保留签名是不可能的。 ...(来源:--tag-name-filter

                      但它也会破坏 GitHub 提交上漂亮的 Verified 徽章(如果以相同方式实现,则在其他 Git 托管位置),所以这也将解决这个问题。 部分。

                      Afaik 不可能通过git 命令破坏(GPG)签名,它包含提交日期而不是签名日期in a simple way,因此甚至如果创作和提交的日期被移动,它仍然是当前日期,例如:

                      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
                      

                      因此,假设您有一个要从某个提交签名的存储库(我会选择根提交;如果其他人在该存储库上工作,则不推荐)。 git commitsays 的文档也从环境变量中提取数据(如果存在),因此我们有一个地方可以输入。

                      要检索数据(可以使用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
                      

                      这将用于分支&lt;branch-name&gt; 的根提交,保留使用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=&lt;fingerprint&gt;

                      这将遍历每个edit-marked 提交,设置提交者的日期以匹配作者的日期,保留任何空提交,不会触及整个补丁主体,并将添加带有日期的签名命令已执行。

                      看到fatal: No rebase in progress? 后,按Ctrl-C 停止循环并检查日志以确认日期匹配并且签名随处可见:

                      git log --pretty=fuller --show-signature
                      

                      如果日志中一切正常,只需发出 git push --force 即可。现在您应该会看到每个提交的 Verified 徽章。

                      Example with a real history tree。 GitHub 似乎并不关心签名的日期(任何地方都没有参考),但它仍然会出现在 git log 中。

                      【讨论】:

                        【解决方案27】:

                        我最近需要这个,我自己的脚本看起来很像 git-redate

                        但是,我的脚本只进行了最少的修改,并且重写(如果您需要更新)许多提交所需的时间更少,因为它一次完成所有提交

                        change_git_history

                        实际上这也允许更改提交消息

                        说明:

                        脚本连接了一堆看起来像这样的 bash if 表达式

                        这里是修改提交日期的那些

                        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"
                        

                        (文档在这里filter-branch man

                        【讨论】:

                        • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
                        • 谢谢@SimasJoneliunas 我已经更新了答案:)
                        猜你喜欢
                        • 2014-07-12
                        • 2018-12-30
                        • 2021-02-06
                        • 2021-02-15
                        • 1970-01-01
                        • 2020-07-30
                        • 2021-12-11
                        相关资源
                        最近更新 更多