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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3042437/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 08:34:29  来源:igfitidea点击:

How to change the commit author for one specific commit?

gitgit-commit

提问by MicTech

I want to change the author of one specific commit in the history. It's not the last commit.

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

I know about this question - How do I change the author of a commit in git?

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

But I am thinking about something, where I identify the commit by hash or short-hash.

但我在想一些事情,我通过散列或短散列来识别提交。

回答by Amber

Interactive rebase off of a point earlier in the history than the commit you need to modify (git rebase -i <earliercommit>). In the list of commits being rebased, change the text from pickto editnext to the hash of the one you want to modify. Then when git prompts you to change the commit, use this:

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

git commit --amend --author="Author Name <[email protected]>" --no-edit


For example, if your commit history is A-B-C-D-E-Fwith Fas HEAD, and you want to change the author of Cand D, then you would...

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

  1. Specify git rebase -i B(here is an example of what you will see after executing the git rebase -i Bcommand)
    • if you need to edit A, use git rebase -i --root
  2. Change the lines for both Cand Dfrom pickto edit
  3. Exit the editor (for vim, this would be pressing Esc and then typing :wq).
  4. Once the rebase started, it would first pause at C
  5. You would git commit --amend --author="Author Name <[email protected]>"
  6. Then git rebase --continue
  7. It would pause again at D
  8. Then you would git commit --amend --author="Author Name <[email protected]>"again
  9. git rebase --continue
  10. The rebase would complete.
  11. Use git push -fto update your origin with the updated commits.
  1. 指定git rebase -i B这是执行git rebase -i B命令后您将看到的示例
    • 如果您需要编辑A,请使用git rebase -i --root
  2. 将两者CDfrom的行更改pickedit
  3. 退出编辑器(对于 vim,这将按 Esc 然后键入:wq)。
  4. 一旦 rebase 开始,它会首先暂停在 C
  5. 你会 git commit --amend --author="Author Name <[email protected]>"
  6. 然后 git rebase --continue
  7. 它会再次暂停 D
  8. 那么你会git commit --amend --author="Author Name <[email protected]>"再次
  9. git rebase --continue
  10. 变基将完成。
  11. 用于使用git push -f更新的提交更新您的源。

回答by merlin2011

The accepted answerto this question is a wonderfully clever use of interactive rebase, but it unfortunately exhibits conflicts if the commit we are trying to change the author of used to be on a branch which was subsequently merged in. More generally, it does not work when handling messy histories.

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

Since I am apprehensive about running scripts which depend on setting and unsetting environment variables to rewrite git history, I am writing a new answer based on this postwhich is similar to this answerbut is more complete.

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

The following is tested and working, unlike the linked answer. Assume for clarity of exposition that 03f482d6is the commit whose author we are trying to replace, and 42627abeis the commit with the new author.

与链接的答案不同,以下内容经过测试和工作。为清楚起见,假设03f482d6是我们试图替换其作者的提交,并且42627abe是新作者的提交。

  1. Checkout the commit we are trying to modify.

    git checkout 03f482d6
    
  2. Make the author change.

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

    Now we have a new commit with hash assumed to be 42627abe.

  3. Checkout the original branch.

  4. Replace the old commit with the new one locally.

    git replace 03f482d6 42627abe
    
  5. Rewrite all future commits based on the replacement.

    git filter-branch -- --all
    
  6. Remove the replacement for cleanliness.

    git replace -d 03f482d6
    
  7. Push the new history (only use --force if the below fails, and only after sanity checking with git logand/or git diff).

    git push --force-with-lease
    
  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
    

Instead of 4-6 you can just rebase onto new commit:

而不是 4-6 你可以只重新提交到新的提交:

git rebase -i 42627abe

回答by olivieradam666

Github documentation contains a script that replaces the committer info for all commits in a branch.

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

  • Run the following script from terminal after changing the variable values

    #!/bin/sh
    
    git filter-branch --env-filter '
    
    OLD_EMAIL="[email protected]"
    CORRECT_NAME="Your Correct Name"
    CORRECT_EMAIL="[email protected]"
    
    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
    
  • Push the corrected history to GitHub:

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

    OR if you like to push selected references of the branches then use

    git push --force --tags origin 'refs/heads/develop'
    
  • 更改变量值后从终端运行以下脚本

    #!/bin/sh
    
    git filter-branch --env-filter '
    
    OLD_EMAIL="[email protected]"
    CORRECT_NAME="Your Correct Name"
    CORRECT_EMAIL="[email protected]"
    
    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'
    

