[PATCH 2/6] update-index: convert to using gitopt

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is an example how how to override gitopt_non_option_cb, as
well as disabling permuting of options to the front of the
command list.  This way, commands like:

	git-update-index --add new_file --remove old_file

will continue to work.

Signed-off-by: Eric Wong <normalperson@xxxxxxxx>

---

 update-index.c |  261 ++++++++++++++++++++++++++++----------------------------
 1 files changed, 130 insertions(+), 131 deletions(-)

50f33d232367e8d7a46bd014f5a5da4d0ad370b3
diff --git a/update-index.c b/update-index.c
index 00cde70..6205f85 100644
--- a/update-index.c
+++ b/update-index.c
@@ -7,6 +7,7 @@ #include "cache.h"
 #include "strbuf.h"
 #include "quote.h"
 #include "tree-walk.h"
+#include "gitopt.h"
 
 /*
  * Default to not allowing changes to the list of files. The
@@ -25,6 +26,14 @@ static int info_only;
 static int force_remove;
 static int verbose;
 static int mark_valid_only = 0;
+static int prefix_length = 0;
+static int line_termination = '\n';
+static const char *prefix = NULL;
+static char set_executable_bit = 0;
+static int read_from_stdin = 0;
+static int newfd = 0;
+static int has_errors = 0;
+
 #define MARK_VALID 1
 #define UNMARK_VALID 2
 
@@ -189,10 +198,9 @@ static struct cache_entry *refresh_entry
 	return updated;
 }
 
-static int refresh_cache(int really)
+static void refresh_cache(int really)
 {
 	int i;
-	int has_errors = 0;
 
 	for (i = 0; i < active_nr; i++) {
 		struct cache_entry *ce, *new;
@@ -205,7 +213,7 @@ static int refresh_cache(int really)
 			if (allow_unmerged)
 				continue;
 			printf("%s: needs merge\n", ce->name);
-			has_errors = 1;
+			has_errors |= 1;
 			continue;
 		}
 
@@ -225,7 +233,7 @@ static int refresh_cache(int really)
 			if (quiet)
 				continue;
 			printf("%s: needs update\n", ce->name);
-			has_errors = 1;
+			has_errors |= 1;
 			continue;
 		}
 		active_cache_changed = 1;
@@ -234,7 +242,7 @@ static int refresh_cache(int really)
 		 * from mmap(). */
 		active_cache[i] = new;
 	}
