Merge branch 'tr/filter-branch'
* tr/filter-branch: filter-branch: nearest-ancestor rewriting outside subdir filter filter-branch: stop special-casing $filter_subdir argument
This commit is contained in:
commit
aa437791d8
@ -159,7 +159,18 @@ to other tags will be rewritten to point to the underlying commit.
|
|||||||
--subdirectory-filter <directory>::
|
--subdirectory-filter <directory>::
|
||||||
Only look at the history which touches the given subdirectory.
|
Only look at the history which touches the given subdirectory.
|
||||||
The result will contain that directory (and only that) as its
|
The result will contain that directory (and only that) as its
|
||||||
project root.
|
project root. Implies --remap-to-ancestor.
|
||||||
|
|
||||||
|
--remap-to-ancestor::
|
||||||
|
Rewrite refs to the nearest rewritten ancestor instead of
|
||||||
|
ignoring them.
|
||||||
|
+
|
||||||
|
Normally, positive refs on the command line are only changed if the
|
||||||
|
commit they point to was rewritten. However, you can limit the extent
|
||||||
|
of this rewriting by using linkgit:rev-list[1] arguments, e.g., path
|
||||||
|
limiters. Refs pointing to such excluded commits would then normally
|
||||||
|
be ignored. With this option, they are instead rewritten to point at
|
||||||
|
the nearest ancestor that was not excluded.
|
||||||
|
|
||||||
--prune-empty::
|
--prune-empty::
|
||||||
Some kind of filters will generate empty commits, that left the tree
|
Some kind of filters will generate empty commits, that left the tree
|
||||||
|
@ -125,6 +125,7 @@ filter_subdir=
|
|||||||
orig_namespace=refs/original/
|
orig_namespace=refs/original/
|
||||||
force=
|
force=
|
||||||
prune_empty=
|
prune_empty=
|
||||||
|
remap_to_ancestor=
|
||||||
while :
|
while :
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
@ -137,6 +138,11 @@ do
|
|||||||
force=t
|
force=t
|
||||||
continue
|
continue
|
||||||
;;
|
;;
|
||||||
|
--remap-to-ancestor)
|
||||||
|
shift
|
||||||
|
remap_to_ancestor=t
|
||||||
|
continue
|
||||||
|
;;
|
||||||
--prune-empty)
|
--prune-empty)
|
||||||
shift
|
shift
|
||||||
prune_empty=t
|
prune_empty=t
|
||||||
@ -182,6 +188,7 @@ do
|
|||||||
;;
|
;;
|
||||||
--subdirectory-filter)
|
--subdirectory-filter)
|
||||||
filter_subdir="$OPTARG"
|
filter_subdir="$OPTARG"
|
||||||
|
remap_to_ancestor=t
|
||||||
;;
|
;;
|
||||||
--original)
|
--original)
|
||||||
orig_namespace=$(expr "$OPTARG/" : '\(.*[^/]\)/*$')/
|
orig_namespace=$(expr "$OPTARG/" : '\(.*[^/]\)/*$')/
|
||||||
@ -257,15 +264,24 @@ git read-tree || die "Could not seed the index"
|
|||||||
# map old->new commit ids for rewriting parents
|
# map old->new commit ids for rewriting parents
|
||||||
mkdir ../map || die "Could not create map/ directory"
|
mkdir ../map || die "Could not create map/ directory"
|
||||||
|
|
||||||
|
# we need "--" only if there are no path arguments in $@
|
||||||
|
nonrevs=$(git rev-parse --no-revs "$@") || exit
|
||||||
|
test -z "$nonrevs" && dashdash=-- || dashdash=
|
||||||
|
rev_args=$(git rev-parse --revs-only "$@")
|
||||||
|
|
||||||
case "$filter_subdir" in
|
case "$filter_subdir" in
|
||||||
"")
|
"")
|
||||||
git rev-list --reverse --topo-order --default HEAD \
|
eval set -- "$(git rev-parse --sq --no-revs "$@")"
|
||||||
--parents --simplify-merges "$@"
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
git rev-list --reverse --topo-order --default HEAD \
|
eval set -- "$(git rev-parse --sq --no-revs "$@" $dashdash \
|
||||||
--parents --simplify-merges "$@" -- "$filter_subdir"
|
"$filter_subdir")"
|
||||||
esac > ../revs || die "Could not get the commits"
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
git rev-list --reverse --topo-order --default HEAD \
|
||||||
|
--parents --simplify-merges $rev_args "$@" > ../revs ||
|
||||||
|
die "Could not get the commits"
|
||||||
commits=$(wc -l <../revs | tr -d " ")
|
commits=$(wc -l <../revs | tr -d " ")
|
||||||
|
|
||||||
test $commits -eq 0 && die "Found nothing to rewrite"
|
test $commits -eq 0 && die "Found nothing to rewrite"
|
||||||
@ -345,19 +361,19 @@ while read commit parents; do
|
|||||||
die "could not write rewritten commit"
|
die "could not write rewritten commit"
|
||||||
done <../revs
|
done <../revs
|
||||||
|
|
||||||
# In case of a subdirectory filter, it is possible that a specified head
|
# If we are filtering for paths, as in the case of a subdirectory
|
||||||
# is not in the set of rewritten commits, because it was pruned by the
|
# filter, it is possible that a specified head is not in the set of
|
||||||
# revision walker. Fix it by mapping these heads to the unique nearest
|
# rewritten commits, because it was pruned by the revision walker.
|
||||||
# ancestor that survived the pruning.
|
# Ancestor remapping fixes this by mapping these heads to the unique
|
||||||
|
# nearest ancestor that survived the pruning.
|
||||||
|
|
||||||
if test "$filter_subdir"
|
if test "$remap_to_ancestor" = t
|
||||||
then
|
then
|
||||||
while read ref
|
while read ref
|
||||||
do
|
do
|
||||||
sha1=$(git rev-parse "$ref"^0)
|
sha1=$(git rev-parse "$ref"^0)
|
||||||
test -f "$workdir"/../map/$sha1 && continue
|
test -f "$workdir"/../map/$sha1 && continue
|
||||||
ancestor=$(git rev-list --simplify-merges -1 \
|
ancestor=$(git rev-list --simplify-merges -1 "$ref" "$@")
|
||||||
$ref -- "$filter_subdir")
|
|
||||||
test "$ancestor" && echo $(map $ancestor) >> "$workdir"/../map/$sha1
|
test "$ancestor" && echo $(map $ancestor) >> "$workdir"/../map/$sha1
|
||||||
done < "$tempdir"/heads
|
done < "$tempdir"/heads
|
||||||
fi
|
fi
|
||||||
|
@ -288,4 +288,22 @@ test_expect_success 'Prune empty commits' '
|
|||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success '--remap-to-ancestor with filename filters' '
|
||||||
|
git checkout master &&
|
||||||
|
git reset --hard A &&
|
||||||
|
test_commit add-foo foo 1 &&
|
||||||
|
git branch moved-foo &&
|
||||||
|
test_commit add-bar bar a &&
|
||||||
|
git branch invariant &&
|
||||||
|
orig_invariant=$(git rev-parse invariant) &&
|
||||||
|
git branch moved-bar &&
|
||||||
|
test_commit change-foo foo 2 &&
|
||||||
|
git filter-branch -f --remap-to-ancestor \
|
||||||
|
moved-foo moved-bar A..master \
|
||||||
|
-- -- foo &&
|
||||||
|
test $(git rev-parse moved-foo) = $(git rev-parse moved-bar) &&
|
||||||
|
test $(git rev-parse moved-foo) = $(git rev-parse master^) &&
|
||||||
|
test $orig_invariant = $(git rev-parse invariant)
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user