如何更改多次提交的作者和提交者姓名/电子邮件?

发布于 2024-07-18 04:01:07 字数 20 浏览 10 评论 0 原文

如何更改一系列提交的作者?

How do I change the author for a range of commits?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

北恋 2024-07-25 04:01:08

我改编了这个解决方案,它通过摄取一个简单的author-来工作conv-file (格式与 git-cvsimport)。 它的工作原理是更改所有分支中 author-conv-file 中定义的所有用户。

我们将其与 cvs2git 结合使用,将我们的存储库从 cvs 迁移到 git。

即示例 author-conv-file

john=John Doe <[email protected]>
jill=Jill Doe <[email protected]>

脚本:

 #!/bin/bash

 export $authors_file=author-conv-file

 git filter-branch -f --env-filter '

 get_name () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=\(.*\) <.*>$/\1/"
 }

 get_email () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=.* <\(.*\)>$/\1/"
 }

 GIT_AUTHOR_NAME=$(get_name $GIT_COMMITTER_NAME) &&
     GIT_AUTHOR_EMAIL=$(get_email $GIT_COMMITTER_NAME) &&
     GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME &&
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL &&
     export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
     export GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
 ' -- --all

I adapted this solution which works by ingesting a simple author-conv-file (format is the same as one for git-cvsimport). It works by changing all users as defined in the author-conv-file across all branches.

We used this in conjunction with cvs2git to migrate our repository from cvs to git.

i.e. Sample author-conv-file

john=John Doe <[email protected]>
jill=Jill Doe <[email protected]>

The script:

 #!/bin/bash

 export $authors_file=author-conv-file

 git filter-branch -f --env-filter '

 get_name () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=\(.*\) <.*>$/\1/"
 }

 get_email () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=.* <\(.*\)>$/\1/"
 }

 GIT_AUTHOR_NAME=$(get_name $GIT_COMMITTER_NAME) &&
     GIT_AUTHOR_EMAIL=$(get_email $GIT_COMMITTER_NAME) &&
     GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME &&
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL &&
     export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
     export GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
 ' -- --all
勿挽旧人 2024-07-25 04:01:08

我发现所提供的版本过于激进,特别是如果您提交其他开发人员的补丁,这实际上会窃取他们的代码。

下面的版本确实适用于所有分支,并分别更改作者和提交者以防止这种情况发生。

感谢 leif81 的 all 选项。

#!/bin/bash

git filter-branch --env-filter '
if [ "$GIT_AUTHOR_NAME" = "<old author>" ];
then
    GIT_AUTHOR_NAME="<new author>";
    GIT_AUTHOR_EMAIL="<[email protected]>";
fi
if [ "$GIT_COMMITTER_NAME" = "<old committer>" ];
then
    GIT_COMMITTER_NAME="<new commiter>";
    GIT_COMMITTER_EMAIL="<[email protected]>";
fi
' -- --all

I found the presented versions way to aggressive, especially if you commit patches from other developers, this will essentially steal their code.

The version below does work on all branches and changes the author and comitter separately to prevent that.

Kudos to leif81 for the all option.

#!/bin/bash

git filter-branch --env-filter '
if [ "$GIT_AUTHOR_NAME" = "<old author>" ];
then
    GIT_AUTHOR_NAME="<new author>";
    GIT_AUTHOR_EMAIL="<[email protected]>";
fi
if [ "$GIT_COMMITTER_NAME" = "<old committer>" ];
then
    GIT_COMMITTER_NAME="<new commiter>";
    GIT_COMMITTER_EMAIL="<[email protected]>";
fi
' -- --all
尸血腥色 2024-07-25 04:01:08
  1. 更改提交作者姓名& 通过 Amend 发送电子邮件,然后将 old-commit 替换为 new-one

    $ git checkout ;   # 签出需要修改的提交   
      $ git commit --amend --author "name <[电子邮件受保护]>”   # 更改作者姓名和电子邮件 
    
      $ git Replace ;   <新提交哈希>   # 将旧的提交替换为新的提交 
      $ git filter-branch -- --all # 根据替换重写所有 future 提交                    
    
      $ git Replace -d ;   # 删除替换以保持清洁  
      $ git push -f origin HEAD # 强制推送  
      
  2. 另一种方式变基

    $ git rebase -i ;   # 回到最后一次良好的提交 
    
      # 编辑器将打开,在提交想要更改作者之前将“pick”替换为“edit” 
    
      $ git commit --amend --author="作者姓名 <[电子邮件受保护]< /a>>"   # 更改作者姓名 &   电子邮件 
    
      # 保存更改并退出编辑器 
    
      $ git rebase --continue # 完成 rebase 
      
  1. Change commit author name & email by Amend, then replacing old-commit with new-one:

    $ git checkout <commit-hash>                            # checkout to the commit need to modify  
    $ git commit --amend --author "name <[email protected]>" # change the author name and email
    
    $ git replace <old-commit-hash> <new-commit-hash>      # replace the old commit by new one
    $ git filter-branch -- --all                           # rewrite all futures commits based on the replacement                   
    
    $ git replace -d <old-commit-hash>     # remove the replacement for cleanliness 
    $ git push -f origin HEAD              # force push 
    
  2. Another way Rebasing:

    $ git rebase -i <good-commit-hash>      # back to last good commit
    
    # Editor would open, replace 'pick' with 'edit' before the commit want to change author
    
    $ git commit --amend --author="author name <[email protected]>"  # change the author name & email
    
    # Save changes and exit the editor
    
    $ git rebase --continue                # finish the rebase
    
