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 |         Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on | ||||||
|         the local end after the transfer is complete. |         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 | Author | ||||||
| ------ | ------ | ||||||
| Written by Junio C Hamano <junkio@cox.net> | Written by Junio C Hamano <junkio@cox.net> | ||||||
|  |  | ||||||
							
								
								
									
										40
									
								
								fetch.c
								
								
								
								
							
							
						
						
									
										40
									
								
								fetch.c
								
								
								
								
							|  | @ -7,6 +7,7 @@ | ||||||
| #include "tag.h" | #include "tag.h" | ||||||
| #include "blob.h" | #include "blob.h" | ||||||
| #include "refs.h" | #include "refs.h" | ||||||
|  | #include "strbuf.h" | ||||||
|  |  | ||||||
| int get_tree = 0; | int get_tree = 0; | ||||||
| int get_history = 0; | int get_history = 0; | ||||||
|  | @ -210,6 +211,45 @@ static int mark_complete(const char *path, const unsigned char *sha1) | ||||||
| 	return 0; | 	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, | int pull(int targets, char **target, const char **write_ref, | ||||||
|          const char *write_ref_log_details) |          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 */ | /* Report what we got under get_verbosely */ | ||||||
| extern void pull_say(const char *, const char *); | 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 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. */ | /* 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, | extern int pull(int targets, char **target, const char **write_ref, | ||||||
|  |  | ||||||
|  | @ -8,8 +8,9 @@ | ||||||
| static int use_link = 0; | static int use_link = 0; | ||||||
| static int use_symlink = 0; | static int use_symlink = 0; | ||||||
| static int use_filecopy = 1; | 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) | void prefetch(unsigned char *sha1) | ||||||
| { | { | ||||||
|  | @ -194,7 +195,7 @@ int fetch_ref(char *ref, unsigned char *sha1) | ||||||
| } | } | ||||||
|  |  | ||||||
| static const char local_pull_usage[] = | 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. |  * 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 -s is specified, then a symlink is attempted. | ||||||
|  * If -n is _not_ specified, then a regular file-to-file copy is done. |  * 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; | 	int commits; | ||||||
| 	char *commit_id; | 	const char **write_ref = NULL; | ||||||
|  | 	char **commit_id; | ||||||
| 	int arg = 1; | 	int arg = 1; | ||||||
|  |  | ||||||
| 	setup_git_directory(); | 	setup_git_directory(); | ||||||
|  | @ -230,20 +232,30 @@ int main(int argc, char **argv) | ||||||
| 		else if (argv[arg][1] == 'v') | 		else if (argv[arg][1] == 'v') | ||||||
| 			get_verbosely = 1; | 			get_verbosely = 1; | ||||||
| 		else if (argv[arg][1] == 'w') | 		else if (argv[arg][1] == 'w') | ||||||
| 			write_ref = argv[++arg]; | 			write_ref = &argv[++arg]; | ||||||
| 		else if (!strcmp(argv[arg], "--recover")) | 		else if (!strcmp(argv[arg], "--recover")) | ||||||
| 			get_recover = 1; | 			get_recover = 1; | ||||||
|  | 		else if (!strcmp(argv[arg], "--stdin")) | ||||||
|  | 			commits_on_stdin = 1; | ||||||
| 		else | 		else | ||||||
| 			usage(local_pull_usage); | 			usage(local_pull_usage); | ||||||
| 		arg++; | 		arg++; | ||||||
| 	} | 	} | ||||||
| 	if (argc < arg + 2) | 	if (argc < arg + 2 - commits_on_stdin) | ||||||
| 		usage(local_pull_usage); | 		usage(local_pull_usage); | ||||||
| 	commit_id = argv[arg]; | 	if (commits_on_stdin) { | ||||||
| 	path = argv[arg + 1]; | 		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; | 		return 1; | ||||||
|  |  | ||||||
|  | 	if (commits_on_stdin) | ||||||
|  | 		pull_targets_free(commits, commit_id, write_ref); | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Petr Baudis
						Petr Baudis