如何更新git commit author,但在修改时保留原始日期?

Ale*_*eks 7 git

如果提交已经完成并推送到存储库,并且如果想要为某个特定提交更改作者,我可以这样做:

git commit --amend --reset-author
Run Code Online (Sandbox Code Playgroud)

但是,这将改变原始的承诺日期.

如何重置作者,但保留原始提交者日期?

Dha*_*tle 54

以下是如何使用rebase并保留提交日期作者日期:

git -c rebase.instructionFormat='%s%nexec GIT_COMMITTER_DATE="%cD" GIT_AUTHOR_DATE="%aD" git commit --amend --no-edit --reset-author' rebase -f <commit/branch before wrong author and email, or --root to rebase all>
Run Code Online (Sandbox Code Playgroud)

基于此 Reddit 线程

  • 最好的!回答!曾经! (4认同)

Hol*_*nke 11

正如其他一些答案中提到的,您可能会使用:

git commit --amend --reset-author --no-edit --date="<old-date>"
Run Code Online (Sandbox Code Playgroud)

虽然这是有效的,但需要大量手动复制或输入才能使旧日期到位。您可能希望通过仅获取日志中最后一个条目的日期来自动获取日期:

git log -n 1 --format=%aD
Run Code Online (Sandbox Code Playgroud)

将两者结合起来并使用一些 shell 魔法:

git commit --amend --reset-author --no-edit --date="$(git log -n 1 --format=%aD)"
Run Code Online (Sandbox Code Playgroud)

这会自动将日志中最后一次提交的日期(也就是要修改的日期)设置为更改作者的新提交的日期。

现在在大量提交上更改作者,比如说因为您忘记在克隆的 git 存储库中设置作者,交互式 rebase 是您的朋友:

git rebase -i <commit before wrong author and email>
Run Code Online (Sandbox Code Playgroud)

然后将所有要调整的提交更改pickedit并保存文件。Git 在每次要编辑的提交时停止,然后您重新运行:

git commit --amend --reset-author --no-edit --date="$(git log -n 1 --format=%aD)" && \
    git rebase --continue
Run Code Online (Sandbox Code Playgroud)

如果是合理的少量提交,您可以使用 shellsarrow-up键重复此命令,直到变基完成。如果有大量提交,那么输入arrow-up+return会变得太乏味,您可能想要创建一个小的 shell 脚本,重复上述命令直到 rebase 完成。

  • 无需重复该命令。您可以使用“-x &lt;cmd&gt;”在待办事项列表的每一行后面附加“exec &lt;cmd&gt;”。当然,您应该在不想编辑的提交后删除“exec &lt;cmd&gt;”。 (4认同)
  • 这非常有帮助!不过请注意:“--date”似乎只更新作者日期。为了更新提交者日期(github 中显示的内容),我必须调整脚本以在每次修改时存储 `GIT_COMMITTER_DATE`: `export GIT_COMMITTER_DATE=$(git log -n 1 --format=%aD) &amp;&amp; git提交 --amend --reset-author --no-edit --date="$GIT_COMMITTER_DATE" &amp;&amp; git rebase --continue` (4认同)
  • 我没有花太多时间研究这个,所以我确信这里有人可以进一步优化它。但如果它对其他人有帮助,我将其作为 git 别名添加到我的 .gitconfig 中: `update-user-keep-date = "!export GIT_COMMITTER_DATE=$(git log -n 1 --format=%aD); git commit --amend --reset-author --no-edit --date=\"$GIT_COMMITTER_DATE\";git rebase --continue"` 所以现在只需在每次提交时运行 `git update-user-keep-date`修改可以轻松更新提交。 (3认同)

Ale*_*eks 9

嗯,最后,我找到了一个更简单的解决方案。我在包含 git project 的目录中创建了一个脚本gitrewrite.sh,并修改了它的权限以便它可以被执行:

$ chmod 700 gitrewrite.sh
Run Code Online (Sandbox Code Playgroud)

然后我放在shell脚本中:

#!/bin/sh

