如何更改多个提交的作者和提交者姓名/电子邮件?

问:

如何更改一系列提交的作者?

答1:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

注意:此答案会更改 SHA1,因此在已推送的分支上使用它时要小心。如果您只想修正姓名的拼写或更新旧电子邮件,Git 允许您执行此操作,而无需使用 .mailmap 重写历史记录。请参阅my other answer。

使用变基

首先,如果您还没有这样做,您可能希望在 git-config 中修复您的名字:

git config --global user.name "New Author Name"
git config --global user.email ""

这是可选的,但它也将确保重置提交者名称,假设这是您需要的。

要使用变基重写一系列提交的元数据,请执行

git rebase -r  \
    --exec 'git commit --amend --no-edit --reset-author'

–exec 将在每次提交被重写后运行 git commit 步骤(就像您重复运行 git commit && git rebase --continue 一样)。

如果您还想更改您的第一个提交(也称为“根”提交),则必须将 --root 添加到 rebase 调用。

这会将提交者和作者都更改为您的 user.name/user.email 配置。如果您不想更改该配置,可以使用 --author “New Author Name email@address.example” 而不是 --reset-author。请注意,这样做不会更新提交者——只是作者。

单次提交

如果您只想更改最近的提交,则不需要 rebase。只需修改提交:

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

对于较旧的 Git 客户端(2020 年 7 月之前)

-r,–rebase-merges 可能不适合您。作为替代,您可以使用 -p。请注意,-p 存在严重问题,现已弃用。

非常适合奇怪的提交 - 如果您正在配对并且忘记更改作者,则很有用

+1 提及典型的错误修复的用例: git commit --amend --author=username

这是完美的,我最常见的用例是我坐在另一台电脑前忘记设置作者,因此通常有 < 5 次左右的提交需要修复。

正确配置 user.name 和 user.email 后,git commit --amend --reset-author 也可以工作。

使用 ~/.gitconfig 中的 user.name 和 user.email 重写 之后所有提交的作者信息:运行 git rebase -i --exec 'git commit --amend --reset-author --no-edit',保存,退出。无需编辑!

答2:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

这个答案使用了 git-filter-branch,文档现在给出了这个警告: git filter-branch 有很多陷阱,可以产生不明显的预期历史重写的错误(并且可以让你几乎没有时间去调查这样问题,因为它的性能如此糟糕)。这些安全和性能问题不能向后兼容修复,因此不建议使用它。请使用替代的历史过滤工具,例如 git filter-repo。如果您仍然需要使用 git filter-branch,请仔细阅读安全(和性能)以了解 filter-branch 的地雷,然后尽可能合理地避免其中列出的许多危害。

更改作者(或提交者)将需要重写所有历史记录。如果您对此感到满意并认为值得,那么您应该查看 git filter-branch。手册页包含几个示例以帮助您入门。另请注意,您可以使用环境变量来更改作者、提交者、日期等的名称——请参阅 git manual page 的“环境变量”部分。

具体来说,您可以使用以下命令修复所有分支和标签的所有错误作者姓名和电子邮件(来源:GitHub help):

#!/bin/sh

git filter-branch --env-filter '
OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

使用替代历史过滤工具git filter-repo,您可以先安装它并按照gitmailmap的格式构造一个git-mailmap。

Proper Name  Commit Name 

然后使用创建的邮件映射运行 filter-repo:

git filter-repo --mailmap git-mailmap

执行脚本后,您可以通过执行“git update-ref -d refs/original/refs/heads/master”删除备份分支。

@rodowi,它复制了我所有的提交。

@RafaelBarros 作者信息(就像历史上的其他任何内容一样)是提交的 sha 密钥的一部分。对历史记录的任何更改都会导致所有提交的新 id 的重写。所以不要重写共享仓库或确保所有用户都知道它......

使用 git push --force --tags origin HEAD:master 解决

重要!!! 在执行脚本之前,请正确设置您的 user.name 和 user.email git config 参数!执行脚本后,您将拥有一些称为“原始”的重复备份历史记录!通过 git update-ref -d refs/original/refs/heads/master 将其删除,然后检查 .git/refs/original 文件夹结构是否为空,然后使用 rm -rf .git/refs/original 将其删除。最后,您可以通过以下方式验证新的重写日志:git log --pretty=format:"[%h] %cd - Committer: %cn (%ce), Author: %an (%ae)"!还有一件事:.git/logs 有一些日志文件仍然使用您的旧名称!

答3:

huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。

一个班轮,但如果您有一个多用户存储库,请小心 - 这会将所有提交更改为具有相同的(新)作者和提交者。

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD

在字符串中使用换行符(这在 bash 中是可能的):

git filter-branch -f --env-filter "
    GIT_AUTHOR_NAME='Newname'
    GIT_AUTHOR_EMAIL='new@email'
    GIT_COMMITTER_NAME='Newname'
    GIT_COMMITTER_EMAIL='new@email'
  " HEAD

如果在命令末尾指定 HEAD,为什么它会重写所有提交?

