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

冷暖自知 提交于 2019-12-05 18:26:23

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

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

但是我正在考虑某些事情,在这里我通过哈希或短哈希来标识提交。


#1楼

在执行git rebase -i时,文档中有一个有趣的地方:

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

  • 如果您有ABCDEF的历史,
  • 并且您想要更改提交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...

您可以删除前几行。


#2楼

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

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

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


#3楼

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

由于我对运行依赖于设置和取消设置环境变量来重写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

#4楼

交互式重新定位在历史记录中比您需要修改的提交更早的一点( git rebase -i <earliercommit> )。 在要重新提交的提交列表中,将文本从pick更改为您想要修改的哈希旁边的edit 。 然后,当git提示您更改提交时,请使用以下命令:

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

例如,如果您的提交历史记录是ABCDEFFHEAD ,并且您想更改CD的作者,那么您将...

  1. 指定git rebase -i B这是执行git rebase -i B命令后将看到的示例
    • 如果您需要编辑A ,请使用git rebase -i --root
  2. CDpick更改为edit
  3. 重新启动基准后,它将首先在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. 重新设置将完成。
  10. 使用git push -f使用更新的提交来更新源。

#5楼

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

作为尝试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
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!