Subject: [PATCH 02/12] Convert starts_with() to skip_prefix() for option parsing

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Wed, 18 Dec 2013 21:53:47 +0700

The code that's not converted to use parse_options() often does

  if (!starts_with(arg, "foo=")) {
     value = atoi(arg + 4);
  }

This patch removes those magic numbers with skip_prefix()

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
---
 builtin/fetch-pack.c     | 13 +++++----
 builtin/index-pack.c     | 17 +++++------
 builtin/ls-remote.c      |  9 +++---
 builtin/mailinfo.c       |  5 ++--
 builtin/reflog.c         |  9 +++---
 builtin/rev-parse.c      | 41 +++++++++++++-------------
 builtin/send-pack.c      | 18 ++++++------
 builtin/unpack-objects.c |  5 ++--
 builtin/update-ref.c     | 21 +++++++-------
 daemon.c                 | 75 ++++++++++++++++++++++++------------------------
 diff.c                   | 49 +++++++++++++++----------------
 git.c                    | 13 +++++----
 merge-recursive.c        | 13 +++++----
 revision.c               | 60 +++++++++++++++++++-------------------
 upload-pack.c            |  5 ++--
 15 files changed, 182 insertions(+), 171 deletions(-)

diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 8b8978a2..2df1423 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -47,13 +47,14 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
 
 	for (i = 1; i < argc && *argv[i] == '-'; i++) {
 		const char *arg = argv[i];
+		const char *optarg;
 
-		if (starts_with(arg, "--upload-pack=")) {
-			args.uploadpack = arg + 14;
+		if ((optarg = skip_prefix(arg, "--upload-pack=")) != NULL) {
+			args.uploadpack = optarg;
 			continue;
 		}
-		if (starts_with(arg, "--exec=")) {
-			args.uploadpack = arg + 7;
+		if ((optarg = skip_prefix(arg, "--exec=")) != NULL) {
+			args.uploadpack = optarg;
 			continue;
 		}
 		if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) {
@@ -89,8 +90,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
 			args.verbose = 1;
 			continue;
 		}
-		if (starts_with(arg, "--depth=")) {
-			args.depth = strtol(arg + 8, NULL, 0);
+		if ((optarg = skip_prefix(arg, "--depth=")) != NULL) {
+			args.depth = strtol(optarg, NULL, 0);
 			continue;
 		}
 		if (!strcmp("--no-progress", arg)) {
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 2f37a38..67eff7a 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1511,6 +1511,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
 
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
+		const char *optarg;
 
 		if (*arg == '-') {
 			if (!strcmp(arg, "--stdin")) {
@@ -1534,11 +1535,11 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
 				stat_only = 1;
 			} else if (!strcmp(arg, "--keep")) {
 				keep_msg = "";
-			} else if (starts_with(arg, "--keep=")) {
-				keep_msg = arg + 7;
-			} else if (starts_with(arg, "--threads=")) {
+			} else if ((optarg = skip_prefix(arg, "--keep=")) != NULL) {
+				keep_msg = optarg;
+			} else if ((optarg = skip_prefix(arg, "--threads=")) != NULL) {
 				char *end;
-				nr_threads = strtoul(arg+10, &end, 0);
+				nr_threads = strtoul(optarg, &end, 0);
 				if (!arg[10] || *end || nr_threads < 0)
 					usage(index_pack_usage);
 #ifdef NO_PTHREADS
@@ -1547,13 +1548,13 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
 						  "ignoring %s"), arg);
 				nr_threads = 1;
 #endif
-			} else if (starts_with(arg, "--pack_header=")) {
+			} else if ((optarg = skip_prefix(arg, "--pack_header=")) != NULL) {
 				struct pack_header *hdr;
 				char *c;
 
 				hdr = (struct pack_header *)input_buffer;
 				hdr->hdr_signature = htonl(PACK_SIGNATURE);
-				hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10));
+				hdr->hdr_version = htonl(strtoul(optarg, &c, 10));
 				if (*c != ',')
 					die(_("bad %s"), arg);
 				hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10));
@@ -1566,9 +1567,9 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
 				if (index_name || (i+1) >= argc)
 					usage(index_pack_usage);
 				index_name = argv[++i];
