使用Git SVN进行作者回溯更正?

52

我有一个代码库,已经从Subversion中克隆了下来。我在Git版本中对这个代码库进行了一些修改,不想再次克隆而失去这个结构。

但是,在我最初克隆代码库时,我没有正确地指定svn.authors属性(或类似的选项)。

现在这个代码库完全转为了Git形式,有没有办法仍然指定SVN作者映射呢?

最好的情况是,我想将所有旧的提交作者更正为表示Git作者而不是原始的SVN用户名。

3个回答

58

首先看看需要清理的内容:

git shortlog -s

对于这些名称中的每一个,创建一个脚本条目,看起来像这样(假设您希望所有作者和提交者都相同):

#!/bin/sh

git filter-branch --env-filter '

n=$GIT_AUTHOR_NAME
m=$GIT_AUTHOR_EMAIL

case ${GIT_AUTHOR_NAME} in
        user1) n="User One" ; m="user1@example.com" ;;
        "User Two") n="User Two" ; m="user2@example.com" ;;
esac

export GIT_AUTHOR_NAME="$n"
export GIT_AUTHOR_EMAIL="$m"
export GIT_COMMITTER_NAME="$n"
export GIT_COMMITTER_EMAIL="$m"
'

这基本上是我最近进行的一个大规模重写所使用的脚本,非常符合你描述的情况(除了我有很多作者)。

编辑 使用π指出我的脚本中存在引用问题。谢谢!


1
应该导出GIT_AUTHOR_NAME="$n",否则只有作者的名字会出现在索引中! - pi.
4
这个脚本运行良好。但是,使用后调用“git svn rebase”会导致错误信息:“无法从工作树历史记录中确定上游 SVN 信息”。 - olenz
你怎么将编辑/更正后的作者推回到远程? - user1027169
我因@olenz的评论而感到害怕尝试这个。在git svn rebase之后,还有其他人成功吗? - Spencer Williams

11

git filter-branch可以用来重写大量的历史记录。

在这种情况下,你可能会执行类似下面的操作(完全未经测试):

git filter-branch --env-filter '
    GIT_AUTHOR_NAME=`echo "${GIT_AUTHOR_NAME}" | sed -e "s/svnname1/Right Name/; s/svnname2/Correct Name/"`
    GIT_COMMITTER_NAME=`echo "${GIT_COMMITTER_NAME}" | sed -e "s/svnname1/Right Name/; s/svnname2/Correct Name/"`
    GIT_AUTHOR_EMAIL=`echo "${GIT_AUTHOR_EMAIL}" | sed -e "s/svnname1/m@i.l/; s/svnname2/correct.name@e.mail/"`
    GIT_COMMITTER_EMAIL=`echo "${GIT_COMMITTER_EMAIL}" | sed -e "s/svnname1/m@i.l/; s/svnname2/correct.name@e.mail/"`
'

像往常一样,以下规则适用:为了重写历史记录,你需要一个阴谋


点赞支持:“一如既往的,当你需要重写历史时,你需要一个阴谋。”说得非常好。(虽然链接已经无法加载) - Matt D
如果您的svn名称是另一个svn名称的子集,那么使用给定的正则表达式可能会遇到问题...这就是为什么上帝赐予我们“^”和“$”。 - Dan
修改后,你不需要将GIT_变量重新导出到环境变量中吗? - FlipMcF

3
你可能需要查看 git-filter-branch,特别是 --commit-filter 选项。该命令是一款强大的链锯工具,可以重写整个存储库的历史记录,更改您想要更改的任何内容。
请注意,当您执行此操作时,应从更新后的存储库中拉取新的克隆,因为每个提交的 SHA1 哈希值可能已更改。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接