如果提交已经被提交并推送到仓库,如果想改变某个特定提交的作者,我可以这样做:
git commit --amend --reset-author
但是,这将更改原始提交日期。我如何重置作者,但保留原始提交日期?
jslywgbw1#
正如在其他一些答案中提到的,你可能会用途:
git commit --amend --reset-author --no-edit --date="<old-date>"
虽然这样做是可行的,但要把旧的日期放回原处需要大量的手工复制或输入。您可能希望通过只获取日志中最后一个条目的日期来自动获取日期:
git log -n 1 --format=%aD
将两者结合起来,使用一些shell魔法:
git commit --amend --reset-author --no-edit --date="$(git log -n 1 --format=%aD)"
这会自动将日志中最后一次提交的日期(也就是要修改的日期)设置为作者变更后的新提交的日期。现在在大量的提交中更改作者,比如说因为你忘记在克隆的git repo中设置作者,交互式rebase是你的朋友:
git rebase -i <commit before wrong author and email>
然后将所有要调整的提交从pick更改为edit并保存文件。Git在每个要编辑的提交时停止,然后重新运行:
pick
edit
git commit --amend --reset-author --no-edit --date="$(git log -n 1 --format=%aD)" && \ git rebase --continue
如果提交的次数比较少,你可以使用shell的arrow-up键重复这个命令,直到rebase完成。如果提交的次数比较多,输入arrow-up + return就太繁琐了,你可能需要创建一个小的shell脚本来重复上面的命令,直到rebase完成。
arrow-up
return
6tdlim6h2#
以下是如何使用rebase并保留 * 提交日期 * 和 * 作者日期:
rebase
git -c rebase.instructionFormat='%s%nexec GIT_COMMITTER_DATE="%cD" GIT_AUTHOR_DATE="%aD" git commit --amend --no-edit --reset-author' rebase -i <commit before wrong author and email>
这会把你带到你的git编辑器,你可以立即退出。如果它把你带到vim,你不知道该怎么做,输入:x,然后按回车键。基于this Reddit thread。
:x
omqzjyyz3#
1.如果您正在执行rebase,则使用committer-date-is-author-date来保持日期与以前相同。
committer-date-is-author-date
$ git commit --amend --committer-date-is-author-date
1.对于正常修改,复制original committer time并在使用--date标志修改时覆盖时间。
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"
iyzzxitl4#
嗯,最后,我找到了一个对我来说更简单的解决方案。我在包含git项目gitrewrite.sh的目录中创建了一个脚本,并修改了它的权限,以便它可以被执行:
gitrewrite.sh
$ chmod 700 gitrewrite.sh
然后我在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
然后在terminal中运行脚本:
$ ./gitrewrite.sh
就这样。历史被改写。将代码推送到存储库并添加force标志。$ git push -f
force
$ git push -f
重要提示:
对于其他阅读它的人,请记住,这将在git历史中创建新的引用,所以只能在私有仓库或尚未与其他人共享的仓库中执行此操作,因为它可能会导致引用损坏!我的是私人回购,所以不用担心这一部分。如果它是公开的,那么也许使用其他建议的答案可能是一个更好的选择。
z2acfund5#
我们可以使用rebase autosquash来获得所需的行为:
git commit --fixup HEAD git rebase --autosquash --committer-date-is-author-date HEAD~2
第一个命令在当前HEAD提交上创建一个新提交作为修正提交,修正提交意味着如果稍后使用--autosquash运行rebase,这个新提交将在旧提交上修正(与交互式rebase中的fixup相同)。第二个触发到HEAD上的rebase ~2 -表示HEAD的第二级父级,或原始HEAD的父级(在我们添加修正之前),所以这将触发一个只包含2个提交的变基。提交将被压缩在一起,并且添加-- committer-date-is-author-date意味着它将使用原始创作的提交的日期,而不是新提交真正创建的当前日期。警告:如果提交已经被推送,如果你以任何方式重写推送的提交并强制推送,你将重写发布的历史,这通常被认为是一件非常糟糕的事情。如果没有其他人会在你的提交之上工作,这不是一个问题。
--autosquash
-- committer-date-is-author-date
dauxcl2d6#
与@Aleks answer非常相似,我在git-tower上找到了最适合我的解决方案:https://www.git-tower.com/learn/git/faq/change-author-name-email您可以根据需要在以下脚本中设置WRONG_EMAIL、NEW_NAME和NEW_EMAIL的值,并在您的git项目中运行它:
WRONG_EMAIL
NEW_NAME
NEW_EMAIL
git filter-branch --env-filter ' WRONG_EMAIL="wrong@example.com" NEW_NAME="New Name Value" NEW_EMAIL="correct@example.com" if [ "$GIT_COMMITTER_EMAIL" = "$WRONG_EMAIL" ] then export GIT_COMMITTER_NAME="$NEW_NAME" export GIT_COMMITTER_EMAIL="$NEW_EMAIL" fi if [ "$GIT_AUTHOR_EMAIL" = "$WRONG_EMAIL" ] then export GIT_AUTHOR_NAME="$NEW_NAME" export GIT_AUTHOR_EMAIL="$NEW_EMAIL" fi ' --tag-name-filter cat -- --branches --tags
警告:这将改变作者和所有提交的电子邮件,其中WRONG_EMAIL显示为作者。引用自https://git-scm.com/docs/git-filter-branchgit filter-branch有很多缺陷[...]。这些安全和性能问题无法向后兼容修复,因此不建议使用它。请使用替代的历史过滤工具,如git filter-repo。如果你还是搞砸了,我希望你知道如何使用git reflog。正如@Aleks已经说过的:只在私人仓库里做这种事
git reflog
1dkrff037#
错误是在使用--author时使用--reset-author,这样就足够了:
--author
--reset-author
git commit --amend --author 'My Name <email@example.com>'
从上面链接的选项的文档中可以看出,用于重置状态的选项:这也会更新作者时间戳。而仅仅覆盖作者的选项(可用的since forever,v1.5.0)没有提到任何这样的副作用。
7条答案
按热度按时间jslywgbw1#
正如在其他一些答案中提到的,你可能会用途:
虽然这样做是可行的,但要把旧的日期放回原处需要大量的手工复制或输入。您可能希望通过只获取日志中最后一个条目的日期来自动获取日期:
将两者结合起来,使用一些shell魔法:
这会自动将日志中最后一次提交的日期(也就是要修改的日期)设置为作者变更后的新提交的日期。
现在在大量的提交中更改作者,比如说因为你忘记在克隆的git repo中设置作者,交互式rebase是你的朋友:
然后将所有要调整的提交从
pick
更改为edit
并保存文件。Git在每个要编辑的提交时停止,然后重新运行:如果提交的次数比较少,你可以使用shell的
arrow-up
键重复这个命令,直到rebase完成。如果提交的次数比较多,输入arrow-up
+return
就太繁琐了,你可能需要创建一个小的shell脚本来重复上面的命令,直到rebase完成。6tdlim6h2#
以下是如何使用
rebase
并保留 * 提交日期 * 和 * 作者日期:这会把你带到你的git编辑器,你可以立即退出。如果它把你带到vim,你不知道该怎么做,输入
:x
,然后按回车键。基于this Reddit thread。
omqzjyyz3#
1.如果您正在执行
rebase
,则使用committer-date-is-author-date
来保持日期与以前相同。1.对于正常修改,复制
original committer time
并在使用--date
标志修改时覆盖时间。iyzzxitl4#
嗯,最后,我找到了一个对我来说更简单的解决方案。我在包含git项目
gitrewrite.sh
的目录中创建了一个脚本,并修改了它的权限,以便它可以被执行:然后我在shell脚本中放置:
然后在terminal中运行脚本:
就这样。历史被改写。
将代码推送到存储库并添加
force
标志。$ git push -f
重要提示:
对于其他阅读它的人,请记住,这将在git历史中创建新的引用,所以只能在私有仓库或尚未与其他人共享的仓库中执行此操作,因为它可能会导致引用损坏!
我的是私人回购,所以不用担心这一部分。如果它是公开的,那么也许使用其他建议的答案可能是一个更好的选择。
z2acfund5#
我们可以使用rebase autosquash来获得所需的行为:
第一个命令在当前HEAD提交上创建一个新提交作为修正提交,修正提交意味着如果稍后使用
--autosquash
运行rebase,这个新提交将在旧提交上修正(与交互式rebase中的fixup相同)。第二个触发到HEAD上的rebase ~2 -表示HEAD的第二级父级,或原始HEAD的父级(在我们添加修正之前),所以这将触发一个只包含2个提交的变基。提交将被压缩在一起,并且添加-- committer-date-is-author-date
意味着它将使用原始创作的提交的日期,而不是新提交真正创建的当前日期。警告:如果提交已经被推送,如果你以任何方式重写推送的提交并强制推送,你将重写发布的历史,这通常被认为是一件非常糟糕的事情。如果没有其他人会在你的提交之上工作,这不是一个问题。
dauxcl2d6#
与@Aleks answer非常相似,我在git-tower上找到了最适合我的解决方案:
https://www.git-tower.com/learn/git/faq/change-author-name-email
您可以根据需要在以下脚本中设置
WRONG_EMAIL
、NEW_NAME
和NEW_EMAIL
的值,并在您的git项目中运行它:警告:这将改变作者和所有提交的电子邮件,其中
WRONG_EMAIL
显示为作者。引用自https://git-scm.com/docs/git-filter-branch
git filter-branch有很多缺陷[...]。这些安全和性能问题无法向后兼容修复,因此不建议使用它。请使用替代的历史过滤工具,如git filter-repo。
如果你还是搞砸了,我希望你知道如何使用
git reflog
。正如@Aleks已经说过的:只在私人仓库里做这种事1dkrff037#
错误是在使用
--author
时使用--reset-author
,这样就足够了:从上面链接的选项的文档中可以看出,用于重置状态的选项:
这也会更新作者时间戳。
而仅仅覆盖作者的选项(可用的since forever,v1.5.0)没有提到任何这样的副作用。