挽梦忆笙歌 2024-07-25 04:01:08

最快、最简单的方法是使用 git rebase 的 --exec 参数:

git rebase -i -p --exec 'git commit --amend --reset-author --no-edit'

这将创建一个如下所示的待办事项列表:

pick ef11092 Blah blah blah
exec git commit --amend --reset-author --no-edit
pick 52d6391 Blah bloh bloo
exec git commit --amend --reset-author --no-edit
pick 30ebbfe Blah bluh bleh
exec git commit --amend --reset-author --no-edit
...

这将自动工作,当您有数百次提交时,它会工作。

The fastest, easiest way to do this is to use the --exec argument of git rebase:

git rebase -i -p --exec 'git commit --amend --reset-author --no-edit'

This will create a todo-list that looks like this:

pick ef11092 Blah blah blah
exec git commit --amend --reset-author --no-edit
pick 52d6391 Blah bloh bloo
exec git commit --amend --reset-author --no-edit
pick 30ebbfe Blah bluh bleh
exec git commit --amend --reset-author --no-edit
...

and this will work all automatically, which works when you have hundreds of commits.

楠木可依 2024-07-25 04:01:08

带有 filter-repo 的单行:

您可以使用 回调功能 git-filter-repo (推荐替换 filter-branch)来更改与所有提交关联的名称和电子邮件:

git filter-repo --name-callback 'return b"New Name"' --email-callback 'return b"[email protected]"'

这比使用 filter-branch 的解决方案性能更高,并且可能更可靠。

请注意,上面的命令更改了所有提交的作者(和提交者),如果您想有效地“编辑”某个作者,并且只修改该特定作者的提交,那么使用--commit-callback 选项如下:(

git filter-repo --commit-callback '
old_email = b"[email protected]"
new_email = b"[email protected]"
new_name = b"New Author"

if commit.author_email == old_email:
    commit.author_email = new_email
    commit.author_name = new_name

if commit.committer_email == old_email:
    commit.committer_email = new_email
    commit.committer_name = new_name
'

只需更改上面命令中的 old_emailnew_emailnew_name 变量到正确的值。)

One-liner with filter-repo:

You can use the callbacks feature of git-filter-repo (a recommended replacement for filter-branch) to change the name and email associated with all the commits:

git filter-repo --name-callback 'return b"New Name"' --email-callback 'return b"[email protected]"'

This is more performant and potentially more reliable than solutions using filter-branch.

Note that the above command changes the authors (and committer) of all commits, if you want to effectively "edit" a certain author, and only modify the commits of that specific author, then use the --commit-callback option like this:

git filter-repo --commit-callback '
old_email = b"[email protected]"
new_email = b"[email protected]"
new_name = b"New Author"

if commit.author_email == old_email:
    commit.author_email = new_email
    commit.author_name = new_name

if commit.committer_email == old_email:
    commit.committer_email = new_email
    commit.committer_name = new_name
'

(Just change the old_email, new_email, and new_name variables in the command above to the right values.)

故人如初 2024-07-25 04:01:08

如果您是此存储库的唯一用户,则可以使用 git filter-branch (如 svick 写道),或 git fast-export/git fast-import 加上过滤器脚本(如 docgnome 答案),或交互式

恢复

如果其他开发人员的工作不是基于重写前的版本,最简单的解决方案就是重新克隆(再次克隆)。

或者,他们可以尝试 git rebase --pull ,如果存储库中没有任何更改,这将快进,或者在重写的提交之上重新建立分支(我们希望避免合并) ,因为它将永远保留预重写提交)。 所有这一切都假设他们没有从事工作; 否则,请使用 git stash 来隐藏更改。

如果其他开发人员使用功能分支,和/或 git pull --rebase 不起作用,例如因为未设置上游,他们必须 rebase 他们在重写后提交之上的工作。 例如,在获取新更改 (git fetch) 后,对于基于 / 从 origin/master 分叉的 master 分支,需要运行

$ git rebase --onto origin/master origin/master@{1} master

这里 origin/master@{1} 是预重写状态(在获取之前),请参阅 gitrevisions


