From: Junio C Hamano Date: Wed, 18 Jul 2018 19:20:32 +0000 (-0700) Subject: Merge branch 'mb/filter-branch-optim' X-Git-Tag: v2.19.0-rc0~152 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/676c7e50b10f1fbb2ce06e46260f15f3a20679f7?hp=-c Merge branch 'mb/filter-branch-optim' "git filter-branch" when used with the "--state-branch" option still attempted to rewrite the commits whose filtered result is known from the previous attempt (which is recorded on the state branch); the command has been corrected not to waste cycles doing so. * mb/filter-branch-optim: filter-branch: skip commits present on --state-branch --- 676c7e50b10f1fbb2ce06e46260f15f3a20679f7 diff --combined git-filter-branch.sh index ccceaf19a7,10096cb999..5c5afa2b98 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@@ -11,8 -11,6 +11,8 @@@ # The following functions will also be available in the commit filter: functions=$(cat << \EOF +EMPTY_TREE=$(git hash-object -t tree /dev/null) + warn () { echo "$*" >&2 } @@@ -48,7 -46,7 +48,7 @@@ git_commit_non_empty_tree( { if test $# = 3 && test "$1" = $(git rev-parse "$3^{tree}"); then map "$3" - elif test $# = 1 && test "$1" = 4b825dc642cb6eb9a060e54bf8d69288fbee4904; then + elif test $# = 1 && test "$1" = $EMPTY_TREE; then : else git commit-tree "$@" @@@ -253,18 -251,8 +253,18 @@@ done < "$tempdir"/backup-ref # The refs should be updated if their heads were rewritten git rev-parse --no-flags --revs-only --symbolic-full-name \ - --default HEAD "$@" > "$tempdir"/raw-heads || exit -sed -e '/^^/d' "$tempdir"/raw-heads >"$tempdir"/heads + --default HEAD "$@" > "$tempdir"/raw-refs || exit +while read ref +do + case "$ref" in ^?*) continue ;; esac + + if git rev-parse --verify "$ref"^0 >/dev/null 2>&1 + then + echo "$ref" + else + warn "WARNING: not rewriting '$ref' (not a committish)" + fi +done >"$tempdir"/heads <"$tempdir"/raw-refs test -s "$tempdir"/heads || die "You must specify a ref to rewrite." @@@ -322,7 -310,7 +322,7 @@@ git rev-list --reverse --topo-order --d die "Could not get the commits" commits=$(wc -l <../revs | tr -d " ") -test $commits -eq 0 && die "Found nothing to rewrite" +test $commits -eq 0 && die_with_status 2 "Found nothing to rewrite" # Rewrite the commits report_progress () @@@ -372,6 -360,7 +372,7 @@@ while read commit parents; d git_filter_branch__commit_count=$(($git_filter_branch__commit_count+1)) report_progress + test -f "$workdir"/../map/$commit && continue case "$filter_subdir" in "") diff --combined t/t7003-filter-branch.sh index ec4b160ddb,451211280b..e23de7d0b5 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@@ -107,6 -107,21 +107,21 @@@ test_expect_success 'test that the dire test dir/D = "$(cat diroh/D.t)" ' + V=$(git rev-parse HEAD) + + test_expect_success 'populate --state-branch' ' + git filter-branch --state-branch state -f --tree-filter "touch file || :" HEAD + ' + + W=$(git rev-parse HEAD) + + test_expect_success 'using --state-branch to skip already rewritten commits' ' + test_when_finished git reset --hard $V && + git reset --hard $V && + git filter-branch --state-branch state -f --tree-filter "touch file || :" HEAD && + test_cmp_rev $W HEAD + ' + git tag oldD HEAD~4 test_expect_success 'rewrite one branch, keeping a side branch' ' git branch modD oldD && @@@ -187,8 -202,7 +202,8 @@@ test_expect_success 'author informatio test \$GIT_COMMIT != $(git rev-parse master) || \ echo Hallo" \ preserved-author) && - test 1 = $(git rev-list --author="B V Uips" preserved-author | wc -l) + git rev-list --author="B V Uips" preserved-author >actual && + test_line_count = 1 actual ' test_expect_success "remove a certain author's commits" ' @@@ -206,8 -220,7 +221,8 @@@ cnt1=$(git rev-list master | wc -l) && cnt2=$(git rev-list removed-author | wc -l) && test $cnt1 -eq $(($cnt2 + 1)) && - test 0 = $(git rev-list --author="B V Uips" removed-author | wc -l) + git rev-list --author="B V Uips" removed-author >actual && + test_line_count = 0 actual ' test_expect_success 'barf on invalid name' ' @@@ -260,8 -273,7 +275,8 @@@ test_expect_success 'Subdirectory filte git commit -m "Re-adding foo" && git filter-branch -f --subdirectory-filter foo && - test $(git rev-list master | wc -l) = 3 + git rev-list master >actual && + test_line_count = 3 actual ' test_expect_success 'Tag name filtering retains tag message' ' @@@ -473,18 -485,4 +488,18 @@@ test_expect_success 'tree-filter deals git show HEAD:$ambiguous ' +test_expect_success 'rewrite repository including refs that point at non-commit object' ' + test_when_finished "git reset --hard original" && + tree=$(git rev-parse HEAD^{tree}) && + test_when_finished "git replace -d $tree" && + echo A >new && + git add new && + new_tree=$(git write-tree) && + git replace $tree $new_tree && + git tag -a -m "tag to a tree" treetag $new_tree && + git reset --hard HEAD && + git filter-branch -f -- --all >filter-output 2>&1 && + ! fgrep fatal filter-output +' + test_done