diff options
Diffstat (limited to 'git.c')
| -rw-r--r-- | git.c | 95 | 
1 files changed, 63 insertions, 32 deletions
@@ -28,6 +28,7 @@  #define NEED_WORK_TREE		(1<<3)  #define DELAY_PAGER_CONFIG	(1<<4)  #define NO_PARSEOPT		(1<<5) /* parse-options is not used */ +#define DEPRECATED		(1<<6)  struct cmd_struct {  	const char *cmd; @@ -51,7 +52,9 @@ const char git_more_info_string[] =  static int use_pager = -1; -static void list_builtins(struct string_list *list, unsigned int exclude_option); +static void list_builtins(struct string_list *list, +			  unsigned int include_option, +			  unsigned int exclude_option);  static void exclude_helpers_from_list(struct string_list *list)  { @@ -88,7 +91,7 @@ static int list_cmds(const char *spec)  		int len = sep - spec;  		if (match_token(spec, len, "builtins")) -			list_builtins(&list, 0); +			list_builtins(&list, 0, 0);  		else if (match_token(spec, len, "main"))  			list_all_main_cmds(&list);  		else if (match_token(spec, len, "others")) @@ -99,6 +102,8 @@ static int list_cmds(const char *spec)  			list_aliases(&list);  		else if (match_token(spec, len, "config"))  			list_cmds_by_config(&list); +		else if (match_token(spec, len, "deprecated")) +			list_builtins(&list, DEPRECATED, 0);  		else if (len > 5 && !strncmp(spec, "list-", 5)) {  			struct strbuf sb = STRBUF_INIT; @@ -322,7 +327,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)  			if (!strcmp(cmd, "parseopt")) {  				struct string_list list = STRING_LIST_INIT_DUP; -				list_builtins(&list, NO_PARSEOPT); +				list_builtins(&list, 0, NO_PARSEOPT);  				for (size_t i = 0; i < list.nr; i++)  					printf("%s ", list.items[i].string);  				string_list_clear(&list, 0); @@ -360,7 +365,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)  	return (*argv) - orig_argv;  } -static int handle_alias(struct strvec *args) +static int handle_alias(struct strvec *args, struct string_list *expanded_aliases)  {  	int envchanged = 0, ret = 0, saved_errno = errno;  	int count, option_count; @@ -371,6 +376,8 @@ static int handle_alias(struct strvec *args)  	alias_command = args->v[0];  	alias_string = alias_lookup(alias_command);  	if (alias_string) { +		struct string_list_item *seen; +  		if (args->nr == 2 && !strcmp(args->v[1], "-h"))  			fprintf_ln(stderr, _("'%s' is aliased to '%s'"),  				   alias_command, alias_string); @@ -418,6 +425,25 @@ static int handle_alias(struct strvec *args)  		if (!strcmp(alias_command, new_argv[0]))  			die(_("recursive alias: %s"), alias_command); +		string_list_append(expanded_aliases, alias_command); +		seen = unsorted_string_list_lookup(expanded_aliases, +						   new_argv[0]); + +		if (seen) { +			struct strbuf sb = STRBUF_INIT; +			for (size_t i = 0; i < expanded_aliases->nr; i++) { +				struct string_list_item *item = &expanded_aliases->items[i]; + +				strbuf_addf(&sb, "\n  %s", item->string); +				if (item == seen) +					strbuf_addstr(&sb, " <=="); +				else if (i == expanded_aliases->nr - 1) +					strbuf_addstr(&sb, " ==>"); +			} +			die(_("alias loop detected: expansion of '%s' does" +			      " not terminate:%s"), expanded_aliases->items[0].string, sb.buf); +		} +  		trace_argv_printf(new_argv,  				  "trace: alias expansion: %s =>",  				  alias_command); @@ -445,7 +471,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct  	const char *prefix;  	int run_setup = (p->option & (RUN_SETUP | RUN_SETUP_GENTLY)); -	help = argc == 2 && !strcmp(argv[1], "-h"); +	help = argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help-all"));  	if (help && (run_setup & RUN_SETUP))  		/* demote to GENTLY to allow 'git cmd -h' outside repo */  		run_setup = RUN_SETUP_GENTLY; @@ -565,6 +591,7 @@ static struct cmd_struct commands[] = {  	{ "init", cmd_init_db },  	{ "init-db", cmd_init_db },  	{ "interpret-trailers", cmd_interpret_trailers, RUN_SETUP_GENTLY }, +	{ "last-modified", cmd_last_modified, RUN_SETUP },  	{ "log", cmd_log, RUN_SETUP },  	{ "ls-files", cmd_ls_files, RUN_SETUP },  	{ "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY }, @@ -590,7 +617,7 @@ static struct cmd_struct commands[] = {  	{ "notes", cmd_notes, RUN_SETUP },  	{ "pack-objects", cmd_pack_objects, RUN_SETUP },  #ifndef WITH_BREAKING_CHANGES -	{ "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT }, +	{ "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT | DEPRECATED },  #endif  	{ "pack-refs", cmd_pack_refs, RUN_SETUP },  	{ "patch-id", cmd_patch_id, RUN_SETUP_GENTLY | NO_PARSEOPT }, @@ -611,6 +638,7 @@ static struct cmd_struct commands[] = {  	{ "repack", cmd_repack, RUN_SETUP },  	{ "replace", cmd_replace, RUN_SETUP },  	{ "replay", cmd_replay, RUN_SETUP }, +	{ "repo", cmd_repo, RUN_SETUP },  	{ "rerere", cmd_rerere, RUN_SETUP },  	{ "reset", cmd_reset, RUN_SETUP },  	{ "restore", cmd_restore, RUN_SETUP | NEED_WORK_TREE }, @@ -647,7 +675,7 @@ static struct cmd_struct commands[] = {  	{ "verify-tag", cmd_verify_tag, RUN_SETUP },  	{ "version", cmd_version },  #ifndef WITH_BREAKING_CHANGES -	{ "whatchanged", cmd_whatchanged, RUN_SETUP }, +	{ "whatchanged", cmd_whatchanged, RUN_SETUP | DEPRECATED },  #endif  	{ "worktree", cmd_worktree, RUN_SETUP },  	{ "write-tree", cmd_write_tree, RUN_SETUP }, @@ -668,11 +696,16 @@ int is_builtin(const char *s)  	return !!get_builtin(s);  } -static void list_builtins(struct string_list *out, unsigned int exclude_option) +static void list_builtins(struct string_list *out, +			  unsigned int include_option, +			  unsigned int exclude_option)  { +	if (include_option && exclude_option) +		BUG("'include_option' and 'exclude_option' are mutually exclusive");  	for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { -		if (exclude_option && -		    (commands[i].option & exclude_option)) +		if (include_option && !(commands[i].option & include_option)) +			continue; +		if (exclude_option && (commands[i].option & exclude_option))  			continue;  		string_list_append(out, commands[i].cmd);  	} @@ -793,14 +826,30 @@ static void execv_dashed_external(const char **argv)  		exit(128);  } +static int is_deprecated_command(const char *cmd) +{ +	struct cmd_struct *builtin = get_builtin(cmd); +	return builtin && (builtin->option & DEPRECATED); +} +  static int run_argv(struct strvec *args)  {  	int done_alias = 0; -	struct string_list cmd_list = STRING_LIST_INIT_DUP; -	struct string_list_item *seen; +	struct string_list expanded_aliases = STRING_LIST_INIT_DUP;  	while (1) {  		/* +		 * Allow deprecated commands to be overridden by aliases. This +		 * creates a seamless path forward for people who want to keep +		 * using the name after it is gone, but want to skip the +		 * deprecation complaint in the meantime. +		 */ +		if (is_deprecated_command(args->v[0]) && +		    handle_alias(args, &expanded_aliases)) { +			done_alias = 1; +			continue; +		} +		/*  		 * If we tried alias and futzed with our environment,  		 * it no longer is safe to invoke builtins directly in  		 * general.  We have to spawn them as dashed externals. @@ -849,35 +898,17 @@ static int run_argv(struct strvec *args)  		/* .. then try the external ones */  		execv_dashed_external(args->v); -		seen = unsorted_string_list_lookup(&cmd_list, args->v[0]); -		if (seen) { -			struct strbuf sb = STRBUF_INIT; -			for (size_t i = 0; i < cmd_list.nr; i++) { -				struct string_list_item *item = &cmd_list.items[i]; - -				strbuf_addf(&sb, "\n  %s", item->string); -				if (item == seen) -					strbuf_addstr(&sb, " <=="); -				else if (i == cmd_list.nr - 1) -					strbuf_addstr(&sb, " ==>"); -			} -			die(_("alias loop detected: expansion of '%s' does" -			      " not terminate:%s"), cmd_list.items[0].string, sb.buf); -		} - -		string_list_append(&cmd_list, args->v[0]); -  		/*  		 * It could be an alias -- this works around the insanity  		 * of overriding "git log" with "git show" by having  		 * alias.log = show  		 */ -		if (!handle_alias(args)) +		if (!handle_alias(args, &expanded_aliases))  			break;  		done_alias = 1;  	} -	string_list_clear(&cmd_list, 0); +	string_list_clear(&expanded_aliases, 0);  	return done_alias;  }  | 
