Git fork

filter-branch: stop depending on Perl

While git-filter-branch(1) is written as a shell script, the
`--state-branch` feature depends on Perl to save and extract the object
ID mappings. This can lead to subtle breakage though:

- We execute `perl` directly without respecting the `PERL_PATH`
configured by the distribution. As such, it may happen that we use
the wrong version of Perl.

- We install the script unchanged even if Perl isn't available at all
on the system, so using `--state-branch` would lead to failure
altogether in that case.

Fix this by dropping Perl and instead implementing the feature with
shell scripting exclusively.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Patrick Steinhardt and committed by
Junio C Hamano
f6d85509 55f7879f

+19 -18
+19 -18
git-filter-branch.sh
··· 295 295 if test -n "$state_commit" 296 296 then 297 297 echo "Populating map from $state_branch ($state_commit)" 1>&2 298 - perl -e'open(MAP, "-|", "git show $ARGV[0]:filter.map") or die; 299 - while (<MAP>) { 300 - m/(.*):(.*)/ or die; 301 - open F, ">../map/$1" or die; 302 - print F "$2" or die; 303 - close(F) or die; 304 - } 305 - close(MAP) or die;' "$state_commit" \ 306 - || die "Unable to load state from $state_branch:filter.map" 298 + 299 + git show "$state_commit:filter.map" >"$tempdir"/filter-map || 300 + die "Unable to load state from $state_branch:filter.map" 301 + while read line 302 + do 303 + case "$line" in 304 + *:*) 305 + echo "${line%:*}" >../map/"${line#*:}";; 306 + *) 307 + die "Unable to load state from $state_branch:filter.map";; 308 + esac 309 + done <"$tempdir"/filter-map 307 310 else 308 311 echo "Branch $state_branch does not exist. Will create" 1>&2 309 312 fi ··· 633 636 then 634 637 echo "Saving rewrite state to $state_branch" 1>&2 635 638 state_blob=$( 636 - perl -e'opendir D, "../map" or die; 637 - open H, "|-", "git hash-object -w --stdin" or die; 638 - foreach (sort readdir(D)) { 639 - next if m/^\.\.?$/; 640 - open F, "<../map/$_" or die; 641 - chomp($f = <F>); 642 - print H "$_:$f\n" or die; 643 - } 644 - close(H) or die;' || die "Unable to save state") 639 + for file in ../map/* 640 + do 641 + from_commit=$(basename "$file") 642 + to_commit=$(cat "$file") 643 + echo "$from_commit:$to_commit" 644 + done | git hash-object -w --stdin || die "Unable to save state" 645 + ) 645 646 state_tree=$(printf '100644 blob %s\tfilter.map\n' "$state_blob" | git mktree) 646 647 if test -n "$state_commit" 647 648 then