Move try_merge_command and checkout_fast_forward to libgit.a
These functions are called in sequencer.c, which is part of libgit.a. This makes libgit.a potentially require builtin/merge.c for external git commands. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Jeff King <peff@peff.net>maint
							parent
							
								
									2cfceefaca
								
							
						
					
					
						commit
						db699a8a1f
					
				
							
								
								
									
										1
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										1
									
								
								Makefile
								
								
								
								
							|  | @ -763,6 +763,7 @@ LIB_OBJS += lockfile.o | |||
| LIB_OBJS += log-tree.o | ||||
| LIB_OBJS += mailmap.o | ||||
| LIB_OBJS += match-trees.o | ||||
| LIB_OBJS += merge.o | ||||
| LIB_OBJS += merge-file.o | ||||
| LIB_OBJS += merge-recursive.o | ||||
| LIB_OBJS += mergesort.o | ||||
|  |  | |||
							
								
								
									
										106
									
								
								builtin/merge.c
								
								
								
								
							
							
						
						
									
										106
									
								
								builtin/merge.c
								
								
								
								
							|  | @ -628,59 +628,6 @@ static void write_tree_trivial(unsigned char *sha1) | |||
| 		die(_("git write-tree failed to write a tree")); | ||||
| } | ||||
|  | ||||
| static const char *merge_argument(struct commit *commit) | ||||
| { | ||||
| 	if (commit) | ||||
| 		return sha1_to_hex(commit->object.sha1); | ||||
| 	else | ||||
| 		return EMPTY_TREE_SHA1_HEX; | ||||
| } | ||||
|  | ||||
| int try_merge_command(const char *strategy, size_t xopts_nr, | ||||
| 		      const char **xopts, struct commit_list *common, | ||||
| 		      const char *head_arg, struct commit_list *remotes) | ||||
| { | ||||
| 	const char **args; | ||||
| 	int i = 0, x = 0, ret; | ||||
| 	struct commit_list *j; | ||||
| 	struct strbuf buf = STRBUF_INIT; | ||||
|  | ||||
| 	args = xmalloc((4 + xopts_nr + commit_list_count(common) + | ||||
| 			commit_list_count(remotes)) * sizeof(char *)); | ||||
| 	strbuf_addf(&buf, "merge-%s", strategy); | ||||
| 	args[i++] = buf.buf; | ||||
| 	for (x = 0; x < xopts_nr; x++) { | ||||
| 		char *s = xmalloc(strlen(xopts[x])+2+1); | ||||
| 		strcpy(s, "--"); | ||||
| 		strcpy(s+2, xopts[x]); | ||||
| 		args[i++] = s; | ||||
| 	} | ||||
| 	for (j = common; j; j = j->next) | ||||
| 		args[i++] = xstrdup(merge_argument(j->item)); | ||||
| 	args[i++] = "--"; | ||||
| 	args[i++] = head_arg; | ||||
| 	for (j = remotes; j; j = j->next) | ||||
| 		args[i++] = xstrdup(merge_argument(j->item)); | ||||
| 	args[i] = NULL; | ||||
| 	ret = run_command_v_opt(args, RUN_GIT_CMD); | ||||
| 	strbuf_release(&buf); | ||||
| 	i = 1; | ||||
| 	for (x = 0; x < xopts_nr; x++) | ||||
| 		free((void *)args[i++]); | ||||
| 	for (j = common; j; j = j->next) | ||||
| 		free((void *)args[i++]); | ||||
| 	i += 2; | ||||
| 	for (j = remotes; j; j = j->next) | ||||
| 		free((void *)args[i++]); | ||||
| 	free(args); | ||||
| 	discard_cache(); | ||||
| 	if (read_cache() < 0) | ||||
| 		die(_("failed to read the cache")); | ||||
| 	resolve_undo_clear(); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static int try_merge_strategy(const char *strategy, struct commit_list *common, | ||||
| 			      struct commit_list *remoteheads, | ||||
| 			      struct commit *head, const char *head_arg) | ||||
|  | @ -762,56 +709,6 @@ static int count_unmerged_entries(void) | |||
| 	return ret; | ||||
| } | ||||
|  | ||||
| int checkout_fast_forward(const unsigned char *head, const unsigned char *remote) | ||||
| { | ||||
| 	struct tree *trees[MAX_UNPACK_TREES]; | ||||
| 	struct unpack_trees_options opts; | ||||
| 	struct tree_desc t[MAX_UNPACK_TREES]; | ||||
| 	int i, fd, nr_trees = 0; | ||||
| 	struct dir_struct dir; | ||||
| 	struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); | ||||
|  | ||||
| 	refresh_cache(REFRESH_QUIET); | ||||
|  | ||||
| 	fd = hold_locked_index(lock_file, 1); | ||||
|  | ||||
| 	memset(&trees, 0, sizeof(trees)); | ||||
| 	memset(&opts, 0, sizeof(opts)); | ||||
| 	memset(&t, 0, sizeof(t)); | ||||
| 	if (overwrite_ignore) { | ||||
| 		memset(&dir, 0, sizeof(dir)); | ||||
| 		dir.flags |= DIR_SHOW_IGNORED; | ||||
| 		setup_standard_excludes(&dir); | ||||
| 		opts.dir = &dir; | ||||
| 	} | ||||
|  | ||||
| 	opts.head_idx = 1; | ||||
| 	opts.src_index = &the_index; | ||||
| 	opts.dst_index = &the_index; | ||||
| 	opts.update = 1; | ||||
| 	opts.verbose_update = 1; | ||||
| 	opts.merge = 1; | ||||
| 	opts.fn = twoway_merge; | ||||
| 	setup_unpack_trees_porcelain(&opts, "merge"); | ||||
|  | ||||
| 	trees[nr_trees] = parse_tree_indirect(head); | ||||
| 	if (!trees[nr_trees++]) | ||||
| 		return -1; | ||||
| 	trees[nr_trees] = parse_tree_indirect(remote); | ||||
| 	if (!trees[nr_trees++]) | ||||
| 		return -1; | ||||
| 	for (i = 0; i < nr_trees; i++) { | ||||
| 		parse_tree(trees[i]); | ||||
| 		init_tree_desc(t+i, trees[i]->buffer, trees[i]->size); | ||||
| 	} | ||||
| 	if (unpack_trees(nr_trees, t, &opts)) | ||||
| 		return -1; | ||||
| 	if (write_cache(fd, active_cache, active_nr) || | ||||
| 		commit_locked_index(lock_file)) | ||||
| 		die(_("unable to write new index file")); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void split_merge_strategies(const char *string, struct strategy **list, | ||||
| 				   int *nr, int *alloc) | ||||
| { | ||||
|  | @ -1424,7 +1321,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix) | |||
| 		} | ||||
|  | ||||
| 		if (checkout_fast_forward(head_commit->object.sha1, | ||||
| 					  commit->object.sha1)) { | ||||
| 					  commit->object.sha1, | ||||
| 					  overwrite_ignore)) { | ||||
| 			ret = 1; | ||||
| 			goto done; | ||||
| 		} | ||||
|  |  | |||
							
								
								
									
										11
									
								
								cache.h
								
								
								
								
							
							
						
						
									
										11
									
								
								cache.h
								
								
								
								
							|  | @ -1265,8 +1265,15 @@ struct startup_info { | |||
| }; | ||||
| extern struct startup_info *startup_info; | ||||
|  | ||||
| /* builtin/merge.c */ | ||||
| int checkout_fast_forward(const unsigned char *from, const unsigned char *to); | ||||
| /* merge.c */ | ||||
| struct commit_list; | ||||
| int try_merge_command(const char *strategy, size_t xopts_nr, | ||||
| 		const char **xopts, struct commit_list *common, | ||||
| 		const char *head_arg, struct commit_list *remotes); | ||||
| int checkout_fast_forward(const unsigned char *from, | ||||
| 			  const unsigned char *to, | ||||
| 			  int overwrite_ignore); | ||||
|  | ||||
|  | ||||
| int sane_execvp(const char *file, char *const argv[]); | ||||
|  | ||||
|  |  | |||
|  | @ -59,9 +59,4 @@ struct tree *write_tree_from_memory(struct merge_options *o); | |||
|  | ||||
| int parse_merge_opt(struct merge_options *out, const char *s); | ||||
|  | ||||
| /* builtin/merge.c */ | ||||
| int try_merge_command(const char *strategy, size_t xopts_nr, | ||||
| 		const char **xopts, struct commit_list *common, | ||||
| 		const char *head_arg, struct commit_list *remotes); | ||||
|  | ||||
| #endif | ||||
|  |  | |||
|  | @ -0,0 +1,112 @@ | |||
| #include "cache.h" | ||||
| #include "commit.h" | ||||
| #include "run-command.h" | ||||
| #include "resolve-undo.h" | ||||
| #include "tree-walk.h" | ||||
| #include "unpack-trees.h" | ||||
| #include "dir.h" | ||||
|  | ||||
| static const char *merge_argument(struct commit *commit) | ||||
| { | ||||
| 	if (commit) | ||||
| 		return sha1_to_hex(commit->object.sha1); | ||||
| 	else | ||||
| 		return EMPTY_TREE_SHA1_HEX; | ||||
| } | ||||
|  | ||||
| int try_merge_command(const char *strategy, size_t xopts_nr, | ||||
| 		      const char **xopts, struct commit_list *common, | ||||
| 		      const char *head_arg, struct commit_list *remotes) | ||||
| { | ||||
| 	const char **args; | ||||
| 	int i = 0, x = 0, ret; | ||||
| 	struct commit_list *j; | ||||
| 	struct strbuf buf = STRBUF_INIT; | ||||
|  | ||||
| 	args = xmalloc((4 + xopts_nr + commit_list_count(common) + | ||||
| 			commit_list_count(remotes)) * sizeof(char *)); | ||||
| 	strbuf_addf(&buf, "merge-%s", strategy); | ||||
| 	args[i++] = buf.buf; | ||||
| 	for (x = 0; x < xopts_nr; x++) { | ||||
| 		char *s = xmalloc(strlen(xopts[x])+2+1); | ||||
| 		strcpy(s, "--"); | ||||
| 		strcpy(s+2, xopts[x]); | ||||
| 		args[i++] = s; | ||||
| 	} | ||||
| 	for (j = common; j; j = j->next) | ||||
| 		args[i++] = xstrdup(merge_argument(j->item)); | ||||
| 	args[i++] = "--"; | ||||
| 	args[i++] = head_arg; | ||||
| 	for (j = remotes; j; j = j->next) | ||||
| 		args[i++] = xstrdup(merge_argument(j->item)); | ||||
| 	args[i] = NULL; | ||||
| 	ret = run_command_v_opt(args, RUN_GIT_CMD); | ||||
| 	strbuf_release(&buf); | ||||
| 	i = 1; | ||||
| 	for (x = 0; x < xopts_nr; x++) | ||||
| 		free((void *)args[i++]); | ||||
| 	for (j = common; j; j = j->next) | ||||
| 		free((void *)args[i++]); | ||||
| 	i += 2; | ||||
| 	for (j = remotes; j; j = j->next) | ||||
| 		free((void *)args[i++]); | ||||
| 	free(args); | ||||
| 	discard_cache(); | ||||
| 	if (read_cache() < 0) | ||||
| 		die(_("failed to read the cache")); | ||||
| 	resolve_undo_clear(); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| int checkout_fast_forward(const unsigned char *head, | ||||
| 			  const unsigned char *remote, | ||||
| 			  int overwrite_ignore) | ||||
| { | ||||
| 	struct tree *trees[MAX_UNPACK_TREES]; | ||||
| 	struct unpack_trees_options opts; | ||||
| 	struct tree_desc t[MAX_UNPACK_TREES]; | ||||
| 	int i, fd, nr_trees = 0; | ||||
| 	struct dir_struct dir; | ||||
| 	struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); | ||||
|  | ||||
| 	refresh_cache(REFRESH_QUIET); | ||||
|  | ||||
| 	fd = hold_locked_index(lock_file, 1); | ||||
|  | ||||
| 	memset(&trees, 0, sizeof(trees)); | ||||
| 	memset(&opts, 0, sizeof(opts)); | ||||
| 	memset(&t, 0, sizeof(t)); | ||||
| 	if (overwrite_ignore) { | ||||
| 		memset(&dir, 0, sizeof(dir)); | ||||
| 		dir.flags |= DIR_SHOW_IGNORED; | ||||
| 		setup_standard_excludes(&dir); | ||||
| 		opts.dir = &dir; | ||||
| 	} | ||||
|  | ||||
| 	opts.head_idx = 1; | ||||
| 	opts.src_index = &the_index; | ||||
| 	opts.dst_index = &the_index; | ||||
| 	opts.update = 1; | ||||
| 	opts.verbose_update = 1; | ||||
| 	opts.merge = 1; | ||||
| 	opts.fn = twoway_merge; | ||||
| 	setup_unpack_trees_porcelain(&opts, "merge"); | ||||
|  | ||||
| 	trees[nr_trees] = parse_tree_indirect(head); | ||||
| 	if (!trees[nr_trees++]) | ||||
| 		return -1; | ||||
| 	trees[nr_trees] = parse_tree_indirect(remote); | ||||
| 	if (!trees[nr_trees++]) | ||||
| 		return -1; | ||||
| 	for (i = 0; i < nr_trees; i++) { | ||||
| 		parse_tree(trees[i]); | ||||
| 		init_tree_desc(t+i, trees[i]->buffer, trees[i]->size); | ||||
| 	} | ||||
| 	if (unpack_trees(nr_trees, t, &opts)) | ||||
| 		return -1; | ||||
| 	if (write_cache(fd, active_cache, active_nr) || | ||||
| 		commit_locked_index(lock_file)) | ||||
| 		die(_("unable to write new index file")); | ||||
| 	return 0; | ||||
| } | ||||
|  | @ -191,7 +191,7 @@ static int fast_forward_to(const unsigned char *to, const unsigned char *from) | |||
| 	struct ref_lock *ref_lock; | ||||
|  | ||||
| 	read_cache(); | ||||
| 	if (checkout_fast_forward(from, to)) | ||||
| 	if (checkout_fast_forward(from, to, 1)) | ||||
| 		exit(1); /* the callee should have complained already */ | ||||
| 	ref_lock = lock_any_ref_for_update("HEAD", from, 0); | ||||
| 	return write_ref_sha1(ref_lock, to, "cherry-pick"); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Nguyễn Thái Ngọc Duy
						Nguyễn Thái Ngọc Duy