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

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

但是我在考虑的地方通过哈希或短哈希提交。

评论


如何修改现有的未推送的提交?

#1 楼

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

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



例如,如果您的提交历史是A-B-C-D-E-F,而FHEAD,并且想要更改CD的作者,那么您将...


指定git rebase -i B(这是执行git rebase -i B命令后将看到的示例)


如果需要编辑A,请使用git rebase -i --root
CD的行从pick更改为edit

退出编辑器(对于vim,这将按Esc键,然后键入:wq)。
一旦开始重新设置基准,它将首先在C

暂停,您将git commit --amend --author="Author Name <email@address.com>"

然后git rebase --continue

它将再次在D处暂停

然后您将再次git commit --amend --author="Author Name <email@address.com>"
git rebase --continue
重新设置将完成。
/>使用git push -f使用更新的提交来更新源。


评论


好的答案,但对于初学者:首先在您要更改的提交之前找到一个提交,然后运行git rebase -i

–马修·伯恩(Mathew Byrne)
2011年8月3日在1:30



如果您不知道自己在使用哪个编辑器,答案可能就是vim。要保存并退出,请输入Esc:w q Enter。另一方面,如果它是Nano,并且在底部看到“ WriteOut:^ O”之类的内容,则应使用Ctrl + O,Enter,Ctrl + X代替。

–琥珀色
2012年6月12日17:02



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

–布伦登
2012年8月31日下午16:52

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

– 5lava
2014年6月9日18:43

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

–诺亚·帕萨拉夸(Noah Passalacqua)
16年5月4日在20:07



#2 楼

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

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

下面的内容经过测试,可以正常工作,与链接的答案不同。
为了清楚说明起见,假设03f482d6是我们要替换其作者的提交,而42627abe是与新作者确认。



检出我们试图修改的提交。

git checkout 03f482d6



更改作者。

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


现在我们有了一个新的提交哈希假定为42627abe

签出原始分支。

用新的本地替换旧的提交。

git replace 03f482d6 42627abe



基于替换重写所有将来的提交。

git filter-branch -- --all



删除替换以保持清洁。

/>
git replace -d 03f482d6



推送新历史记录(仅在以下情况失败时才使用--force,并且仅在通过git log和/或git diff进行完好性检查之后使用)。

git push --force-with-lease



而不是4-6,您可以基于新的提交:

git rebase -i 42627abe


评论


请在第2步后在此处添加注释以重新签出原始分支。

–本杰明·里格斯(Benjamin Riggs)
2015年3月11日,0:26

对于可怕的git rebase -i来说,这看起来很清楚。从来没有听说过这个git replace的东西。 +1

– FractalSpace
15年7月8日在23:29

对于清洁裁判/原始/ ...备份,请参阅此处

–alexis
16 Mar 9 '16 at 17:54



我建议使用--force-with-lease而不是-f。更安全

–杰伊·巴祖兹(Jay Bazuzi)
17年7月3日在17:14

警告:请注意git filter-branch--所有正在更改原始提交所在的所有分支中的提交。如果您没有足够的凭据(或者您不想更改其他分支的历史记录),最好小心这个答案。

–ribamar
18年1月11日在10:45



#3 楼

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'




评论


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

– Artjom B.
2015年6月9日在16:20



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

–罗斯兰·杰拉西莫夫(Ruslan Gerasimov)
16年8月8日在19:31

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

–VasiliNovikov
18年1月18日在17:33



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

–mjs
18年8月10日在14:47

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

– LWY
18年11月16日在1:45

#4 楼



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

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


现在重置提交作者,而无需进行编辑:

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



评论


不,这不对。看一下OP:这不是最后一次提交。那么他们将如何修改呢?

– underscore_d
17年8月31日在13:25



太好了,可惜这只是最后一次提交。幸运的是,我在最近的两次上都需要它,所以只做了git reset HEAD〜,运行了建议的行,然后再次手动进行了下一次提交。工作正常!

–马特·弗莱彻(Matt Fletcher)
17年9月18日在10:56

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

–卢卡斯·P。
18年11月13日在11:23

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

– oHo
19-10-14在12:32



#5 楼

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

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

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

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



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




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

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

评论


如果您需要更改多个提交,而不是单独编辑它们,则还可以执行选择操作,并在每行之后添加git git---no-edit --amend --author =“ MyNewAuthor

– Pierre-Olivier Vares
2月5日9:05

