git是否提供了一种方法自动根据.mailmap
文件中指定的替换重写git存储库历史记录(详见git help shortlog
)?< / p>
cd repository.git
somecommand /path/to/.mailmap # <-- ???
答案 0 :(得分:6)
没有简短的git命令。我需要使用git filter-branch --commit-filter <command> [...]
<command>
使用GIT_AUTHOR_NAME
GIT_AUTHOR_EMAIL
更改GIT_COMMITTER_NAME
,GIT_COMMITTER_EMAIL
,git check-mailmap
和-c mailmap.file=/path/to/.mailmap
变量1}}或-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
这当然适用于具有POSIX shell的系统。
请注意,这不会在提交消息中重写任何Signed-off-by:
或类似的行。
答案 1 :(得分:0)
我今天需要这个,但是与另一个--commit-filter
结合使用(以获得根据How do I get a list of old->new rewritten commit SHAs from 'git filter-branch'?的旧到新提交ID的映射文件)。
我最终以@BooK出色的comment作为起点,所以让我们将其转化为正确的答案。
git filter branch
提供了--env-filter
选项,可以在提交之前更改元信息,而--commit-filter
会在提交期间更改它们。承诺。这意味着我们可以将信息修复和实际提交分为两个单独的过滤器脚本
“缺点”是env-filter
需要export
变量,因此它们会一直保留到提交阶段。
@jotik's answer的环境过滤器版本如下:
# 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
此后可选进行清理:
git rm .mailmap
git commit -m "delete mailmap after fixing history, no longer needed."