# 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
# 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
filter_msg=cat
filter_commit='git-commit-tree "$@"'
filter_tag_name=
+filter_subdir=
while case "$#" in 0) usage;; esac
do
case "$1" in
--tag-name-filter)
filter_tag_name="$OPTARG"
;;
+ --subdirectory-filter)
+ filter_subdir="$OPTARG"
+ ;;
*)
usage
;;
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"
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
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