替代解决方案是使用 refs/replace/ 机制,该机制自版本 1.6.5 起在 Git 中可用。 在此解决方案中,您为具有错误电子邮件的提交提供替换; 然后任何获取“替换”引用的人(例如 fetch = +refs/replace/*:refs/replace/* refspec 在 他们的 .git 中的适当位置/config)将透明地获得替换,而那些不获取这些引用的人将看到旧的提交。

该过程如下所示:

  1. 查找所有包含错误电子邮件的提交,例如使用

    $ git log [电子邮件受保护] --all 
      
  2. 对于每个错误的提交,创建替换提交,并将其添加到对象数据库

    $ git cat-file -p <错误提交的 ID>;   |  
        sed -e 's/user@wrong\.email/[电子邮件受保护]/g' >   tmp.txt 
      $ git hash-object -t commit -w tmp.txt 
      <更正提交的 ID> 
      
  3. 现在您已经更正了对象数据库中的提交,您必须告诉 git 自动且透明地替换错误的提交使用 git Replace 更正了一个命令:

    $ git Replace <错误提交的 ID>;   <更正提交的 ID> 
      
  4. 最后,列出所有替换以检查此过程是否有效成功

    <前><代码>$ git 替换 -l

    并检查是否进行更换

    $ git log [电子邮件受保护] --all 
      

您当然可以自动化此过程......好吧,除了使用 git Replace 之外,还没有批处理模式,因此您必须使用 shell 循环,或者替换“手动”。

未经测试! YMMV。

请注意,在使用refs/replace/机制时,您可能会遇到一些困难:它是新的,尚未经过很好的测试

If you are the only user of this repository, you can rewrite history using either git filter-branch (as svick wrote), or git fast-export/git fast-import plus filter script (as described in article referenced in docgnome answer), or interactive rebase. But either of those would change revisions from first changed commit onwards; this means trouble for anybody that based his/her changes on your branch pre-rewrite.

RECOVERY

If other developers didn't based their work on pre-rewrite version, simplest solution would be to re-clone (clone again).

Alternatively they can try git rebase --pull, which would fast-forward if there weren't any changes in their repository, or rebase their branch on top of re-written commits (we want to avoid merge, as it would keep pre-rewrite comits forever). All of this assuming that they do not have not comitted work; use git stash to stash away changes otherwise.

If other developers use feature branches, and/or git pull --rebase doesn't work e.g. because upstream is not set up, they have to rebase their work on top of post-rewrite commits. For example just after fetching new changes (git fetch), for a master branch based on / forked from origin/master, one needs to run

$ git rebase --onto origin/master origin/master@{1} master

Here origin/master@{1} is pre-rewrite state (before fetch), see gitrevisions.


Alternate solution would be to use refs/replace/ mechanism, available in Git since version 1.6.5. In this solution you provide replacements for commits that have wrong email; then anybody who fetches 'replace' refs (something like fetch = +refs/replace/*:refs/replace/* refspec in appropriate place in their .git/config) would get replacements transparently, and those who do not fetch those refs would see old commits.

The procedure goes something like this:

  1. Find all commits with wrong email, for example using

    $ git log [email protected] --all
    
  2. For each wrong commit, create a replacement commit, and add it to object database

    $ git cat-file -p <ID of wrong commit> | 
      sed -e 's/user@wrong\.email/[email protected]/g' > tmp.txt
    $ git hash-object -t commit -w tmp.txt
    <ID of corrected commit>
    
  3. Now that you have corrected commit in object database, you have to tell git to automatically and transparently replace wrong commit by corrected one using git replace command:

    $ git replace <ID of wrong commit> <ID of corrected commit>
    
  4. Finally, list all replacement to check if this procedure succeded

    $ git replace -l
    

    and check if replacements take place

    $ git log [email protected] --all
    

You can of course automate this procedure... well, all except using git replace which doesn't have (yet) batch mode, so you would have to use shell loop for that, or replace "by hand".

NOT TESTED! YMMV.

Note that you might encounter some rough corners when using refs/replace/ mechanism: it is new, and not yet very well tested.

り繁华旳梦境 2024-07-25 04:01:08

请注意,git 存储两个不同的电子邮件地址,一个用于提交者(提交更改的人),另一个用于作者 (编写更改的人)。

大多数地方不会显示提交者信息,但您可以使用 git log -1 --format=%cn,%ce 查看它(或使用 show 而不是log 来指定特定的提交)。

更改上次提交的作者就像 git commit --amend --author "Author Name <[电子邮件受保护]>",没有任何单行或参数可以对提交者信息执行相同的操作。

解决方案是(暂时或不)更改您的用户信息,然后修改提交,这会将提交者更新为您当前的信息:

git config user.email [email protected] 
git commit --amend

Note that git stores two different e-mail addresses, one for the committer (the person who committed the change) and another one for the author (the person who wrote the change).

The committer information isn't displayed in most places, but you can see it with git log -1 --format=%cn,%ce (or use show instead of log to specify a particular commit).

While changing the author of your last commit is as simple as git commit --amend --author "Author Name <[email protected]>", there is no one-liner or argument to do the same to the committer information.

The solution is to (temporarily, or not) change your user information, then amend the commit, which will update the committer to your current information:

git config user.email [email protected] 
git commit --amend
清欢 2024-07-25 04:01:08

重置所有提交(包括第一次提交)到当前用户和当前时间戳:

git rebase --root --exec "git commit --amend --no-edit --date 'now' --reset-author"

For reset ALL commits (including first commit) to current user and current timestamp:

git rebase --root --exec "git commit --amend --no-edit --date 'now' --reset-author"
半衬遮猫 2024-07-25 04:01:08

如果您要修复的提交是最新的,并且只有其中几个,您可以使用 git reset 和 git stash 的组合来返回提交它们配置正确的姓名和电子邮件后再次进行。

序列将是这样的(对于 2 次错误的提交,没有挂起的更改):

git config user.name <good name>
git config user.email <good email>
git reset HEAD^
git stash
git reset HEAD^
git commit -a
git stash pop
git commit -a

If the commits you want to fix are the latest ones, and just a couple of them, you can use a combination of git reset and git stash to go back an commit them again after configuring the right name and email.

The sequence will be something like this (for 2 wrong commits, no pending changes):

git config user.name <good name>
git config user.email <good email>
git reset HEAD^
git stash
git reset HEAD^
git commit -a
git stash pop
git commit -a
且行且努力 2024-07-25 04:01:08

如果您将 Eclipse 与 Egit 一起使用,那么有一个非常简单的解决方案。
假设:您在本地分支“local_master_user_x”中有提交,由于用户无效,无法将其推送到远程分支“master”。

  1. 签出远程分支“master”
  2. 选择“local_master_user_x”包含更改的项目/文件夹/文件
  3. 右键单击-替换为-分支-“local_master_user_x”
  4. 再次提交这些更改,这次以正确的用户身份提交到本地分支“ master'
  5. 推送到远程“master”

If you are using Eclipse with EGit, then there is a quite easy solution.
Assumption: you have commits in a local branch 'local_master_user_x' which cannot be pushed to a remote branch 'master' because of the invalid user.

  1. Checkout the remote branch 'master'
  2. Select the projects/folders/files for which 'local_master_user_x' contains changes
  3. Right-click - Replace with - Branch - 'local_master_user_x'
  4. Commit these changes again, this time as the correct user and into the local branch 'master'
  5. Push to remote 'master'
往日 2024-07-25 04:01:08

使用交互式变基,您可以在每次要更改的提交后放置修改命令。 例如:

pick a07cb86 Project tile template with full details and styling
x git commit --amend --reset-author -Chead

Using interactive rebase, you can place an amend command after each commit you want to alter. For instance:

pick a07cb86 Project tile template with full details and styling
x git commit --amend --reset-author -Chead
如若梦似彩虹 2024-07-25 04:01:08

今天我们遇到了一个问题,即作者姓名中的 UTF8 字符在构建服务器上造成了问题,因此我们必须重写历史记录来纠正此问题。 采取的步骤是:

步骤 1:按照此处的说明,更改 git 中的用户名以用于将来的所有提交:
https://help.github.com/articles/setting-your- username-in-git/

步骤 2:运行以下 bash 脚本:

#!/bin/sh

REPO_URL=ssh://path/to/your.git
REPO_DIR=rewrite.tmp

# Clone the repository
git clone ${REPO_URL} ${REPO_DIR}

# Change to the cloned repository
cd ${REPO_DIR}

# Checkout all the remote branches as local tracking branches
git branch --list -r origin/* | cut -c10- | xargs -n1 git checkout

# Rewrite the history, use a system that will preseve the eol (or lack of in commit messages) - preferably Linux not OSX
git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="New Me"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
fi
' --tag-name-filter cat -- --branches --tags

# Force push the rewritten branches + tags to the remote
git push -f

# Remove all knowledge that we did something
rm -rf ${REPO_DIR}

# Tell your colleagues to `git pull --rebase` on all their local remote tracking branches

快速概述:将存储库签出到临时文件,签出所有远程分支,运行将重写历史记录的脚本,强制推送新状态,并告诉所有同事进行变基拉取以获取更改。

我们在 OS X 上运行这个程序时遇到了麻烦,因为它以某种方式弄乱了提交消息中的行结尾,因此我们后来不得不在 Linux 机器上重新运行它。

We have experienced an issue today where a UTF8 character in an author name was causing trouble on the build server, so we had to rewrite the history to correct this. The steps taken were:

Step 1: Change your username in git for all future commits, as per instructions here:
https://help.github.com/articles/setting-your-username-in-git/

Step 2: Run the following bash script:

#!/bin/sh

REPO_URL=ssh://path/to/your.git
REPO_DIR=rewrite.tmp

# Clone the repository
git clone ${REPO_URL} ${REPO_DIR}

# Change to the cloned repository
cd ${REPO_DIR}

# Checkout all the remote branches as local tracking branches
git branch --list -r origin/* | cut -c10- | xargs -n1 git checkout

# Rewrite the history, use a system that will preseve the eol (or lack of in commit messages) - preferably Linux not OSX
git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="New Me"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
fi
' --tag-name-filter cat -- --branches --tags

# Force push the rewritten branches + tags to the remote
git push -f

# Remove all knowledge that we did something
rm -rf ${REPO_DIR}

# Tell your colleagues to `git pull --rebase` on all their local remote tracking branches

Quick overview: Checkout your repository to a temp file, checkout all the remote branches, run the script which will rewrite the history, do a force push of the new state, and tell all your colleagues to do a rebase pull to get the changes.

We had trouble with running this on OS X because it somehow messed up line endings in commit messages, so we had to re-run it on a Linux machine afterwards.

北恋 2024-07-25 04:01:08

你的问题确实很普遍。 请参阅“使用 Mailmap 进行修复Git 中的作者列表

为了简单起见,我创建了一个脚本来简化该过程: git-changemail

将该脚本放入您的路径后,您可以发出如下命令:

顺便说一下,进行更改后,使用以下命令清除过滤器分支中的备份: git-backup-clean

Your problem is really common. See "Using Mailmap to Fix Authors List in Git"

For the sake of simplicity, I have created a script to ease the process: git-changemail

After putting that script on your path, you can issue commands like:

  • Change author matchings on current branch

    $ git changemail -a [email protected] -n newname -m [email protected]
    
  • Change author and committer matchings on <branch> and <branch2>. Pass -f to filter-branch to allow rewriting backups

    $ git changemail -b [email protected] -n newname -m [email protected] -- -f <branch> <branch2>
    
  • Show existing users on repo

    $ git changemail --show-both
    

By the way, after making your changes, clean the backup from the filter-branch with: git-backup-clean

烟酒忠诚 2024-07-25 04:01:07

注意:此答案会更改 SHA1,因此在已推送的分支上使用它时要小心。 如果您只想修复名称的拼写或更新旧电子邮件,Git 可以让您无需使用 .mailmap 重写历史记录即可完成此操作。 请参阅我的其他答案

首先使用Rebase

,如果您还没有这样做,您可能会想要在 git-config 中修复您的名称:

git config --global user.name "New Author Name"
git config --global user.email "<[email protected]>"

这是可选的,但它也将确保重置提交者名称,假设这就是您所需要的。

要使用变基重写一系列提交的元数据, do

git rebase -r <some commit before all of your bad commits> \
    --exec 'git commit --amend --no-edit --reset-author'

--exec 将在每次重写后运行 git commit 步骤(就像您运行 git重复提交 & git rebase --continue )。

如果您还想更改第一个提交(也称为“根”提交),则必须将 --root 添加到 rebase 调用中。

这会将提交者和作者更改为您的 user.name/user.email 配置。 如果您不想更改该配置,可以使用 --author "New Author Name <[电子邮件受保护]>” 而不是 --reset-author。 请注意,这样做将不会更新提交者——仅更新作者。

单次提交

如果您只想更改最近的提交,则不需要变基。 只需修改提交即可:

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

整个项目历史记录

git rebase -r --root --exec "git commit --amend --no-edit --reset-author"

对于较旧的 Git 客户端(2020 年 7 月之前),

-r,--rebase-merges 可能不存在。 作为替代,您可以使用 -p。 请注意,-p 存在严重问题,现已弃用。

NOTE: This answer changes SHA1s, so take care when using it on a branch that has already been pushed. If you only want to fix the spelling of a name or update an old email, Git lets you do this without rewriting history using .mailmap. See my other answer.

Using Rebase

First, if you haven't already done so, you will likely want to fix your name in git-config:

git config --global user.name "New Author Name"
git config --global user.email "<[email protected]>"

This is optional, but it will also make sure to reset the committer name, too, assuming that's what you need.

To rewrite metadata for a range of commits using a rebase, do

git rebase -r <some commit before all of your bad commits> \
    --exec 'git commit --amend --no-edit --reset-author'

--exec will run the git commit step after each commit is rewritten (as if you ran git commit && git rebase --continue repeatedly).

If you also want to change your first commit (also called the 'root' commit), you will have to add --root to the rebase call.

This will change both the committer and the author to your user.name/user.email configuration. If you did not want to change that config, you can use --author "New Author Name <[email protected]>" instead of --reset-author. Note that doing so will not update the committer -- just the author.

Single Commit

If you just want to change the most recent commit, a rebase is not necessary. Just amend the commit:

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

Entire project history

git rebase -r --root --exec "git commit --amend --no-edit --reset-author"

For older Git clients (pre-July 2020)

-r,--rebase-merges may not exist for you. As a replacement, you can use -p. Note that -p has serious issues and is now deprecated.

旧人哭 2024-07-25 04:01:07

此答案使用 git-filter-branch,其中 文档现在给出此警告:

git filter-branch 有很多陷阱,可能会对预期的历史重写产生不明显的损坏(并且可能会让您几乎没有时间调查此类问题,因为它的性能如此糟糕)。 这些安全和性能问题无法向后兼容地修复,因此不建议使用它。 请使用替代历史记录过滤工具,例如 git filter-repo。 如果您仍然需要使用 git filter-branch,请仔细阅读 SAFETY (和性能)了解filter-branch的地雷,然后尽可能多地警惕地避免列出的危险。

更改作者(或提交者)将需要重写所有历史记录。 如果您对此感到满意并且认为值得,那么您应该查看 git 过滤器-分支。 手册页包含几个帮助您入门的示例。 另请注意,您可以使用环境变量来更改作者、提交者、日期等的姓名 - 请参阅 git 手册页

具体来说,您可以使用此命令修复所有分支和标签的所有错误作者姓名和电子邮件(来源:GitHub 帮助):

#!/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

用于使用替代历史记录过滤工具git filter-repo,可以先安装它,并按照gitmailmap

Proper Name <[email protected]> Commit Name <[email protected]>

然后使用创建的邮件映射运行filter-repo:

git filter-repo --mailmap git-mailmap

This answer uses git-filter-branch, for which the docs now give this warning:

git filter-branch has a plethora of pitfalls that can produce non-obvious manglings of the intended history rewrite (and can leave you with little time to investigate such problems since it has such abysmal performance). These safety and performance issues cannot be backward compatibly fixed and as such, its use is not recommended. Please use an alternative history filtering tool such as git filter-repo. If you still need to use git filter-branch, please carefully read SAFETY (and PERFORMANCE) to learn about the land mines of filter-branch, and then vigilantly avoid as many of the hazards listed there as reasonably possible.

Changing the author (or committer) would require rewriting all of the history. If you're okay with that and think it's worth it then you should check out git filter-branch. The manual page includes several examples to get you started. Also note that you can use environment variables to change the name of the author, committer, dates, etc. -- see the "Environment Variables" section of the git manual page.

Specifically, you can fix all the wrong author names and emails for all branches and tags with this command (source: GitHub help):

#!/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

For using alternative history filtering tool git filter-repo, you can first install it and construct a git-mailmap according to the format of gitmailmap.

Proper Name <[email protected]> Commit Name <[email protected]>

And then run filter-repo with the created mailmap:

git filter-repo --mailmap git-mailmap
江湖正好 2024-07-25 04:01:07

一行,但如果您有一个多用户存储库,请小心 - 这将更改所有提交以具有相同的(新)作者和提交者。

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD

在字符串中使用换行符(这在 bash 中是可能的):

git filter-branch -f --env-filter "
    GIT_AUTHOR_NAME='Newname'
    GIT_AUTHOR_EMAIL='new@email'
    GIT_COMMITTER_NAME='Newname'
    GIT_COMMITTER_EMAIL='new@email'
  " HEAD

One liner, but be careful if you have a multi-user repository - this will change all commits to have the same (new) author and committer.

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD

With linebreaks in the string (which is possible in bash):

git filter-branch -f --env-filter "
    GIT_AUTHOR_NAME='Newname'
    GIT_AUTHOR_EMAIL='new@email'
    GIT_COMMITTER_NAME='Newname'
    GIT_COMMITTER_EMAIL='new@email'
  " HEAD
疏忽 2024-07-25 04:01:07

您还可以执行以下操作:

git filter-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

注意,如果您在 Windows 命令提示符下使用此命令,则需要使用 " 而不是 '

git filter-branch --commit-filter "
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi" HEAD

You can also do:

git filter-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

Note, if you are using this command in the Windows command prompt, then you need to use " instead of ':

git filter-branch --commit-filter "
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi" HEAD
浊酒尽余欢 2024-07-25 04:01:07

当您没有初始化 $HOME/.gitconfig 时就会发生这种情况。 您可以将其修复为:

git config --global user.name "you name"
git config --global user.email [email protected]
git commit --amend --reset-author

使用 Git 版本 1.7.5.4 进行测试。

请注意,这仅修复最后一次提交。

It happens when you do not have a $HOME/.gitconfig initialized. You may fix this as:

git config --global user.name "you name"
git config --global user.email [email protected]
git commit --amend --reset-author

Tested with Git version 1.7.5.4.

Note that this fixes only the last commit.

草莓酥 2024-07-25 04:01:07

如果只有前几个提交的作者不好,您可以使用 exec 命令和 --amend< 在 git rebase -i 内完成所有这些操作/code> commit,如下:

git rebase -i HEAD~6 # as required

它向您提供可编辑的提交列表:

pick abcd Someone else's commit
pick defg my bad commit 1
pick 1234 my bad commit 2

然后在所有包含不良作者的行之后添加 exec ... --author="..." 行:

pick abcd Someone else's commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name <[email protected]>" -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name <[email protected]>" -C HEAD

保存并退出编辑器(运行)。

这个解决方案可能比其他解决方案的输入时间更长,但它是高度可控的 - 我确切地知道它击中了什么提交。

感谢@asmeurer 的灵感。

In the case where just the top few commits have bad authors, you can do this all inside git rebase -i using the exec command and the --amend commit, as follows:

git rebase -i HEAD~6 # as required

which presents you with the editable list of commits:

pick abcd Someone else's commit
pick defg my bad commit 1
pick 1234 my bad commit 2

Then add exec ... --author="..." lines after all lines with bad authors:

pick abcd Someone else's commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name <[email protected]>" -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name <[email protected]>" -C HEAD

save and exit editor (to run).

This solution may be longer to type than some others, but it's highly controllable - I know exactly what commits it hits.

Thanks to @asmeurer for the inspiration.

十年九夏 2024-07-25 04:01:07

对于单个提交:(

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

摘自 asmeurer 的答案)

For a single commit:

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

(extracted from asmeurer's answer)

段念尘 2024-07-25 04:01:07

GitHub 最初有一个很好的解决方案(损坏的链接),它是以下 shell 脚本:

#!/bin/sh

git filter-branch --env-filter '

an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITTER_NAME"
cm="$GIT_COMMITTER_EMAIL"

if [ "$GIT_COMMITTER_EMAIL" = "[email protected]" ]
then
    cn="Your New Committer Name"
    cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ]
then
    an="Your New Author Name"
    am="Your New Author Email"
fi

export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_COMMITTER_EMAIL="$cm"
'

GitHub originally had a nice solution (broken link), which was the following shell script:

#!/bin/sh

git filter-branch --env-filter '

an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITTER_NAME"
cm="$GIT_COMMITTER_EMAIL"

if [ "$GIT_COMMITTER_EMAIL" = "[email protected]" ]
then
    cn="Your New Committer Name"
    cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ]
then
    an="Your New Author Name"
    am="Your New Author Email"
fi

export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_COMMITTER_EMAIL="$cm"
'
空心空情空意 2024-07-25 04:01:07

单个命令可更改最后 N 次提交的作者:

git rebase -i HEAD~N -x "git commit --amend --author 'Author Name <[email protected]>' --no-edit"

NOTES

  • HEAD~N 替换为引用,直到您想要重写提交为止。 这可以是哈希值、HEAD~4、分支名称……
  • --no-edit 标志确保 git commit --amend< /code> 当您使用 git rebase -i 时,不会要求额外的确认
  • ,您可以手动选择要更改作者的提交,

您编辑的文件将如下所示:

pick 897fe9e simplify code a little
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit
pick dc18f70 bugfix
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit

然后您仍然可以修改一些行以查看要更改作者的位置。 这为您在自动化和控制之间提供了一个很好的中间立场:您可以看到将运行的步骤,一旦保存,所有内容都将立即应用。

请注意,如果您已经使用 git config user.name 和 git config user.email 修复了作者信息,您也可以使用此命令:

git rebase -i HEAD~N -x "git commit --amend --reset-author --no-edit"

A single command to change the author for the last N commits:

git rebase -i HEAD~N -x "git commit --amend --author 'Author Name <[email protected]>' --no-edit"

NOTES

  • replace HEAD~N with the reference until where you want to rewrite your commits. This can be a hash, HEAD~4, a branch name, ...
  • the --no-edit flag makes sure the git commit --amend doesn't ask an extra confirmation
  • when you use git rebase -i, you can manually select the commits where to change the author,

the file you edit will look like this:

pick 897fe9e simplify code a little
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit
pick dc18f70 bugfix
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit

You can then still modify some lines to see where you want to change the author. This gives you a nice middle ground between automation and control: you see the steps that will run, and once you save everything will be applied at once.

Note that if you already fixed the author information with git config user.name <your_name> and git config user.email <your_email>, you can also use this command:

git rebase -i HEAD~N -x "git commit --amend --reset-author --no-edit"
我三岁 2024-07-25 04:01:07

正如 docgnome 提到的,重写历史是危险的,会破坏其他人的存储库。

但如果你真的想这样做,并且你处于 bash 环境中(在 Linux 中没问题,在 Windows 上,你可以使用 git bash,它随 git 安装一起提供),请使用 git filter-branch

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL'

为了加快速度,您可以指定要重写的一系列修订:

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL' HEAD~20..HEAD

As docgnome mentioned, rewriting history is dangerous and will break other people's repositories.

But if you really want to do that and you are in a bash environment (no problem in Linux, on Windows, you can use git bash, that is provided with the installation of git), use git filter-branch:

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL'

To speed things up, you can specify a range of revisions you want to rewrite:

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL' HEAD~20..HEAD
梨涡少年 2024-07-25 04:01:07

我应该指出,如果唯一的问题是作者/电子邮件与您平常的不同,那么这不是问题。 正确的解决方法是在目录底部创建一个名为 .mailmap 的文件,其中包含以下行,

Name you want <email you want> Name you don't want <email you don't want>

从那时起,诸如 git Shortlog 这样的命令将认为这两个名称是一样(除非你明确告诉他们不要这样做)。 请参阅 https://schacon.github.io/git/git-shortlog.html 了解更多信息。

这具有这里所有其他解决方案的优点,因为您不必重写历史记录,如果您有上游,这可能会导致问题,并且始终是意外丢失数据的好方法。

当然,如果您以自己的名义提交了某些内容,并且实际上应该是其他人,并且您不介意此时重写历史记录,则出于归因目的,更改提交作者可能是一个好主意(在这种情况下,我将引导您访问我的其他答案此处)。

I should point out that if the only problem is that the author/email is different from your usual, this is not a problem. The correct fix is to create a file called .mailmap at the base of the directory with lines like

Name you want <email you want> Name you don't want <email you don't want>

And from then on, commands like git shortlog will consider those two names to be the same (unless you specifically tell them not to). See https://schacon.github.io/git/git-shortlog.html for more information.

This has the advantage of all the other solutions here in that you don't have to rewrite history, which can cause problems if you have an upstream, and is always a good way to accidentally lose data.

Of course, if you committed something as yourself and it should really be someone else, and you don't mind rewriting history at this point, changing the commit author is probably a good idea for attribution purposes (in which case I direct you to my other answer here).

瑕疵 2024-07-25 04:01:07

您可以使用它作为别名,这样您就可以执行以下操作:

git change-commits GIT_AUTHOR_NAME "old name" "new name"

或者对于最近 10 次提交:

git change-commits GIT_AUTHOR_EMAIL "[email protected]" "[email protected]" HEAD~10..HEAD

添加到 ~/.gitconfig:

[alias]
    change-commits = "!f() { VAR=$1; OLD=$2; NEW=$3; shift 3; git filter-branch --env-filter \"if [[ \\\"

您可以使用它作为别名,这样您就可以执行以下操作:

git change-commits GIT_AUTHOR_NAME "old name" "new name"

或者对于最近 10 次提交:

git change-commits GIT_AUTHOR_EMAIL "[email protected]" "[email protected]" HEAD~10..HEAD

添加到 ~/.gitconfig:

echo $VAR`\\\" = '$OLD' ]]; then export $VAR='$NEW'; fi\" $@; }; f "

来源:https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig

希望它有用。

You can use this as a alias so you can do:

git change-commits GIT_AUTHOR_NAME "old name" "new name"

or for the last 10 commits:

git change-commits GIT_AUTHOR_EMAIL "[email protected]" "[email protected]" HEAD~10..HEAD

Add to ~/.gitconfig:

[alias]
    change-commits = "!f() { VAR=$1; OLD=$2; NEW=$3; shift 3; git filter-branch --env-filter \"if [[ \\\"

You can use this as a alias so you can do:

git change-commits GIT_AUTHOR_NAME "old name" "new name"

or for the last 10 commits:

git change-commits GIT_AUTHOR_EMAIL "[email protected]" "[email protected]" HEAD~10..HEAD

Add to ~/.gitconfig:

echo $VAR`\\\" = '$OLD' ]]; then export $VAR='$NEW'; fi\" $@; }; f "

Source: https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig

Hope it is useful.

帅的被狗咬 2024-07-25 04:01:07

这是@Brian 版本的更详细版本:

要更改作者和提交者,您可以执行以下操作this(在 bash 中可能存在字符串中的换行符):

git filter-branch --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all

您可能会收到以下错误之一:

  1. 临时目录已存在
  2. refs/original 开头的参考文献已存在
    (这意味着之前已在存储库上运行了另一个过滤器分支,然后原始分支引用备份在refs/original)。

如果您想在出现这些错误的情况下强制运行,请添加--force 标志:

git filter-branch --force --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all

可能需要对 -- --all 选项进行一些解释:它使过滤器分支适用于所有对所有参考文献(包括所有分支)的修订。 例如,这意味着标签也会被重写并且在重写的分支上可见。

一个常见的“错误”是使用 HEAD,这意味着仅过滤当前分支上的所有修订。 然后重写的分支中将不存在标签(或其他引用)。

This is a more elaborated version of @Brian's version:

To change the author and committer, you can do this (with linebreaks in the string which is possible in bash):

git filter-branch --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all

You might get one of these errors:

  1. The temporary directory exists already
  2. Refs starting with refs/original exists already
    (this means another filter-branch has been run previously on the repository and the then original branch reference is backed up at refs/original)

If you want to force the run in spite of these errors, add the --force flag:

git filter-branch --force --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all

A little explanation of the -- --all option might be needed: It makes the filter-branch work on all revisions on all refs (which includes all branches). This means, for example, that tags are also rewritten and is visible on the rewritten branches.

A common "mistake" is to use HEAD instead, which means filtering all revisions on just the current branch. And then no tags (or other refs) would exist in the rewritten branch.

三五鸿雁 2024-07-25 04:01:07

当从其他作者那里接管未合并的提交时,有一个简单的方法来处理这个问题。

git commit --amend --reset-author

When taking over an unmerged commit from another author, there is an easy way to handle this.

git commit --amend --reset-author

你怎么这么可爱啊 2024-07-25 04:01:07

git 的 filter-branch 的更安全替代方案是 filter-repo 工具,如 git 文档 此处

git filter-repo --commit-callback '
  old_email = b"[email protected]"
  correct_name = b"Your Correct Name"
  correct_email = b"[email protected]"
  
  if commit.committer_email == old_email :
    commit.committer_name = correct_name
    commit.committer_email = correct_email

  if commit.author_email == old_email : 
    commit.author_name = correct_name
    commit.author_email = correct_email
  '

上面的命令反映了 脚本,但使用filter-repo而不是filter-branch

commit-callback 选项之后的代码主体基本上是用于处理提交的 python 代码。 您可以在这里用 python 编写自己的逻辑。 查看有关 commit 对象及其属性的更多信息 这里

由于 filter-repo 工具未与 git 捆绑在一起,因此您需要单独安装它。

请参阅先决条件安装指南

如果你的 python 环境 >= 3.5,你可以使用 pip安装它。

pip3 install git-filter-repo

注意:强烈建议在新克隆上尝试 filter-repo 工具。 操作完成后,遥控器也会被移除。 点击此处了解有关为何删除遥控器的更多信息。 另请阅读 INTERNALS 部分。

A safer alternative to git's filter-branch is filter-repo tool as suggested by git docs here.

git filter-repo --commit-callback '
  old_email = b"[email protected]"
  correct_name = b"Your Correct Name"
  correct_email = b"[email protected]"
  
  if commit.committer_email == old_email :
    commit.committer_name = correct_name
    commit.committer_email = correct_email

  if commit.author_email == old_email : 
    commit.author_name = correct_name
    commit.author_email = correct_email
  '

The above command mirrors the logic used in this script but uses filter-repo instead of filter-branch.

The code body after commit-callback option is basically python code used for processing commits. You can write your own logic in python here. See more about commit object and its attributes here.

Since filter-repo tool is not bundled with git you need to install it separately.

See Prerequisties and Installation Guide

If you have a python env >= 3.5, you can use pip to install it.

pip3 install git-filter-repo

Note: It is strongly recommended to try filter-repo tool on a fresh clone. Also remotes are removed once the operation is done. Read more on why remotes are removed here. Also read the limitations of this tool under INTERNALS section.

我偏爱纯白色 2024-07-25 04:01:07
  1. 运行git rebase -i

  2. 使用 edit (或 e)


  3. 循环以下两个命令,直到处理完所有提交:

    git commit --amend --reuse-message=HEAD --author="新作者 [电子邮件受保护]>"
    ;
    git rebase --继续

这将保留所有其他提交信息(包括日期)。
--reuse-message=HEAD 选项会阻止消息编辑器启动。

  1. run git rebase -i <sha1 or ref of starting point>

  2. mark all commits that you want to change with edit (or e)

  3. loop the following two commands until you have processed all the commits:

    git commit --amend --reuse-message=HEAD --author="New Author <[email protected]>"
    ;
    git rebase --continue

This will keep all the other commit information (including the dates).
The --reuse-message=HEAD option prevents the message editor from launching.

π浅易 2024-07-25 04:01:07

我使用以下内容重写整个存储库的作者,包括标签和所有分支:

git filter-branch -f --tag-name-filter cat --env-filter "
  export GIT_AUTHOR_NAME='New name';
  export GIT_AUTHOR_EMAIL='New email'
" -- --all

然后,如 filter-branch的MAN页,删除filter-branch备份的所有原始引用(这是破坏性的,请先备份):

git for-each-ref --format="%(refname)" refs/original/ | \
xargs -n 1 git update-ref -d

I use the following to rewrite the author for an entire repository, including tags and all branches:

git filter-branch -f --tag-name-filter cat --env-filter "
  export GIT_AUTHOR_NAME='New name';
  export GIT_AUTHOR_EMAIL='New email'
" -- --all

Then, as described in the MAN page of filter-branch, remove all original refs backed up by filter-branch (this is destructive, backup first):

git for-each-ref --format="%(refname)" refs/original/ | \
xargs -n 1 git update-ref -d
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文