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


Answers:


3562

交互式变基距历史记录中早于您需要修改的提交的点(git rebase -i <earliercommit>)。在被衍合的提交的列表,文本从改变pickedit你旁边要修改的一个的哈希值。然后,当git提示您更改提交时,请使用以下命令:

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

例如,如果你的提交历史是A-B-C-D-E-FF作为HEAD的,你想改变的作者CD,然后你会......

  1. 指定git rebase -i B这是执行git rebase -i B命令后将看到的示例
    • 如果您需要编辑A,请使用git rebase -i --root
  2. 更改线都CD来自pickedit
  3. 退出编辑器(对于vim,将按Esc,然后键入:wq)。
  4. 重新启动基准后,它将首先在 C
  5. 你会 git commit --amend --author="Author Name <email@address.com>"
  6. 然后 git rebase --continue
  7. 它会在 D
  8. 然后你会git commit --amend --author="Author Name <email@address.com>"再次
  9. git rebase --continue
  10. 重新设置将完成。
  11. 用于使用git push -f更新的提交来更新您的来源。

90
好的答案,但是对初学者来说:首先在您想要更改的提交之前找到一个提交,然后运行git rebase -i <commit>
Mathew Byrne

47
如果您不知道自己所处的编辑器,则很可能会找到答案vim。要保存并退出,请键入Esc:wq Enter。另一方面,如果是Nano,并且在底部看到“ WriteOut:^ O”之类的内容,则应使用Ctrl + O,Enter,Ctrl + X代替。
2012年

30
如果要修改第一次提交怎么办?那么,先前的提交哈希是什么?
布伦登

218
使用--no-edit选项。git commit --amend --reset-author --no-edit将不会打开编辑器。自git 1.7.9起可用。
5lava 2014年

51
@Brenden修改项目中的第一个提交,使用git rebase -i --root
Noah Passalacqua

488

这个问题的公认答案是非常巧妙地使用交互式资源库,但是不幸的是,如果我们尝试更改其作者的提交曾经位于随后合并的分支中,则它会表现出冲突。更一般地说,它不起作用处理混乱的历史时。

由于我对运行依赖于设置和取消设置环境变量来重写git历史记录的脚本感到不安,因此我根据此帖子写了一个新答案,该答案此答案类似,但更为完整。

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

  1. 检出我们尝试修改的提交。

    git checkout 03f482d6
    
  2. 更改作者。

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

    现在,我们有了一个新的提交,假设哈希为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

9
请把记在那里重新签你的原分公司步骤2之后
本杰明·里格斯

42
这看起来可以替代恐怖的东西git rebase -igit replace以前从未听说过这个东西。+1
FractalSpace 2015年

3
对于干净的裁判/原始/ ...备份,请参阅此处
Alexis

5
我建议使用--force-with-lease代替-f。更安全
杰·巴祖兹

11
警告:请注意,git filter-branch -- --all正在更改原始提交所在的所有分支中的提交。如果您没有足够的凭据(或者您只是不想更改其他分支的历史记录),则最好谨慎对待此答案。
ribamar

225

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
    
  • 将更正的历史记录推送到GitHub:

    git push --force --tags origin 'refs/heads/*'
    

    或者,如果您想推送分支的选定引用,请使用

    git push --force --tags origin 'refs/heads/develop'
    

12
这会改变所有提交,而不仅仅是一次。有趣的是,我不到30分钟前就做了。
Artjom B.

当我阅读以前的答案后找到此答案时,我认为值得尝试一下,瞧,它确实起作用了。但是就我而言,它仅在初始提交中更改了提交者名称。顺便说一下,在我尝试第一个答案的想法之前。也许它以某种方式影响了系统。
Ruslan Gerasimov

2
请注意,如果避免使用clone/ push,则会得到一个备份名称空间refs/original/。我找不到智能删除此命名空间的方法,因此我最终删除了有效的目录.git/refs/original
VasiliNovikov