git filter-branch --env-filter '
NEW_NAME="MyName"
NEW_EMAIL="my-name@my-domain.com"
if [ "$GIT_COMMIT" = "afdkjh1231jkh123hk1j23" ] || [ "$GIT_COMMIT" = "43hkjwldfpkmsdposdfpsdifn" ]
then
    export GIT_COMMITTER_NAME="$NEW_NAME"
    export GIT_COMMITTER_EMAIL="$NEW_EMAIL"
    export GIT_AUTHOR_NAME="$NEW_NAME"
    export GIT_AUTHOR_EMAIL="$NEW_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
Run Code Online (Sandbox Code Playgroud)

然后在终端中运行脚本:

$ ./gitrewrite.sh
Run Code Online (Sandbox Code Playgroud)

就是这样。历史被改写了。

将代码推送到存储库并添加一个force标志。

$ git push -f

重要的提示:

对于阅读它的其他人,请记住,这将在 git 历史记录中创建新的引用,因此只能在私有存储库或仍未与他人共享的存储库中执行此操作,因为它可能导致引用损坏!

我的是一个私人回购,所以不用担心那部分。如果它是公开的,那么使用其他建议的答案可能是更好的选择。


Saj*_*han 8

  1. 如果您正在rebase使用committer-date-is-author-date,那么使用以保持日期相同.

    $ git commit --amend --committer-date-is-author-date
    
    Run Code Online (Sandbox Code Playgroud)
  2. 对于正常修改,复制original committer time并覆盖修改使用--date标志的时间.

    $ git log                     # copy the 'original-committer-time'
    $ git commit --amend --reset-author --date="<original-committer-time>"
    
    # e.g. git commit --amend --date="Fri Dec 23 18:53:11 2016 +0600"
    
    Run Code Online (Sandbox Code Playgroud)

  • `git commit` 说 `未知选项 \`committer-date-is-author-date'` (11认同)
  • 好的,但顺便说一句,在执行 rebase 时使用了 `--committer-date-is-author-date`,而不是在提交时使用。当与 `git commit --committer-date-is-author-date` 一起使用时,它报告为未知命令。在这两种情况下它都不起作用。 (3认同)

avm*_*han 5

我们可以使用 rebase autosquash 获得所需的行为:

git commit --fixup HEAD
git rebase --autosquash --committer-date-is-author-date HEAD~2
Run Code Online (Sandbox Code Playgroud)

第一个命令在当前 HEAD 提交上创建一个新提交作为修复提交。--autosquash修复提交意味着如果 rebase 稍后运行,则此新提交将在旧提交上修复(与交互式 rebase 中的修复相同)。第二个触发对 HEAD~2 的变基 - 表示 HEAD 的第二级父级,或原始 HEAD 的父级(在我们添加修复之前),因此这将仅触发 2 次提交的变基。由于我们添加了--autosquash,提交将被压缩在一起,添加-- committer-date-is-author-date意味着它将使用原始创作提交的日期,而不是实际创建新提交的当前日期。

警告:如果提交已经被推送,如果你以任何方式重写推送的提交并强制推送,你将重写已发布的历史,这通常被认为是一件非常糟糕的事情。如果没有其他人将他们的工作建立在您的提交之上,这不是问题。

  • 我不确定这有什么帮助?您能否解释这些步骤,以便我们和普通 SO 用户知道他在做什么? (3认同)

sam*_*mpi 5

错误是使用这样的--reset-author方式就足够了:--author

git commit --amend --author 'My Name <email@example.com>'
Run Code Online (Sandbox Code Playgroud)

从上面链接的选项的文档中可以看出,重置选项状态:

这也更新了作者时间戳。

虽然仅覆盖作者的选项(v1.5.0 起永远可用)并没有提及任何此类副作用。

要修改多个提交或整个提交历史记录,可以使用以下命令:

git rebase -r <commit/branch before wrong author and email or '--root' for all commits> --exec "git commit --amend --no-edit --author 'My Name <email@example.com>'"
Run Code Online (Sandbox Code Playgroud)