首页 > 解决方案 > 文件结尾意外(期望“)”),将命令传递给 git filter-branch

问题描述

您好,我已经编写了一个脚本来大写提交者的姓名并更改他们的电子邮件

git filter-branch --commit-filter \
'export GIT_AUTHOR_NAME=$( sed -r 's/\<./\U&/g' <<< $GIT_AUTHOR_NAME) \
export GIT_AUTHOR_EMAIL=$(sed 's/@[^,]*/@foo.net/' <<< $GIT_COMMITTER_EMAIL) \
export GIT_COMMITTER_NAME=$( sed -r 's/\<./\U&/g' <<< $GIT_AUTHOR_NAME) \
export GIT_COMMITTER_EMAIL=$(sed 's/@[^,]*/@foo.net/' <<< $GIT_COMMITTER_EMAIL) \
git commit-tree "$@"'

sed 命令在自己运行时可以工作,但作为一个整体它会抛出

Rewrite e3acbe28d660ffc6ef8e9a5a79ba9bd24c3b48bd (1/22)git commit-tree:48:
git commit-tree: Syntax error: end of file unexpected (expecting ")")
could not write rewritten commit

标签: bashgitgit-bash

解决方案


命令中的单引号export被读取为句法,而不是文字。

解决此问题的一种方法是将您的命令字符串设置在引用的 heredoc 中,并在以后扩展它:

cmd=$(cat <<'EOF'
GIT_AUTHOR_NAME=$(sed -r 's/\<./\U&/g' <<<"$GIT_AUTHOR_NAME")
GIT_AUTHOR_EMAIL=$(sed 's/@[^,]*/@foo.net/' <<<"$GIT_COMMITTER_EMAIL")
GIT_COMMITTER_NAME=$(sed -r 's/\<./\U&/g' <<<"$GIT_AUTHOR_NAME")
GIT_COMMITTER_EMAIL=$(sed 's/@[^,]*/@foo.net/' <<<"$GIT_COMMITTER_EMAIL")
git commit-tree "$@"
EOF
)

git filter-branch --commit-filter "$cmd"

<<'EOF'用于防止在分配之前处理heredoc内部的扩展。

请注意,exports 消失了——shell 会自动将任何更新导出到环境中已经存在的变量中,并且在启动 shell 之前将其导出到环境正是git filter-branch确保值首先可用的方式。


推荐阅读