git filter-branch -f --index-filter \
      'git ls-files -s | sed -i "s-\t\"*-&dirname/-" |
                GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
                git update-index --index-info &&
       mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD

如果dirname是硬编码的,上述代码可以正常工作。但我需要从命令行参数中传递dirname给脚本。我正在像下面这样尝试,但没有成功。

 'set subdir=$folder;git ls-files -s | sed -i "s-\t\"*-&$subdir/-" |

sed说输入文件丢失。我不能直接把输入文件传给 sed。我看到的错误如下。

Rewrite 9c86de42b7f3228e3d45a278c8caf7e24c8e55cf (1/2) (0 seconds passed, remaining 0 predicted)
sed: no input files
    
linux
git
sed
git-filter-branch
intechops6
intechops6
发布于 2019-05-29
2 个回答
torek
torek
发布于 2019-05-29
已采纳
0 人赞同

你在这里有两个选择。 你可以评估$subdir来建立一个固定的sed命令,然后将其设置为你的过滤器;或者你可以评估git filter-branch将调用的shell片段中的一个变量。

为了理解后者,请意识到你的--index-filter字符串变成了一个普通的shell变量:

--index-filter)
    filter_index="$OPTARG"

which is then passed to eval:

eval "$filter_index" < /dev/null ||
    die "index filter failed: $filter_index"

替换代码5】意味着$filter_index中的表达式,由你的--index-filter参数设置,可以访问所有的shell变量和函数。过滤分支脚本. 不幸的是,它没有一个私营变量持有你想要的表达式--但你可以访问其environment变量,这意味着你可以把数值放到环境变量中。 换句话说,你可以把subdir=<whatever>作为一个environment到你原来的表达。

在任何情况下,由于bk2204 回答你需要删除-i选项。 除此之外,有些版本的sed不接受\t作为制表符(估计你的版本接受,只是要注意这个)。

要在前面扩展变量,只需这样做。 比如说

... --index-filter \
    'git ls-files -s | sed "s-\t\"*-&'$folder'/-" | ...

(我自己把这里的-i去掉了)。 请注意,这里是如何退出单引号,展开$folder,然后重新进入单引号的。 如果$folder可能包含空格,请确保在这里扩展它时使用双引号。

... --index-filter \
    'git ls-files -s | sed "s-\t\"*-&'"$folder"'/-" | ...