我想改变历史上某个特定承诺的作者。这不是最新的承诺。
相关:如何更改多次提交的作者和提交人姓名/电子邮件?
我想改变历史上某个特定承诺的作者。这不是最新的承诺。
相关:如何更改多次提交的作者和提交人姓名/电子邮件?
交互式重新基准历史中比您需要修改的提交更早的一点(git rebase-i<earlier commit>)。在要重设基础的提交列表中,将要修改的提交的哈希旁边的文本从pick更改为edit。然后,当git提示您更改提交时,使用以下命令:
git commit --amend --author="Author Name <email@address.com>" --no-edit
例如,如果您的提交历史是A-B-C-D-E-F,F是HEAD,并且您想更改C和D的作者,那么您应该。。。
指定gitrebase-i B(以下是执行gitrebase-iB命令后将看到的示例)如果需要编辑A,请使用git-rebase-i--root将C和D的行从拾取更改为编辑退出编辑器(对于vim,这将是按Esc,然后键入:wq)。一旦重新启动,它将首先在C处暂停您可以gitcommit--modify--author=“作者姓名”<email@address.com>"然后git rebase--继续它会在D时再次暂停然后您将gitcommit--modify--author=“作者姓名”<email@address.com>“”再次git rebase—继续重新基础将完成。使用git push-f使用更新的提交更新源代码。
你所链接的问题中的答案是好答案,涵盖了你的情况(另一个问题更为一般,因为它涉及重写多次提交)。
作为尝试gitfilter分支的借口,我编写了一个脚本来重写给定提交的作者名和/或作者电子邮件:
#!/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
在执行git rebase-i时,文档中有一个有趣的部分:
如果要将两个或多个提交合并为一个,请将第二次和后续提交的命令“pick”替换为“squash”或“fixup”。如果提交的作者不同,则折叠提交将归于第一次提交的作者。折叠提交的建议提交消息是第一次提交的提交消息和使用“squash”命令的提交消息的串联,但使用“fixup”命令省略了提交的提交信息。
如果你有A-B-C-D-E-F病史,并且您希望更改提交B和D(=2个提交),
那么您可以执行以下操作:
git-config user.name“更正新名称”git-config user.email“correct@new.email"创建空提交(每个提交一个):你需要一条消息来重新设置基础gitcommit--允许空-m“空”启动重新启动操作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...
你可以删除前几行。
这个问题的公认答案是交互式rebase的巧妙使用,但不幸的是,如果我们试图更改作者的提交曾经位于一个随后被合并的分支上,则会出现冲突。更一般而言,它在处理混乱的历史时不起作用。
由于我担心运行依赖于设置和取消设置环境变量来重写git历史的脚本,因此我正在根据这篇文章编写一个新的答案,该答案与此答案类似,但更完整。
与链接的答案不同,以下内容经过测试并有效。为了说明清楚,假设03f482d6是我们试图替换其作者的提交,42627abe是新作者的提交。
签出我们试图修改的提交。git结帐03f482d6让作者改变。gitcommit--modify--author“新作者姓名<新作者电子邮件>”
现在我们有了一个新的提交,哈希值假定为42627abe。
签出原始分支。用本地新提交替换旧提交。git替换03f482d6 42627abe基于替换重写所有未来提交。git筛选器分支--全部拆下替换件以保持清洁。git替换-d 03f482d6推送新的历史记录(仅在以下操作失败时使用--force,并且仅在使用gitlog和/或gitdiff进行健全性检查后使用)。git push—强制执行租约
而不是4-5,你可以重新开始新的提交:
git rebase -i 42627abe
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'
您可以使用下面的命令更改上次提交的作者。
gitcommit--modify--author=“作者名称<email@address.com>"
然而,如果您想更改多个提交的作者名称,这有点棘手。您需要启动一个交互式的rebase,然后将提交标记为edit,然后逐一修改并完成。
使用git rebase-i开始重新定基。它会向你展示这样的东西。
更改pick关键字以编辑要更改作者名称的提交。
然后关闭编辑器。对于初学者,点击Escape,然后键入:wq并点击Enter。
然后你会看到你的终端就像什么都没发生一样。事实上,您正在进行交互式重设基。现在是使用上面的命令修改提交的作者名称的时候了。它将再次打开编辑器。退出并继续使用git rebase重新创建数据库--继续。对要编辑的提交计数重复相同的操作。您可以确保在执行No rebase时完成交互式rebase?消息
如果您只想更改上次提交的作者,可以执行以下操作:
将电子邮件重置为全局配置:git-config--全局用户电子邮件example@email.com现在重置提交的作者,无需编辑:gitcommit--修改--重置作者--无编辑
注意,这也会更改作者时间戳。
提交时间:
要修复所有提交的作者,您可以从@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
如果您需要更改的是上一次提交的作者,而没有其他人正在使用您的存储库,您可以使用以下方法撤消上一次的提交:
git push -f origin last_commit_hash:branch_name
更改提交的作者名称:
git commit --amend --author "type new author here"
退出打开的编辑器并再次推送代码:
git push
为了进一步解释Eugen Konkov的回答,从根提交开始,使用--root标志。--noedit标志也很有用,因为使用它,每次提交都不会提示您进入编辑器。
git rebase --root --exec "git commit --amend --author='name <email>' --no-edit"
对于这个问题,也有一种懒惰的方法,特别是当您有多个提交需要更改时。在我的案例中,我有一个新的分支,它与错误的作者进行了多次提交,所以是什么帮助了我:
转到您的原始分支:
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签出分支名称
在要更改的提交之前查找提交并查找其哈希。然后发出rebase命令。
git rebase-i-p提交哈希
然后将打开一个编辑器,并输入“edit”以查看要更改的提交。让其他人保留默认的“选择”选项。一旦更改,输入“esc”键和wq!退出。
然后发出带有修正选项的gitcommit命令。
gitcommit--modify--author=“用户名电子邮件”--无编辑
然后发出以下命令。
git rebase—继续
在本地存储库中更新提交作者后,将更改推送到远程存储库。
推送提交后重命名作者名称的步骤
首先键入“gitlog”以获取提交id和更多详细信息git rebase i HEAD~10(10是要在rebase上显示的提交总数)如果您有以下内容致命:似乎已经有一个rebase合并目录,并且我想知道你是不是在另一个地方。如果这是箱子,请试试git rebase(--continue|--abort|--skip)如果不是这样,请rm-fr“.git/rebase合并”再跑一次。我要停下来,以防你还有事在那里很有价值。然后根据需要键入“git-rebase--continue”或“git-rebase--abort”现在您将重新创建窗口,单击键盘上的“i”键然后,您将得到提交列表为10[因为我们已经通过了上面的10个提交]如下图所示pick 897fe9e稍微简化了代码pick abb60f9添加新功能pick dc18f70错误修复现在,您需要在要编辑的提交下面添加下面的命令,如下所示pick 897fe9e稍微简化了代码exec git commit--modify--author的作者名称<author.name@mail.com>'pick abb60f9添加新功能exec git commit--modify--author的作者名称<author.name@mail.com>' pick dc18f70错误修复exec git commit--modify--author的作者名称<author.name@mail.com>'就这样,现在只需按ESC键,:wq,即可完成所有设置然后git push origin HEAD:BRANCH NAME-f[请注意-f Force push]像gitpush-f或gitpushorigin HEAD:dev-f
对于合并提交消息,我发现我不能通过使用rebase来修改它,至少在gitlab上是这样。它将合并显示为提交,但我无法重新基于该#sha。我发现这篇文章很有用。
git checkout <sha of merge>
git commit --amend # edit message
git rebase HEAD previous_branch
这三行代码完成了更改合并提交消息的工作(如作者)。
在全球范围内更改提交人姓名和电子邮件:
$ 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>"
提示:对于其他情况和阅读更多信息,请阅读帖子参考。
找到一种可以快速改变用户并且不会对其他提交产生副作用的方法。
简单明了的方式:
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从选择的提交id反向开始到最近的提交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
您可以从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 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比只使用-f更能保护您
GL
来源ZSH公司
溶液
安装git filter repo(git项目建议在filter分支上安装filter repo)$PACKAGE_TOOL安装git筛选器repo在git存储库的根目录中创建一个文件.mailmap,其中包含新名称<new@ema.il> <old@ema.il>运行gitfilter repo--使用mailmap
更多详细信息
gitfilter repo在其文档中将其列为示例不要像上面的示例那样替换名称和电子邮件,请查看gitmailmap文档中的其他示例您可以通过使用参数--mailmap<filename>调用gitfilter repo来指定mailmap文件,而不是默认使用名为.mailmap的文件。关于如何进一步过滤分支/标签/任何内容的更多示例,可以在gitfilter repo项目的README.md中找到。
如果您的机器上缺少设置,例如,在格式化之后,或者在没有正确设置(正确)这些命令的情况下没有正确配置Git,则可能会发生这种情况。
git config user.name "Author Name"
git config user.email "<email@address.com>"
为什么不遵循Atlassian的这篇文章,让你的生活更简单?
gitcommit--modify--author=“作者名称<email@address.com>"如果分支受到保护,请取消对其的保护。在本例中,它是master;因此,它将受到源代码存储库的保护git推送原点master—力
这是最后一次提交的最简单场景。要选择任何“随机”提交,您需要:
git rebase-i<早期提交>。更改您感兴趣的提交的编辑选择gitcommit--modify--author=“作者名称<email@address.com>"如果分支受到保护,请取消对其的保护。在本例中,它是master;因此,它将受到源代码存储库的保护git推送原点master—力
在推送之前,您可以随时在两者之间进行git登录,以确定您所在的位置。
有一个快捷方式适用于投票最多的问题:使用exec而不是edit。
exec允许对指定的提交运行命令。使用它可以避免使用edit、退出终端并为每个git提交运行git命令。如果您必须更改历史记录中的多次提交,这尤其有用。
步骤如下:
执行对早期提交的重新基础(gitrebase-i<earliercommit>)在打开的编辑器中,在要编辑的每个提交行后添加一行,然后添加exec git commit--modify--author=“作者名称<email@address.com>“--不编辑(如果要重置为gitconfig中设置的值,请使用--reset-author)”保存并退出-这将为每次提交运行指定的命令,有效地更改作者
编辑器内容示例(更改前两个提交作者):
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.
#
作为Eugen Konkov回答的补充,可以保留提交/作者日期。要只修改作者而不修改最后三次提交的日期,请使用
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
首选的答案是,使用gitrebase-i是有效的,但正如在另一个答案中强调的那样,当要编辑的提交周围有合并时,就会变得混乱。使用gitreplace是明智的,但gitfilter分支会重写其他分支和标记的所有历史,这不是我们通常想要的。
我想分享一个替代第一个答案的方法,即使有合并,它仍然很简单。在我的例子中,当我使用gitrebase-I<earlycommit>时,在继续rebase之前,我首先要解决一个冲突。事实上,使用break命令比使用edit命令更容易。并直接重新基于我们的目标提交。
让我们举个例子,假设git日志显示。。。
commit a12afg
...
commit dloe7a
...
commit gh7ag1
...
commit qp3zaa
...
假设您想更新提交gh7ag1的作者、消息或提交签名。您可以继续使用git rebase-i gh7ag1。在编辑器中,您将看到:
pick dloe7a
pick a12afg
只需添加一个break命令:
break
pick dloe7a
pick a12afg
保存(:wq与VI,Ctrl+O,然后Ctrl+X与nano)。现在,你在承诺后马上回来了。您可以运行gitcommit--modify来更新作者、消息或签名(例如gitcommit--modify-S--author=“Your Name<Your email>”)。使用git-log进行验证--显示签名。如果正确,可以继续使用git-rebase--continue。
在rebase中可以有任意多的break命令。continue将移动到下一个break(如果有),或者应用剩余的提交(如果它们标记为pick)。
我2019年的评论转化为答案:
修复最后六次提交的创作
首先为当前Git repo设置正确的作者git-config--本地user.name“FirstName LastName”git-config--本地用户.emailfirst.last@example.com然后将修复应用于最后六次提交git rebase--on HEAD~6--exec“git commit--modify--reset author--no edit”HEAD~6最后强制推送到远程Git repogit push—强制执行租约
使用交互式回扣
git rebase -i -p <some HEAD before all of your bad commits>
然后在rebase文件中将所有错误提交标记为“edit”,当git要求您修改每个提交时
git commit --amend --author "New Author Name <email@address.com>"
编辑或关闭打开的编辑器,然后执行
git rebase --continue
以继续重新启动。
您可以通过附加--no edit来跳过在此处完全打开编辑器,这样命令将是:
git commit --amend --author "New Author Name <email@address.com>" --no-edit && \
git rebase --continue
单次提交
正如一些评论所指出的,如果您只想更改最近的提交,那么rebase命令是不必要的。就这样吧
git commit --amend --author "New Author Name <email@address.com>"
这会将author更改为指定的名称,但committer将设置为gitconfig user.name和gitconfig user.email中配置的用户。如果要将committer设置为指定的值,这将同时设置author和committer:
git -c user.name="New Author Name" -c user.email=email@address.com commit --amend --reset-author