这不适用于我的 bitbucket 存储库,知道吗?我在建议的命令之后执行 git push --force --tags origin 'refs/heads/*'

推送命令是:$git push --force --tags origin 'refs/heads/master'

整洁的;这也保留了旧的时间戳。

@HARSHNILESHPATHAK 请注意,对于最近创建的存储库,分支 master 已重命名为 main,因此命令变为 $git push --force --tags origin 'refs/heads/main'

答4:

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

你也可以这样做:

git filter-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "" ];
        then
                GIT_COMMITTER_NAME="";
                GIT_AUTHOR_NAME="";
                GIT_COMMITTER_EMAIL="";
                GIT_AUTHOR_EMAIL="";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

请注意,如果您在 Windows 命令提示符下使用此命令,则需要使用 " 而不是 ':

git filter-branch --commit-filter "
        if [ "$GIT_COMMITTER_NAME" = "" ];
        then
                GIT_COMMITTER_NAME="";
                GIT_AUTHOR_NAME="";
                GIT_COMMITTER_EMAIL="";
                GIT_AUTHOR_EMAIL="";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi" HEAD

使用 env-filter 不是更简单的解决方案吗?不知道为什么这会获得更多选票。

然后链接坏了。我们如何将这些更改推送到另一个存储库?

env-filter 将更改所有提交。该解决方案允许有条件的。

"A previous backup already exists in refs/original/ Force overwriting the backup with -f" 抱歉,但是当您执行此脚本两次时,-f -flag 将在哪里。实际上,这是在布赖恩的回答中,对于过滤器分支之后的干扰是解决方案感到抱歉。

@user208769 env-filter 也允许有条件的;看看我的回答:-)

答5:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

当您没有初始化 $HOME/.gitconfig 时会发生这种情况。您可以将其修复为:

git config --global user.name "you name"
git config --global user.email you@domain.example
git commit --amend --reset-author

使用 Git 版本 1.7.5.4 进行测试。

请注意,这仅修复了最后一次提交。

这在最后一次提交时效果很好。很好很简单。 必须是全局更改,使用 --local 也可以

这个是我的大赢家!如果您使用错误的作者信息创建提交,然后通过 git config 事后设置正确的作者,git commit --amend --reset-author --no-edit 命令特别有用。当我不得不更新我的电子邮件时,刚刚节省了我的 a$$。

答案可能有点矫枉过正。首先检查这是否满足您的用例 - stackoverflow.com/a/67363253/8293309

答6:

huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。

如果只有前几个提交的作者不好,您可以使用 exec 命令和 --amend 提交在 git rebase -i 内执行所有操作,如下所示:

git rebase -i HEAD~6 # as required

它为您提供了可编辑的提交列表:

pick abcd Someone else's commit
pick defg my bad commit 1
pick 1234 my bad commit 2

然后在所有作者不好的行之后添加 exec … --author=“…” 行:

pick abcd Someone else's commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name " -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name " -C HEAD

保存并退出编辑器(运行)。

这个解决方案的打字时间可能比其他解决方案长,但它是高度可控的——我确切地知道它命中了什么提交。

感谢@asmeurer 的启发。

绝对棒极了。您可以通过在 repo 的本地配置中设置 user.name 和 user.email 来缩短它,然后每行只有 exec git commit --amend --reset-author -C HEAD 吗?

使用过滤器分支的规范答案只是为我删除了 refs/heads/master。所以 +1 为您的可控、可编辑的解决方案。谢谢!

代替 git rebase -i HEAD^^^^^^ 你也可以写 git rebase -i HEAD~6

请注意,这会更改提交的时间戳。请参阅 stackoverflow.com/a/11179245/1353267 以恢复到正确的时间戳

对于与我遇到同样问题的其他人,如果您尝试包含初始提交并且您得到 fatal: Needed a single revision,请尝试 git rebase -i --root

答7:

一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会

对于单个提交:

git commit --amend --author="Author Name "

(摘自 asmeurer 的回答)

但这只是在它是最近的提交的情况下

根据 git help commit,git commit --amend 在“当前分支的尖端”(即 HEAD)更改提交。这通常是最近的提交,但您可以通过第一个使用 git checkout 或 git checkout 提交的 checking out 使其成为您想要的任何提交。

但是如果你这样做,所有已经将该提交作为父提交的提交都将指向错误的提交。此时最好使用过滤器分支。

@JohnGietzen:您可以将提交重新设置为已更改以解决该问题的提交。但是,如果您进行 >1 次提交,那么如前所述,filter-branch 可能会容易得多。

请注意,此更改仅提交 author 而不是 committer

答8:

huntsbot.com – 高效赚钱,自由工作

GitHub 最初有一个很好的解决方案 (broken link),它是以下 shell 脚本:

#!/bin/sh

git filter-branch --env-filter '

an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITTER_NAME"
cm="$GIT_COMMITTER_EMAIL"

if [ "$GIT_COMMITTER_EMAIL" = "your@email.to.match.example" ]
then
    cn="Your New Committer Name"
    cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "your@email.to.match.example" ]
