git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 1/4] filter-branch: stop depending on Perl

From
Patrick Steinhardt <ps@pks.im>
Date
Apr 16, 2025, 12:16 UTC
Message-ID
<20250416-b4-pks-drop-perl-v2-1-bdd0492e9498@pks.im>
In-Reply-To
<20250416-b4-pks-drop-perl-v2-0-bdd0492e9498@pks.im>

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>
---
 git-filter-branch.sh | 37 +++++++++++++++++++------------------
 1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index 3a51d4507c7..24fa317aaaa 100755
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -295,15 +295,18 @@ then
 	if test -n "$state_commit"
 	then
 		echo "Populating map from $state_branch ($state_commit)" 1>&2
-		perl -e'open(MAP, "-|", "git show $ARGV[0]:filter.map") or die;
-			while (<MAP>) {
-				m/(.*):(.*)/ or die;
-				open F, ">../map/$1" or die;
-				print F "$2" or die;
-				close(F) or die;
-			}
-			close(MAP) or die;' "$state_commit" \
-				|| die "Unable to load state from $state_branch:filter.map"
+
+		git show "$state_commit:filter.map" >"$tempdir"/filter-map ||
+			die "Unable to load state from $state_branch:filter.map"
+		while read line
+		do
+			case "$line" in
+			*:*)
+				echo "${line%:*}" >../map/"${line#*:}";;
+			*)
+				die "Unable to load state from $state_branch:filter.map";;
+			esac
+		done <"$tempdir"/filter-map
 	else
 		echo "Branch $state_branch does not exist. Will create" 1>&2
 	fi
@@ -633,15 +636,13 @@ if test -n "$state_branch"
 then
 	echo "Saving rewrite state to $state_branch" 1>&2
 	state_blob=$(
-		perl -e'opendir D, "../map" or die;
-			open H, "|-", "git hash-object -w --stdin" or die;
-			foreach (sort readdir(D)) {
-				next if m/^\.\.?$/;
-				open F, "<../map/$_" or die;
-				chomp($f = <F>);
-				print H "$_:$f\n" or die;
-			}
-			close(H) or die;' || die "Unable to save state")
+		for file in ../map/*
+		do
+			from_commit=$(basename "$file")
+			to_commit=$(cat "$file")
+			echo "$from_commit:$to_commit"
+		done | git hash-object -w --stdin || die "Unable to save state"
+	)
 	state_tree=$(printf '100644 blob %s\tfilter.map\n' "$state_blob" | git mktree)
 	if test -n "$state_commit"
 	then
-- 
2.49.0.805.g082f7c87e0.dirty
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 11 of 14 in “Drop Perl dependency in a couple of subsystems”
  1. 0/4 Drop Perl dependency in a couple of subsystemsPatrick Steinhardt, Apr 15, 2025
  2. 1/4 filter-branch: stop depending on PerlPatrick Steinhardt, Apr 15, 2025
  3. Junio C HamanoApr 15, 2025
  4. 2/4 request-pull: stop depending on PerlPatrick Steinhardt, Apr 15, 2025
  5. Junio C HamanoApr 15, 2025
  6. Patrick SteinhardtApr 16, 2025
  7. 3/4 Documentation: stop depending on Perl to massage user manualPatrick Steinhardt, Apr 15, 2025
  8. 4/4 Documentation: stop depending on Perl to generate command listPatrick Steinhardt, Apr 15, 2025
  9. Junio C HamanoApr 15, 2025
  10. 0/4 Drop Perl dependency in a couple of subsystemsPatrick Steinhardt, Apr 16, 2025
  11. 1/4 filter-branch: stop depending on PerlPatrick Steinhardt, Apr 16, 2025
  12. 2/4 request-pull: stop depending on PerlPatrick Steinhardt, Apr 16, 2025
  13. 4/4 Documentation: stop depending on Perl to generate command listPatrick Steinhardt, Apr 16, 2025
  14. 3/4 Documentation: stop depending on Perl to massage user manualPatrick Steinhardt, Apr 16, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.