Teach git-local-fetch the --stdin switch
This makes it possible to fetch many commits (refs) at once, greatly speeding up cg-clone. Signed-off-by: Petr Baudis <pasky@suse.cz> Signed-off-by: Junio C Hamano <junkio@cox.net>maint
							parent
							
								
									4211e4d10c
								
							
						
					
					
						commit
						8e87ca6615
					
				|  | @ -29,6 +29,12 @@ OPTIONS | |||
|         Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on | ||||
|         the local end after the transfer is complete. | ||||
|  | ||||
| --stdin:: | ||||
| 	Instead of a commit id on the commandline (which is not expected in this | ||||
| 	case), 'git-local-fetch' expects lines on stdin in the format | ||||
|  | ||||
| 		<commit-id>['\t'<filename-as-in--w>] | ||||
|  | ||||
| Author | ||||
| ------ | ||||
| Written by Junio C Hamano <junkio@cox.net> | ||||
|  |  | |||
							
								
								
									
										40
									
								
								fetch.c
								
								
								
								
							
							
						
						
									
										40
									
								
								fetch.c
								
								
								
								
							|  | @ -7,6 +7,7 @@ | |||
| #include "tag.h" | ||||
| #include "blob.h" | ||||
| #include "refs.h" | ||||
| #include "strbuf.h" | ||||
|  | ||||
| int get_tree = 0; | ||||
| int get_history = 0; | ||||
|  | @ -210,6 +211,45 @@ static int mark_complete(const char *path, const unsigned char *sha1) | |||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int pull_targets_stdin(char ***target, const char ***write_ref) | ||||
| { | ||||
| 	int targets = 0, targets_alloc = 0; | ||||
| 	struct strbuf buf; | ||||
| 	*target = NULL; *write_ref = NULL; | ||||
| 	strbuf_init(&buf); | ||||
| 	while (1) { | ||||
| 		char *rf_one = NULL; | ||||
| 		char *tg_one; | ||||
|  | ||||
| 		read_line(&buf, stdin, '\n'); | ||||
| 		if (buf.eof) | ||||
| 			break; | ||||
| 		tg_one = buf.buf; | ||||
| 		rf_one = strchr(tg_one, '\t'); | ||||
| 		if (rf_one) | ||||
| 			*rf_one++ = 0; | ||||
|  | ||||
| 		if (targets >= targets_alloc) { | ||||
| 			targets_alloc = targets_alloc ? targets_alloc * 2 : 64; | ||||
| 			*target = xrealloc(*target, targets_alloc * sizeof(**target)); | ||||
| 			*write_ref = xrealloc(*write_ref, targets_alloc * sizeof(**write_ref)); | ||||
| 		} | ||||
| 		(*target)[targets] = strdup(tg_one); | ||||
| 		(*write_ref)[targets] = rf_one ? strdup(rf_one) : NULL; | ||||
| 		targets++; | ||||
| 	} | ||||
| 	return targets; | ||||
| } | ||||
|  | ||||
| void pull_targets_free(int targets, char **target, const char **write_ref) | ||||
| { | ||||
| 	while (targets--) { | ||||
| 		free(target[targets]); | ||||
| 		if (write_ref[targets]) | ||||
| 			free((char *) write_ref[targets]); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int pull(int targets, char **target, const char **write_ref, | ||||
|          const char *write_ref_log_details) | ||||
| { | ||||
|  |  | |||
							
								
								
									
										6
									
								
								fetch.h
								
								
								
								
							
							
						
						
									
										6
									
								
								fetch.h
								
								
								
								
							|  | @ -40,6 +40,12 @@ extern int get_recover; | |||
| /* Report what we got under get_verbosely */ | ||||
| extern void pull_say(const char *, const char *); | ||||
|  | ||||
| /* Load pull targets from stdin */ | ||||
| extern int pull_targets_stdin(char ***target, const char ***write_ref); | ||||
|  | ||||
| /* Free up loaded targets */ | ||||
| extern void pull_targets_free(int targets, char **target, const char **write_ref); | ||||
|  | ||||
| /* If write_ref is set, the ref filename to write the target value to. */ | ||||
| /* If write_ref_log_details is set, additional text will appear in the ref log. */ | ||||
| extern int pull(int targets, char **target, const char **write_ref, | ||||
|  |  | |||
|  | @ -8,8 +8,9 @@ | |||
| static int use_link = 0; | ||||
| static int use_symlink = 0; | ||||
| static int use_filecopy = 1; | ||||
| static int commits_on_stdin = 0; | ||||
|  | ||||
| static char *path; /* "Remote" git repository */ | ||||
| static const char *path; /* "Remote" git repository */ | ||||
|  | ||||
| void prefetch(unsigned char *sha1) | ||||
| { | ||||
|  | @ -194,7 +195,7 @@ int fetch_ref(char *ref, unsigned char *sha1) | |||
| } | ||||
|  | ||||
| static const char local_pull_usage[] = | ||||
| "git-local-fetch [-c] [-t] [-a] [-v] [-w filename] [--recover] [-l] [-s] [-n] commit-id path"; | ||||
| "git-local-fetch [-c] [-t] [-a] [-v] [-w filename] [--recover] [-l] [-s] [-n] [--stdin] commit-id path"; | ||||
|  | ||||
| /* | ||||
|  * By default we only use file copy. | ||||
|  | @ -202,10 +203,11 @@ static const char local_pull_usage[] = | |||
|  * If -s is specified, then a symlink is attempted. | ||||
|  * If -n is _not_ specified, then a regular file-to-file copy is done. | ||||
|  */ | ||||
| int main(int argc, char **argv) | ||||
| int main(int argc, const char **argv) | ||||
| { | ||||
| 	const char *write_ref = NULL; | ||||
| 	char *commit_id; | ||||
| 	int commits; | ||||
| 	const char **write_ref = NULL; | ||||
| 	char **commit_id; | ||||
| 	int arg = 1; | ||||
|  | ||||
| 	setup_git_directory(); | ||||
|  | @ -230,20 +232,30 @@ int main(int argc, char **argv) | |||
| 		else if (argv[arg][1] == 'v') | ||||
| 			get_verbosely = 1; | ||||
| 		else if (argv[arg][1] == 'w') | ||||
| 			write_ref = argv[++arg]; | ||||
| 			write_ref = &argv[++arg]; | ||||
| 		else if (!strcmp(argv[arg], "--recover")) | ||||
| 			get_recover = 1; | ||||
| 		else if (!strcmp(argv[arg], "--stdin")) | ||||
| 			commits_on_stdin = 1; | ||||
| 		else | ||||
| 			usage(local_pull_usage); | ||||
| 		arg++; | ||||
| 	} | ||||
| 	if (argc < arg + 2) | ||||
| 	if (argc < arg + 2 - commits_on_stdin) | ||||
| 		usage(local_pull_usage); | ||||
| 	commit_id = argv[arg]; | ||||
| 	path = argv[arg + 1]; | ||||
| 	if (commits_on_stdin) { | ||||
| 		commits = pull_targets_stdin(&commit_id, &write_ref); | ||||
| 	} else { | ||||
| 		commit_id = (char **) &argv[arg++]; | ||||
| 		commits = 1; | ||||
| 	} | ||||
| 	path = argv[arg]; | ||||
|  | ||||
| 	if (pull(1, &commit_id, &write_ref, path)) | ||||
| 	if (pull(commits, commit_id, write_ref, path)) | ||||
| 		return 1; | ||||
|  | ||||
| 	if (commits_on_stdin) | ||||
| 		pull_targets_free(commits, commit_id, write_ref); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Petr Baudis
						Petr Baudis