then
    an="Your New Author Name"
    am="Your New Author Email"
fi

export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_COMMITTER_EMAIL="$cm"
'

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

工作完美。只需要在其他本地存储库上 git reset --hard HEAD^ 几次才能将它们升级到早期版本,git pull-ed 修改后的版本,这里我没有任何包含 unknown 的行(喜欢 git 的默认设置) .

在这之后我无法推动。我必须使用“-f”吗?

我做了git push -f。此外,在此之后必须重新克隆本地存储库。

如果您需要在特定分支上运行 shell 脚本,您可以将最后一行更改为:“' master..your-branch-name”(假设您是 master 的分支)。

由于脚本已更新,请单击链接

答9:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

用于更改最后 N 次提交的作者的单个命令:

git rebase -i HEAD~N -x "git commit --amend --author 'Author Name ' --no-edit"

笔记

将 HEAD~N 替换为参考,直到您要重写提交。这可以是哈希、HEAD~4、分支名称、…

–no-edit 标志确保 git commit --amend 不要求额外确认

当您使用 git rebase -i 时,您可以手动选择更改作者的提交,

您编辑的文件将如下所示:

pick 897fe9e simplify code a little
exec git commit --amend --author 'Author Name ' --no-edit
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name ' --no-edit
pick dc18f70 bugfix
exec git commit --amend --author 'Author Name ' --no-edit

然后,您仍然可以修改一些行以查看要更改作者的位置。这为您在自动化和控制之间提供了一个很好的中间地带:您会看到将要运行的步骤,一旦您保存,所有内容都会立即应用。

请注意,如果您已经使用 git config user.name <your_name> 和 git config user.email <your_email> 修复了作者信息,您还可以使用此命令:

git rebase -i HEAD~N -x "git commit --amend --reset-author --no-edit"

打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!

我使用了 HEAD~8,它显示的比最后 8 次提交要多。

@BryanBryce 如果涉及合并提交,事情会变得复杂:)

您使用 --root 而不是 HEAD~N 来编辑整个历史记录(包括初始提交),并使用 --reset-author 而不是 --author ... 来获取当前提交者

我的用例是我必须更改一些私人存储库中的所有过去提交,因为我的推送使用不同的用户名,没有附加电子邮件。第一个位允许我更改前 N 次提交的作者和电子邮件,但它没有保留提交时间戳,这些时间戳随之更新。我解决了这个by using this script。它既漂亮又干净,允许我将整个提交历史更改为单个用户名和电子邮件,同时保留提交时间戳。

@PedroHenrique:您需要将 HEAD~4 替换为引用,直到您要重写提交的位置...我会尝试在我的回答中使这一点更清楚。正如我之前提到的:当心合并提交,你会遇到复杂的东西

答10:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

正如 docgnome 所提到的,重写历史是危险的,并且会破坏其他人的存储库。

但是如果你真的想这样做并且你在一个 bash 环境中(在 Linux 上没问题,在 Windows 上,你可以使用 git bash,它是 git 安装提供的),使用 git filter-branch:

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL'

为了加快速度,您可以指定要重写的修订范围:

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL' HEAD~20..HEAD

请注意,这将留下任何指向旧提交的标签。 --tag-name-filter cat 是“让它工作”选项。

@romkyns 关于如何更改标签的任何想法?

@NickVolynkin 是的,您指定 --tag-name-filter cat。这确实应该是默认行为。

答案可能有点矫枉过正。首先检查这是否满足您的用例 - stackoverflow.com/a/67363253/8293309

答11:

huntsbot.com – 高效赚钱,自由工作

您可以将其用作别名,以便执行以下操作:

git change-commits GIT_AUTHOR_NAME "old name" "new name"

或最后 10 次提交:

git change-commits GIT_AUTHOR_EMAIL "old@email.com" "new@email.com" HEAD~10..HEAD

添加到 ~/.gitconfig:

[alias]
    change-commits = "!f() { VAR=$1; OLD=$2; NEW=$3; shift 3; git filter-branch --env-filter \"if [[ \\\"$`echo $VAR`\\\" = '$OLD' ]]; then export $VAR='$NEW'; fi\" $@; }; f "

来源:https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig

希望它是有用的。

“git:'change-commits' 不是 git 命令。请参阅 'git --help'。”

执行此命令并与 master 同步后,历史记录中的所有提交都会重复!即使是其他用户:(

@Vladimir 这是预期的,请研究 git 中的历史变化

对我来说,它似乎在 /bin/sh 中运行,所以我不得不将 bash 特定的测试 [[ ]] 替换为 sh 兼容的测试 [ ](单括号)。除此之外它工作得很好,谢谢!

@Native_Mobile_Arch_Dev 你需要这个: git config --global alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-过滤器 \"如果 [[ \\\"\$echo $VAR\\\" = '\$OLD' ]];然后导出 \$VAR='\$NEW'; fi\" \$@; }; f"

原文链接:https://www.huntsbot.com/qa/3V5v/how-do-i-change-the-author-and-committer-name-email-for-multiple-commits?lang=zh_CN&from=csdn

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值