回答by pravbeatle

  • Reset your email to the config globally:

    git config --global user.email [email protected]

  • Now reset the author of your commit without edit required:

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

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

    git config --global user.email [email protected]

  • 现在无需编辑即可重置提交的作者:

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

回答by Fatih Acet

You can change author of last commit using the command below.

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

git commit --amend --author="Author Name <[email protected]>"

git commit --amend --author="Author Name <[email protected]>"

However, if you want to change more than one commits author name, it's a bit tricky. You need to start an interactive rebase then mark commits as edit then amend them one by one and finish.

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

Start rebasing with git rebase -i. It will show you something like this.

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

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

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

Change the pickkeyword to editfor the commits you want to change the author name.

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

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

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

Then close the editor. For the beginners, hit Escapethen type :wqand hit Enter.

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

Then you will see your terminal like nothing happened. Actually you are in the middle of an interactive rebase. Now it's time to amend your commit's author name using the command above. It will open the editor again. Quit and continue rebase with git rebase --continue. Repeat the same for the commit count you want to edit. You can make sure that interactive rebase finished when you get the No rebase in progress?message.

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

回答by Chris Johnsen

The answers in the question to which you linked are good answers and cover your situation (the other question is more general since it involves rewriting multiple commits).

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

As an excuse to try out git filter-branch, I wrote a script to rewrite the Author Name and/or Author Email for a given commit:

作为尝试的借口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" = "x-f"; then
    force='-f'
    shift
fi

die() {
    printf '%s\n' "$@"
    exit 128
}
targ="$(git rev-parse --verify "" 2>/dev/null)" || die " 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

回答by Eugen Konkov

Commit before:

之前提交:

enter image description here

在此处输入图片说明

To fix author for all commits you can apply command from @Amber's answer:

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

git commit --amend --author="Author Name <[email protected]>"

Or to reuse your name and email you can just write:

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

git commit --amend --author=Eugen

Commit after the command:

在命令后提交:

enter image description here

在此处输入图片说明

For example to change all starting from 4025621:

例如,从4025621以下开始更改所有内容:

enter image description here

在此处输入图片说明

You must run:

你必须运行:

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

Note: To include an author containing spaces such as a name and email address, the author must be surrounded by escaped quotes. For example:

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

git rebase --onto 4025621 --exec "git commit --amend --author=\"Foo Bar <[email protected]>\"" 4025621

or add this alias into ~/.gitconfig:

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

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

And then run:

然后运行:

git reauthor 4025621 Eugen

回答by Fabian76

There is one additional step to Amber's answerif you're using a centralized repository:

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

git push -fto force the update of the central repository.

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

Be careful that there are not a lot of people working on the same branch because it can ruin consistency.

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

回答by dnozay

When doing git rebase -ithere is this interesting bit in the doc:

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

If you want to fold two or more commits into one, replace the command "pick"for the second and subsequent commits with "squash"or "fixup". If the commits had different authors, the folded commit will be attributed to the author of the first commit. The suggested commit message for the folded commit is the concatenation of the commit messages of the first commit and of those with the "squash"command, but omits the commit messages of commits with the "fixup"command.

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

  • If you have an history of A-B-C-D-E-F,
  • and you want to change commits Band D(= 2 commits),
  • 如果你有历史A-B-C-D-E-F
  • 并且您想更改提交BD(= 2 次提交),

then you can do:

那么你可以这样做:

  • git config user.name "Correct new name"
  • git config user.email "[email protected]"
  • create empty commits (one for each commit):
    • you need a message for rebase purpose
    • git commit --allow-empty -m "empty"
  • start the rebase operation
    • git rebase -i B^
    • B^selects the parent of B.
  • you will want to put one empty commit beforeeach commit to modify
  • you will want to change pickto squashfor those.
  • git config user.name "Correct new name"
  • git config user.email "[email protected]"
  • 创建空提交(每个提交一个):
    • 您需要一条消息用于 rebase 目的
    • git commit --allow-empty -m "empty"
  • 开始变基操作
    • git rebase -i B^
    • B^选择 的父级B
  • 您需要每次提交修改之前放置一个空提交
  • 你将要改变picksquash这些。

Example of what git rebase -i B^will give you:

什么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 that to:

将其更改为:

# 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

It will prompt you to edit the messages:

它将提示您编辑消息:

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

and you can just remove the first few lines.

你可以删除前几行。

回答by korwalskiy

In furtherance to Eugen Konkovresponse, to start from the root commit, use --rootflag. The --no-editflag is helpful too

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

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