 4d7f95ed1f
			
		
	
	4d7f95ed1f
	
	
	
		
			
			The add_pattern() function takes a pattern string, but neither makes a copy of it nor takes ownership of the memory. So it is the caller's responsibility to make sure the string hangs around as long as the pattern_list which references it. There are a few cases in sparse-checkout where we use string literal patterns by stuffing them into a strbuf, detaching the buffer, and then passing the result into add_pattern(). This creates a leak when the pattern_list is eventually cleared, since we don't retain a copy of the detached buffer to free. But we can observe that the whole strbuf dance is unnecessary. The point was presumably[1] to satisfy the lifetime requirement of the string. But string literals have static duration; we can count on them lasting for the whole program. So we can fix the leak by just passing them directly. And as a bonus, that simplifies the code. The leaks can be seen in t7002, which drops from 25 leaks to 22 with this patch. It also makes t3602 and t1090 leak-free. In the long run, we will also want to clean up this (undocumented!) memory lifetime requirement of add_pattern(). But that can come in a later patch; passing the string literals directly will be the right thing either way. [1] The code in question comes from416adc8711(sparse-checkout: update working directory in-process for 'init', 2019-11-21) and99dfa6f970(sparse-checkout: use in-process update for disable subcommand, 2019-11-21), but I didn't see anything in their commit messages or on the list explaining the strbufs. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
		
			
				
	
	
		
			111 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/sh
 | |
| 
 | |
| test_description='sparse checkout scope tests'
 | |
| 
 | |
| GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 | |
| export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 | |
| 
 | |
| TEST_CREATE_REPO_NO_TEMPLATE=1
 | |
| TEST_PASSES_SANITIZE_LEAK=true
 | |
| . ./test-lib.sh
 | |
| 
 | |
| test_expect_success 'setup' '
 | |
| 	echo "initial" >a &&
 | |
| 	echo "initial" >b &&
 | |
| 	echo "initial" >c &&
 | |
| 	git add a b c &&
 | |
| 	git commit -m "initial commit"
 | |
| '
 | |
| 
 | |
| test_expect_success 'create feature branch' '
 | |
| 	git checkout -b feature &&
 | |
| 	echo "modified" >b &&
 | |
| 	echo "modified" >c &&
 | |
| 	git add b c &&
 | |
| 	git commit -m "modification"
 | |
| '
 | |
| 
 | |
| test_expect_success 'perform sparse checkout of main' '
 | |
| 	git config --local --bool core.sparsecheckout true &&
 | |
| 	mkdir .git/info &&
 | |
| 	echo "!/*" >.git/info/sparse-checkout &&
 | |
| 	echo "/a" >>.git/info/sparse-checkout &&
 | |
| 	echo "/c" >>.git/info/sparse-checkout &&
 | |
| 	git checkout main &&
 | |
| 	test_path_is_file a &&
 | |
| 	test_path_is_missing b &&
 | |
| 	test_path_is_file c
 | |
| '
 | |
| 
 | |
| test_expect_success 'merge feature branch into sparse checkout of main' '
 | |
| 	git merge feature &&
 | |
| 	test_path_is_file a &&
 | |
| 	test_path_is_missing b &&
 | |
| 	test_path_is_file c &&
 | |
| 	test "$(cat c)" = "modified"
 | |
| '
 | |
| 
 | |
| test_expect_success 'return to full checkout of main' '
 | |
| 	git checkout feature &&
 | |
| 	echo "/*" >.git/info/sparse-checkout &&
 | |
| 	git checkout main &&
 | |
| 	test_path_is_file a &&
 | |
| 	test_path_is_file b &&
 | |
| 	test_path_is_file c &&
 | |
| 	test "$(cat b)" = "modified"
 | |
| '
 | |
| 
 | |
| test_expect_success 'skip-worktree on files outside sparse patterns' '
 | |
| 	git sparse-checkout disable &&
 | |
| 	git sparse-checkout set --no-cone "a*" &&
 | |
| 	git checkout-index --all --ignore-skip-worktree-bits &&
 | |
| 
 | |
| 	git ls-files -t >output &&
 | |
| 	! grep ^S output >actual &&
 | |
| 	test_must_be_empty actual &&
 | |
| 
 | |
| 	test_config sparse.expectFilesOutsideOfPatterns true &&
 | |
| 	cat <<-\EOF >expect &&
 | |
| 	S b
 | |
| 	S c
 | |
| 	EOF
 | |
| 	git ls-files -t >output &&
 | |
| 	grep ^S output >actual &&
 | |
| 	test_cmp expect actual
 | |
| '
 | |
| 
 | |
| test_expect_success 'in partial clone, sparse checkout only fetches needed blobs' '
 | |
| 	test_create_repo server &&
 | |
| 	git clone --template= "file://$(pwd)/server" client &&
 | |
| 
 | |
| 	test_config -C server uploadpack.allowfilter 1 &&
 | |
| 	test_config -C server uploadpack.allowanysha1inwant 1 &&
 | |
| 	echo a >server/a &&
 | |
| 	echo bb >server/b &&
 | |
| 	mkdir server/c &&
 | |
| 	echo ccc >server/c/c &&
 | |
| 	git -C server add a b c/c &&
 | |
| 	git -C server commit -m message &&
 | |
| 
 | |
| 	test_config -C client core.sparsecheckout 1 &&
 | |
| 	mkdir client/.git/info &&
 | |
| 	echo "!/*" >client/.git/info/sparse-checkout &&
 | |
| 	echo "/a" >>client/.git/info/sparse-checkout &&
 | |
| 	git -C client fetch --filter=blob:none origin &&
 | |
| 	git -C client checkout FETCH_HEAD &&
 | |
| 
 | |
| 	git -C client rev-list HEAD \
 | |
| 		--quiet --objects --missing=print >unsorted_actual &&
 | |
| 	(
 | |
| 		printf "?" &&
 | |
| 		git hash-object server/b &&
 | |
| 		printf "?" &&
 | |
| 		git hash-object server/c/c
 | |
| 	) >unsorted_expect &&
 | |
| 	sort unsorted_actual >actual &&
 | |
| 	sort unsorted_expect >expect &&
 | |
| 	test_cmp expect actual
 | |
| '
 | |
| 
 | |
| test_done
 |