#6 楼

您链接到的问题中的答案是不错的答案,可以解决您的情况(另一个问题是更笼统的,因为它涉及重写多个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
 


评论


+1谢谢。 assembla.com git repo似乎并未更改该repo的web视图中的所有作者引用,但'git pull / clone'的结果似乎正常。

–约翰尼·犹他州
2012年10月31日,下午2:05

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

– GuillaumeLemaître
2014年1月17日的14:00

Github文档包含类似的脚本

–olivieradam666
14年6月18日在11:56

@ olivieradam666就像一个魅力,更容易阅读

–fregante
2014年6月30日12:48

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

–seane
2015年6月9日14:37

#7 楼

之前提交:



要修复作者的所有提交,可以从@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  --exec \"git commit --amend --author=\" ' --


然后运行:

git reauthor 4025621 Eugen


评论


为了验证命令是否按预期工作,我查看了git shortlog -e -s的输出。

–泰勒·埃德米斯顿(Taylor Edmiston)
18年1月1日在16:36

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

–达托
19 Mar 2 '19 at 17:02

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

–达托
19 Mar 2 '19 at 21:51

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

– J_A_X
19年4月11日在1:29

那对我没有帮助。现在我有继续重新设置失败错误

– Alexey Sh。
19年8月14日在21:09



#8 楼

为了促进Eugen Konkov的回答,请从根提交开始,使用--root标志。 --no-edit标志也很有用,因为它不会提示您每次提交都进入编辑器。

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


#9 楼

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

简单明了的方法:

 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 to update

< pre class =“ lang-sh prettyprint-override”> git push --force-with-lease

评论


如果我要更改的提交是第一次提交,并且之后有3个提交,那么第一个解决方案是否可行? @NOZUONOHIGH

– strix25
9月12日8:46

这里的危险是您在config中更改了user.name和user.email,但是不要将它们改回来。如果您不更改它们,所有以后的提交也将由新用户承担!这就是为什么最好在git commit上使用--author标志。

–尼克F
9月15日下午14:53



#10 楼

如果您使用的是集中式存储库,则Amber的答案还有一个附加步骤:

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

请注意,没有很多人在同一分支上工作,因为它可能破坏一致性。

#11 楼

在执行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的父级。


您将要在每次提交修改前放置一个空提交
,您将需要将这些更改从pick更改为squash。 >
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...


,您只需删除前几行即可。

#12 楼

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

git checkout branch_name

在要更改的提交之前找到提交并查找其哈希。然后发出rebase命令。保留其他默认的“ pick”选项。更改后,请输入“ esc”键并输入密码!退出。

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


然后发出以下命令。


一旦在本地存储库中更新了提交作者,请将更改推送到远程存储库。 br />

#13 楼

对于这个问题,还有一种懒惰的方法,尤其是当您要更改多个提交时。就我而言,我有一个新的分支,其中的多个提交与一个错误的作者,所以对我有帮助的是:

转到您原来的分支:

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"


就这样,您可以推送更改。

#14 楼

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


首先键入“ git log”以获取提交ID和更多详细信息


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.


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


现在将打开“ rebase”窗口,请单击键盘上的“ i”键
那么您将获得10个提交的列表[因为我们已经通过了10个以上的提交]
像下面这样

pick 897fe9e simplify code a little

pick abb60f9 add new feature

pick dc18f70 bugfix


现在,您需要在要编辑的提交的下方添加以下命令,例如以下

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


就这样,现在只需按ESC,:wq就可以了。
然后git push origin HEAD:BRANCH NAME -f [请注意-f Force push]

git push -fgit push origin HEAD: dev -f



#15 楼

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

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


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

#16 楼

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

$ 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>"


提示:对于其他情况和更多信息,请阅读文章参考。

#17 楼

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

git push -f origin last_commit_hash:branch_name 


更改作者姓名提交的内容:

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


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

git push


#18 楼

您可以在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


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

#19 楼

可选:如果不想将它们发送到远程,请确保保存本地更改。
$ 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相比,您受到的保护甚至更多。

评论


投反对票的原因是,如果有一种方法可以不用git push -f,那么就不用git push -f。

–赛斯
8月17日0:55

@Seth我在这里使用--with-lease更新了答案。无论如何,您以什么方式推荐?我将尝试优化命令。感谢您的反馈

–布莱恩·科罗内尔(Braian Coronel)
8月17日23:57