我想更改历史中一个特定提交的作者。这不是最新的提交。
相关: How do I change the author and committer name/email for multiple commits?
user
,所以我需要的是 git commit --amend --reset-author
交互式变基在历史记录中比您需要修改的提交 (git rebase -i <earliercommit>
) 更早。在要修改的提交列表中,将文本从 pick
更改为 edit
,并在您要修改的提交的哈希旁边。然后当 git 提示您更改提交时,使用以下命令:
git commit --amend --author="Author Name <email@address.com>" --no-edit
例如,如果您的提交历史记录是 A-B-C-D-E-F
,其中 F
为 HEAD
,并且您想更改 C
和 D
的作者,那么您将...
指定 git rebase -i B (这是执行 git rebase -i B 命令后看到的示例)如果需要编辑 A,请使用 git rebase -i --root 将 C 和 D 的行从选择编辑 退出编辑器(对于 vim,这将是按 Esc 然后输入 :wq)。一旦变基开始,它首先会在 C 处暂停 你会 git commit --amend --author="Author Name
这个问题的 accepted answer 是对交互式变基的巧妙使用,但不幸的是,如果我们试图更改作者的提交曾经位于随后被合并的分支上,它就会出现冲突。更一般地说,它不会在处理混乱的历史时工作。
由于我担心运行依赖于设置和取消设置环境变量来重写 git 历史的脚本,我正在编写一个基于 this post 的新答案,它类似于 this answer 但更完整。
与链接的答案不同,以下内容经过测试和工作。为清楚起见,假设 03f482d6
是我们试图替换其作者的提交,而 42627abe
是新作者的提交。
签出我们正在尝试修改的提交。 git checkout 03f482d6 更改作者。 git commit --amend --author "新作者姓名<新作者电子邮件>"
现在我们有一个新的提交,哈希假定为 42627abe
。
签出原始分支。用本地的新提交替换旧提交。 git replace 03f482d6 42627abe 根据替换重写所有未来的提交。 git filter-branch -- --all 删除替换以保持清洁。 git replace -d 03f482d6 推送新的历史记录(仅在以下失败时使用--force,并且仅在使用 git log 和/或 git diff 进行健全性检查后使用)。 git push --force-with-lease
而不是 4-5 你可以重新提交到新的提交:
git rebase -i 42627abe
git rebase -i
更明显。以前从未听说过这 git replace
的事情。 +1
--force-with-lease
而不是 -f
。它更安全。
git filter-branch -- --all
正在更改原始提交所在的所有分支中的提交。如果您没有足够的凭据(或者您只是不想更改其他分支的历史记录),最好小心这个答案。
Github 文档包含 a script that replaces the committer info for all commits in a branch(现在无法恢复,这是 last snapshot)。
更改变量值后从终端运行以下脚本 #!/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" ] 然后 export GIT_COMMITTER_NAME="$CORRECT_NAME" export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL" fi if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]然后 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'
```
clone
/ push
,您最终会得到一个备份命名空间 refs/original/
。我找不到智能删除这个命名空间的方法,所以我最终删除了目录 .git/refs/original
,这很有效。
git push -f
强制将更改推送到存储库。
如果您只想更改上次提交的作者,可以这样做:
将您的电子邮件重置为全局配置: git config --global user.email example@email.com
现在无需编辑即可重置提交的作者: git commit --amend --reset-author --no-edit
It's not last commit.
那么他们会如何amend
呢?
git reset HEAD~
,运行了您建议的行,然后再次手动进行了下一次提交。工作得很好!
git config --local user.name FirstName LastName
和 git config --local user.email first.last@example.com
为当前 Git 存储库设置正确的作者。然后使用 git rebase --onto HEAD~6 --exec "git commit --amend --reset-author --no-edit" HEAD~6
应用到最后六个提交。最后使用 git push --force-with-lease
将其推送到远程 Git 存储库。
您可以使用以下命令更改上次提交的作者。
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
。
然后你会看到你的终端就像什么都没发生一样。实际上,您正处于交互式变基的中间。现在是时候使用上面的命令修改提交的作者姓名了。它将再次打开编辑器。退出并使用 git rebase --continue
继续变基。对要编辑的提交计数重复相同的操作。当您收到 No rebase in progress?
消息时,您可以确保交互式变基已完成。
pick
操作,并在每行之后添加 exec git commit --no-edit --amend --author="MyNewAuthor <my@new-auth.or>"
rebase -i -p
),但最后这是我需要的。谢谢
git commit
之前运行 git config --global core.editor nano
,然后您可以使用 Ctrl+O、Ctrl+X 退出编辑器。
您链接到的问题中的答案是很好的答案并且涵盖了您的情况(另一个问题更笼统,因为它涉及重写多个提交)。
作为尝试 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
之前提交:
https://i.stack.imgur.com/fpvKO.jpg
要修复所有提交的作者,您可以从@Amber 的答案中应用命令:
git commit --amend --author="Author Name <email@address.com>"
或者要重复使用您的姓名和电子邮件,您可以写:
git commit --amend --author=Eugen
在命令后提交:
https://i.stack.imgur.com/ClooR.jpg
例如更改从 4025621
开始的所有内容:
https://i.stack.imgur.com/1FjkF.jpg
您必须运行:
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
git shortlog -e -s
的输出。
找到一种可以快速更改用户并且对其他提交没有副作用的方法。
简单明了的方法:
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推送更新
git push --force-with-lease
user.name
和 user.email
但随后不将它们改回来。如果您不将它们改回来,所有 future 提交也将由新用户完成!这就是为什么在 git commit
上使用 --author
标志可能会更好的原因。
为了促进 Eugen Konkov 的回答,要从根提交开始,请使用 --root
标志。 --no-edit
标志也很有帮助,因为使用它不会提示您每次提交都进入编辑器。
git rebase --root --exec "git commit --amend --author='name <email>' --no-edit"
执行 git rebase -i
时,文档中有一个有趣的部分:
如果要将两个或多个提交合并为一个,请将第二个和后续提交的命令“pick”替换为“squash”或“fixup”。如果提交有不同的作者,折叠的提交将归属于第一个提交的作者。折叠提交的建议提交消息是第一个提交的提交消息和使用“squash”命令的提交消息的串联,但省略了使用“fixup”命令的提交的提交消息。
如果您有 ABCDEF 病史,
并且您想更改提交 B 和 D(= 2 次提交),
那么你可以这样做:
git config user.name "正确的新名称"
git config user.email "正确@new.email"
创建空提交(每个提交一个):您需要一条用于 rebase 目的的消息 git commit --allow-empty -m "empty"
您需要一条消息用于变基
git commit --allow-empty -m "empty"
开始 rebase 操作 git rebase -i B^ B^ 选择 B 的父级。
git rebase -i B^
B^ 选择 B 的父级。
您将希望在每次修改之前放置一个空提交
你会想把这些改成壁球。
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...
你可以删除前几行。
如果您要更改的提交不是最后一次提交,请按照以下步骤操作。如果您的提交在不同的分支中,则首先切换到该分支。
git checkout 分支名称
在要更改的提交之前查找提交并找到其哈希。然后发出 rebase 命令。
git rebase -i -p 提交哈希
然后编辑器将打开并为您要更改的提交输入“编辑”。让其他人使用默认的“选择”选项。一旦改变输入'esc'键和wq!退出。
然后发出带有修正选项的 git commit 命令。
git commit --amend --author="用户名电子邮件" --no-edit
然后发出以下命令。
git rebase -- 继续
在本地存储库中更新提交作者后,将更改推送到远程存储库。
提交推送后重命名作者姓名的步骤
首先键入“git log”以获取提交 id 和更多详细信息 git rebase i HEAD~10(10 是在 rebase 上显示的总提交)如果你得到类似以下的任何东西致命:似乎已经有一个 rebase-merge 目录,我想知道你是否在另一个变基中。如果是这样,请尝试 git rebase (--continue | --abort | --skip) 如果不是这样,请 rm -fr ".git/rebase-merge" 并再次运行我。我会停下来,以防你那里还有什么有价值的东西。然后根据您的需要键入“git rebase --continue”或“git rebase --abort”现在您将打开rebase窗口,单击键盘上的“i”键然后您将获得提交列表到10 [因为我们已经通过了10上面提交] 像下面选择 897fe9e 简化代码一点点选择 abb60f9 添加新功能选择 dc18f70 错误修复现在您需要在要编辑的提交下方添加以下命令,例如下面选择 897fe9e 简化代码一点点 exec git commit --amend --author 'Author Name
可选:如果您不想将本地更改发送到远程,请确保存储本地更改。
$ git status
$ git stash
更新最后一次提交的作者。
$ git log // Old author in local and remote
$ git commit --amend --author="Author Name <email@address.com>"
$ git log // New Author in local
$ git push origin <branch> --force-with-lease
$ git log // New Author in remote
然后,如果您使用 git stash
,则恢复您的暂存更改
$ git stash pop
$ git status
然后,您应该为当前项目的下一次提交更新配置。
$ git config user.name "Author Name"
$ git config user.email "<email@address.com>"
并使用 git config --edit
检查或编辑它
澄清:在您使用 $ ggpush -f
丢失提交的极少数情况下,您可以使用 reflog 恢复它们。无论如何,使用 --force-with-lease
比只使用 -f
更受保护
总帐
资源
ZSH
如果您的机器上缺少设置,例如,在格式化之后,或者在没有设置(正确)这些命令的情况下没有正确配置 Git 时,可能会发生这种情况。
git config user.name "Author Name"
git config user.email "<email@address.com>"
为什么不关注 this article by Atlassian 让您的生活更简单?
git commit --amend --author="Author Name
这是最后一次提交的最简单场景。要获取任何“随机”提交,您需要:
git rebase -i <早期提交>。在该提交上更改选择编辑,您对此感兴趣 git commit --amend --author="Author Name
在推动之前,您始终可以在两者之间git log
确定您的位置。
对于合并提交消息,我发现我无法使用 rebase
来修改它,至少在 gitlab 上是这样。它将合并显示为提交,但我无法基于该#sha。我发现 this 个帖子很有帮助。
git checkout <sha of merge>
git commit --amend # edit message
git rebase HEAD previous_branch
这三行代码完成了更改合并提交消息的工作(如作者)。
您可以从 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
在这里,您可以将旧电子邮件更改为您的新用户名和电子邮件地址。
解决方案
安装 git filter-repo (Git 项目建议 filter-repo 优于 filter-branch) $ PACKAGE_TOOL install git-filter-repo 在 git 存储库的根目录中创建一个文件 .mailmap,其中包含 New Name
更多细节
git-filter-repo 在他们的文档中将此列为示例
不要像上面的示例那样根据电子邮件过滤器替换名称和电子邮件,而是查看 git mailmap 文档中的其他示例
您可以通过使用参数 --mailmap
在 git-filter-repo 项目的 README.md 中可以找到更多关于如何进一步过滤分支/标签/任何内容的示例。
有一个适用于投票最多的问题的捷径:使用 exec
而不是 edit
。
exec
允许在指定的提交上运行命令。
使用它可以避免使用 edit
,退出到终端并为每个 git 提交运行 git
命令。
这在以下情况下特别有用您必须更改历史记录中的多个提交。
步骤是:
在打开的编辑器中对较早的提交(git rebase -i
示例编辑器内容(更改前 2 个提交作者):
pick 1fc6c95 Patch A
exec git commit --amend --author="Author Name <email@address.com>" --no-edit
pick 6b2481b Patch B
exec git commit --amend --author="Author Name <email@address.com>" --no-edit
pick dd1475d something I want to split
pick c619268 A fix for Patch B
pick fa39187 something to add to patch A
pick 4ca2acc i cant' typ goods
pick 7b36971 something to move before patch B
# Rebase 41a72e6..7b36971 onto 41a72e6
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
对于这个问题还有一种懒惰的方法,特别是如果您有多个要更改的提交。就我而言,我有一个新分支,其中有几个提交错误的作者,所以对我有什么帮助:
转到您的原始分支:
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
之后,您可以删除作者错误的分支。
在全球范围内更改您的提交者姓名和电子邮件:
$ 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>"
提示:对于其他情况并阅读更多信息,请参阅 the post reference。
如果您需要更改的是最后一次提交的作者并且没有其他人正在使用您的存储库,您可以撤消您的最后一次提交:
git push -f origin last_commit_hash:branch_name
更改提交的作者姓名:
git commit --amend --author "type new author here"
退出打开的编辑器并再次推送您的代码:
git push
作为 Eugen Konkov's answer 的补充,可以保留提交/作者日期。仅修改作者而不修改最后三个提交的日期,请使用
git rebase --onto HEAD~3 --exec 'GIT_COMMITTER_DATE="$(git log -n 1 --format=%aD)" git commit --amend --reset-author --no-edit --date="$(git log -n 1 --format=%aD)"' HEAD~3
然后施加力推
git push --force-with-lease
使用 git rebase -i
的 preferred answer 是有效的,但正如 this other answer 中突出显示的那样,当要编辑的提交周围存在合并时,它会变得混乱。而且git replace
的使用很聪明,但是git filter-branch
重写了其他分支和标签的所有历史,这不是我们一般想要的。
我想分享第一个答案的替代方案,即使有合并也很容易。就我而言,当我使用 git rebase -i <earlier-commit>
时,我首先要解决一个冲突,然后再继续进行变基。事实上,使用 break 命令比使用 edit 命令更容易。并直接基于我们的目标提交。
让我们举个例子,假设 git log
显示...
commit a12afg
...
commit dloe7a
...
commit gh7ag1
...
commit qp3zaa
...
假设您要更新提交 gh7ag1
的作者、消息或提交签名。您可以继续 git rebase -i gh7ag1
。在您的编辑器中,您将看到:
pick dloe7a
pick a12afg
只需添加一个中断命令:
break
pick dloe7a
pick a12afg
保存(:wq
与 VI,Ctrl+O
然后 Ctrl+X
与 nano)。现在,您在提交后马上回来了。您可以运行 git commit --amend
来更新作者、消息或签名(例如 git commit --amend -S --author="Your Name <your-email>"
)。使用 git log --show-signature
进行验证。如果正确,您可以继续使用 git rebase --continue
。
而且你可以在变基中拥有尽可能多的 break 命令。 continue 将移动到下一个中断(如果有),或者应用剩余的提交(前提是它们被标记为 pick
)。
vim
。要保存并退出,请键入 Esc : wq Enter。另一方面,如果它是 Nano,并且您在底部看到诸如“WriteOut: ^O”之类的东西,那么您应该使用 Ctrl+O、Enter、Ctrl+X。git commit --amend --reset-author
将提交作者设置为当前用户--no-edit
选项。git commit --amend --reset-author --no-edit
不会打开编辑器。从 git 1.7.9 开始可用。git rebase -i --root