[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