如何修改Git中的几个提交来改变作者

pau*_*doo 153 git git-commit git-rewrite-history

我在Git中做了一系列提交,现在我意识到我忘记了正确设置我的用户名和用户邮件属性(新机器).我还没有将这些提交推送到我的存储库,所以在我这样做之前如何更正这些提交(只有主分支上的3个最新提交)?

我一直在看git resetgit commit -C <id> --reset-author,但我不认为我是在正确的轨道上.

Cas*_*bel 200

当您拥有filter-branch的强大功能时,重新/修改似乎效率低下:

git filter-branch --env-filter 'if [ "$GIT_AUTHOR_EMAIL" = "incorrect@email" ]; then
     GIT_AUTHOR_EMAIL=correct@email;
     GIT_AUTHOR_NAME="Correct Name";
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL;
     GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; fi' -- --all
Run Code Online (Sandbox Code Playgroud)

(为清晰起见,分隔线,但没有必要)

完成后一定要检查结果,以确保你没有改变任何你不想做的事情!

  • 要在**最后两次提交中执行此操作,我将` - --all`替换为`HEAD~1..HEAD` (9认同)
  • 另请参阅https://help.github.com/articles/changing-author-info/,该文档还将`--tag-name-filter cat`添加到`filter-branch`以便将标签迁移到新的历史记录。它还使用`--branches --tags`而不是`--all`,它仅重写分支和标签历史记录,而单独保留其他`refs'(尽管除非您例如使用[`git-notes`](https://git-scm.com/docs/git-notes)) (2认同)

Ale*_*lex 128

当与exec一起使用时,交互式rebase方法非常好.您可以针对特定提交或rebase中的所有提交运行任何shell命令.

首先设置你的git作者设置

git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
Run Code Online (Sandbox Code Playgroud)

然后在给定的SHA之后重置作者的所有提交

git rebase -i YOUR_SHA -x "git commit --amend --reset-author -CHEAD"
Run Code Online (Sandbox Code Playgroud)

这将弹出您的编辑器以确认更改.您需要做的就是保存并退出,它将遍历每次提交并运行-x标志中指定的命令.

根据Per @ Dave的评论,您还可以在保持原始时间戳的同时更改作者:

git rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <new_address@example.com>' -CHEAD"
Run Code Online (Sandbox Code Playgroud)

  • 要更改作者但保持原始时间戳,请使用`git rebase -i YOUR_SHA -x"git commit --amend --author'新名称<new_address@example.com>'-CHEAD" (20认同)
  • 要重新设置包括root在内的所有提交,请使用:git rebase -i --root…,而不是传递SHA。 (3认同)
  • 感谢您向我介绍-x选项.它非常棒!对于-i选项,我使用HEAD~4来修复我最近4次提交的电子邮件地址.像魅力一样工作. (2认同)
  • 如果你只是想修复你的最后一次提交:)这比`filter-branch`简单得多.但请注意,这会更改提交的时间戳. (2认同)
  • @Connor`git log`也为我显示了旧的作者身份,但是git status正确地识别了新的提交,并且在强制推送之后它们就像我想要的那样. (2认同)
  • 刚刚尝试了@Dave 答案,但原始时间戳未保留(您可以在此处查看 https://github.com/oncet/coel/commits/temp)。使用 git 2.25.1。 (2认同)
  • 要在保留日期的同时进行修改: `git rebase -i YOUR_SHA -x 'git commit --amend --reset-author --no-edit --date="$(git log -n 1 --format=%aD) ”'` (2认同)

Chr*_*aes 67

要仅为最后一次提交更改作者:

git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
Run Code Online (Sandbox Code Playgroud)

假设您只想更改最后N次提交的作者:

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit"
Run Code Online (Sandbox Code Playgroud)

笔记

  • --no-edit标志可以确保git commit --amend不要求额外的确认
  • 当您使用时git rebase -i,您可以手动选择提交更改作者的位置,

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

pick 897fe9e simplify code a little
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
pick dc18f70 bugfix
Run Code Online (Sandbox Code Playgroud)

  • @ChrisMaes:请注意 **`git commit --amend --author ...` 不会更改提交者,只会更改作者!** 因此,虽然可能“看起来”您的电子邮件已更改,但在事实上,存储库中的元数据表明了旧提交者是谁。虽然“filter-branch”(或“filter-repo”)方法更为粗糙,但它们实际上改变了两者。证明:`curl -s https://api.github.com/repos/sshine/author-committer/commits | jq '.[0].commit | { 作者,提交者 }'` -- 我在这里做了一个 `git commit --amend --author="John Doe ..."` ,你可以看到提交者不是 John Doe。 (11认同)
  • 我建议添加“--rebase-merges”(简称“-r”)选项,以在分支包含一些合并时保持分支的拓扑完整。 (3认同)
  • 对于所有来自 root 的提交。git rebase -i --root UPTO_COMMIT_SHA -x "git commit --amend --author 'NEW_CHANGE' --no-edit" (2认同)

cha*_*rsi 54

这里得票最高的答案现在已经过时了。当使用 git filter-branch 时,Git 显示这个可怕的警告 -

WARNING: git-filter-branch has a glut of gotchas generating mangled history
         rewrites. Hit Ctrl-C before proceeding to abort, then use an
         alternative filtering tool such as 'git filter-repo'
         (https://github.com/newren/git-filter-repo/) instead.
Run Code Online (Sandbox Code Playgroud)

filter-repo还不是 git 的一部分,需要单独安装。

WARNING: git-filter-branch has a glut of gotchas generating mangled history
         rewrites. Hit Ctrl-C before proceeding to abort, then use an
         alternative filtering tool such as 'git filter-repo'
         (https://github.com/newren/git-filter-repo/) instead.
Run Code Online (Sandbox Code Playgroud)

要仅替换以前提交中的电子邮件,请运行如下命令 -

# Requires git v2.22+ and python v3.5+. Check with -
git --version && python3 --version
    
# Install using pip
pip3 install git-filter-repo    
    
Run Code Online (Sandbox Code Playgroud)

要替换之前提交中的电子邮件和作者姓名,请运行如下命令 -

git filter-repo --email-callback '
    return email if email != b"incorrect@email" else b"correct@email"
' 
Run Code Online (Sandbox Code Playgroud)

确保将命令粘贴到终端时有缩进。回调使用 python 语法,因此缩进很重要。

在文档中阅读有关过滤器存储库回调的更多信息。

  • 谢谢。有效!如果您在 Mac 上收到 `zsh: command not found: pip`,请尝试 pip3 - `pip3 install git-filter-repo`。 (5认同)

use*_*745 8

GitHub 为此目的记录了此方法(尽管 GitHub 已将其删除)。步骤是:

  1. 打开终端并制作你的 repo的克隆
git clone --bare https://github.com/user/repo.git
cd repo
Run Code Online (Sandbox Code Playgroud)
  1. 编辑下面的脚本(取代OLD_EMAILCORRECT_EMAILCORRECT_NAME
#!/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
Run Code Online (Sandbox Code Playgroud)
  1. 将脚本复制/粘贴到您的终端中,然后按 Enter 运行它。
  2. 推送您的更改,git push --force --tags origin 'refs/heads/*'您就完成了!