-			} else if (starts_with(arg, "--index-version=")) {
+			} else if ((optarg = skip_prefix(arg, "--index-version=")) != NULL) {
 				char *c;
-				opts.version = strtoul(arg + 16, &c, 10);
+				opts.version = strtoul(optarg, &c, 10);
 				if (opts.version > 2)
 					die(_("bad %s"), arg);
 				if (*c == ',')
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index 39e5144..15c9fb3 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -48,14 +48,15 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
+		const char *optarg;
 
 		if (*arg == '-') {
-			if (starts_with(arg, "--upload-pack=")) {
-				uploadpack = arg + 14;
+			if ((optarg = skip_prefix(arg, "--upload-pack=")) != NULL) {
+				uploadpack = optarg;
 				continue;
 			}
-			if (starts_with(arg, "--exec=")) {
-				uploadpack = arg + 7;
+			if ((optarg = skip_prefix(arg, "--exec=")) != NULL) {
+				uploadpack = optarg;
 				continue;
 			}
 			if (!strcmp("--tags", arg) || !strcmp("-t", arg)) {
diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c
index 2c3cd8e..2100e23 100644
--- a/builtin/mailinfo.c
+++ b/builtin/mailinfo.c
@@ -1002,6 +1002,7 @@ static const char mailinfo_usage[] =
 int cmd_mailinfo(int argc, const char **argv, const char *prefix)
 {
 	const char *def_charset;
+	const char *optarg;
 
 	/* NEEDSWORK: might want to do the optional .git/ directory
 	 * discovery
@@ -1020,8 +1021,8 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix)
 			metainfo_charset = def_charset;
 		else if (!strcmp(argv[1], "-n"))
 			metainfo_charset = NULL;
-		else if (starts_with(argv[1], "--encoding="))
-			metainfo_charset = argv[1] + 11;
+		else if ((optarg = skip_prefix(argv[1], "--encoding=")) != NULL)
+			metainfo_charset = optarg;
 		else if (!strcmp(argv[1], "--scissors"))
 			use_scissors = 1;
 		else if (!strcmp(argv[1], "--no-scissors"))
diff --git a/builtin/reflog.c b/builtin/reflog.c
index 852cff6..84a8bd9 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -608,15 +608,16 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
 
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
+		const char *optarg;
 		if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
 			cb.dry_run = 1;
-		else if (starts_with(arg, "--expire=")) {
-			if (parse_expiry_date(arg + 9, &cb.expire_total))
+		else if ((optarg = skip_prefix(arg, "--expire=")) != NULL) {
+			if (parse_expiry_date(optarg, &cb.expire_total))
 				die(_("'%s' is not a valid timestamp"), arg);
 			explicit_expiry |= EXPIRE_TOTAL;
 		}
-		else if (starts_with(arg, "--expire-unreachable=")) {
-			if (parse_expiry_date(arg + 21, &cb.expire_unreachable))
+		else if ((optarg = skip_prefix(arg, "--expire-unreachable=")) != NULL) {
+			if (parse_expiry_date(optarg, &cb.expire_unreachable))
 				die(_("'%s' is not a valid timestamp"), arg);
 			explicit_expiry |= EXPIRE_UNREACH;
 		}
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 6e802fd..1a0bd12 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -505,6 +505,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 	git_config(git_default_config, NULL);
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
+		const char *optarg;
 
 		if (as_is) {
 			if (show_file(arg, output_prefix) && as_is < 2)
@@ -618,8 +619,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 				for_each_ref(show_reference, NULL);
 				continue;
 			}
-			if (starts_with(arg, "--disambiguate=")) {
-				for_each_abbrev(arg + 15, show_abbrev, NULL);
+			if ((optarg = skip_prefix(arg, "--disambiguate=")) != NULL) {
+				for_each_abbrev(optarg, show_abbrev, NULL);
 				continue;
 			}
 			if (!strcmp(arg, "--bisect")) {
@@ -627,8 +628,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 				for_each_ref_in("refs/bisect/good", anti_reference, NULL);
 				continue;
 			}
-			if (starts_with(arg, "--branches=")) {
-				for_each_glob_ref_in(show_reference, arg + 11,
+			if ((optarg = skip_prefix(arg, "--branches=")) != NULL) {
+				for_each_glob_ref_in(show_reference, optarg,
 					"refs/heads/", NULL);
 				clear_ref_exclusion(&ref_excludes);
 				continue;
@@ -638,8 +639,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 				clear_ref_exclusion(&ref_excludes);
 				continue;
 			}
-			if (starts_with(arg, "--tags=")) {
-				for_each_glob_ref_in(show_reference, arg + 7,
+			if ((optarg = skip_prefix(arg, "--tags=")) != NULL) {
+				for_each_glob_ref_in(show_reference, optarg,
 					"refs/tags/", NULL);
 				clear_ref_exclusion(&ref_excludes);
 				continue;
@@ -649,13 +650,13 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 				clear_ref_exclusion(&ref_excludes);
 				continue;
 			}
-			if (starts_with(arg, "--glob=")) {
-				for_each_glob_ref(show_reference, arg + 7, NULL);
+			if ((optarg = skip_prefix(arg, "--glob=")) != NULL) {
+				for_each_glob_ref(show_reference, optarg, NULL);
 				clear_ref_exclusion(&ref_excludes);
 				continue;
 			}
-			if (starts_with(arg, "--remotes=")) {
-				for_each_glob_ref_in(show_reference, arg + 10,
+			if ((optarg = skip_prefix(arg, "--remotes=")) != NULL) {
+				for_each_glob_ref_in(show_reference, optarg,
 					"refs/remotes/", NULL);
 				clear_ref_exclusion(&ref_excludes);
 				continue;
@@ -665,8 +666,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 				clear_ref_exclusion(&ref_excludes);
 				continue;
 			}
-			if (starts_with(arg, "--exclude=")) {
-				add_ref_exclusion(&ref_excludes, arg + 10);
+			if ((optarg = skip_prefix(arg, "--exclude=")) != NULL) {
+				add_ref_exclusion(&ref_excludes, optarg);
 				continue;
 			}
 			if (!strcmp(arg, "--local-env-vars")) {
@@ -747,20 +748,20 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 						: "false");
 				continue;
 			}
-			if (starts_with(arg, "--since=")) {
-				show_datestring("--max-age=", arg+8);
+			if ((optarg = skip_prefix(arg, "--since=")) != NULL) {
+				show_datestring("--max-age=", optarg);
 				continue;
 			}
-			if (starts_with(arg, "--after=")) {
-				show_datestring("--max-age=", arg+8);
+			if ((optarg = skip_prefix(arg, "--after=")) != NULL) {
+				show_datestring("--max-age=", optarg);
 				continue;
 			}
-			if (starts_with(arg, "--before=")) {
-				show_datestring("--min-age=", arg+9);
+			if ((optarg = skip_prefix(arg, "--before=")) != NULL) {
+				show_datestring("--min-age=", optarg);
 				continue;
 			}
-			if (starts_with(arg, "--until=")) {
-				show_datestring("--min-age=", arg+8);
+			if ((optarg = skip_prefix(arg, "--until=")) != NULL) {
+				show_datestring("--min-age=", optarg);
 				continue;
 			}
 			if (show_flag(arg) && verify)
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index e7f0b97..9efc422 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -113,18 +113,19 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 	argv++;
 	for (i = 1; i < argc; i++, argv++) {
 		const char *arg = *argv;
+		const char *optarg;
 
 		if (*arg == '-') {
-			if (starts_with(arg, "--receive-pack=")) {
-				receivepack = arg + 15;
+			if ((optarg = skip_prefix(arg, "--receive-pack=")) != NULL) {
+				receivepack = optarg;
 				continue;
 			}
-			if (starts_with(arg, "--exec=")) {
-				receivepack = arg + 7;
+			if ((optarg = skip_prefix(arg, "--exec=")) != NULL) {
+				receivepack = optarg;
 				continue;
 			}
-			if (starts_with(arg, "--remote=")) {
-				remote_name = arg + 9;
+			if ((optarg = skip_prefix(arg, "--remote=")) != NULL) {
+				remote_name = optarg;
 				continue;
 			}
 			if (!strcmp(arg, "--all")) {
@@ -181,9 +182,8 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 					exit(1);
 				continue;
 			}
-			if (starts_with(arg, "--" CAS_OPT_NAME "=")) {
-				if (parse_push_cas_option(&cas,
-							  strchr(arg, '=') + 1, 0) < 0)
+			if ((optarg = skip_prefix(arg, "--" CAS_OPT_NAME "=")) != NULL) {
+				if (parse_push_cas_option(&cas, optarg, 0) < 0)
 					exit(1);
 				continue;
 			}
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 62ff673..a7cd823 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -505,6 +505,7 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
 
 	for (i = 1 ; i < argc; i++) {
 		const char *arg = argv[i];
+		const char *optarg;
 
 		if (*arg == '-') {
 			if (!strcmp(arg, "-n")) {
@@ -523,13 +524,13 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
 				strict = 1;
 				continue;
 			}
-			if (starts_with(arg, "--pack_header=")) {
+			if ((optarg = skip_prefix(arg, "--pack_header=")) != NULL) {
 				struct pack_header *hdr;
 				char *c;
 
 				hdr = (struct pack_header *)buffer;
 				hdr->hdr_signature = htonl(PACK_SIGNATURE);
-				hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10));
+				hdr->hdr_version = htonl(strtoul(optarg, &c, 10));
 				if (*c != ',')
 					die("bad %s", arg);
 				hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10));
diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 1292cfe..09c921a 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -222,6 +222,7 @@ static void parse_cmd_option(const char *next)
 static void update_refs_stdin(void)
 {
 	struct strbuf cmd = STRBUF_INIT;
+	const char *optarg;
 
 	/* Read each line dispatch its command */
 	while (strbuf_getline(&cmd, stdin, line_termination) != EOF)
@@ -229,16 +230,16 @@ static void update_refs_stdin(void)
 			die("empty command in input");
 		else if (isspace(*cmd.buf))
 			die("whitespace before command: %s", cmd.buf);
-		else if (starts_with(cmd.buf, "update "))
-			parse_cmd_update(cmd.buf + 7);
-		else if (starts_with(cmd.buf, "create "))
-			parse_cmd_create(cmd.buf + 7);
-		else if (starts_with(cmd.buf, "delete "))
-			parse_cmd_delete(cmd.buf + 7);
-		else if (starts_with(cmd.buf, "verify "))
-			parse_cmd_verify(cmd.buf + 7);
-		else if (starts_with(cmd.buf, "option "))
-			parse_cmd_option(cmd.buf + 7);
+		else if ((optarg = skip_prefix(cmd.buf, "update ")) != NULL)
+			parse_cmd_update(optarg);
+		else if ((optarg = skip_prefix(cmd.buf, "create ")) != NULL)
+			parse_cmd_create(optarg);
+		else if ((optarg = skip_prefix(cmd.buf, "delete ")) != NULL)
+			parse_cmd_delete(optarg);
+		else if ((optarg = skip_prefix(cmd.buf, "verify ")) != NULL)
+			parse_cmd_verify(optarg);
+		else if ((optarg = skip_prefix(cmd.buf, "option ")) != NULL)
+			parse_cmd_option(optarg);
 		else
 			die("unknown command: %s", cmd.buf);
 
diff --git a/daemon.c b/daemon.c
index 7bee953..9d3cc18 100644
--- a/daemon.c
+++ b/daemon.c
@@ -39,8 +39,8 @@ static int strict_paths;
 static int export_all_trees;
 
 /* Take all paths relative to this one if non-NULL */
-static char *base_path;
-static char *interpolated_path;
+static const char *base_path;
+static const char *interpolated_path;
 static int base_path_relaxed;
 
 /* Flag indicating client sent extra args. */
@@ -253,7 +253,7 @@ static int daemon_error(const char *dir, const char *msg)
 	return -1;
 }
 
-static char *access_hook;
+static const char *access_hook;
 
 static int run_access_hook(struct daemon_service *service, const char *dir, const char *path)
 {
@@ -1164,15 +1164,16 @@ int main(int argc, char **argv)
 
 	for (i = 1; i < argc; i++) {
 		char *arg = argv[i];
+		const char *optarg;
 
-		if (starts_with(arg, "--listen=")) {
-			string_list_append(&listen_addr, xstrdup_tolower(arg + 9));
+		if ((optarg = skip_prefix(arg, "--listen=")) != NULL) {
+			string_list_append(&listen_addr, xstrdup_tolower(optarg));
 			continue;
 		}
-		if (starts_with(arg, "--port=")) {
+		if ((optarg = skip_prefix(arg, "--port=")) != NULL) {
 			char *end;
 			unsigned long n;
-			n = strtoul(arg+7, &end, 0);
+			n = strtoul(optarg, &end, 0);
 			if (arg[7] && !*end) {
 				listen_port = n;
 				continue;
@@ -1199,20 +1200,20 @@ int main(int argc, char **argv)
 			export_all_trees = 1;
 			continue;
 		}
-		if (starts_with(arg, "--access-hook=")) {
-			access_hook = arg + 14;
+		if ((optarg = skip_prefix(arg, "--access-hook=")) != NULL) {
+			access_hook = optarg;
 			continue;
 		}
-		if (starts_with(arg, "--timeout=")) {
-			timeout = atoi(arg+10);
+		if ((optarg = skip_prefix(arg, "--timeout=")) != NULL) {
+			timeout = atoi(optarg);
 			continue;
 		}
-		if (starts_with(arg, "--init-timeout=")) {
-			init_timeout = atoi(arg+15);
+		if ((optarg = skip_prefix(arg, "--init-timeout=")) != NULL) {
+			init_timeout = atoi(optarg);
 			continue;
 		}
-		if (starts_with(arg, "--max-connections=")) {
-			max_connections = atoi(arg+18);
+		if ((optarg = skip_prefix(arg, "--max-connections=")) != NULL) {
+			max_connections = atoi(optarg);
 			if (max_connections < 0)
 				max_connections = 0;	        /* unlimited */
 			continue;
@@ -1221,16 +1222,16 @@ int main(int argc, char **argv)
 			strict_paths = 1;
 			continue;
 		}
-		if (starts_with(arg, "--base-path=")) {
-			base_path = arg+12;
+		if ((optarg = skip_prefix(arg, "--base-path=")) != NULL) {
+			base_path = optarg;
 			continue;
 		}
 		if (!strcmp(arg, "--base-path-relaxed")) {
 			base_path_relaxed = 1;
 			continue;
 		}
-		if (starts_with(arg, "--interpolated-path=")) {
-			interpolated_path = arg+20;
+		if ((optarg = skip_prefix(arg, "--interpolated-path=")) != NULL) {
+			interpolated_path = optarg;
 			continue;
 		}
 		if (!strcmp(arg, "--reuseaddr")) {
@@ -1241,12 +1242,12 @@ int main(int argc, char **argv)
 			user_path = "";
 			continue;
 		}
-		if (starts_with(arg, "--user-path=")) {
-			user_path = arg + 12;
+		if ((optarg = skip_prefix(arg, "--user-path=")) != NULL) {
+			user_path = optarg;
 			continue;
 		}
-		if (starts_with(arg, "--pid-file=")) {
-			pid_file = arg + 11;
+		if ((optarg = skip_prefix(arg, "--pid-file=")) != NULL) {
+			pid_file = optarg;
 			continue;
 		}
 		if (!strcmp(arg, "--detach")) {
@@ -1254,35 +1255,35 @@ int main(int argc, char **argv)
 			log_syslog = 1;
 			continue;
 		}
-		if (starts_with(arg, "--user=")) {
-			user_name = arg + 7;
+		if ((optarg = skip_prefix(arg, "--user=")) != NULL) {
+			user_name = optarg;
 			continue;
 		}
-		if (starts_with(arg, "--group=")) {
-			group_name = arg + 8;
+		if ((optarg = skip_prefix(arg, "--group=")) != NULL) {
+			group_name = optarg;
 			continue;
 		}
-		if (starts_with(arg, "--enable=")) {
-			enable_service(arg + 9, 1);
+		if ((optarg = skip_prefix(arg, "--enable=")) != NULL) {
+			enable_service(optarg, 1);
 			continue;
 		}
-		if (starts_with(arg, "--disable=")) {
-			enable_service(arg + 10, 0);
+		if ((optarg = skip_prefix(arg, "--disable=")) != NULL) {
+			enable_service(optarg, 0);
 			continue;
 		}
-		if (starts_with(arg, "--allow-override=")) {
-			make_service_overridable(arg + 17, 1);
+		if ((optarg = skip_prefix(arg, "--allow-override=")) != NULL) {
+			make_service_overridable(optarg, 1);
 			continue;
 		}
-		if (starts_with(arg, "--forbid-override=")) {
-			make_service_overridable(arg + 18, 0);
+		if ((optarg = skip_prefix(arg, "--forbid-override=")) != NULL) {
+			make_service_overridable(optarg, 0);
 			continue;
 		}
-		if (starts_with(arg, "--informative-errors")) {
+		if ((optarg = skip_prefix(arg, "--informative-errors")) != NULL) {
 			informative_errors = 1;
 			continue;
 		}
-		if (starts_with(arg, "--no-informative-errors")) {
+		if ((optarg = skip_prefix(arg, "--no-informative-errors")) != NULL) {
 			informative_errors = 0;
 			continue;
 		}
diff --git a/diff.c b/diff.c
index b79432b..90a1929 100644
--- a/diff.c
+++ b/diff.c
@@ -2353,6 +2353,7 @@ static void builtin_diff(const char *name_a,
 		xdemitconf_t xecfg;
 		struct emit_callback ecbdata;
 		const struct userdiff_funcname *pe;
+		const char *optarg;
 
 		if (must_show_header) {
 			fprintf(o->file, "%s", header.buf);
@@ -2387,10 +2388,10 @@ static void builtin_diff(const char *name_a,
 			xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);
 		if (!diffopts)
 			;
-		else if (starts_with(diffopts, "--unified="))
-			xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
-		else if (starts_with(diffopts, "-u"))
-			xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
+		else if ((optarg = skip_prefix(diffopts, "--unified=")) != NULL)
+			xecfg.ctxlen = strtoul(optarg, NULL, 10);
+		else if ((optarg = skip_prefix(diffopts, "-u")) != NULL)
+			xecfg.ctxlen = strtoul(optarg, NULL, 10);
 		if (o->word_diff)
 			init_diff_words_data(&ecbdata, o, one, two);
 		xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
@@ -3614,17 +3615,17 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
 		options->output_format |= DIFF_FORMAT_SHORTSTAT;
 	else if (!strcmp(arg, "-X") || !strcmp(arg, "--dirstat"))
 		return parse_dirstat_opt(options, "");
-	else if (starts_with(arg, "-X"))
-		return parse_dirstat_opt(options, arg + 2);
-	else if (starts_with(arg, "--dirstat="))
-		return parse_dirstat_opt(options, arg + 10);
+	else if ((optarg = skip_prefix(arg, "-X")) != NULL)
+		return parse_dirstat_opt(options, optarg);
+	else if ((optarg = skip_prefix(arg, "--dirstat=")) != NULL)
+		return parse_dirstat_opt(options, optarg);
 	else if (!strcmp(arg, "--cumulative"))
 		return parse_dirstat_opt(options, "cumulative");
 	else if (!strcmp(arg, "--dirstat-by-file"))
 		return parse_dirstat_opt(options, "files");
-	else if (starts_with(arg, "--dirstat-by-file=")) {
+	else if ((optarg = skip_prefix(arg, "--dirstat-by-file=")) != NULL) {
 		parse_dirstat_opt(options, "files");
-		return parse_dirstat_opt(options, arg + 18);
+		return parse_dirstat_opt(options, optarg);
 	}
 	else if (!strcmp(arg, "--check"))
 		options->output_format |= DIFF_FORMAT_CHECKDIFF;
@@ -3674,9 +3675,9 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
 		DIFF_OPT_CLR(options, RENAME_EMPTY);
 	else if (!strcmp(arg, "--relative"))
 		DIFF_OPT_SET(options, RELATIVE_NAME);
-	else if (starts_with(arg, "--relative=")) {
+	else if ((optarg = skip_prefix(arg, "--relative=")) != NULL) {
 		DIFF_OPT_SET(options, RELATIVE_NAME);
-		options->prefix = arg + 11;
+		options->prefix = optarg;
 	}
 
 	/* xdiff options */
@@ -3727,8 +3728,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
 		DIFF_OPT_CLR(options, FOLLOW_RENAMES);
 	else if (!strcmp(arg, "--color"))
 		options->use_color = 1;
-	else if (starts_with(arg, "--color=")) {
-		int value = git_config_colorbool(NULL, arg+8);
+	else if ((optarg = skip_prefix(arg, "--color=")) != NULL) {
+		int value = git_config_colorbool(NULL, optarg);
 		if (value < 0)
 			return error("option `color' expects \"always\", \"auto\", or \"never\"");
 		options->use_color = value;
@@ -3739,17 +3740,17 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
 		options->use_color = 1;
 		options->word_diff = DIFF_WORDS_COLOR;
 	}
-	else if (starts_with(arg, "--color-words=")) {
+	else if ((optarg = skip_prefix(arg, "--color-words=")) != NULL) {
 		options->use_color = 1;
 		options->word_diff = DIFF_WORDS_COLOR;
-		options->word_regex = arg + 14;
+		options->word_regex = optarg;
 	}
 	else if (!strcmp(arg, "--word-diff")) {
 		if (options->word_diff == DIFF_WORDS_NONE)
 			options->word_diff = DIFF_WORDS_PLAIN;
 	}
-	else if (starts_with(arg, "--word-diff=")) {
-		const char *type = arg + 12;
+	else if ((optarg = skip_prefix(arg, "--word-diff=")) != NULL) {
+		const char *type = optarg;
 		if (!strcmp(type, "plain"))
 			options->word_diff = DIFF_WORDS_PLAIN;
 		else if (!strcmp(type, "color")) {
@@ -3784,13 +3785,13 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
 	else if (!strcmp(arg, "--ignore-submodules")) {
 		DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG);
 		handle_ignore_submodules_arg(options, "all");
-	} else if (starts_with(arg, "--ignore-submodules=")) {
+	} else if ((optarg = skip_prefix(arg, "--ignore-submodules=")) != NULL) {
 		DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG);
-		handle_ignore_submodules_arg(options, arg + 20);
+		handle_ignore_submodules_arg(options, optarg);
 	} else if (!strcmp(arg, "--submodule"))
 		DIFF_OPT_SET(options, SUBMODULE_LOG);
-	else if (starts_with(arg, "--submodule="))
-		return parse_submodule_opt(options, arg + 12);
+	else if ((optarg = skip_prefix(arg, "--submodule=")) != NULL)
+		return parse_submodule_opt(options, optarg);
 
 	/* misc options */
 	else if (!strcmp(arg, "-z"))
@@ -3825,8 +3826,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
 	}
 	else if (!strcmp(arg, "--abbrev"))
 		options->abbrev = DEFAULT_ABBREV;
-	else if (starts_with(arg, "--abbrev=")) {
-		options->abbrev = strtoul(arg + 9, NULL, 10);
+	else if ((optarg = skip_prefix(arg, "--abbrev=")) != NULL) {
+		options->abbrev = strtoul(optarg, NULL, 10);
 		if (options->abbrev < MINIMUM_ABBREV)
 			options->abbrev = MINIMUM_ABBREV;
 		else if (40 < options->abbrev)
diff --git a/git.c b/git.c
index 3799514..35fda7e 100644
--- a/git.c
+++ b/git.c
@@ -40,6 +40,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
 
 	while (*argc > 0) {
 		const char *cmd = (*argv)[0];
+		const char *optarg;
 		if (cmd[0] != '-')
 			break;
 
@@ -92,8 +93,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 ((optarg = skip_prefix(cmd, "--git-dir=")) != NULL) {
+			setenv(GIT_DIR_ENVIRONMENT, optarg, 1);
 			if (envchanged)
 				*envchanged = 1;
 		} else if (!strcmp(cmd, "--namespace")) {
@@ -106,8 +107,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 ((optarg = skip_prefix(cmd, "--namespace=")) != NULL) {
+			setenv(GIT_NAMESPACE_ENVIRONMENT, optarg, 1);
 			if (envchanged)
 				*envchanged = 1;
 		} else if (!strcmp(cmd, "--work-tree")) {
@@ -120,8 +121,8 @@ 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 ((optarg = skip_prefix(cmd, "--work-tree=")) != NULL) {
+			setenv(GIT_WORK_TREE_ENVIRONMENT, optarg, 1);
 			if (envchanged)
 				*envchanged = 1;
 		} else if (!strcmp(cmd, "--bare")) {
diff --git a/merge-recursive.c b/merge-recursive.c
index a18bd15..ba7ecb6 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -2055,6 +2055,7 @@ void init_merge_options(struct merge_options *o)
 
 int parse_merge_opt(struct merge_options *o, const char *s)
 {
+	const char *optarg;
 	if (!s || !*s)
 		return -1;
 	if (!strcmp(s, "ours"))
@@ -2063,14 +2064,14 @@ int parse_merge_opt(struct merge_options *o, const char *s)
 		o->recursive_variant = MERGE_RECURSIVE_THEIRS;
 	else if (!strcmp(s, "subtree"))
 		o->subtree_shift = "";
-	else if (starts_with(s, "subtree="))
-		o->subtree_shift = s + strlen("subtree=");
+	else if ((optarg = skip_prefix(s, "subtree=")) != NULL)
+		o->subtree_shift = optarg;
 	else if (!strcmp(s, "patience"))
 		o->xdl_opts = DIFF_WITH_ALG(o, PATIENCE_DIFF);
 	else if (!strcmp(s, "histogram"))
 		o->xdl_opts = DIFF_WITH_ALG(o, HISTOGRAM_DIFF);
-	else if (starts_with(s, "diff-algorithm=")) {
-		long value = parse_algorithm_value(s + strlen("diff-algorithm="));
+	else if ((optarg = skip_prefix(s, "diff-algorithm=")) != NULL) {
+		long value = parse_algorithm_value(optarg);
 		if (value < 0)
 			return -1;
 		/* clear out previous settings */
@@ -2088,8 +2089,8 @@ int parse_merge_opt(struct merge_options *o, const char *s)
 		o->renormalize = 1;
 	else if (!strcmp(s, "no-renormalize"))
 		o->renormalize = 0;
-	else if (starts_with(s, "rename-threshold=")) {
-		const char *score = s + strlen("rename-threshold=");
+	else if ((optarg = skip_prefix(s, "rename-threshold=")) != NULL) {
+		const char *score = optarg;
 		if ((o->rename_score = parse_rename_score(&score)) == -1 || *score != 0)
 			return -1;
 	}
diff --git a/revision.c b/revision.c
index a68fde6..94b66e8 100644
--- a/revision.c
+++ b/revision.c
@@ -1652,8 +1652,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
 		revs->max_count = atoi(argv[1]);
 		revs->no_walk = 0;
 		return 2;
-	} else if (starts_with(arg, "-n")) {
-		revs->max_count = atoi(arg + 2);
+	} else if ((optarg = skip_prefix(arg, "-n")) != NULL) {
+		revs->max_count = atoi(optarg);
 		revs->no_walk = 0;
 	} else if ((argcount = parse_long_opt("max-age", argv, &optarg))) {
 		revs->max_age = atoi(optarg);
@@ -1712,11 +1712,11 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
 	} else if (!strcmp(arg, "--author-date-order")) {
 		revs->sort_order = REV_SORT_BY_AUTHOR_DATE;
 		revs->topo_order = 1;
-	} else if (starts_with(arg, "--early-output")) {
+	} else if ((optarg = skip_prefix(arg, "--early-output")) != NULL) {
 		int count = 100;
-		switch (arg[14]) {
+		switch (optarg[0]) {
 		case '=':
-			count = atoi(arg+15);
+			count = atoi(optarg + 1);
 			/* Fallthrough */
 		case 0:
 			revs->topo_order = 1;
@@ -1737,12 +1737,12 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
 		revs->min_parents = 2;
 	} else if (!strcmp(arg, "--no-merges")) {
 		revs->max_parents = 1;
-	} else if (starts_with(arg, "--min-parents=")) {
-		revs->min_parents = atoi(arg+14);
+	} else if ((optarg = skip_prefix(arg, "--min-parents=")) != NULL) {
+		revs->min_parents = atoi(optarg);
 	} else if (starts_with(arg, "--no-min-parents")) {
 		revs->min_parents = 0;
-	} else if (starts_with(arg, "--max-parents=")) {
-		revs->max_parents = atoi(arg+14);
+	} else if ((optarg = skip_prefix(arg, "--max-parents=")) != NULL) {
+		revs->max_parents = atoi(optarg);
 	} else if (starts_with(arg, "--no-max-parents")) {
 		revs->max_parents = -1;
 	} else if (!strcmp(arg, "--boundary")) {
@@ -1818,32 +1818,30 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
 		revs->verbose_header = 1;
 		revs->pretty_given = 1;
 		get_commit_format(arg+8, revs);
-	} else if (starts_with(arg, "--pretty=") || starts_with(arg, "--format=")) {
+	} else if ((optarg = skip_prefix(arg, "--pretty=")) != NULL ||
+		   (optarg = skip_prefix(arg, "--format=")) != NULL) {
 		/*
 		 * Detached form ("--pretty X" as opposed to "--pretty=X")
 		 * not allowed, since the argument is optional.
 		 */
 		revs->verbose_header = 1;
 		revs->pretty_given = 1;
-		get_commit_format(arg+9, revs);
+		get_commit_format(optarg, revs);
 	} else if (!strcmp(arg, "--show-notes") || !strcmp(arg, "--notes")) {
 		revs->show_notes = 1;
 		revs->show_notes_given = 1;
 		revs->notes_opt.use_default_notes = 1;
 	} else if (!strcmp(arg, "--show-signature")) {
 		revs->show_signature = 1;
-	} else if (starts_with(arg, "--show-notes=") ||
-		   starts_with(arg, "--notes=")) {
+	} else if ((optarg = skip_prefix(arg, "--show-notes=")) != NULL ||
+		   (optarg = skip_prefix(arg, "--notes=")) != NULL) {
 		struct strbuf buf = STRBUF_INIT;
 		revs->show_notes = 1;
 		revs->show_notes_given = 1;
-		if (starts_with(arg, "--show-notes")) {
-			if (revs->notes_opt.use_default_notes < 0)
-				revs->notes_opt.use_default_notes = 1;
-			strbuf_addstr(&buf, arg+13);
-		}
-		else
-			strbuf_addstr(&buf, arg+8);
+		if (starts_with(arg, "--show-notes") &&
+		    revs->notes_opt.use_default_notes < 0)
+			revs->notes_opt.use_default_notes = 1;
+		strbuf_addstr(&buf, optarg);
 		expand_notes_ref(&buf);
 		string_list_append(&revs->notes_opt.extra_notes_refs,
 				   strbuf_detach(&buf, NULL));
@@ -1880,8 +1878,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
 		revs->abbrev = 0;
 	} else if (!strcmp(arg, "--abbrev")) {
 		revs->abbrev = DEFAULT_ABBREV;
-	} else if (starts_with(arg, "--abbrev=")) {
-		revs->abbrev = strtoul(arg + 9, NULL, 10);
+	} else if ((optarg = skip_prefix(arg, "--abbrev=")) != NULL) {
+		revs->abbrev = strtoul(optarg, NULL, 10);
 		if (revs->abbrev < MINIMUM_ABBREV)
 			revs->abbrev = MINIMUM_ABBREV;
 		else if (revs->abbrev > 40)
@@ -2027,20 +2025,20 @@ static int handle_revision_pseudo_opt(const char *submodule,
 	} else if ((argcount = parse_long_opt("exclude", argv, &optarg))) {
 		add_ref_exclusion(&revs->ref_excludes, optarg);
 		return argcount;
-	} else if (starts_with(arg, "--branches=")) {
+	} else if ((optarg = skip_prefix(arg, "--branches=")) != NULL) {
 		struct all_refs_cb cb;
 		init_all_refs_cb(&cb, revs, *flags);
-		for_each_glob_ref_in(handle_one_ref, arg + 11, "refs/heads/", &cb);
+		for_each_glob_ref_in(handle_one_ref, optarg, "refs/heads/", &cb);
 		clear_ref_exclusion(&revs->ref_excludes);
-	} else if (starts_with(arg, "--tags=")) {
+	} else if ((optarg = skip_prefix(arg, "--tags=")) != NULL) {
 		struct all_refs_cb cb;
 		init_all_refs_cb(&cb, revs, *flags);
-		for_each_glob_ref_in(handle_one_ref, arg + 7, "refs/tags/", &cb);
+		for_each_glob_ref_in(handle_one_ref, optarg, "refs/tags/", &cb);
 		clear_ref_exclusion(&revs->ref_excludes);
-	} else if (starts_with(arg, "--remotes=")) {
+	} else if ((optarg = skip_prefix(arg, "--remotes=")) != NULL) {
 		struct all_refs_cb cb;
 		init_all_refs_cb(&cb, revs, *flags);
-		for_each_glob_ref_in(handle_one_ref, arg + 10, "refs/remotes/", &cb);
+		for_each_glob_ref_in(handle_one_ref, optarg, "refs/remotes/", &cb);
 		clear_ref_exclusion(&revs->ref_excludes);
 	} else if (!strcmp(arg, "--reflog")) {
 		handle_reflog(revs, *flags);
@@ -2048,14 +2046,14 @@ static int handle_revision_pseudo_opt(const char *submodule,
 		*flags ^= UNINTERESTING | BOTTOM;
 	} else if (!strcmp(arg, "--no-walk")) {
 		revs->no_walk = REVISION_WALK_NO_WALK_SORTED;
-	} else if (starts_with(arg, "--no-walk=")) {
+	} else if ((optarg = skip_prefix(arg, "--no-walk=")) != NULL) {
 		/*
 		 * Detached form ("--no-walk X" as opposed to "--no-walk=X")
 		 * not allowed, since the argument is optional.
 		 */
-		if (!strcmp(arg + 10, "sorted"))
+		if (!strcmp(optarg, "sorted"))
 			revs->no_walk = REVISION_WALK_NO_WALK_SORTED;
-		else if (!strcmp(arg + 10, "unsorted"))
+		else if (!strcmp(optarg, "unsorted"))
 			revs->no_walk = REVISION_WALK_NO_WALK_UNSORTED;
 		else
 			return error("invalid argument to --no-walk");
diff --git a/upload-pack.c b/upload-pack.c
index ec56cdb..8523b42 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -799,6 +799,7 @@ int main(int argc, char **argv)
 
 	for (i = 1; i < argc; i++) {
 		char *arg = argv[i];
+		const char *optarg;
 
 		if (arg[0] != '-')
 			break;
@@ -814,8 +815,8 @@ int main(int argc, char **argv)
 			strict = 1;
 			continue;
 		}
-		if (starts_with(arg, "--timeout=")) {
-			timeout = atoi(arg+10);
+		if ((optarg = skip_prefix(arg, "--timeout=")) != NULL) {
+			timeout = atoi(optarg);
 			daemon_mode = 1;
 			continue;
 		}
-- 
1.8.5.1.208.g019362e