根据.mailmap文件重写git历史记录

根据.mailmap文件重写git历史记录,git,git-filter-branch,Git,Git Filter Branch,git是否提供了一种方法,可以根据.mailmap文件中指定的替换自动重写git存储库历史记录(有关详细信息,请参见git help shortlog) cd repository.git somecommand/path/to/.mailmap#没有用于此操作的短git命令。需要使用git filter branch--commit filter[…]其中更改git\u作者姓名,git\u作者电子邮件,GIT\u COMMITTER\u NAME和GIT\u COMMITTER\u EMAIL

git是否提供了一种方法,可以根据
.mailmap
文件中指定的替换自动重写git存储库历史记录(有关详细信息,请参见
git help shortlog

cd repository.git

somecommand/path/to/.mailmap#没有用于此操作的短git命令。需要使用
git filter branch--commit filter[…]
其中
更改
git\u作者姓名
git\u作者电子邮件
GIT\u COMMITTER\u NAME
GIT\u COMMITTER\u EMAIL
变量使用
GIT check mailmap
-c mailmap.file=/path/to/.mailmap
-c mailmap.blob=SOMEREV:path/to/.mailmap
,例如要使用主分支的
.mailmap
文件,可以使用

git filter-branch --commit-filter '
    R=`echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" | git -c mailmap.blob=master:.mailmap check-mailmap --stdin`
    GIT_AUTHOR_NAME="${R% <*@*>}"
    R="${R##* <}"
    GIT_AUTHOR_EMAIL="${R%>}"
    R=`echo "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" | git -c mailmap.blob=master:.mailmap check-mailmap --stdin`
    GIT_COMMITTER_NAME="${R% <*@*>}"
    R="${R##* <}"
    GIT_COMMITTER_EMAIL="${R%>}"
    git commit-tree "$@"
' HEAD
git过滤器分支--提交过滤器'
R=`echo“$GIT_AUTHOR_NAME”| GIT-c mailmap.blob=master:.mailmap检查mailmap--stdin`
GIT_AUTHOR_NAME=“${R%}”
R=“${R###*}”
R=`echo“$GIT_COMMITTER_NAME”| GIT-c mailmap.blob=master:.mailmap check mailmap--stdin`
GIT_提交人_NAME=“${R%}”
R=“${R###*}”
git提交树“$@”
”“头
这当然适用于带有POSIX外壳的系统


请注意,这不会重写提交消息中由以下人员签署的任何
或类似行。

没有用于此操作的短git命令。需要使用
git filter branch--commit filter[…]
其中
更改
git\u作者姓名
git\u作者电子邮件
GIT\u COMMITTER\u NAME
GIT\u COMMITTER\u EMAIL
变量使用
GIT check mailmap
-c mailmap.file=/path/to/.mailmap
-c mailmap.blob=SOMEREV:path/to/.mailmap
,例如要使用主分支的
.mailmap
文件,可以使用

git filter-branch --commit-filter '
    R=`echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" | git -c mailmap.blob=master:.mailmap check-mailmap --stdin`
    GIT_AUTHOR_NAME="${R% <*@*>}"
    R="${R##* <}"
    GIT_AUTHOR_EMAIL="${R%>}"
    R=`echo "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" | git -c mailmap.blob=master:.mailmap check-mailmap --stdin`
    GIT_COMMITTER_NAME="${R% <*@*>}"
    R="${R##* <}"
    GIT_COMMITTER_EMAIL="${R%>}"
    git commit-tree "$@"
' HEAD
git过滤器分支--提交过滤器'
R=`echo“$GIT_AUTHOR_NAME”| GIT-c mailmap.blob=master:.mailmap检查mailmap--stdin`
GIT_AUTHOR_NAME=“${R%}”
R=“${R###*}”
R=`echo“$GIT_COMMITTER_NAME”| GIT-c mailmap.blob=master:.mailmap check mailmap--stdin`
GIT_提交人_NAME=“${R%}”
R=“${R###*}”
git提交树“$@”
”“头
这当然适用于带有POSIX外壳的系统


请注意,这不会重写提交消息中由“
或类似行”签署的任何

我今天需要它,但需要与另一个
--提交筛选器组合使用(以根据获取旧提交ID到新提交ID的映射文件)

我最终以@BooK的优秀作为出发点,让我们把它变成一个正确的答案


git-filter-branch
提供了
--env-filter
选项来在提交之前更改元信息,而
--commit-filter
会在提交期间影响元信息。这意味着我们可以将信息修复和实际提交分离为两个单独的过滤脚本

“缺点”是
env filter
需要
export
变量,因此它们会一直保存到提交阶段

的环境过滤器版本如下所示:

# make sure we have a copy of the mailmap that won't be affected by other parts of the filter-branch
cp .mailmap /tmp/mailmap

git filter-branch \
    --your-other-filters-here
    --env-filter '
    # fix author
    # apply mailmap to "current" person tagline, store in temp $R
    R=$(echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" | git -c mailmap.file=/tmp/mailmap check-mailmap --stdin)
    # extract mailmapped, pieces from $R using shell variable replacements
    export GIT_AUTHOR_NAME="${R% <*@*>}"
    R="${R##* <}"
    export GIT_AUTHOR_EMAIL="${R%>}"

    # repeat for committer
    R=$(echo "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" | git -c mailmap.file=/tmp/mailmap check-mailmap --stdin)
    export GIT_COMMITTER_NAME="${R% <*@*>}"
    R="${R##* <}"
    export GIT_COMMITTER_EMAIL="${R%>}"
'  -- --all

我今天需要它,但它与另一个
--commit filter
结合使用(根据获得新旧提交ID的映射文件)

我最终以@BooK的优秀作为出发点,让我们把它变成一个正确的答案


git-filter-branch
提供了
--env-filter
选项来在提交之前更改元信息,而
--commit-filter
会在提交期间影响元信息。这意味着我们可以将信息修复和实际提交分离为两个单独的过滤脚本

“缺点”是
env filter
需要
export
变量,因此它们会一直保存到提交阶段

的环境过滤器版本如下所示:

# make sure we have a copy of the mailmap that won't be affected by other parts of the filter-branch
cp .mailmap /tmp/mailmap

git filter-branch \
    --your-other-filters-here
    --env-filter '
    # fix author
    # apply mailmap to "current" person tagline, store in temp $R
    R=$(echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" | git -c mailmap.file=/tmp/mailmap check-mailmap --stdin)
    # extract mailmapped, pieces from $R using shell variable replacements
    export GIT_AUTHOR_NAME="${R% <*@*>}"
    R="${R##* <}"
    export GIT_AUTHOR_EMAIL="${R%>}"

    # repeat for committer
    R=$(echo "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" | git -c mailmap.file=/tmp/mailmap check-mailmap --stdin)
    export GIT_COMMITTER_NAME="${R% <*@*>}"
    R="${R##* <}"
    export GIT_COMMITTER_EMAIL="${R%>}"
'  -- --all

通过编写您在此处引用为
somecommand
的脚本。我们猜不出你期望它做什么。。。我们中的一些人可能甚至不熟悉
.mailmap
文件是什么,或者它可能包含什么…git
的格式。mailmap
文件记录在
man 1 git shortlog
中。重新表述我的问题。通过编写您在此处引用为
somecommand
的脚本。我们猜不出你期望它做什么。。。我们中的一些人可能甚至不熟悉
.mailmap
文件是什么,或者它可能包含什么…git
的格式。mailmap
文件记录在
man 1 git shortlog
中。重新表述我的问题。我很难做到这一点,因为我没有意识到
.mailmap
文件不在我的历史记录中。将其添加为最后一次提交也不起作用。在git config的文档中,我还找到了
mailmap.file
,我可以将其指向存储库之外的文件。我使用了
--env-filter
,而不是
--commit-filter
,并将
git-commit-tree
命令替换为环境变量所需的
export
命令。请注意,如果您有带注释的标记,
--tag name-filter
的文档说明:“也不支持更改作者或时间戳(或标记消息)。“我认为这意味着你需要自己用
git tag
命令重写这些标记。我很难做到这一点,因为我没有意识到
.mailmap
文件不在我的历史记录中。将其添加为最后一次提交也不起作用。在git config的文档中,我还找到了
mailmap.file
,我可以将其指向存储库之外的文件。我没有使用
--commit filter
,而是使用了
--env filter
,并将
git commit tree
命令替换为环境变量所需的
export
命令。请注意,如果您有带注释的标记,文档