From: Junio C Hamano Date: Tue, 19 Jul 2016 20:22:19 +0000 (-0700) Subject: Merge branch 'jk/common-main' X-Git-Tag: v2.10.0-rc0~107 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/d4c6375fd8996d7d809fb34b9743339d7192c58b?hp=-c Merge branch 'jk/common-main' There are certain house-keeping tasks that need to be performed at the very beginning of any Git program, and programs that are not built-in commands had to do them exactly the same way as "git" potty does. It was easy to make mistakes in one-off standalone programs (like test helpers). A common "main()" function that calls cmd_main() of individual program has been introduced to make it harder to make mistakes. * jk/common-main: mingw: declare main()'s argv as const common-main: call git_setup_gettext() common-main: call restore_sigpipe_to_default() common-main: call sanitize_stdfds() common-main: call git_extract_argv0_path() add an extra level of indirection to main() --- d4c6375fd8996d7d809fb34b9743339d7192c58b diff --combined Makefile index 3cb1d601a3,717dc344ab..c1e88dfcdd --- a/Makefile +++ b/Makefile @@@ -939,7 -939,7 +939,7 @@@ BUILTIN_OBJS += builtin/verify-tag. BUILTIN_OBJS += builtin/worktree.o BUILTIN_OBJS += builtin/write-tree.o - GITLIBS = $(LIB_FILE) $(XDIFF_LIB) + GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) EXTLIBS = GIT_USER_AGENT = git/$(GIT_VERSION) @@@ -1572,7 -1572,15 +1572,15 @@@ TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_ DIFF_SQ = $(subst ','\'',$(DIFF)) PERLLIB_EXTRA_SQ = $(subst ','\'',$(PERLLIB_EXTRA)) - LIBS = $(GITLIBS) $(EXTLIBS) + # We must filter out any object files from $(GITLIBS), + # as it is typically used like: + # + # foo: foo.o $(GITLIBS) + # $(CC) $(filter %.o,$^) $(LIBS) + # + # where we use it as a dependency. Since we also pull object files + # from the dependency list, that would make each entry appear twice. + LIBS = $(filter-out %.o, $(GITLIBS)) $(EXTLIBS) BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \ $(COMPAT_CFLAGS) @@@ -1708,8 -1716,8 +1716,8 @@@ git.sp git.s git.o: EXTRA_CPPFLAGS = '-DGIT_INFO_PATH="$(infodir_relative_SQ)"' git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS) - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) git.o \ - $(BUILTIN_OBJS) $(LIBS) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \ + $(filter %.o,$^) $(LIBS) help.sp help.s help.o: common-cmds.h @@@ -1902,6 -1910,7 +1910,7 @@@ TEST_OBJS := $(patsubst %$X,%.o,$(TEST_ OBJECTS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \ $(XDIFF_OBJS) \ $(VCSSVN_OBJS) \ + common-main.o \ git.o ifndef NO_CURL OBJECTS += http.o http-walker.o remote-curl.o @@@ -2063,10 -2072,7 +2072,10 @@@ XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) - --keyword=gettextln --keyword=eval_gettextln XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H) -LOCALIZED_SH = $(SCRIPT_SH) git-parse-remote.sh +LOCALIZED_SH = $(SCRIPT_SH) +LOCALIZED_SH += git-parse-remote.sh +LOCALIZED_SH += git-rebase--interactive.sh +LOCALIZED_SH += git-sh-setup.sh LOCALIZED_PERL = $(SCRIPT_PERL) ifdef XGETTEXT_INCLUDE_TESTS diff --combined compat/mingw.h index 9a8803b876,1ac9086a82..233933ee86 --- a/compat/mingw.h +++ b/compat/mingw.h @@@ -532,10 -532,10 +532,10 @@@ extern CRITICAL_SECTION pinfo_cs * A replacement of main() that adds win32 specific initialization. */ -void mingw_startup(); -#define main(c,v) dummy_decl_mingw_main(); \ +void mingw_startup(void); +#define main(c,v) dummy_decl_mingw_main(void); \ static int mingw_main(c,v); \ - int main(int argc, char **argv) \ + int main(int argc, const char **argv) \ { \ mingw_startup(); \ return mingw_main(__argc, (void *)__argv); \ diff --combined daemon.c index 46dddaca5a,569997c98f..e647254c19 --- a/daemon.c +++ b/daemon.c @@@ -1,6 -1,5 +1,5 @@@ #include "cache.h" #include "pkt-line.h" - #include "exec_cmd.h" #include "run-command.h" #include "strbuf.h" #include "string-list.h" @@@ -32,7 -31,7 +31,7 @@@ static const char daemon_usage[] " [...]"; /* List of acceptable pathname prefixes */ - static char **ok_paths; + static const char **ok_paths; static int strict_paths; /* If this is set, git-daemon-export-ok is not required */ @@@ -240,7 -239,7 +239,7 @@@ static const char *path_ok(const char * } if ( ok_paths && *ok_paths ) { - char **pp; + const char **pp; int pathlen = strlen(path); /* The validation is done on the paths after enter_repo @@@ -669,15 -668,6 +668,15 @@@ static void hostinfo_clear(struct hosti strbuf_release(&hi->tcp_port); } +static void set_keep_alive(int sockfd) +{ + int ka = 1; + + if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &ka, sizeof(ka)) < 0) + logerror("unable to set SO_KEEPALIVE on socket: %s", + strerror(errno)); +} + static int execute(void) { char *line = packet_buffer; @@@ -690,7 -680,6 +689,7 @@@ if (addr) loginfo("Connection from %s:%s", addr, port); + set_keep_alive(0); alarm(init_timeout ? init_timeout : timeout); pktlen = packet_read(0, NULL, NULL, packet_buffer, sizeof(packet_buffer), 0); alarm(0); @@@ -961,8 -950,6 +960,8 @@@ static int setup_named_sock(char *liste continue; } + set_keep_alive(sockfd); + if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) { logerror("Could not bind to %s: %s", ip2str(ai->ai_family, ai->ai_addr, ai->ai_addrlen), @@@ -1022,8 -1009,6 +1021,8 @@@ static int setup_named_sock(char *liste return 0; } + set_keep_alive(sockfd); + if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) { logerror("Could not bind to %s: %s", ip2str(AF_INET, (struct sockaddr *)&sin, sizeof(sin)), @@@ -1192,7 -1177,7 +1191,7 @@@ static int serve(struct string_list *li return service_loop(&socklist); } - int main(int argc, char **argv) + int cmd_main(int argc, const char **argv) { int listen_port = 0; struct string_list listen_addr = STRING_LIST_INIT_NODUP; @@@ -1202,12 -1187,8 +1201,8 @@@ struct credentials *cred = NULL; int i; - git_setup_gettext(); - - git_extract_argv0_path(argv[0]); - for (i = 1; i < argc; i++) { - char *arg = argv[i]; + const char *arg = argv[i]; const char *v; if (skip_prefix(arg, "--listen=", &v)) { @@@ -1381,8 -1362,7 +1376,7 @@@ if (detach) { if (daemonize()) die("--detach not supported on this platform"); - } else - sanitize_stdfds(); + } if (pid_file) write_file(pid_file, "%"PRIuMAX, (uintmax_t) getpid()); diff --combined fast-import.c index 59630cee14,84a13756cc..bf53ac95da --- a/fast-import.c +++ b/fast-import.c @@@ -164,9 -164,7 +164,8 @@@ Format of STDIN stream #include "refs.h" #include "csum-file.h" #include "quote.h" - #include "exec_cmd.h" #include "dir.h" +#include "run-command.h" #define PACK_ID_BITS 16 #define MAX_PACK_ID ((1<next) + if (e->pack_id == id) + e->pack_id = MAX_PACK_ID; + } + + for (lu = 0; lu < branch_table_sz; lu++) { + struct branch *b; + + for (b = branch_table[lu]; b; b = b->table_next_branch) + if (b->pack_id == id) + b->pack_id = MAX_PACK_ID; + } + + for (t = first_tag; t; t = t->next_tag) + if (t->pack_id == id) + t->pack_id = MAX_PACK_ID; +} + static unsigned int hc_str(const char *s, size_t len) { unsigned int r = 0; @@@ -980,23 -950,6 +979,23 @@@ static void unkeep_all_packs(void } } +static int loosen_small_pack(const struct packed_git *p) +{ + struct child_process unpack = CHILD_PROCESS_INIT; + + if (lseek(p->pack_fd, 0, SEEK_SET) < 0) + die_errno("Failed seeking to start of '%s'", p->pack_name); + + unpack.in = p->pack_fd; + unpack.git_cmd = 1; + unpack.stdout_to_stderr = 1; + argv_array_push(&unpack.args, "unpack-objects"); + if (!show_stats) + argv_array_push(&unpack.args, "-q"); + + return run_command(&unpack); +} + static void end_packfile(void) { static int running; @@@ -1019,14 -972,6 +1018,14 @@@ fixup_pack_header_footer(pack_data->pack_fd, pack_data->sha1, pack_data->pack_name, object_count, cur_pack_sha1, pack_size); + + if (object_count <= unpack_limit) { + if (!loosen_small_pack(pack_data)) { + invalidate_pack_id(pack_id); + goto discard_pack; + } + } + close(pack_data->pack_fd); idx_name = keep_pack(create_index()); @@@ -1057,7 -1002,6 +1056,7 @@@ pack_id++; } else { +discard_pack: close(pack_data->pack_fd); unlink_or_warn(pack_data->pack_name); } @@@ -3375,7 -3319,6 +3374,7 @@@ static void parse_option(const char *op static void git_pack_config(void) { int indexversion_value; + int limit; unsigned long packsizelimit_value; if (!git_config_get_ulong("pack.depth", &max_depth)) { @@@ -3400,11 -3343,6 +3399,11 @@@ if (!git_config_get_ulong("pack.packsizelimit", &packsizelimit_value)) max_packsize = packsizelimit_value; + if (!git_config_get_int("fastimport.unpacklimit", &limit)) + unpack_limit = limit; + else if (!git_config_get_int("transfer.unpacklimit", &limit)) + unpack_limit = limit; + git_config(git_default_config, NULL); } @@@ -3445,14 -3383,10 +3444,10 @@@ static void parse_argv(void read_marks(); } - int main(int argc, char **argv) + int cmd_main(int argc, const char **argv) { unsigned int i; - git_extract_argv0_path(argv[0]); - - git_setup_gettext(); - if (argc == 2 && !strcmp(argv[1], "-h")) usage(fast_import_usage); diff --combined git-compat-util.h index c99cddc54b,1930444ef0..590bfddf73 --- a/git-compat-util.h +++ b/git-compat-util.h @@@ -473,23 -473,6 +473,23 @@@ static inline int skip_prefix(const cha return 0; } +/* + * Like skip_prefix, but promises never to read past "len" bytes of the input + * buffer, and returns the remaining number of bytes in "out" via "outlen". + */ +static inline int skip_prefix_mem(const char *buf, size_t len, + const char *prefix, + const char **out, size_t *outlen) +{ + size_t prefix_len = strlen(prefix); + if (prefix_len <= len && !memcmp(buf, prefix, prefix_len)) { + *out = buf + prefix_len; + *outlen = len - prefix_len; + return 1; + } + return 0; +} + /* * If buf ends with suffix, return 1 and subtract the length of the suffix * from *len. Otherwise, return 0 and leave *len untouched. @@@ -1062,3 -1045,5 +1062,5 @@@ struct tm *git_gmtime_r(const time_t * #endif #endif + + extern int cmd_main(int, const char **); diff --combined imap-send.c index 50377c5b88,9cbe27fcd4..db0fafee99 --- a/imap-send.c +++ b/imap-send.c @@@ -1443,7 -1443,6 +1443,7 @@@ static CURL *setup_curl(struct imap_ser if (0 < verbosity || getenv("GIT_CURL_VERBOSE")) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + setup_curl_trace(curl); return curl; } @@@ -1495,16 -1494,12 +1495,12 @@@ static int curl_append_msgs_to_imap(str } #endif - int main(int argc, char **argv) + int cmd_main(int argc, const char **argv) { struct strbuf all_msgs = STRBUF_INIT; int total; int nongit_ok; - git_extract_argv0_path(argv[0]); - - git_setup_gettext(); - setup_git_directory_gently(&nongit_ok); git_imap_config(); diff --combined t/helper/test-config.c index 509aeef400,d143cd7222..3c6d08cd09 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@@ -25,9 -25,6 +25,9 @@@ * ascending order of priority from a config_set * constructed from files entered as arguments. * + * iterate -> iterate over all values using git_config(), and print some + * data for each + * * Examples: * * To print the value with highest priority for key "foo.bAr Baz.rock": @@@ -35,38 -32,8 +35,38 @@@ * */ +static const char *scope_name(enum config_scope scope) +{ + switch (scope) { + case CONFIG_SCOPE_SYSTEM: + return "system"; + case CONFIG_SCOPE_GLOBAL: + return "global"; + case CONFIG_SCOPE_REPO: + return "repo"; + case CONFIG_SCOPE_CMDLINE: + return "cmdline"; + default: + return "unknown"; + } +} +static int iterate_cb(const char *var, const char *value, void *data) +{ + static int nr; + + if (nr++) + putchar('\n'); + + printf("key=%s\n", var); + printf("value=%s\n", value ? value : "(null)"); + printf("origin=%s\n", current_config_origin_type()); + printf("name=%s\n", current_config_name()); + printf("scope=%s\n", scope_name(current_config_scope())); + + return 0; +} - int main(int argc, char **argv) + int cmd_main(int argc, const char **argv) { int i, val; const char *v; @@@ -167,9 -134,6 +167,9 @@@ printf("Value not found for \"%s\"\n", argv[2]); goto exit1; } + } else if (!strcmp(argv[1], "iterate")) { + git_config(iterate_cb, NULL); + goto exit0; } die("%s: Please check the syntax and the function name", argv[0]); diff --combined t/helper/test-date.c index d9ab360909,0f3cfb1721..506054bcd5 --- a/t/helper/test-date.c +++ b/t/helper/test-date.c @@@ -1,12 -1,11 +1,12 @@@ #include "cache.h" static const char *usage_msg = "\n" -" test-date show [time_t]...\n" +" test-date relative [time_t]...\n" +" test-date show: [time_t]...\n" " test-date parse [date]...\n" " test-date approxidate [date]...\n"; - static void show_relative_dates(char **argv, struct timeval *now) -static void show_dates(const char **argv, struct timeval *now) ++static void show_relative_dates(const char **argv, struct timeval *now) { struct strbuf buf = STRBUF_INIT; @@@ -18,30 -17,7 +18,30 @@@ strbuf_release(&buf); } - static void show_dates(char **argv, const char *format) ++static void show_dates(const char **argv, const char *format) +{ + struct date_mode mode; + + parse_date_format(format, &mode); + for (; *argv; argv++) { - char *arg = *argv; ++ char *arg; + time_t t; + int tz; + + /* + * Do not use our normal timestamp parsing here, as the point + * is to test the formatting code in isolation. + */ - t = strtol(arg, &arg, 10); ++ t = strtol(*argv, &arg, 10); + while (*arg == ' ') + arg++; + tz = atoi(arg); + + printf("%s -> %s\n", *argv, show_date(t, tz, &mode)); + } +} + - static void parse_dates(char **argv, struct timeval *now) + static void parse_dates(const char **argv, struct timeval *now) { struct strbuf result = STRBUF_INIT; @@@ -60,7 -36,7 +60,7 @@@ strbuf_release(&result); } - static void parse_approxidate(char **argv, struct timeval *now) + static void parse_approxidate(const char **argv, struct timeval *now) { for (; *argv; argv++) { time_t t; @@@ -69,7 -45,7 +69,7 @@@ } } - int main(int argc, char **argv) + int cmd_main(int argc, const char **argv) { struct timeval now; const char *x; @@@ -85,10 -61,8 +85,10 @@@ argv++; if (!*argv) usage(usage_msg); - if (!strcmp(*argv, "show")) - show_dates(argv+1, &now); + if (!strcmp(*argv, "relative")) + show_relative_dates(argv+1, &now); + else if (skip_prefix(*argv, "show:", &x)) + show_dates(argv+1, x); else if (!strcmp(*argv, "parse")) parse_dates(argv+1, &now); else if (!strcmp(*argv, "approxidate")) diff --combined t/helper/test-parse-options.c index 2c63298fab,d51d29251e..a01430c24b --- a/t/helper/test-parse-options.c +++ b/t/helper/test-parse-options.c @@@ -12,7 -12,7 +12,7 @@@ static int dry_run = 0, quiet = 0 static char *string = NULL; static char *file = NULL; static int ambiguous; -static struct string_list list; +static struct string_list list = STRING_LIST_INIT_NODUP; static struct { int called; @@@ -94,7 -94,7 +94,7 @@@ static void show(struct string_list *ex strbuf_release(&buf); } - int main(int argc, char **argv) + int cmd_main(int argc, const char **argv) { const char *prefix = "prefix/"; const char *usage[] = { diff --combined t/helper/test-regex.c index eff26f534f,37b7f06e55..b5ea8a97c5 --- a/t/helper/test-regex.c +++ b/t/helper/test-regex.c @@@ -1,23 -1,6 +1,23 @@@ #include "git-compat-util.h" +#include "gettext.h" -int cmd_main(int argc, const char **argv) +struct reg_flag { + const char *name; + int flag; +}; + +static struct reg_flag reg_flags[] = { + { "EXTENDED", REG_EXTENDED }, + { "NEWLINE", REG_NEWLINE }, + { "ICASE", REG_ICASE }, + { "NOTBOL", REG_NOTBOL }, +#ifdef REG_STARTEND + { "STARTEND", REG_STARTEND }, +#endif + { NULL, 0 } +}; + +static int test_regex_bug(void) { char *pat = "[^={} \t]+"; char *str = "={}\nfred"; @@@ -33,43 -16,5 +33,43 @@@ if (m[0].rm_so == 3) /* matches '\n' when it should not */ die("regex bug confirmed: re-build git with NO_REGEX=1"); - exit(0); + return 0; +} + - int main(int argc, char **argv) ++int cmd_main(int argc, const char **argv) +{ + const char *pat; + const char *str; + int flags = 0; + regex_t r; + regmatch_t m[1]; + + if (argc == 2 && !strcmp(argv[1], "--bug")) + return test_regex_bug(); + else if (argc < 3) + usage("test-regex --bug\n" + "test-regex []"); + + argv++; + pat = *argv++; + str = *argv++; + while (*argv) { + struct reg_flag *rf; + for (rf = reg_flags; rf->name; rf++) + if (!strcmp(*argv, rf->name)) { + flags |= rf->flag; + break; + } + if (!rf->name) + die("do not recognize %s", *argv); + argv++; + } + git_setup_gettext(); + + if (regcomp(&r, pat, flags)) + die("failed regcomp() for pattern '%s'", pat); + if (regexec(&r, str, 1, m, 0)) + return 1; + + return 0; } diff --combined t/helper/test-submodule-config.c index 7922ffba1d,2cffded116..61049b87a0 --- a/t/helper/test-submodule-config.c +++ b/t/helper/test-submodule-config.c @@@ -2,7 -2,7 +2,7 @@@ #include "submodule-config.h" #include "submodule.h" - static void die_usage(int argc, char **argv, const char *msg) + static void die_usage(int argc, const char **argv, const char *msg) { fprintf(stderr, "%s\n", msg); fprintf(stderr, "Usage: %s [ ] ...\n", argv[0]); @@@ -14,9 -14,9 +14,9 @@@ static int git_test_config(const char * return parse_submodule_config_option(var, value); } - int main(int argc, char **argv) + int cmd_main(int argc, const char **argv) { - char **arg = argv; + const char **arg = argv; int my_argc = argc; int output_url = 0; int lookup_name = 0; @@@ -49,7 -49,7 +49,7 @@@ path_or_name = arg[1]; if (commit[0] == '\0') - hashcpy(commit_sha1, null_sha1); + hashclr(commit_sha1); else if (get_sha1(commit, commit_sha1) < 0) die_usage(argc, argv, "Commit not found."); diff --combined upload-pack.c index f93787003a,b97a7659d1..d4cc414bc2 --- a/upload-pack.c +++ b/upload-pack.c @@@ -14,12 -14,8 +14,12 @@@ #include "sigchain.h" #include "version.h" #include "string-list.h" +#include "parse-options.h" -static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=] "; +static const char * const upload_pack_usage[] = { + N_("git upload-pack [] "), + NULL +}; /* Remember to update object flag allocation in object.h */ #define THEY_HAVE (1u << 11) @@@ -56,28 -52,26 +56,28 @@@ static int keepalive = 5 static int use_sideband; static int advertise_refs; static int stateless_rpc; +static const char *pack_objects_hook; static void reset_timeout(void) { alarm(timeout); } -static ssize_t send_client_data(int fd, const char *data, ssize_t sz) +static void send_client_data(int fd, const char *data, ssize_t sz) { - if (use_sideband) - return send_sideband(1, fd, data, sz, use_sideband); + if (use_sideband) { + send_sideband(1, fd, data, sz, use_sideband); + return; + } if (fd == 3) /* emergency quit */ fd = 2; if (fd == 2) { /* XXX: are we happy to lose stuff here? */ xwrite(fd, data, sz); - return sz; + return; } write_or_die(fd, data, sz); - return sz; } static int write_one_shallow(const struct commit_graft *graft, void *cb_data) @@@ -99,14 -93,6 +99,14 @@@ static void create_pack_file(void int i; FILE *pipe_fd; + if (!pack_objects_hook) + pack_objects.git_cmd = 1; + else { + argv_array_push(&pack_objects.args, pack_objects_hook); + argv_array_push(&pack_objects.args, "git"); + pack_objects.use_shell = 1; + } + if (shallow_nr) { argv_array_push(&pack_objects.args, "--shallow-file"); argv_array_push(&pack_objects.args, ""); @@@ -129,6 -115,7 +129,6 @@@ pack_objects.in = -1; pack_objects.out = -1; pack_objects.err = -1; - pack_objects.git_cmd = 1; if (start_command(&pack_objects)) die("git upload-pack: unable to fork git-pack-objects"); @@@ -242,7 -229,9 +242,7 @@@ } else buffered = -1; - sz = send_client_data(1, data, sz); - if (sz < 0) - goto fail; + send_client_data(1, data, sz); } /* @@@ -269,7 -258,9 +269,7 @@@ /* flush the data */ if (0 <= buffered) { data[0] = buffered; - sz = send_client_data(1, data, 1); - if (sz < 0) - goto fail; + send_client_data(1, data, 1); fprintf(stderr, "flushed.\n"); } if (use_sideband) @@@ -821,46 -812,53 +821,43 @@@ static int upload_pack_config(const cha keepalive = git_config_int(var, value); if (!keepalive) keepalive = -1; + } else if (current_config_scope() != CONFIG_SCOPE_REPO) { + if (!strcmp("uploadpack.packobjectshook", var)) + return git_config_string(&pack_objects_hook, var, value); } return parse_hide_refs_config(var, value, "uploadpack"); } - int main(int argc, const char **argv) + int cmd_main(int argc, const char **argv) { const char *dir; - int i; int strict = 0; + struct option options[] = { + OPT_BOOL(0, "stateless-rpc", &stateless_rpc, + N_("quit after a single request/response exchange")), + OPT_BOOL(0, "advertise-refs", &advertise_refs, + N_("exit immediately after intial ref advertisement")), + OPT_BOOL(0, "strict", &strict, + N_("do not try /.git/ if is no Git directory")), + OPT_INTEGER(0, "timeout", &timeout, + N_("interrupt transfer after seconds of inactivity")), + OPT_END() + }; - git_setup_gettext(); - packet_trace_identity("upload-pack"); - git_extract_argv0_path(argv[0]); check_replace_refs = 0; - for (i = 1; i < argc; i++) { - const char *arg = argv[i]; + argc = parse_options(argc, argv, NULL, options, upload_pack_usage, 0); - if (arg[0] != '-') - break; - if (!strcmp(arg, "--advertise-refs")) { - advertise_refs = 1; - continue; - } - if (!strcmp(arg, "--stateless-rpc")) { - stateless_rpc = 1; - continue; - } - if (!strcmp(arg, "--strict")) { - strict = 1; - continue; - } - if (starts_with(arg, "--timeout=")) { - timeout = atoi(arg+10); - daemon_mode = 1; - continue; - } - if (!strcmp(arg, "--")) { - i++; - break; - } - } + if (argc != 1) + usage_with_options(upload_pack_usage, options); - if (i != argc-1) - usage(upload_pack_usage); + if (timeout) + daemon_mode = 1; setup_path(); - dir = argv[i]; + dir = argv[0]; if (!enter_repo(dir, strict)) die("'%s' does not appear to be a git repository", dir);