diff options
Diffstat (limited to 'git.c')
| -rw-r--r-- | git.c | 87 | 
1 files changed, 67 insertions, 20 deletions
@@ -20,6 +20,43 @@ const char git_more_info_string[] =  static struct startup_info git_startup_info;  static int use_pager = -1; +static char *orig_cwd; +static const char *env_names[] = { +	GIT_DIR_ENVIRONMENT, +	GIT_WORK_TREE_ENVIRONMENT, +	GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, +	GIT_PREFIX_ENVIRONMENT +}; +static char *orig_env[4]; +static int saved_environment; + +static void save_env(void) +{ +	int i; +	if (saved_environment) +		return; +	saved_environment = 1; +	orig_cwd = xgetcwd(); +	for (i = 0; i < ARRAY_SIZE(env_names); i++) { +		orig_env[i] = getenv(env_names[i]); +		if (orig_env[i]) +			orig_env[i] = xstrdup(orig_env[i]); +	} +} + +static void restore_env(void) +{ +	int i; +	if (orig_cwd && chdir(orig_cwd)) +		die_errno("could not move to %s", orig_cwd); +	free(orig_cwd); +	for (i = 0; i < ARRAY_SIZE(env_names); i++) { +		if (orig_env[i]) +			setenv(env_names[i], orig_env[i], 1); +		else +			unsetenv(env_names[i]); +	} +}  static void commit_pager_choice(void) {  	switch (use_pager) { @@ -54,8 +91,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)  		/*  		 * Check remaining flags.  		 */ -		if (starts_with(cmd, "--exec-path")) { -			cmd += 11; +		if (skip_prefix(cmd, "--exec-path", &cmd)) {  			if (*cmd == '=')  				git_set_argv_exec_path(cmd + 1);  			else { @@ -78,7 +114,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)  			if (envchanged)  				*envchanged = 1;  		} else if (!strcmp(cmd, "--no-replace-objects")) { -			read_replace_refs = 0; +			check_replace_refs = 0;  			setenv(NO_REPLACE_OBJECTS_ENVIRONMENT, "1", 1);  			if (envchanged)  				*envchanged = 1; @@ -92,8 +128,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)  				*envchanged = 1;  			(*argv)++;  			(*argc)--; -		} else if (starts_with(cmd, "--git-dir=")) { -			setenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1); +		} else if (skip_prefix(cmd, "--git-dir=", &cmd)) { +			setenv(GIT_DIR_ENVIRONMENT, cmd, 1);  			if (envchanged)  				*envchanged = 1;  		} else if (!strcmp(cmd, "--namespace")) { @@ -106,8 +142,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)  				*envchanged = 1;  			(*argv)++;  			(*argc)--; -		} else if (starts_with(cmd, "--namespace=")) { -			setenv(GIT_NAMESPACE_ENVIRONMENT, cmd + 12, 1); +		} else if (skip_prefix(cmd, "--namespace=", &cmd)) { +			setenv(GIT_NAMESPACE_ENVIRONMENT, cmd, 1);  			if (envchanged)  				*envchanged = 1;  		} else if (!strcmp(cmd, "--work-tree")) { @@ -120,14 +156,15 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)  				*envchanged = 1;  			(*argv)++;  			(*argc)--; -		} else if (starts_with(cmd, "--work-tree=")) { -			setenv(GIT_WORK_TREE_ENVIRONMENT, cmd + 12, 1); +		} else if (skip_prefix(cmd, "--work-tree=", &cmd)) { +			setenv(GIT_WORK_TREE_ENVIRONMENT, cmd, 1);  			if (envchanged)  				*envchanged = 1;  		} else if (!strcmp(cmd, "--bare")) { -			static char git_dir[PATH_MAX+1]; +			char *cwd = xgetcwd();  			is_bare_repository_cfg = 1; -			setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 0); +			setenv(GIT_DIR_ENVIRONMENT, cwd, 0); +			free(cwd);  			setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1);  			if (envchanged)  				*envchanged = 1; @@ -272,6 +309,7 @@ static int handle_alias(int *argcp, const char ***argv)   * RUN_SETUP for reading from the configuration file.   */  #define NEED_WORK_TREE		(1<<3) +#define NO_SETUP		(1<<4)  struct cmd_struct {  	const char *cmd; @@ -290,7 +328,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)  	if (!help) {  		if (p->option & RUN_SETUP)  			prefix = setup_git_directory(); -		if (p->option & RUN_SETUP_GENTLY) { +		else if (p->option & RUN_SETUP_GENTLY) {  			int nongit_ok;  			prefix = setup_git_directory_gently(&nongit_ok);  		} @@ -352,7 +390,7 @@ static struct cmd_struct commands[] = {  	{ "cherry", cmd_cherry, RUN_SETUP },  	{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },  	{ "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE }, -	{ "clone", cmd_clone }, +	{ "clone", cmd_clone, NO_SETUP },  	{ "column", cmd_column, RUN_SETUP_GENTLY },  	{ "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },  	{ "commit-tree", cmd_commit_tree, RUN_SETUP }, @@ -378,8 +416,8 @@ static struct cmd_struct commands[] = {  	{ "hash-object", cmd_hash_object },  	{ "help", cmd_help },  	{ "index-pack", cmd_index_pack, RUN_SETUP_GENTLY }, -	{ "init", cmd_init_db }, -	{ "init-db", cmd_init_db }, +	{ "init", cmd_init_db, NO_SETUP }, +	{ "init-db", cmd_init_db, NO_SETUP },  	{ "log", cmd_log, RUN_SETUP },  	{ "ls-files", cmd_ls_files, RUN_SETUP },  	{ "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY }, @@ -441,6 +479,7 @@ static struct cmd_struct commands[] = {  	{ "upload-archive", cmd_upload_archive },  	{ "upload-archive--writer", cmd_upload_archive_writer },  	{ "var", cmd_var, RUN_SETUP_GENTLY }, +	{ "verify-commit", cmd_verify_commit, RUN_SETUP },  	{ "verify-pack", cmd_verify_pack },  	{ "verify-tag", cmd_verify_tag, RUN_SETUP },  	{ "version", cmd_version }, @@ -484,6 +523,10 @@ static void handle_builtin(int argc, const char **argv)  		struct cmd_struct *p = commands+i;  		if (strcmp(p->cmd, cmd))  			continue; +		if (saved_environment && (p->option & NO_SETUP)) { +			restore_env(); +			break; +		}  		exit(run_builtin(p, argc, argv));  	}  } @@ -539,7 +582,10 @@ static int run_argv(int *argcp, const char ***argv)  		 * of overriding "git log" with "git show" by having  		 * alias.log = show  		 */ -		if (done_alias || !handle_alias(argcp, argv)) +		if (done_alias) +			break; +		save_env(); +		if (!handle_alias(argcp, argv))  			break;  		done_alias = 1;  	} @@ -568,6 +614,8 @@ int main(int argc, char **av)  	git_setup_gettext(); +	trace_command_performance(argv); +  	/*  	 * "git-xxxx" is the same as "git xxxx", but we obviously:  	 * @@ -578,8 +626,7 @@ int main(int argc, char **av)  	 * So we just directly call the builtin handler, and die if  	 * that one cannot handle it.  	 */ -	if (starts_with(cmd, "git-")) { -		cmd += 4; +	if (skip_prefix(cmd, "git-", &cmd)) {  		argv[0] = cmd;  		handle_builtin(argc, argv);  		die("cannot handle %s as a builtin", cmd); @@ -590,8 +637,8 @@ int main(int argc, char **av)  	argc--;  	handle_options(&argv, &argc, NULL);  	if (argc > 0) { -		if (starts_with(argv[0], "--")) -			argv[0] += 2; +		/* translate --help and --version into commands */ +		skip_prefix(argv[0], "--", &argv[0]);  	} else {  		/* The user didn't specify a command; give them help */  		commit_pager_choice();  | 
