如何使用挂钩在提交时更改作者电子邮件

时间:2011-02-16 15:02:38

标签: git hook commit

问题说明了一切。

我希望通过使用我自己的别名来提交真实的电子邮件地址来为我的用户提供一些隐私。是否有可以帮助我做到这一点的钩子?

3 个答案:

答案 0 :(得分:8)

您可以让他们更改本地存储库中的user.email属性。

git config user.email email@server.com

答案 1 :(得分:3)

无论发生什么,如果您更改某些内容 - 甚至是用户名和/或电子邮件中的单个字符 - 在某些提交中,您将获得一个新的,不同的提交。 (这是因为提交ID包含提交内容的加密校验和。所以,好吧,如果你可以打破加密,你可以提出两个具有相同ID的不同提交。但是你已经完全打破了git,并且可能也获得了图灵奖或诺贝尔奖。:-))

您在另一个答案的评论中链接到的“工作挂钩”可能是您最好的选择。此问题可归结为一件事:您无法对发布的提交进行任何更改(不会对该发布的使用者造成问题),但您可以对进行任何更改私人提交只要你“知道你在做什么”。在每次提交的基础上使用git commit --amend --author "$user <$email>" -C HEAD,当他们进入您的repo副本时,保证您使用新的,稍微不同的未发布的提交替换未发布的提交。 (我假设你把它放在post-commit钩子里。)

我不确定你对哪一部分不满意,也许是[ -n "$richo_git_rewrite" ] && exit 0?这是检测递归的一种相当聪明的方法。另一种方法是跳过递归检测,而是将提交中的现有用户和电子邮件与所需的用户和电子邮件进行比较。

这是一个执行该操作的脚本(除了我使用env变量SWITCHY = true来进行测试):

#! /bin/sh
# first, pick which git config variables to get
if ${SWITCHY-false}; then
    config=user.work
else
    config=user
fi
# next, find out if they're set
can_rewrite=false
target_author=$(git config --get $config.name) &&
    target_email=$(git config --get $config.email) &&
    can_rewrite=true
# If they ARE set, we can "rewrite" (replace) the commit;
# if not, we can't.  Just because we can, though, does not
# mean we should.  Find out if the current author and email
# differ from the desired ones.
if $can_rewrite; then
    current_author=$(git log --pretty=format:%an HEAD -n 1)
    current_email=$(git log --pretty=format:%ae HEAD -n 1)
    if [ "$current_author" != "$target_author" -o \
          "$current_email" != "$target_email" ]; then
        # may want --allow-empty here, if you're allowing empty commits
        # at all, otherwise empty ones don't get the rewrite done
        git commit --amend --author "$target_author <$target_email>" -C HEAD
    fi
fi

注意:您需要在hooks/post-merge中设置相同的挂钩,以修改与更新的名称和电子邮件的合并。当然你可以稍微简化一下钩子(不需要实际的can_rewrite变量,只需要用&&做两个git config get ops并继续使用另一个&&)。拥有的不仅仅是user vs user.work,也可能是user vs user.ModeA vs user.ModeB等,你可以将它驱逐出你喜欢的任何测试(env变量,是否存在命令,等等。


好的,根据评论,这里是一个预提交钩子。不幸的是它不适用于git merge(预提交钩子运行和抱怨然后合并提交进入)。

#! /bin/sh
fatal()
{
    echo "$@" 1>&2
    exit 1
}
# pick which git config variables to get
if ${SWITCHY-false}; then
    config=user.work
else
    config=user
fi
# tn, te = target author name/email
# an, ae = what git will use for author name/email
tn=$(git config --get $config.name) || exit 0
te=$(git config --get $config.email) || exit 0

an=${GIT_AUTHOR_NAME-$(git config --get user.name)} ||
    fatal "no author name set"
ae=${GIT_AUTHOR_EMAIL-$(git config --get user.email)} ||
    fatal "no author email set"
[ "$an" = "$tn" -a "$ae" = "$te" ] ||
    fatal "git will use author $an <$ae>
but you want them as $tn <$te>
fix your environment variables and try again"

您可以将此预提交挂钩与合并后重写 - 提交挂钩( eww :-))结合使用。我没有尝试冲突的提交,但可能是预提交钩子会捕获需要你自己提交的冲突合并。

(还值得注意的是,这个预提交钩子不会查看工作树或索引,因此它没有通常的“检查工作树但是提交索引”缺陷。)

答案 2 :(得分:1)

http://progit.org/book/ch6-4.html解释了如何重写历史记录。靠近底部,有这个命令

git filter-branch --commit-filter '
    if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
    then
            GIT_AUTHOR_NAME="Scott Chacon";
            GIT_AUTHOR_EMAIL="schacon@example.com";
            git commit-tree "$@";
    else
            git commit-tree "$@";
    fi' HEAD

将所有提交从schacon@localhost更改为schacon@example.com

警告:这会从最早的电子邮件更改开始更改所有提交ID。