add: convert to use parse_pathspec
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									931eab64ad
								
							
						
					
					
						commit
						5a76aff1a6
					
				
							
								
								
									
										103
									
								
								builtin/add.c
								
								
								
								
							
							
						
						
									
										103
									
								
								builtin/add.c
								
								
								
								
							|  | @ -226,21 +226,6 @@ static char *prune_directory(struct dir_struct *dir, const char **pathspec, | |||
| 	return seen; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Checks the index to see whether any path in pathspec refers to | ||||
|  * something inside a submodule.  If so, dies with an error message. | ||||
|  */ | ||||
| static void treat_gitlinks(const char **pathspec) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	if (!pathspec || !*pathspec) | ||||
| 		return; | ||||
|  | ||||
| 	for (i = 0; pathspec[i]; i++) | ||||
| 		pathspec[i] = check_path_for_gitlink(pathspec[i]); | ||||
| } | ||||
|  | ||||
| static void refresh(int verbose, const char **pathspec) | ||||
| { | ||||
| 	char *seen; | ||||
|  | @ -258,25 +243,6 @@ static void refresh(int verbose, const char **pathspec) | |||
|         free(seen); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Normalizes argv relative to prefix, via get_pathspec(), and then | ||||
|  * runs die_if_path_beyond_symlink() on each path in the normalized | ||||
|  * list. | ||||
|  */ | ||||
| static const char **validate_pathspec(const char **argv, const char *prefix) | ||||
| { | ||||
| 	const char **pathspec = get_pathspec(prefix, argv); | ||||
|  | ||||
| 	if (pathspec) { | ||||
| 		const char **p; | ||||
| 		for (p = pathspec; *p; p++) { | ||||
| 			die_if_path_beyond_symlink(*p, prefix); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return pathspec; | ||||
| } | ||||
|  | ||||
| int run_add_interactive(const char *revision, const char *patch_mode, | ||||
| 			const char **pathspec) | ||||
| { | ||||
|  | @ -308,17 +274,23 @@ int run_add_interactive(const char *revision, const char *patch_mode, | |||
|  | ||||
| int interactive_add(int argc, const char **argv, const char *prefix, int patch) | ||||
| { | ||||
| 	const char **pathspec = NULL; | ||||
| 	struct pathspec pathspec; | ||||
|  | ||||
| 	if (argc) { | ||||
| 		pathspec = validate_pathspec(argv, prefix); | ||||
| 		if (!pathspec) | ||||
| 			return -1; | ||||
| 	} | ||||
| 	/* | ||||
| 	 * git-add--interactive itself does not parse pathspec. It | ||||
| 	 * simply passes the pathspec to other builtin commands. Let's | ||||
| 	 * hope all of them support all magic, or we'll need to limit | ||||
| 	 * the magic here. There is still a problem with prefix. But | ||||
| 	 * that'll be worked on later on. | ||||
| 	 */ | ||||
| 	parse_pathspec(&pathspec, PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP, | ||||
| 		       PATHSPEC_PREFER_FULL | | ||||
| 		       PATHSPEC_SYMLINK_LEADING_PATH, | ||||
| 		       prefix, argv); | ||||
|  | ||||
| 	return run_add_interactive(NULL, | ||||
| 				   patch ? "--patch" : NULL, | ||||
| 				   pathspec); | ||||
| 				   pathspec.raw); | ||||
| } | ||||
|  | ||||
| static int edit_patch(int argc, const char **argv, const char *prefix) | ||||
|  | @ -445,7 +417,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) | |||
| { | ||||
| 	int exit_status = 0; | ||||
| 	int newfd; | ||||
| 	const char **pathspec; | ||||
| 	struct pathspec pathspec; | ||||
| 	struct dir_struct dir; | ||||
| 	int flags; | ||||
| 	int add_new_files; | ||||
|  | @ -526,11 +498,19 @@ int cmd_add(int argc, const char **argv, const char *prefix) | |||
| 		fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n")); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	pathspec = validate_pathspec(argv, prefix); | ||||
|  | ||||
| 	if (read_cache() < 0) | ||||
| 		die(_("index file corrupt")); | ||||
| 	treat_gitlinks(pathspec); | ||||
|  | ||||
| 	/* | ||||
| 	 * Check the "pathspec '%s' did not match any files" block | ||||
| 	 * below before enabling new magic. | ||||
| 	 */ | ||||
| 	parse_pathspec(&pathspec, 0, | ||||
| 		       PATHSPEC_PREFER_FULL | | ||||
| 		       PATHSPEC_SYMLINK_LEADING_PATH | | ||||
| 		       PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE, | ||||
| 		       prefix, argv); | ||||
|  | ||||
| 	if (add_new_files) { | ||||
| 		int baselen; | ||||
|  | @ -543,34 +523,40 @@ int cmd_add(int argc, const char **argv, const char *prefix) | |||
| 		} | ||||
|  | ||||
| 		/* This picks up the paths that are not tracked */ | ||||
| 		baselen = fill_directory(&dir, implicit_dot ? NULL : pathspec); | ||||
| 		if (pathspec) | ||||
| 			seen = prune_directory(&dir, pathspec, baselen, | ||||
| 		baselen = fill_directory(&dir, implicit_dot ? NULL : pathspec.raw); | ||||
| 		if (pathspec.nr) | ||||
| 			seen = prune_directory(&dir, pathspec.raw, baselen, | ||||
| 					implicit_dot ? WARN_IMPLICIT_DOT : 0); | ||||
| 	} | ||||
|  | ||||
| 	if (refresh_only) { | ||||
| 		refresh(verbose, pathspec); | ||||
| 		refresh(verbose, pathspec.raw); | ||||
| 		goto finish; | ||||
| 	} | ||||
| 	if (implicit_dot && prefix) | ||||
| 		refresh_cache(REFRESH_QUIET); | ||||
|  | ||||
| 	if (pathspec) { | ||||
| 	if (pathspec.nr) { | ||||
| 		int i; | ||||
|  | ||||
| 		if (!seen) | ||||
| 			seen = find_pathspecs_matching_against_index(pathspec); | ||||
| 		for (i = 0; pathspec[i]; i++) { | ||||
| 			if (!seen[i] && pathspec[i][0] | ||||
| 			    && !file_exists(pathspec[i])) { | ||||
| 			seen = find_pathspecs_matching_against_index(pathspec.raw); | ||||
|  | ||||
| 		/* | ||||
| 		 * file_exists() assumes exact match | ||||
| 		 */ | ||||
| 		GUARD_PATHSPEC(&pathspec, PATHSPEC_FROMTOP); | ||||
|  | ||||
| 		for (i = 0; pathspec.raw[i]; i++) { | ||||
| 			if (!seen[i] && pathspec.raw[i][0] | ||||
| 			    && !file_exists(pathspec.raw[i])) { | ||||
| 				if (ignore_missing) { | ||||
| 					int dtype = DT_UNKNOWN; | ||||
| 					if (is_excluded(&dir, pathspec[i], &dtype)) | ||||
| 						dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i])); | ||||
| 					if (is_excluded(&dir, pathspec.raw[i], &dtype)) | ||||
| 						dir_add_ignored(&dir, pathspec.raw[i], strlen(pathspec.raw[i])); | ||||
| 				} else | ||||
| 					die(_("pathspec '%s' did not match any files"), | ||||
| 					    pathspec[i]); | ||||
| 					    pathspec.raw[i]); | ||||
| 			} | ||||
| 		} | ||||
| 		free(seen); | ||||
|  | @ -586,10 +572,11 @@ int cmd_add(int argc, const char **argv, const char *prefix) | |||
| 		 */ | ||||
| 		update_data.implicit_dot = prefix; | ||||
| 		update_data.implicit_dot_len = strlen(prefix); | ||||
| 		pathspec = NULL; | ||||
| 		free_pathspec(&pathspec); | ||||
| 		memset(&pathspec, 0, sizeof(pathspec)); | ||||
| 	} | ||||
| 	update_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT; | ||||
| 	update_files_in_cache(prefix, pathspec, &update_data); | ||||
| 	update_files_in_cache(prefix, pathspec.raw, &update_data); | ||||
|  | ||||
| 	exit_status |= !!update_data.add_errors; | ||||
| 	if (add_new_files) | ||||
|  |  | |||
							
								
								
									
										43
									
								
								pathspec.c
								
								
								
								
							
							
						
						
									
										43
									
								
								pathspec.c
								
								
								
								
							|  | @ -57,49 +57,6 @@ char *find_pathspecs_matching_against_index(const char **pathspec) | |||
| 	return seen; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Check the index to see whether path refers to a submodule, or | ||||
|  * something inside a submodule.  If the former, returns the path with | ||||
|  * any trailing slash stripped.  If the latter, dies with an error | ||||
|  * message. | ||||
|  */ | ||||
| const char *check_path_for_gitlink(const char *path) | ||||
| { | ||||
| 	int i, path_len = strlen(path); | ||||
| 	for (i = 0; i < active_nr; i++) { | ||||
| 		struct cache_entry *ce = active_cache[i]; | ||||
| 		if (S_ISGITLINK(ce->ce_mode)) { | ||||
| 			int ce_len = ce_namelen(ce); | ||||
| 			if (path_len <= ce_len || path[ce_len] != '/' || | ||||
| 			    memcmp(ce->name, path, ce_len)) | ||||
| 				/* path does not refer to this | ||||
| 				 * submodule or anything inside it */ | ||||
| 				continue; | ||||
| 			if (path_len == ce_len + 1) { | ||||
| 				/* path refers to submodule; | ||||
| 				 * strip trailing slash */ | ||||
| 				return xstrndup(ce->name, ce_len); | ||||
| 			} else { | ||||
| 				die (_("Path '%s' is in submodule '%.*s'"), | ||||
| 				     path, ce_len, ce->name); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return path; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Dies if the given path refers to a file inside a symlinked | ||||
|  * directory in the index. | ||||
|  */ | ||||
| void die_if_path_beyond_symlink(const char *path, const char *prefix) | ||||
| { | ||||
| 	if (has_symlink_leading_path(path, strlen(path))) { | ||||
| 		int len = prefix ? strlen(prefix) : 0; | ||||
| 		die(_("'%s' is beyond a symbolic link"), path + len); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Magic pathspec | ||||
|  * | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Nguyễn Thái Ngọc Duy
						Nguyễn Thái Ngọc Duy