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

[RFC PATCH 3/3] filter-branch: support --submodule-filter

From
Thomas Rast <trast@student.ethz.ch>
Date
Dec 31, 2010, 15:29 UTC
Message-ID
<44e6104ba28c80a6befe0f39fa4e2d6eeec56aa9.1293809100.git.trast@student.ethz.ch>
In-Reply-To
<cover.1293809100.git.trast@student.ethz.ch>

This new filter gets each submodule's current sha1 and path on stdin, separated by a tab. It can then emit a new submodule sha1 and/or path, and filter-branch will:

* if the path differs, remove the submodule at the old path;
* add/replace the new sha1 at the new path.
Additionally, returning an empty new sha1 deletes the submodule.

You can tie this together with the last two commits to filter the super-project after a subproject filtering as follows:

  ( cd sub1 && git filter-branch --dump-map map <filters|args> )
  ( cd sub2 && git filter-branch --dump-map map <filters|args> )
  cat sub1/map sub2/map > map
  git filter-branch --load-map map \
  	--submodule-filter "map $(cut -f1)" \
	<args>

Other use-cases should also be covered since we also pass through the path.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-filter-branch.sh |   24 ++++++++++++++++++++++++
 1 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index 9feeb26..4a321c4 100755
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -122,6 +122,7 @@ filter_msg=cat
 filter_commit=
 filter_tag_name=
 filter_subdir=
+filter_submodule=
 orig_namespace=refs/original/
 force=
 prune_empty=
@@ -193,6 +194,9 @@ do
 		filter_subdir="$OPTARG"
 		remap_to_ancestor=t
 		;;
+	--submodule-filter)
+		filter_submodule="$OPTARG"
+		;;
 	--original)
 		orig_namespace=$(expr "$OPTARG/" : '\(.*[^/]\)/*$')/
 		;;
@@ -379,6 +383,26 @@ while read commit parents; do
 	eval "$filter_index" < /dev/null ||
 		die "index filter failed: $filter_index"
 
+	if [ "$filter_submodule" ]; then
+		git ls-files -s |
+		grep '^160000' |
+		while read mode sha1 stage path; do
+			printf "$sha1\t$path\n" |
+			{ eval "$filter_submodule" ||
+				die "submodule filter failed: $filter_submodule"; } |
+			read newsha1 newpath
+			if [ -z "$newsha1" ] || [ "$path" != "$newpath" ]; then
+				git update-index --remove "$path" ||
+					die "failed to remove submodule $path"
+			fi
+			if [ -n "$newsha1" ] && [ "$sha1" != "$newsha1" ]; then
+				git update-index --add --replace --cacheinfo \
+					160000 "$newsha1" "$newpath" ||
+					die "failed to add submodule $newpath"
+			fi
+		done
+	fi
+
 	parentstr=
 	for parent in $parents; do
 		for reparent in $(map "$parent"); do
-- 
1.7.4.rc0.240.g44e61
Previous: Johannes SixtNext: Johannes Sixt
Message 6 of 11 in “Submodule filtering for filter-branch”
  1. 0/3 Submodule filtering for filter-branchThomas Rast, Dec 31, 2010
  2. 1/3 filter-branch: optionally dump all mappings at the endThomas Rast, Dec 31, 2010
  3. Johannes SixtDec 31, 2010
  4. 2/3 filter-branch: optionally load existing mappings prior to filteringThomas Rast, Dec 31, 2010
  5. Johannes SixtDec 31, 2010
  6. 3/3 filter-branch: support --submodule-filterThomas Rast, Dec 31, 2010
  7. Johannes SixtDec 31, 2010
  8. Jeffrey Phillips FreemanJan 3, 2011
  9. Thomas RastJan 4, 2011
  10. Junio C HamanoJan 4, 2011
  11. Johannes SixtDec 31, 2010

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.