sparse-checkout: write using lockfile
If two 'git sparse-checkout set' subcommands are launched at the same time, the behavior can be unexpected as they compete to write the sparse-checkout file and update the working directory. Take a lockfile around the writes to the sparse-checkout file. In addition, acquire this lock around the working directory update to avoid two commands updating the working directory in different ways. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									99dfa6f970
								
							
						
					
					
						commit
						fb10ca5b54
					
				|  | @ -170,25 +170,32 @@ static int write_patterns_and_update(struct pattern_list *pl) | |||
| { | ||||
| 	char *sparse_filename; | ||||
| 	FILE *fp; | ||||
| 	int fd; | ||||
| 	struct lock_file lk = LOCK_INIT; | ||||
| 	int result; | ||||
|  | ||||
| 	result = update_working_directory(pl); | ||||
| 	sparse_filename = get_sparse_checkout_filename(); | ||||
| 	fd = hold_lock_file_for_update(&lk, sparse_filename, | ||||
| 				      LOCK_DIE_ON_ERROR); | ||||
|  | ||||
| 	result = update_working_directory(pl); | ||||
| 	if (result) { | ||||
| 		rollback_lock_file(&lk); | ||||
| 		free(sparse_filename); | ||||
| 		clear_pattern_list(pl); | ||||
| 		update_working_directory(NULL); | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	sparse_filename = get_sparse_checkout_filename(); | ||||
| 	fp = fopen(sparse_filename, "w"); | ||||
| 	fp = xfdopen(fd, "w"); | ||||
|  | ||||
| 	if (core_sparse_checkout_cone) | ||||
| 		write_cone_to_file(fp, pl); | ||||
| 	else | ||||
| 		write_patterns_to_file(fp, pl); | ||||
|  | ||||
| 	fclose(fp); | ||||
| 	fflush(fp); | ||||
| 	commit_lock_file(&lk); | ||||
|  | ||||
| 	free(sparse_filename); | ||||
| 	clear_pattern_list(pl); | ||||
|  |  | |||
|  | @ -277,4 +277,11 @@ test_expect_success 'revert to old sparse-checkout on empty update' ' | |||
| 	) | ||||
| ' | ||||
|  | ||||
| test_expect_success 'fail when lock is taken' ' | ||||
| 	test_when_finished rm -rf repo/.git/info/sparse-checkout.lock && | ||||
| 	touch repo/.git/info/sparse-checkout.lock && | ||||
| 	test_must_fail git -C repo sparse-checkout set deep 2>err && | ||||
| 	test_i18ngrep "File exists" err | ||||
| ' | ||||
|  | ||||
| test_done | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Derrick Stolee
						Derrick Stolee