如果OLD_EMAIL不匹配,为什么这会导致回购更改?由于某种原因,一些(但不是全部!)提交哈希值发生了变化。
mjs

1
我用这个答案的用例是:我有两个github帐户,一个是我无意中用来提交的。该脚本通过重命名错误的提交者电子邮件/名称来帮助修复我的所有提交。当然,如果我从错误的用户(例如,从第50次提交到第500次提交)进行了提交,那么会有450个不同的提交。无论如何,正如@andrej指出的那样,运行脚本后,您需要git push -f强制将更改推送到存储库。
LWY18年

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

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

  • 现在,无需修改即可重置提交的作者:

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


2
不,这不对。看一下OP:It's not last commit.那么他们会如何amend
underscore_d

2
太好了,可惜这只是最后一次提交。幸运的是,我需要在最近的两次提交中使用它,所以只需执行一次git reset HEAD~,运行您建议的行,然后再次手动进行下一次提交。工作正常!
马特·弗莱彻

2
谢谢!--reset-author为我完成了窍门,因为没有它,作者会更改,但“提交者”将保留旧的作者详细信息。
卢卡斯(Lucas P.)

9
要修复我的最后六个提交:首先,使用git config --local user.name FirstName LastName 和设置当前Git存储库的正确作者git config --local user.email first.last@example.com。然后使用应用于最后六个提交git rebase --onto HEAD~6 --exec "git commit --amend --reset-author --no-edit" HEAD~6。最后使用将其推送到远程Git存储库git push --force-with-lease
olibre

@olibre,它就像一种魅力,谢谢。
布鲁诺·加斯帕洛托

88

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

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

但是,如果您要更改多个提交者姓名,则有些棘手。您需要启动一个交互式基础,然后将提交标记为编辑,然后逐一修改并完成。

开始使用进行基础调整git rebase -i。它会向您显示这样的内容。

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

pick关键字更改edit为要更改作者名称的提交。

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

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

然后,您将看到终端没有任何反应。实际上,您处于交互式基础的中间。现在是时候使用上面的命令修改提交的作者姓名了。它将再次打开编辑器。退出并继续使用进行重新设置git rebase --continue。对要编辑的提交计数重复相同的操作。您可以确保在收到No rebase in progress?消息后完成交互式变基。


你能更新你的照片吗?
Shimmy Weitzhandler,

1
如果您要更改多个提交,而不必单独编辑它们,则也可以让该pick操作并在每行之后添加exec git commit --no-edit --amend --author="MyNewAuthor <my@new-auth.or>"
Pierre-Olivier Vares

60

您链接到的问题中的答案是不错的答案,可以解决您的情况(另一个问题更笼统,因为它涉及重写多个提交)。

作为尝试的借口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

+1谢谢。assembla.com git repo似乎并没有改变该repo的web视图中的所有作者引用,但是'git pull / clone'的结果似乎都可以正常工作。
约翰尼·犹他州

很棒的解决方案,因为它只会更改预期的内容,而不会更改其他字段(例如提交日期)。
GuillaumeLemaître2014年

12
Github文档包含一个 类似的脚本
olivieradam666 2014年

2
@ olivieradam666就像魅力一样,更容易阅读
fregante

@ olivieradam666谢谢。您应该真正将其添加为答案,以便引起更多关注。
seane 2015年

44

提交之前:

在此处输入图片说明

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

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

要重用您的姓名和电子邮件,您可以写:

git commit --amend --author=Eugen

在命令后提交:

在此处输入图片说明

例如,从4025621以下位置更改所有内容:

在此处输入图片说明

您必须运行:

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

注意:要包括一个包含空格(例如姓名和电子邮件地址)的作者,该作者必须被转义的引号引起来。例如:

git rebase --onto 4025621 --exec "git commit --amend --author=\"Foo Bar <foo@bar.com>\"" 4025621

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

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

然后运行:

git reauthor 4025621 Eugen

1
为了验证该命令是否按预期工作,我查看了的输出git shortlog -e -s
泰勒·埃德米斯顿