-	return has_errors;
+	return;
 }
 
 /*
@@ -600,15 +608,123 @@ static int do_unresolve(int ac, const ch
 	return err;
 }
 
+static void write_cache_if_changed ()
+{
+	if (active_cache_changed) {
+		if (write_cache(newfd, active_cache, active_nr) ||
+		    commit_index_file(&cache_file))
+			die("Unable to write new cachefile");
+	}
+}
+
+gitopt_eat(opt_q, quiet = 1;)
+gitopt_eat(opt_add, allow_add = 1;)
+gitopt_eat(opt_replace, allow_replace = 1;)
+gitopt_eat(opt_remove, allow_remove = 1;)
+gitopt_eat(opt_unmerged, allow_unmerged = 1;)
+gitopt_eat(opt_refresh, refresh_cache(0);)
+gitopt_eat(opt_really_refresh, refresh_cache(1);)
+
+static struct exec_args *opt_cacheinfo(const struct opt_spec *s,
+			const int argc, const char **argv, int *argc_pos)
+{
+	struct exec_args *ea = new_exec_args(4);
+	unsigned char sha1[20];
+	unsigned int mode;
+
+	ea->argc = 1;
+	ea->argv[0] = argv[*argc_pos];
+	while (*argc_pos < (argc-1) && ea->argc < 4)
+		ea->argv[ea->argc++] = argv[++(*argc_pos)];
+	if (ea->argc != 4)
+		die("git-update-index: --cacheinfo <mode> <sha1> <path>");
+
+	if ((sscanf(ea->argv[1], "%o", &mode) != 1) ||
+				get_sha1_hex(ea->argv[2], sha1) ||
+				add_cacheinfo(mode, sha1, ea->argv[3], 0))
+		die("git-update-index: --cacheinfo cannot add %s",ea->argv[3]);
+
+	return nil_exec_args(ea);
+}
+
+gitopt_eat_one_arg(opt_chmod,
+		if (*argc_pos + 1 >= argc)
+			die("git-update-index: --chmod=%s <path>",ea->argv[0]);
+		set_executable_bit = ea->argv[0][0];)
+
+gitopt_eat(opt_assume_unchanged, mark_valid_only = MARK_VALID;)
+gitopt_eat(opt_no_assume_unchanged, mark_valid_only = UNMARK_VALID;)
+gitopt_eat(opt_info_only, info_only = 1;)
+gitopt_eat(opt_force_remove, force_remove = 1;)
+gitopt_eat(opt_z, line_termination = 0;)
+gitopt_eat(opt_stdin,
+		if (*argc_pos != argc - 1)
+			die("--stdin must be at the end");
+		read_from_stdin = 1;)
+
+gitopt_eat(opt_index_info,
+		if (*argc_pos != argc - 1)
+			die("--index-info must be at the end");
+		allow_add = allow_replace = allow_remove = 1;
+		read_index_info(line_termination);)
+
+gitopt_eat(opt_unresolve,
+		has_errors = do_unresolve(argc - *argc_pos, argv + *argc_pos,
+					prefix, prefix_length);
+		if (has_errors)
+			active_cache_changed = 0;
+		write_cache_if_changed();
+		exit(has_errors ? 1 : 0);)
+
+gitopt_eat(opt_ignore_missing, not_new = 1;)
+gitopt_eat(opt_verbose, verbose = 1;)
+gitopt_eat(opt_h, usage(update_index_usage);)
+
+static const struct opt_spec update_index_ost[] = {
+	{ 0,			'q',	0,	0,	opt_q },
+	{ "add",		0,	0,	0,	opt_add },
+	{ "replace",		0,	0,	0,	opt_replace },
+	{ "remove",		0,	0,	0,	opt_remove },
+	{ "unmerged",		0,	0,	0,	opt_unmerged },
+	{ "refresh",		0,	0,	0,	opt_refresh },
+	{ "really-refresh",	0,	0,	0,	opt_really_refresh },
+	{ "cacheinfo",		0,	0,	ARG_TRE, opt_cacheinfo},
+	{ "chmod",		0,	"%s",	ARG_ONE, opt_chmod },
+	{ "assume-unchanged",	0,	0,	0,	opt_assume_unchanged },
+	{ "no-assume-unchanged",0,	0,	0,	opt_no_assume_unchanged},
+	{ "info-only",		0,	0,	0,	opt_info_only },
+	{ "force-remove",	0,	0,	0,	opt_force_remove },
+	{ 0,			'z',	0,	0,	opt_z },
+	{ "stdin",		0,	0,	0,	opt_stdin },
+	{ "index-info",		0,	0,	0,	opt_index_info },
+	{ "unresolve",		0,	0,	0,	opt_unresolve },
+	{ "ignore-missing",	0,	0,	0,	opt_ignore_missing },
+	{ "verbose",		0,	0,	0,	opt_verbose },
+	{ "help",		'h',	0,	0,	opt_h },
+	{ 0, 0 }
+};
+
+/* call this for every non-option (and everything after "--") we have */
+static void update_index_non_option_cb(struct exec_args *b, const int argc,
+					const char **argv, int *argc_pos)
+{
+	const char *arg = argv[*argc_pos];
+	update_one(arg, prefix, prefix_length);
+	if (set_executable_bit)
+		chmod_path(set_executable_bit, arg);
+}
+
 int main(int argc, const char **argv)
 {
-	int i, newfd, entries, has_errors = 0, line_termination = '\n';
-	int allow_options = 1;
-	int read_from_stdin = 0;
-	const char *prefix = setup_git_directory();
-	int prefix_length = prefix ? strlen(prefix) : 0;
-	char set_executable_bit = 0;
+	int entries;
+	struct exec_args *a;
+
+	prefix = setup_git_directory();
+	if (prefix)
+		prefix_length = strlen(prefix);
 
+	a = new_exec_args(argc);	/* argv[0] and options: */
+	gitopt_non_option_cb = update_index_non_option_cb;
 	git_config(git_default_config);
 
 	newfd = hold_index_file_for_update(&cache_file, get_index_file());
@@ -619,120 +735,9 @@ int main(int argc, const char **argv)
 	if (entries < 0)
 		die("cache corrupted");
 
-	for (i = 1 ; i < argc; i++) {
-		const char *path = argv[i];
+	if (gitopt_parse_ost_split(a, a, update_index_ost, argc, argv) < 0)
+		usage(update_index_usage);
 
-		if (allow_options && *path == '-') {
-			if (!strcmp(path, "--")) {
-				allow_options = 0;
-				continue;
-			}
-			if (!strcmp(path, "-q")) {
-				quiet = 1;
-				continue;
-			}
-			if (!strcmp(path, "--add")) {
-				allow_add = 1;
-				continue;
-			}
-			if (!strcmp(path, "--replace")) {
-				allow_replace = 1;
-				continue;
-			}
-			if (!strcmp(path, "--remove")) {
-				allow_remove = 1;
-				continue;
-			}
-			if (!strcmp(path, "--unmerged")) {
-				allow_unmerged = 1;
-				continue;
-			}
-			if (!strcmp(path, "--refresh")) {
-				has_errors |= refresh_cache(0);
-				continue;
-			}
-			if (!strcmp(path, "--really-refresh")) {
-				has_errors |= refresh_cache(1);
-				continue;
-			}
-			if (!strcmp(path, "--cacheinfo")) {
-				unsigned char sha1[20];
-				unsigned int mode;
-
-				if (i+3 >= argc)
-					die("git-update-index: --cacheinfo <mode> <sha1> <path>");
-
-				if ((sscanf(argv[i+1], "%o", &mode) != 1) ||
-				    get_sha1_hex(argv[i+2], sha1) ||
-				    add_cacheinfo(mode, sha1, argv[i+3], 0))
-					die("git-update-index: --cacheinfo"
-					    " cannot add %s", argv[i+3]);
-				i += 3;
-				continue;
-			}
-			if (!strcmp(path, "--chmod=-x") ||
-			    !strcmp(path, "--chmod=+x")) {
-				if (argc <= i+1)
-					die("git-update-index: %s <path>", path);
-				set_executable_bit = path[8];
-				continue;
-			}
-			if (!strcmp(path, "--assume-unchanged")) {
-				mark_valid_only = MARK_VALID;
-				continue;
-			}
-			if (!strcmp(path, "--no-assume-unchanged")) {
-				mark_valid_only = UNMARK_VALID;
-				continue;
-			}
-			if (!strcmp(path, "--info-only")) {
-				info_only = 1;
-				continue;
-			}
-			if (!strcmp(path, "--force-remove")) {
-				force_remove = 1;
-				continue;
-			}
-			if (!strcmp(path, "-z")) {
-				line_termination = 0;
-				continue;
-			}
-			if (!strcmp(path, "--stdin")) {
-				if (i != argc - 1)
-					die("--stdin must be at the end");
-				read_from_stdin = 1;
-				break;
-			}
-			if (!strcmp(path, "--index-info")) {
-				if (i != argc - 1)
-					die("--index-info must be at the end");
-				allow_add = allow_replace = allow_remove = 1;
-				read_index_info(line_termination);
-				break;
-			}
-			if (!strcmp(path, "--unresolve")) {
-				has_errors = do_unresolve(argc - i, argv + i,
-							  prefix, prefix_length);
-				if (has_errors)
-					active_cache_changed = 0;
-				goto finish;
-			}
-			if (!strcmp(path, "--ignore-missing")) {
-				not_new = 1;
-				continue;
-			}
-			if (!strcmp(path, "--verbose")) {
-				verbose = 1;
-				continue;
-			}
-			if (!strcmp(path, "-h") || !strcmp(path, "--help"))
-				usage(update_index_usage);
-			die("unknown option %s", path);
-		}
-		update_one(path, prefix, prefix_length);
-		if (set_executable_bit)
-			chmod_path(set_executable_bit, path);
-	}
 	if (read_from_stdin) {
 		struct strbuf buf;
 		strbuf_init(&buf);
@@ -757,12 +762,6 @@ int main(int argc, const char **argv)
 		}
 	}
 
- finish:
-	if (active_cache_changed) {
-		if (write_cache(newfd, active_cache, active_nr) ||
-		    commit_index_file(&cache_file))
-			die("Unable to write new cachefile");
-	}
-
+	write_cache_if_changed();
 	return has_errors ? 1 : 0;
 }
-- 
1.3.2.g0a3ae

-
: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]