From: Junio C Hamano Date: Tue, 30 Oct 2018 06:43:39 +0000 (+0900) Subject: Merge branch 'md/filter-trees' X-Git-Tag: v2.20.0-rc0~129 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=77d503757d6328703f9571a4432dd83800bc26bb;p=thirdparty%2Fgit.git Merge branch 'md/filter-trees' The "rev-list --filter" feature learned to exclude all trees via "tree:0" filter. * md/filter-trees: list-objects: support for skipping tree traversal filter-trees: code clean-up of tests list-objects-filter: implement filter tree:0 list-objects-filter-options: do not over-strbuf_init list-objects-filter: use BUG rather than die revision: mark non-user-given objects instead rev-list: handle missing tree objects properly list-objects: always parse trees gently list-objects: refactor to process_tree_contents list-objects: store common func args in struct --- 77d503757d6328703f9571a4432dd83800bc26bb diff --cc builtin/rev-list.c index cc1b70522f,49d6deed70..5064d08e1b --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@@ -370,9 -372,10 +372,10 @@@ int cmd_rev_list(int argc, const char * usage(rev_list_usage); git_config(git_default_config, NULL); - init_revisions(&revs, prefix); + repo_init_revisions(the_repository, &revs, prefix); revs.abbrev = DEFAULT_ABBREV; revs.commit_format = CMIT_FMT_UNSPECIFIED; + revs.do_not_die_on_missing_tree = 1; /* * Scan the argument list before invoking setup_revisions(), so that we diff --cc t/t5317-pack-objects-filter-objects.sh index 2e718f0bde,d9dccf4d4d..24541ea137 --- a/t/t5317-pack-objects-filter-objects.sh +++ b/t/t5317-pack-objects-filter-objects.sh @@@ -54,19 -48,58 +54,60 @@@ test_expect_success 'verify blob:none p ' test_expect_success 'verify normal and blob:none packfiles have same commits/trees' ' - git -C r1 verify-pack -v ../all.pack \ - | grep -E "commit|tree" \ - | awk -f print_1.awk \ - | sort >expected && - git -C r1 verify-pack -v ../filter.pack \ - | grep -E "commit|tree" \ - | awk -f print_1.awk \ - | sort >observed && - test_cmp observed expected + git -C r1 verify-pack -v ../all.pack >verify_result && + grep -E "commit|tree" verify_result | + awk -f print_1.awk | + sort >expected && + + git -C r1 verify-pack -v ../filter.pack >verify_result && + grep -E "commit|tree" verify_result | + awk -f print_1.awk | + sort >observed && + + test_cmp expected observed ' + test_expect_success 'get an error for missing tree object' ' + git init r5 && + echo foo >r5/foo && + git -C r5 add foo && + git -C r5 commit -m "foo" && + del=$(git -C r5 rev-parse HEAD^{tree} | sed "s|..|&/|") && + rm r5/.git/objects/$del && + test_must_fail git -C r5 pack-objects --rev --stdout 2>bad_tree <<-EOF && + HEAD + EOF + grep "bad tree object" bad_tree + ' + + test_expect_success 'setup for tests of tree:0' ' + mkdir r1/subtree && + echo "This is a file in a subtree" >r1/subtree/file && + git -C r1 add subtree/file && + git -C r1 commit -m subtree + ' + + test_expect_success 'verify tree:0 packfile has no blobs or trees' ' + git -C r1 pack-objects --rev --stdout --filter=tree:0 >commitsonly.pack <<-EOF && + HEAD + EOF + git -C r1 index-pack ../commitsonly.pack && + git -C r1 verify-pack -v ../commitsonly.pack >objs && + ! grep -E "tree|blob" objs + ' + + test_expect_success 'grab tree directly when using tree:0' ' + # We should get the tree specified directly but not its blobs or subtrees. + git -C r1 pack-objects --rev --stdout --filter=tree:0 >commitsonly.pack <<-EOF && + HEAD: + EOF + git -C r1 index-pack ../commitsonly.pack && + git -C r1 verify-pack -v ../commitsonly.pack >objs && + awk "/tree|blob/{print \$1}" objs >trees_and_blobs && + git -C r1 rev-parse HEAD: >expected && + test_cmp expected trees_and_blobs + ' + # Test blob:limit=[kmg] filter. # We boundary test around the size parameter. The filter is strictly less than # the value, so size 500 and 1000 should have the same results, but 1001 should diff --cc t/t6112-rev-list-filters-objects.sh index 53975c5724,c6aae93b57..eb32505a6e --- a/t/t6112-rev-list-filters-objects.sh +++ b/t/t6112-rev-list-filters-objects.sh @@@ -21,31 -21,36 +21,43 @@@ test_expect_success 'setup r1' test_expect_success 'verify blob:none omits all 5 blobs' ' git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 \ - | awk -f print_2.awk \ - | sort >expected && - git -C r1 rev-list HEAD --quiet --objects --filter-print-omitted --filter=blob:none \ - | awk -f print_1.awk \ - | sed "s/~//" \ - | sort >observed && - test_cmp observed expected + >ls_files_result && + awk -f print_2.awk ls_files_result | + sort >expected && + + git -C r1 rev-list --quiet --objects --filter-print-omitted \ + --filter=blob:none HEAD >revs && + awk -f print_1.awk revs | + sed "s/~//" | + sort >observed && + + test_cmp expected observed ' + test_expect_success 'specify blob explicitly prevents filtering' ' + file_3=$(git -C r1 ls-files -s file.3 | + awk -f print_2.awk) && + + file_4=$(git -C r1 ls-files -s file.4 | + awk -f print_2.awk) && + + git -C r1 rev-list --objects --filter=blob:none HEAD $file_3 >observed && + grep "$file_3" observed && + ! grep "$file_4" observed + ' + test_expect_success 'verify emitted+omitted == all' ' - git -C r1 rev-list HEAD --objects \ - | awk -f print_1.awk \ - | sort >expected && - git -C r1 rev-list HEAD --objects --filter-print-omitted --filter=blob:none \ - | awk -f print_1.awk \ - | sed "s/~//" \ - | sort >observed && - test_cmp observed expected + git -C r1 rev-list --objects HEAD >revs && + awk -f print_1.awk revs | + sort >expected && + + git -C r1 rev-list --objects --filter-print-omitted --filter=blob:none \ + HEAD >revs && + awk -f print_1.awk revs | + sed "s/~//" | + sort >observed && + + test_cmp expected observed ' @@@ -219,19 -198,66 +231,69 @@@ test_expect_success 'verify sparse:oid= ' test_expect_success 'verify sparse:oid=oid-ish omits top-level files' ' - git -C r3 ls-files -s pattern sparse1 sparse2 \ - | awk -f print_2.awk \ - | sort >expected && - git -C r3 rev-list HEAD --quiet --objects --filter-print-omitted --filter=sparse:oid=master:pattern \ - | awk -f print_1.awk \ - | sed "s/~//" \ - | sort >observed && - test_cmp observed expected + git -C r3 ls-files -s pattern sparse1 sparse2 >ls_files_result && + awk -f print_2.awk ls_files_result | + sort >expected && + + git -C r3 rev-list --quiet --objects --filter-print-omitted \ + --filter=sparse:oid=master:pattern HEAD >revs && + awk -f print_1.awk revs | + sed "s/~//" | + sort >observed && + + test_cmp expected observed ' + test_expect_success 'rev-list W/ --missing=print and --missing=allow-any for trees' ' + TREE=$(git -C r3 rev-parse HEAD:dir1) && + + # Create a spare repo because we will be deleting objects from this one. + git clone r3 r3.b && + + rm r3.b/.git/objects/$(echo $TREE | sed "s|^..|&/|") && + + git -C r3.b rev-list --quiet --missing=print --objects HEAD \ + >missing_objs 2>rev_list_err && + echo "?$TREE" >expected && + test_cmp expected missing_objs && + + # do not complain when a missing tree cannot be parsed + test_must_be_empty rev_list_err && + + git -C r3.b rev-list --missing=allow-any --objects HEAD \ + >objs 2>rev_list_err && + ! grep $TREE objs && + test_must_be_empty rev_list_err + ' + + # Test tree:0 filter. + + test_expect_success 'verify tree:0 includes trees in "filtered" output' ' + git -C r3 rev-list --quiet --objects --filter-print-omitted \ + --filter=tree:0 HEAD >revs && + + awk -f print_1.awk revs | + sed s/~// | + xargs -n1 git -C r3 cat-file -t >unsorted_filtered_types && + + sort -u unsorted_filtered_types >filtered_types && + test_write_lines blob tree >expected && + test_cmp expected filtered_types + ' + + # Make sure tree:0 does not iterate through any trees. + + test_expect_success 'filter a GIANT tree through tree:0' ' + GIT_TRACE=1 git -C r3 rev-list \ + --objects --filter=tree:0 HEAD 2>filter_trace && + grep "Skipping contents of tree [.][.][.]" filter_trace >actual && + # One line for each commit traversed. + test_line_count = 2 actual && + + # Make sure no other trees were considered besides the root. + ! grep "Skipping contents of tree [^.]" filter_trace + ' + # Delete some loose objects and use rev-list, but WITHOUT any filtering. # This models previously omitted objects that we did not receive.