5
这是最符合我的目的的答案,谢谢。而且由于我只是想调整的电子邮件地址,因此在更新.git / config后,可以使用--exec =“ git commit --amend --reset-author”运行。
拿督

1
eh,不知道为什么我忘了!现在做。
拿督

很好的答案,很容易解决。爱别名!
J_A_X

那没有帮助我。现在,我有Continue Rebase Failed错误
Alexey Sh。

17

如果您使用的是集中式存储库,那么Amber的答案还有一个额外的步骤:

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

注意在同一分支上工作的人很少,因为它可能破坏一致性。


16

这样做git rebase -i时,文档中有一个有趣的地方:

如果你想将两个或更多的提交折叠成一个,替换命令"pick"与第二次及以后提交"squash""fixup"。如果提交具有不同的作者,则折叠的提交将归因于第一个提交的作者。折叠提交的建议提交消息是第一次提交的提交消息与使用"squash"命令的提交消息的串联,但是省略了使用"fixup"命令提交的提交消息。

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

那么您可以执行以下操作:

  • git config user.name "Correct new name"
  • git config user.email "correct@new.email"
  • 创建空的提交(每个提交一个):
    • 您需要一条消息用于变基
    • git commit --allow-empty -m "empty"
  • 开始变基操作
    • git rebase -i B^
    • B^选择的父项B
  • 您将需要每次修改之前放置一个空的提交
  • 你将要改变picksquash这些。

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...

您可以删除前几行。


16

为了促进Eugen Konkov的响应,从根提交开始,使用--rootflag。该--no-edit标志也很有帮助

git rebase --root --exec "git commit --amend --author='name <email>' --no-edit"

这对所有提交都起作用并改变了。
SagarKapasi09919年

1
感谢您的回答。它必须添加--interactive才能起作用。git rebase --root --interactive --exec“ git commit --amend --author ='name <email>'
no

8

找到一种可以快速更改用户并且对其他提交没有副作用的方法。

简单明了的方法:

git config user.name "New User"
git config user.email "newuser@gmail.com"

git log
git rebase -i 1f1357
# change the word 'pick' to 'edit', save and exit

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

git push --force-with-lease

详细操作

  • 显示提交日志并找出要更改的提交之前的提交ID:
git log
  • git rebase从选择的提交ID开始到最近的反向:
git config user.name "New User"
git config user.email "newuser@gmail.com"
git rebase -i 1f1357

# change word pick to edit, save and exit
edit 809b8f7 change code order 
pick 9baaae5 add prometheus monitor kubernetes
edit 5d726c3 fix liquid escape issue   
edit 3a5f98f update tags
pick 816e21c add prometheus monitor kubernetes
  • rebase将在下一个提交ID处停止,输出:
Stopped at 809b8f7...  change code order 
You can amend the commit now, with
  git commit --amend 

Once you are satisfied with your changes, run

  git rebase --continue
  • 确认并继续您的变基直到成功完成 refs/heads/master.
# each continue will show you an amend message
# use git commit --amend --reset-author --no-edit to comfirm
# use git rebase --skip to skip
git commit --amend --reset-author --no-edit
git rebase --continue
git commit --amend --reset-author --no-edit
...
git rebase --continue
Successfully rebased and updated refs/heads/master.
  • git push更新
git push --force-with-lease

5

如果您要更改的提交不是最后的提交,请执行以下步骤。如果您的提交在另一个分支中,那么请首先切换到该分支。

git checkout branch_name

在要更改的提交之前查找提交,并找到其哈希。然后发出rebase命令。

git rebase -i -p提交哈希

然后,编辑器将打开,并为要更改的提交输入“ edit”。让其他人使用默认的“ pick”选项。更改后,请输入“ esc”键并输入密码!退出。

然后发出带有commit选项的git commit命令。

git commit --amend --author =“用户名电子邮件” --no-edit

然后发出以下命令。

git rebase-继续

在本地存储库中更新提交作者后,将更改推送到远程存储库。


