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

[PATCH 1/3 v2] Add --blob-filter option to filter-branch.

From
Avery Pennarun <apenwarr@gmail.com>
Date
Apr 23, 2008, 20:18 UTC
Message-ID
<1208981890-758-1-git-send-email-apenwarr@gmail.com>
In-Reply-To
<alpine.DEB.1.00.0804232113480.20267@eeepc-johanness>
From: Jeff King <peff@peff.net>
This patch allows
  git filter-branch --blob-filter 'tr a-z A-Z'

However, it's _still_ horribly slow. Shell script is nice and flexible, but running a tight loop like this is just painful. I suspect filter-branch in something like perl would be a lot faster and just as flexible.

It is still much better performance than a tree filter, though:
  $ cd git && time git filter-branch --tree-filter '
      find . -type f | while read f; do
        tr a-z A-Z <"$f" >tmp
        mv tmp "$f"
      done
    ' HEAD~10..HEAD
  real    4m38.626s
  user    1m32.726s
  sys     2m51.163s
  $ cd git && git filter-branch --blob-filter 'tr a-z A-Z' HEAD~10..HEAD
  real    1m40.809s
  user    0m36.822s
  sys     1m14.273s
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 git-filter-branch.sh |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index ea59015..980c431 100755
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -54,6 +54,23 @@ EOF
 
 eval "$functions"
 
+munge_blobs() {
+	while read mode sha1 stage path
+	do
+		if ! test -r "$workdir/../blob-cache/$sha1"
+		then
+			new=`git cat-file blob $sha1 |
+			     eval "$filter_blob" |
+			     git hash-object -w --stdin`
+			printf $new >$workdir/../blob-cache/$sha1
+		fi
+		printf "%s %s\t%s\n" \
+			"$mode" \
+			$(cat "$workdir/../blob-cache/$sha1") \
+			"$path"
+	done
+}
+
 # When piped a commit, output a script to set the ident of either
 # "author" or "committer
 
@@ -105,6 +122,7 @@ tempdir=.git-rewrite
 filter_env=
 filter_tree=
 filter_index=
+filter_blob=
 filter_parent=
 filter_msg=cat
 filter_commit='git commit-tree "$@"'
@@ -150,6 +168,9 @@ do
 	--index-filter)
 		filter_index="$OPTARG"
 		;;
+	--blob-filter)
+		filter_blob="$OPTARG"
+		;;
 	--parent-filter)
 		filter_parent="$OPTARG"
 		;;
@@ -227,6 +248,9 @@ ret=0
 # map old->new commit ids for rewriting parents
 mkdir ../map || die "Could not create map/ directory"
 
+# cache rewritten blobs for blob filter
+mkdir ../blob-cache || die "Could not create blob-cache/ directory"
+
 case "$filter_subdir" in
 "")
 	git rev-list --reverse --topo-order --default HEAD \
@@ -295,6 +319,12 @@ while read commit parents; do
 	eval "$filter_index" < /dev/null ||
 		die "index filter failed: $filter_index"
 
+	if test -n "$filter_blob"; then
+		git ls-files --stage |
+		munge_blobs |
+		git update-index --index-info
+	fi
+
 	parentstr=
 	for parent in $parents; do
 		for reparent in $(map "$parent"); do
-- 
1.5.4.3
Previous: Johannes SchindelinNext: Johannes Schindelin
Message 7 of 11 in “Add --blob-filter option to filter-branch.”
  1. 1/3 Add --blob-filter option to filter-branch.Avery Pennarun, Apr 23, 2008
  2. 2/3 Make filter-branch --glob-filter much faster by not calling 'cat'Avery Pennarun, Apr 23, 2008
  3. 3/3 Update documentation to describe git filter-branch --blob-filter.Avery Pennarun, Apr 23, 2008
  4. Johannes SchindelinApr 23, 2008
  5. Avery PennarunApr 23, 2008
  6. Johannes SchindelinApr 23, 2008
  7. 1/3 Add --blob-filter option to filter-branch.Avery Pennarun, Apr 23, 2008
  8. Johannes SchindelinApr 23, 2008
  9. Jeff KingApr 23, 2008
  10. Avery PennarunApr 23, 2008
  11. Jeff KingApr 24, 2008

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.