Skip to content

Commit

Permalink
Teach filter-branch about subdirectory filtering
Browse files Browse the repository at this point in the history
With git-filter-branch --subdirectory-filter <subdirectory> you can
get at the history, as seen by a certain subdirectory. The history
of the rewritten branch will only contain commits that touched that
subdirectory, and the subdirectory will be rewritten to be the new
project root.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Johannes Schindelin authored and Junio C Hamano committed Jun 9, 2007
1 parent 3520e1e commit 685ef54
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 3 deletions.
33 changes: 30 additions & 3 deletions git-filter-branch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@
# attached, the rewritten tag won't have it. Sorry. (It is by
# definition impossible to preserve signatures at any rate, though.)
#
# --subdirectory-filter DIRECTORY:: Only regard the history, as seen by
# the given subdirectory. The result will contain that directory as
# its project root.
#
# EXAMPLE USAGE
# -------------
# Suppose you want to remove a file (containing confidential information
Expand Down Expand Up @@ -224,7 +228,13 @@ set_ident () {

# list all parent's object names for a given commit
get_parents () {
git-rev-list -1 --parents "$1" | sed "s/^[0-9a-f]*//"
case "$filter_subdir" in
"")
git-rev-list -1 --parents "$1"
;;
*)
git-rev-list -1 --parents "$1" -- "$filter_subdir"
esac | sed "s/^[0-9a-f]*//"
}

tempdir=.git-rewrite
Expand All @@ -235,6 +245,7 @@ filter_parent=
filter_msg=cat
filter_commit='git-commit-tree "$@"'
filter_tag_name=
filter_subdir=
while case "$#" in 0) usage;; esac
do
case "$1" in
Expand Down Expand Up @@ -280,6 +291,9 @@ do
--tag-name-filter)
filter_tag_name="$OPTARG"
;;
--subdirectory-filter)
filter_subdir="$OPTARG"
;;
*)
usage
;;
Expand Down Expand Up @@ -313,7 +327,14 @@ ret=0

mkdir ../map # map old->new commit ids for rewriting parents

git-rev-list --reverse --topo-order --default HEAD "$@" >../revs
case "$filter_subdir" in
"")
git-rev-list --reverse --topo-order --default HEAD "$@"
;;
*)
git-rev-list --reverse --topo-order --default HEAD "$@" \
-- "$filter_subdir"
esac > ../revs
commits=$(cat ../revs | wc -l | tr -d " ")

test $commits -eq 0 && die "Found nothing to rewrite"
Expand All @@ -323,7 +344,13 @@ while read commit; do
i=$(($i+1))
printf "$commit ($i/$commits) "

git-read-tree -i -m $commit
case "$filter_subdir" in
"")
git-read-tree -i -m $commit
;;
*)
git-read-tree -i -m $commit:"$filter_subdir"
esac

export GIT_COMMIT=$commit
git-cat-file commit "$commit" >../commit
Expand Down
24 changes: 24 additions & 0 deletions t/t7003-filter-branch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,28 @@ test_expect_success 'common ancestor is still common (unchanged)' '
test "$(git-merge-base modD D)" = "$(git-rev-parse B)"
'

test_expect_success 'filter subdirectory only' '
mkdir subdir &&
touch subdir/new &&
git add subdir/new &&
test_tick &&
git commit -m "subdir" &&
echo H > a &&
test_tick &&
git commit -m "not subdir" a &&
echo A > subdir/new &&
test_tick &&
git commit -m "again subdir" subdir/new &&
git rm a &&
test_tick &&
git commit -m "again not subdir" &&
git-filter-branch --subdirectory-filter subdir sub
'

test_expect_success 'subdirectory filter result looks okay' '
test 2 = $(git-rev-list sub | wc -l) &&
git show sub:new &&
! git show sub:subdir
'

test_done

0 comments on commit 685ef54

Please sign in to comment.