我认为这是最简单的方法。我正在使用reword命令,但失败了。我了解到我需要使用edit命令。也许“ edit”关键字可以突出显示。感谢您的回答@ChannaB👍–
Berk

确实很容易遵循步骤。谢谢!
哈比巴

4

对于这个问题,还有一种懒惰的方法,尤其是当您要更改多个提交时。在我的情况下,我有一个新分支,其中有多个提交带有错误的作者,因此对我有帮助的是:

转到原始分支:

git checkout develop

从中创建新分支:

git checkout -b myFeature develop 

合并没有提交信息的一次提交:

git merge --no-commit --squash branchWrongAuthor

您可能还想分阶段进行更改:

git stage .

更改作者姓名并提交更改:

git commit --amend --author "New Author Name <New Author Email>" -m "new feature added"

就是这样,您可以推动更改。

git push

之后,您可以使用错误的作者删除分支。


4

提交提交后重命名作者名称的步骤

  1. 首先输入“ git log”以获取提交ID和更多详细信息
  2. git rebase i HEAD〜10(10是要显示在rebase上的总提交)

    If you Get anything like below

    fatal: It seems that there is already a rebase-merge directory, and I wonder if you are in the middle of another rebase. If that is the case, please try

    git rebase (--continue | --abort | --skip) If that is not the case, please rm -fr ".git/rebase-merge" and run me again. I am stopping in case you still have something valuable there.

  3. 然后根据需要键入“ git rebase --continue”或“ git rebase --abort”

    • 现在您的将变基窗口打开,单击键盘上的“ i”键
    • 那么您将获得10次提交的列表[因为我们已经通过了10次提交]如下所示

    pick 897fe9e simplify code a little

    pick abb60f9 add new feature

    pick dc18f70 bugfix

  4. 现在,您需要在要编辑的提交下方添加以下命令,如下所示

    pick 897fe9e simplify code a little exec git commit --amend --author 'Author Name <author.name@mail.com>' pick abb60f9 add new feature exec git commit --amend --author 'Author Name <author.name@mail.com>' pick dc18f70 bugfix exec git commit --amend --author 'Author Name <author.name@mail.com>'

    1. 就是这样,现在只需按ESC,:wq,就可以设置好了

    2. 然后git push origin HEAD:BRANCH NAME -f [请注意-f Force push]

    喜欢 git push -fgit push origin HEAD: dev -f


好的答案,您可以使用git push命令示例更新第6点吗?
卢卡斯(Lukasz'Severiaan'Grela)

1
@ Lukasz'Severiaan'Grela编辑,请立即检查,谢谢
Kirtikumar A.19 / 09/26

3

全局更改您的提交者姓名和电子邮件:

$ git config --global user.name "John Doe"
$ git config --global user.email "john@doe.org"

更改每个存储库的提交者名称和电子邮件:

$ git config user.name "John Doe"
$ git config user.email "john@doe.org"

仅为下一次提交更改作者信息:

$ git commit --author="John Doe <john@doe.org>"

提示:有关其他情况和更多信息,请阅读帖子参考


2

如果您需要更改的是最后一次提交的作者,而没有其他人正在使用您的存储库,则可以使用以下方法撤消您的最后一次提交:

git push -f origin last_commit_hash:branch_name 

使用以下命令更改提交的作者名称:

git commit --amend --author "type new author here"

退出打开的编辑器,然后再次推送代码:

git push

2

对于合并提交消息,我发现rebase至少在gitlab上无法使用来修改它。它将合并显示为提交,但是我无法基于该#sha。我发现这篇文章很有帮助。

git checkout <sha of merge>
git commit --amend # edit message
git rebase HEAD previous_branch

这三行代码完成了更改合并提交消息的工作(例如作者)。


1

您可以从github的官方页面使用这些命令

https://help.github.com/en/github/using-git/changing-author-info

这是命令

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

在这里,您可以将旧电子邮件更改为新的用户名和电子邮件地址。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.