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

[PATCH] filter-branch: fix ancestor discovery for --subdirectory-filter

From
Thomas Rast <trast@student.ethz.ch>
Date
Aug 8, 2008, 14:16 UTC
Message-ID
<1218204962-17900-1-git-send-email-trast@student.ethz.ch>
In-Reply-To
<200808081614.44422.trast@student.ethz.ch>

The previous code failed on any refs that are (pre-rewrite) ancestors of commits marked for rewriting. This means that in a situation

   A -- B(topic) -- C(master)

where B is dropped by --subdirectory-filter pruning, the 'topic' is not moved up to A as intended, but left unrewritten.

Fix this by using a more stupid approach: we let 'rev-list -1' figure out a nearby ancestor, which handles the pruning automatically.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---

I guarded it with a $filter_subdir check to not cause any unintended harm. It might be useful in some border cases of rev-list arguments given to filter-branch too, but I can't figure out a safe way to handle that.

Either way, this fixes the problem.
- Thomas
 git-filter-branch.sh |   27 +++++++++++----------------
 1 files changed, 11 insertions(+), 16 deletions(-)
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index a324cf0..7924aa1 100755
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -317,24 +317,19 @@ done <../revs
 
 # In case of a subdirectory filter, it is possible that a specified head
 # is not in the set of rewritten commits, because it was pruned by the
-# revision walker.  Fix it by mapping these heads to the next rewritten
-# ancestor(s), i.e. the boundaries in the set of rewritten commits.
+# revision walker.  Fix it by mapping these heads to a (random!) nearby
+# ancestor that survived the pruning.
 
-# NEEDSWORK: we should sort the unmapped refs topologically first
-while read ref
-do
-	sha1=$(git rev-parse "$ref"^0)
-	test -f "$workdir"/../map/$sha1 && continue
-	# Assign the boundarie(s) in the set of rewritten commits
-	# as the replacement commit(s).
-	# (This would look a bit nicer if --not --stdin worked.)
-	for p in $( (cd "$workdir"/../map; ls | sed "s/^/^/") |
-		git rev-list $ref --boundary --stdin |
-		sed -n "s/^-//p")
+if test "$filter_subdir"
+then
+	while read ref
 	do
-		map $p >> "$workdir"/../map/$sha1
-	done
-done < "$tempdir"/heads
+		sha1=$(git rev-parse "$ref"^0)
+		test -f "$workdir"/../map/$sha1 && continue
+		ancestor=$(git rev-list -1 $ref -- "$filter_subdir")
+		test "$ancestor" && echo $(map $ancestor) >> "$workdir"/../map/$sha1
+	done < "$tempdir"/heads
+fi
 
 # Finally update the refs
 
-- 
1.6.0.rc2.22.g7d28.dirty
Previous: Thomas RastNext: Johannes Schindelin
Message 14 of 35 in “git filter-branch --subdirectory-filter, still a mistery”
  1. Jan WielemakerAug 6, 2008
  2. Jan WielemakerAug 7, 2008
  3. Thomas RastAug 7, 2008
  4. Jan WielemakerAug 7, 2008
  5. Thomas RastAug 7, 2008
  6. filter-branch: be more helpful when an annotated tag changesThomas Rast, Aug 7, 2008
  7. filter-branch: add option --delete-unchangedThomas Rast, Aug 8, 2008
  8. Johannes SchindelinAug 9, 2008
  9. Jan WielemakerAug 11, 2008
  10. Felipe ContrerasSep 14, 2008
  11. [RFH] filter-branch: ancestor detection weirdnessThomas Rast, Aug 7, 2008
  12. Johannes SchindelinAug 8, 2008
  13. Thomas RastAug 8, 2008
  14. filter-branch: fix ancestor discovery for --subdirectory-filterThomas Rast, Aug 8, 2008
  15. Johannes SchindelinAug 8, 2008
  16. Thomas RastAug 8, 2008
  17. filter-branch: fix ref rewriting with --subdirectory-filterThomas Rast, Aug 8, 2008
  18. Johannes SchindelinAug 9, 2008
  19. Junio C HamanoAug 9, 2008
  20. Thomas RastAug 9, 2008
  21. Thomas RastAug 9, 2008
  22. filter-branch: use --simplify-mergesThomas Rast, Aug 10, 2008
  23. Junio C HamanoAug 12, 2008
  24. Junio C HamanoAug 12, 2008
  25. Thomas RastAug 12, 2008
  26. Junio C HamanoAug 12, 2008
  27. Petr BaudisAug 12, 2008
  28. Junio C HamanoAug 12, 2008
  29. Thomas RastAug 9, 2008
  30. Junio C HamanoAug 12, 2008
  31. Thomas RastAug 12, 2008
  32. Jan WielemakerAug 8, 2008
  33. Jan WielemakerAug 8, 2008
  34. Documentation: filter-branch: document how to filter all refsThomas Rast, Aug 7, 2008
  35. Documentation: filter-branch: document how to filter all refsThomas Rast, Aug 7, 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.