题 如何更改一个特定提交的提交作者?


我想更改历史记录中某个特定提交的作者。这不是最后一次提交。

我知道这个问题 - 如何在git中更改提交的作者?

但我正在考虑一些事情,我通过哈希或短哈希来识别提交。


1388
2018-06-15 04:00


起源


可能重复 如何修改现有的,未删除的提交? - tkruse


答案:


交互式rebase在历史记录中早于某个点,而不是您需要修改的提交(git rebase -i <earliercommit>)。在重新提交的提交列表中,更改文本 pick 至 edit 在您要修改的哈希旁边。然后,当git提示您更改提交时,请使用以下命令:

git commit --amend --author="Author Name <email@address.com>"

例如,如果您的提交历史记录是 A-B-C-D-E-F 同 F 如 HEAD,你想改变作者 C 和 D那么你会......

  1. 指定 git rebase -i B (这是执行后你会看到的一个例子 git rebase -i B 命令
    • 如果你需要编辑 A, 使用 git rebase -i --root
  2. 改变两者的线条 C 和 D 从 pick 至 edit
  3. 一旦rebase开始,它将首先暂停 C
  4. 你会 git commit --amend --author="Author Name <email@address.com>"
  5. 然后 git rebase --continue
  6. 它会再次暂停 D
  7. 那你会的 git commit --amend --author="Author Name <email@address.com>" 再次
  8. git rebase --continue
  9. rebase将完成。

2330
2018-06-15 04:31



很好的答案,但对于初学者:首先在你想要改变的那个之前找到一个提交,然后运行 git rebase -i <commit> - Mathew Byrne
如果你不知道你在哪个编辑器,答案是可能的 vim。要保存并退出,请键入Esc:w q Enter。另一方面,如果是Nano,你会在底部看到“WriteOut:^ O”之类的东西,那么你应该使用Ctrl + O,Enter,Ctrl + X代替。 - Amber
如果你想修改第一次提交怎么办?之前的提交哈希是什么? - Brenden
使用 --no-edit 选项。 git commit --amend --reset-author --no-edit 不会打开编辑器。自git 1.7.9起可用。 - 5lava
@Brenden修改项目中的第一个提交,使用 git rebase -i --root - Noah Passalacqua


接受了答案 对于这个问题是一个非常巧妙地使用交互式rebase,但不幸的是,如果我们试图改变曾经的作者在一个随后被合并的分支上的提交,它会表现出冲突。更一般地说,它在处理凌乱时不起作用历史。

由于我担心运行依赖于设置和取消设置环境变量的脚本来重写git历史记录,我正在编写一个基于的新答案 这个帖子 这类似于 这个答案 但更完整。

与链接的答案不同,以下内容经过测试和运行。 假设为了清楚说明 03f482d6 是我们正在尝试替换的作者的提交,以及 42627abe 是新作者的提交。

  1. 签出我们试图修改的提交。

    git checkout 03f482d6
    
  2. 让作者改变。

    git commit --amend --author "New Author Name <New Author Email>"
    

    现在我们有一个假定为hash的新提交 42627abe

  3. 签出原始分支。

  4. 在本地替换旧的提交。

    git replace 03f482d6 42627abe
    
  5. 根据替换重写所有未来的提交。

    git filter-branch -- --all
    
  6. 取下更换清洁度。

    git replace -d 03f482d6
    
  7. 推送新历史记录(如果以下操作失败,则仅使用--force,并且只有在进行完整性检查后才能使用 git log 和/或 git diff)。

    git push --force-with-lease
    

而不是4-6你可以改变到新的提交:

git rebase -i 42627abe

315
2018-03-04 02:11



请在第2步之后在那里放一张纸条重新检查您的原始分支。 - Benjamin Riggs
这看起来很明显替代可怕的 git rebase -i。从来没有听说过这个 git replace 之前的事情。 +1 - FractalSpace
要清理refs / original / ... backup,请参阅 这里 - alexis
我推荐使用 --force-with-lease 代替 -f。它更安全。 - Jay Bazuzi
@ merlin2011,谢谢你的精彩帖子。我实际上已经尝试过它并且效果很好,但是经过一些小改动:之后 git replace -d 在 Step 5 一个 git checkout master 似乎需要命令。否则我仍然在一个未命名的分支上 git push 在那里不起作用。你对此有何看法? - Lukasz Czerwinski


Github文档包含 一个脚本,用于替换分支中所有提交的提交者信息

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

130
2018-06-09 16:02



这会在所有提交中更改它,而不仅仅是一个。有趣的是,我在不到30分钟前做到了这一点。 - Artjom B.
当我在阅读完之前的答案后发现这个答案时,我认为值得一试,瞧它完成了这项工作。但是在我的情况下,它仅在初始提交时更改了提交者名称。顺便说一句,在我尝试第一个答案的想法之前。也许它以某种方式影响了系统。 - Ruslan Gerasimov
git push -f完成了魔术。谢谢你的珍珠! - andrej
请注意,如果您避免使用 clone / push,你最终会得到一个备份命名空间 refs/original/。我找不到一种方法来智能地删除这个命名空间,所以我最终删除了目录 .git/refs/original 哪个有效。 - VasyaNovikov


您可以使用以下命令更改上次提交的作者。

git commit --amend --author="Author Name <email@address.com>"

但是,如果要更改多个提交作者名称,则有点棘手。您需要启动交互式rebase,然后将提交标记为编辑,然后逐个修改它们并完成。

用。开始变基 git rebase -i。它会告诉你这样的事情。

https://monosnap.com/file/G7sdn66k7JWpT91uiOUAQWMhPrMQVT.png

改变 pick 关键字到 edit 对于要更改作者姓名的提交。

https://monosnap.com/file/dsq0AfopQMVskBNknz6GZZwlWGVwWU.png

然后关闭编辑器。对于初学者来说,点击 Escape 然后键入 :wq 并击中 Enter

然后你会看到你的终端没有发生任何事情。实际上,你正处于一个互动的rebase中间。现在是时候使用上面的命令修改提交的作者姓名了。它将再次打开编辑器。退出并继续使用 git rebase --continue。对要编辑的提交计数重复相同的操作。当你得到时,你可以确保交互式rebase完成 No rebase in progress? 信息。


60
2017-08-29 00:52





  • 将您的电子邮件重置为全局配置:

    git config --global user.email example@email.com

  • 现在重置提交的作者而不需要编辑:

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


54
2018-04-05 12:44



不,这不对。看看OP: It's not last commit. 那他们怎么样? amend 它? - underscore_d
这很棒,但遗憾的是它只是最后一次提交。幸运的是,我最近需要它,所以只做了一次 git reset HEAD~,运行建议的行,然后再次手动执行下一次提交。工作得很好! - Matt Fletcher


您链接的问题中的答案是很好的答案并涵盖您的情况(另一个问题是更一般的,因为它涉及重写多个提交)。

作为尝试的借口 git filter-branch,我写了一个脚本来重写给定提交的作者姓名和/或作者电子邮件:

#!/bin/sh

#
# Change the author name and/or email of a single commit.
#
# change-author [-f] commit-to-change [branch-to-rewrite [new-name [new-email]]]
#
#     If -f is supplied it is passed to "git filter-branch".
#
#     If <branch-to-rewrite> is not provided or is empty HEAD will be used.
#     Use "--all" or a space separated list (e.g. "master next") to rewrite
#     multiple branches.
#
#     If <new-name> (or <new-email>) is not provided or is empty, the normal
#     user.name (user.email) Git configuration value will be used.
#

force=''
if test "x$1" = "x-f"; then
    force='-f'
    shift
fi

die() {
    printf '%s\n' "$@"
    exit 128
}
targ="$(git rev-parse --verify "$1" 2>/dev/null)" || die "$1 is not a commit"
br="${2:-HEAD}"

TARG_COMMIT="$targ"
TARG_NAME="${3-}"
TARG_EMAIL="${4-}"
export TARG_COMMIT TARG_NAME TARG_EMAIL

filt='

    if test "$GIT_COMMIT" = "$TARG_COMMIT"; then
        if test -n "$TARG_EMAIL"; then
            GIT_AUTHOR_EMAIL="$TARG_EMAIL"
            export GIT_AUTHOR_EMAIL
        else
            unset GIT_AUTHOR_EMAIL
        fi
        if test -n "$TARG_NAME"; then
            GIT_AUTHOR_NAME="$TARG_NAME"
            export GIT_AUTHOR_NAME
        else
            unset GIT_AUTHOR_NAME
        fi
    fi

'

git filter-branch $force --env-filter "$filt" -- $br

46
2018-06-15 05:24



+1谢谢。 assembla.com git repo似乎没有更改repo的web视图中的所有作者引用,但'git pull / clone'的结果似乎都可以正常工作。 - Johnny Utahh
很好的解决方案,因为它只会改变目标,而不是其他字段,例如提交日期。 - Guillaume Lemaître
Github文档包含一个 类似的剧本 - olivieradam666
@ olivieradam666就像一个魅力,它更容易阅读 - bfred.it
@seane 我添加了一个新答案 - olivieradam666


做的时候 git rebase -i 文档中有这个有趣的内容:

如果要将两个或多个提交折叠为一个,请替换该命令 "pick" 对于第二次及以后的提交 "squash" 要么 "fixup"。如果提交具有不同的作者,则折叠的提交将归因于第一次提交的作者。折叠提交的建议提交消息是第一次提交的提交消息和具有该提交的提交消息的串联 "squash" 命令,但省略了提交的提交消息 "fixup" 命令。

  • 如果你有历史 A-B-C-D-E-F
  • 并且您想要更改提交 B 和 D (= 2次提交),

然后你可以这样做:

  • git config user.name "Correct new name"
  • git config user.email "correct@new.email"
  • 创建空提交(每次提交一次):
    • 你需要一个用于rebase目的的消息
    • git commit --allow-empty -m "empty"
  • 启动rebase操作
    • git rebase -i B^
    • B^ 选择父母 B
  • 你会想要一个空提交 之前 每个提交修改
  • 你会想要改变 pick 至 squash 对于那些。

什么的例子 git rebase -i B^ 会给你:

pick sha-commit-B some message
pick sha-commit-C some message
pick sha-commit-D some message
pick sha-commit-E some message
pick sha-commit-F some message
# pick sha-commit-empty1 empty
# pick sha-commit-empty2 empty

改为:

# change commit B's author
pick sha-commit-empty1 empty
squash sha-commit-B some message
# leave commit C alone
pick sha-commit-C some message
# change commit D's author
pick sha-commit-empty2 empty
squash sha-commit-D some message
# leave commit E-F alone
pick sha-commit-E some message
pick sha-commit-F some message

它会提示您编辑消息:

# This is a combination of 2 commits.
# The first commit's message is:

empty

# This is the 2nd commit message:

...some useful commit message there...

你可以删除前几行。


12
2017-08-28 01:03





还有一个步骤 琥珀的答案 如果您使用的是集中式存储库:

git push -f 强制更新中央存储库。

要小心,没有很多人在同一个分支上工作,因为它会破坏一致性。


11
2017-12-20 15:06



这是评论而不是答案 - vsync


承诺之前:

enter image description here

要修复所有提交的作者,您可以从@ Amber的答案中应用命令:

git commit --amend --author="Author Name <email@address.com>"

或者重复使用您的姓名和电子邮件,您可以写:

git commit --amend --author=Eugen

命令后提交:

enter image description here

例如,从更改开始 4025621

enter image description here

你必须运行:

git rebase --onto 4025621 --exec "git commit --amend --author=Eugen" 4025621

或者将此别名添加到 ~/.gitconfig

[alias]
    reauthor = !bash -c 'git rebase --onto $1 --exec \"git commit --amend --author=$2\" $1' --

然后运行:

git reauthor 4025621 Eugen

1
2018-06-30 12:16