![](/img/trans.png)
[英]Convenience script for renaming commit authors with git-filter-branch
[英]git edit authors name in commit range, script
我想创建一个git脚本,在指定的提交范围(abcd..dcba)中用作者“B”替换作者“A”。 我怎样才能做到这一点? 这是我到目前为止:
#!/bin/sh
#
# git-myCommand
#
#
git filter-branch --commit-filter '
if [ git rev-list --boundary 02e60c8..dc4c65f ]; then
if [ "$GIT_AUTHOR_NAME" = "A" ];then
GIT_AUTHOR_NAME="B";
fi;
fi;
git commit-tree "$@"'
问题是git说
Rewrite $SHA1-Number git commit-tree: line 48: [: too many arguments
git rev-list --boundary命令在if语句中是否合法? 如果我删除if [git rev-list ...]语句,它将起作用。
理想的是,如果我可以添加输入变量。 所以命令看起来像
git myCommand $AuthorExpression $AuthorReplace $CommitA..$CommitB
编辑:有人认为这个问题已经被提出。 对于那些人,请再次阅读上面的问题,并将其与以前的问题进行比较。 AFAIK这个问题(测试提交是否在提交A和提交B之间)尚未提出。 如果我错了,很抱歉浪费您的时间。 感谢那些试图回答这个问题的人!
如果要为脚本使用参数,只需执行
#!/bin/sh
#
# git-myCommand
#
#
AuthorExpression=$1
AuthorReplace=$2
CommitA=$3
CommitB=$4
git filter-branch --commit-filter "
if git rev-list --boundary '$CommitA'..'$CommitB'; then
if [ \"\$GIT_AUTHOR_NAME\" = '$AuthorExpression' ];then
GIT_AUTHOR_NAME='$AuthorReplace';
fi;
fi;
git commit-tree \"\$@\""
但请注意,您可能还想编辑GIT_COMMITTER_NAME
, GIT_COMMITTER_EMAIL
和GIT_AUTHOR_EMAIL
。 看到这个答案 。
您可以将shell脚本中的变量替换为传递给git filter-branch
的脚本。 你只需要小心得到正确的引用。 由于你是单引号,你不能直接替换变量,但你可以结束单引号并为替换打开双引号字符串,然后关闭双引号字符串并再次打开单引号字符串; 字符串将在扩展后追加。 在单引号字符串中,如果它包含空格或其他字符,则应包含将从变量中包围扩展字符串的引号。
与其尝试在过滤器脚本中限制修订版,不如将修订版传递到git filter-branch
这样它只会对那些提交做任何事情。 git filter-branch
在命令末尾使用与git rev-list
相同的参数(尽管你必须用--
分隔它们--
以便它将--boundary
解释为rev-list
参数)。
#!/bin/sh
#
# git-myCommand
#
#
AuthorExpression=$1
AuthorReplace=$2
CommitA=$3
CommitB=$4
git filter-branch --commit-filter '
if [ "$GIT_AUTHOR_NAME" = "'"$AuthorExpression"'" ];then
GIT_AUTHOR_NAME="'"$AuthorReplace"'";
fi;
git commit-tree "$@"' -- --boundary "$CommitA".."$CommitB"
编辑 :第一次回答时,用git rev-list
错过了问题。
其他人已经解决了参数引用。 剩下的最大问题是测试:
if [ git-rev-list ... ]
提交过滤器只是一个shell脚本片段,因此这告诉shell运行命令:
[ git-rev-list ... ]
并测试该命令的退出状态是零(true)还是不(false)。 [
command,也称为test
,没有任何git
内置函数。
您似乎想要的是判断被过滤的原始提交是否是A
.. B
范围内的成员。 让我们首先从过滤器分支文档中注意到这一点:
过滤器的应用顺序如下。 始终使用eval命令在shell上下文中评估<command>参数(出于技术原因,提交过滤器有明显的例外)。 在此之前,
$GIT_COMMIT
环境变量将被设置为包含要重写的提交的id。
因此,你可以这样写:
A=$(git rev-parse $3) || exit 1
B=$(git rev-parse $4) || exit 1
git filter-branch --commit-filter "
if git merge-base --is-ancestor \$GIT_COMMIT $B &&
! git merge-base --is-ancestor \$GIT_COMMIT $A^; then
第一个merge-base
测试$GIT_COMMIT
是否是更高转速的祖先(等于$B
或者在拓扑之前“来”)。 第二个不包括在较低转速( $A
)之前的提交,使用帽子后缀来避免排除$A
本身。
这是Brian Campbell使用此技术的脚本的变体(嗯,我也更改了引号扩展技术)。
#! /bin/sh
case $# in
4) ;;
*) echo "usage: $0 oldauthor newauthor firstrev lastrev" >&2; exit 1;;
esac
AuthorExpression=$1
AuthorReplace=$2
A=$(git rev-parse --verify $3^{commit}) || exit 1
B=$(git rev-parse --verify $4^{commit}) || exit 1
git filter-branch --commit-filter "
if git merge-base --is-ancestor \$GIT_COMMIT $B &&
! git merge-base --is-ancestor \$GIT_COMMIT $A^; then
if [ \"\$GIT_AUTHOR_NAME\" = '$AuthorExpression' ]; then
GIT_AUTHOR_NAME='$AuthorReplace'
fi
fi
git commit-tree \"\$@\""
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.