filter-branch: fix ref rewriting with --subdirectory-filter
authorThomas Rast <trast@student.ethz.ch>
Tue, 12 Aug 2008 08:45:58 +0000 (10:45 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 13 Aug 2008 00:27:17 +0000 (17:27 -0700)
commita0e46390d397e71182e42930b98b6b59a1a84898
tree9c38ceb70da87ef412ea2ce5eca887549f482a90
parent6e84b712373d343ea3531740d8eb048e84240a39
filter-branch: fix ref rewriting with --subdirectory-filter

The previous ancestor discovery 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' was
not moved up to A as intended, but left unrewritten because we asked
about 'git rev-list ^master topic', which does not return anything.

Instead, we use the straightforward

   git rev-list -1 $ref -- $filter_subdir

to find the right ancestor.  To justify this, note that the nearest
ancestor is unique: We use the output of

  git rev-list --parents -- $filter_subdir

to rewrite commits in the first pass, before any ref rewriting.  If B
is a non-merge commit, the only candidate is its parent.  If it is a
merge, there are two cases:

- All sides of the merge bring the same subdirectory contents.  Then
  rev-list already pruned away the merge in favour for just one of its
  parents, so there is only one candidate.

- Some merge sides, or the merge outcome, differ.  Then the merge is
  not pruned and can be rewritten directly.

So it is always safe to use rev-list -1.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git-filter-branch.sh
t/t7003-filter-branch.sh