int cmd_merge_base(int argc, const char **argv, const char *prefix) { struct commit **rev; int rev_nr = 0; int show_all = 0; int octopus = 0; int reduce = 0; struct option options[] = { OPT_BOOLEAN('a', "all", &show_all, "output all common ancestors"), OPT_BOOLEAN(0, "octopus", &octopus, "find ancestors for a single n-way merge"), OPT_BOOLEAN(0, "independent", &reduce, "list revs not reachable from others"), OPT_END() }; git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, merge_base_usage, 0); if (!octopus && !reduce && argc < 2) usage_with_options(merge_base_usage, options); if (reduce && (show_all || octopus)) die("--independent cannot be used with other options"); if (octopus || reduce) return handle_octopus(argc, argv, reduce, show_all); rev = xmalloc(argc * sizeof(*rev)); while (argc-- > 0) rev[rev_nr++] = get_commit_reference(*argv++); return show_merge_base(rev, rev_nr, show_all); }
int cmd_shortlog(int argc, const char **argv, const char *prefix) { static struct shortlog log; static struct rev_info rev; int nongit = !startup_info->have_repository; static const struct option options[] = { OPT_BOOLEAN('n', "numbered", &log.sort_by_number, "sort output according to the number of commits per author"), OPT_BOOLEAN('s', "summary", &log.summary, "Suppress commit descriptions, only provides commit count"), OPT_BOOLEAN('e', "email", &log.email, "Show the email address of each author"), { OPTION_CALLBACK, 'w', NULL, &log, "w[,i1[,i2]]", "Linewrap output", PARSE_OPT_OPTARG, &parse_wrap_args }, OPT_END(), }; struct parse_opt_ctx_t ctx; git_config(git_default_config, NULL); shortlog_init(&log); init_revisions(&rev, prefix); parse_options_start(&ctx, argc, argv, prefix, options, PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0); for (;;) { switch (parse_options_step(&ctx, options, shortlog_usage)) { case PARSE_OPT_HELP: exit(129); case PARSE_OPT_DONE: goto parse_done; } parse_revision_opt(&rev, &ctx, options, shortlog_usage); } parse_done: argc = parse_options_end(&ctx); if (setup_revisions(argc, argv, &rev, NULL) != 1) { error(_("unrecognized argument: %s"), argv[1]); usage_with_options(shortlog_usage, options); } log.user_format = rev.commit_format == CMIT_FMT_USERFORMAT; log.abbrev = rev.abbrev; /* assume HEAD if from a tty */ if (!nongit && !rev.pending.nr && isatty(0)) add_head_to_pending(&rev); if (rev.pending.nr == 0) { if (isatty(0)) fprintf(stderr, _("(reading log message from standard input)\n")); read_from_stdin(&log); } else get_from_rev(&rev, &log); shortlog_output(&log); return 0; }
static void parse_args(int argc, const char **argv) { const char * const * usage_str = action == REVERT ? revert_usage : cherry_pick_usage; unsigned char sha1[20]; const char *arg; int noop; struct option options[] = { OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"), OPT_BOOLEAN('e', "edit", &edit, "edit the commit message"), OPT_BOOLEAN('x', NULL, &no_replay, "append commit name when cherry-picking"), OPT_BOOLEAN('r', NULL, &noop, "no-op (backward compatibility)"), OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"), OPT_INTEGER('m', "mainline", &mainline, "parent number"), OPT_END(), }; if (parse_options(argc, argv, options, usage_str, 0) != 1) usage_with_options(usage_str, options); arg = argv[0]; if (get_sha1(arg, sha1)) die ("Cannot find '%s'", arg); commit = (struct commit *)parse_object(sha1); if (!commit) die ("Could not find %s", sha1_to_hex(sha1)); if (commit->object.type == OBJ_TAG) { commit = (struct commit *) deref_tag((struct object *)commit, arg, strlen(arg)); } if (commit->object.type != OBJ_COMMIT) die ("'%s' does not point to a commit", arg); }
static int prune(int argc, const char **argv, const char *prefix) { struct notes_tree *t; int show_only = 0, verbose = 0; struct option options[] = { OPT_BOOLEAN('n', "dry-run", &show_only, "do not remove, show only"), OPT_BOOLEAN('v', "verbose", &verbose, "report pruned notes"), OPT_END() }; argc = parse_options(argc, argv, prefix, options, git_notes_prune_usage, 0); if (argc) { error("too many parameters"); usage_with_options(git_notes_prune_usage, options); } t = init_notes_check("prune"); prune_notes(t, (verbose ? NOTES_PRUNE_VERBOSE : 0) | (show_only ? NOTES_PRUNE_VERBOSE|NOTES_PRUNE_DRYRUN : 0) ); if (!show_only) commit_notes(t, "Notes removed by 'git notes prune'"); free_notes(t); return 0; }
int cmd_push(int argc, const char **argv, const char *prefix) { int flags = 0; int tags = 0; int rc; const char *repo = NULL; /* default repository */ struct option options[] = { OPT__VERBOSITY(&verbosity), OPT_STRING( 0 , "repo", &repo, N_("repository"), N_("repository")), OPT_BIT( 0 , "all", &flags, N_("push all refs"), TRANSPORT_PUSH_ALL), OPT_BIT( 0 , "mirror", &flags, N_("mirror all refs"), (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)), OPT_BOOLEAN( 0, "delete", &deleterefs, N_("delete refs")), OPT_BOOLEAN( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")), OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN), OPT_BIT( 0, "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN), OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE), { OPTION_CALLBACK, 0, "recurse-submodules", &flags, N_("check"), N_("control recursive pushing of submodules"), PARSE_OPT_OPTARG, option_parse_recurse_submodules }, OPT_BOOLEAN( 0 , "thin", &thin, N_("use thin pack")), OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", N_("receive pack program")), OPT_STRING( 0 , "exec", &receivepack, "receive-pack", N_("receive pack program")), OPT_BIT('u', "set-upstream", &flags, N_("set upstream for git pull/status"), TRANSPORT_PUSH_SET_UPSTREAM), OPT_BOOL(0, "progress", &progress, N_("force progress reporting")), OPT_BIT(0, "prune", &flags, N_("prune locally removed refs"), TRANSPORT_PUSH_PRUNE), OPT_BIT(0, "no-verify", &flags, N_("bypass pre-push hook"), TRANSPORT_PUSH_NO_HOOK), OPT_BIT(0, "follow-tags", &flags, N_("push missing but relevant tags"), TRANSPORT_PUSH_FOLLOW_TAGS), OPT_END() }; packet_trace_identity("push"); git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, push_usage, 0); if (deleterefs && (tags || (flags & (TRANSPORT_PUSH_ALL | TRANSPORT_PUSH_MIRROR)))) die(_("--delete is incompatible with --all, --mirror and --tags")); if (deleterefs && argc < 2) die(_("--delete doesn't make sense without any refs")); if (tags) add_refspec("refs/tags/*"); if (argc > 0) { repo = argv[0]; set_refspecs(argv + 1, argc - 1); } rc = do_push(repo, flags); if (rc == -1) usage_with_options(push_usage, options); else return rc; }
static int __cmd_evlist(const char *file_name, struct perf_attr_details *details) { struct perf_session *session; struct perf_evsel *pos; struct perf_data_file file = { .path = file_name, .mode = PERF_DATA_MODE_READ, .force = details->force, }; session = perf_session__new(&file, 0, NULL); if (session == NULL) return -1; evlist__for_each(session->evlist, pos) perf_evsel__fprintf(pos, details, stdout); perf_session__delete(session); return 0; } int cmd_evlist(int argc, const char **argv, const char *prefix __maybe_unused) { struct perf_attr_details details = { .verbose = false, }; const struct option options[] = { OPT_STRING('i', "input", &input_name, "file", "Input file name"), OPT_BOOLEAN('F', "freq", &details.freq, "Show the sample frequency"), OPT_BOOLEAN('v', "verbose", &details.verbose, "Show all event attr details"), OPT_BOOLEAN('g', "group", &details.event_group, "Show event group information"), OPT_BOOLEAN('f', "force", &details.force, "don't complain, do it"), OPT_END() }; const char * const evlist_usage[] = { "perf evlist [<options>]", NULL }; argc = parse_options(argc, argv, options, evlist_usage, 0); if (argc) usage_with_options(evlist_usage, options); if (details.event_group && (details.verbose || details.freq)) { usage_with_options_msg(evlist_usage, options, "--group option is not compatible with other options\n"); } return __cmd_evlist(input_name, &details); }
int main(int argc, const char **argv) { int force = 0; int num = 0; const char *path = NULL; struct argparse_option options[] = { OPT_HELP(), OPT_BOOLEAN('f', "force", &force, "force to do", NULL), OPT_STRING('p', "path", &path, "path to read", NULL), OPT_INTEGER('n', "num", &num, "selected num", NULL), OPT_END(), }; struct argparse argparse; argparse_init(&argparse, options, usage, 0); argc = argparse_parse(&argparse, argc, argv); if (force != 0) printf("force: %d\n", force); if (path != NULL) printf("path: %s\n", path); if (num != 0) printf("num: %d\n", num); if (argc != 0) { printf("argc: %d\n", argc); int i; for (i = 0; i < argc; i++) { printf("argv[%d]: %s\n", i, *(argv + i)); } } return 0; }
int main(int argc, const char **argv) { const char *usage[] = { "test-parse-options <options>", NULL }; struct option options[] = { OPT_BOOLEAN('b', "boolean", &boolean, "get a boolean"), OPT_INTEGER('i', "integer", &integer, "get a integer"), OPT_INTEGER('j', NULL, &integer, "get a integer, too"), OPT_GROUP("string options"), OPT_STRING('s', "string", &string, "string", "get a string"), OPT_STRING(0, "string2", &string, "str", "get another string"), OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"), OPT_STRING('o', NULL, &string, "str", "get another string"), OPT_GROUP("magic arguments"), OPT_ARGUMENT("quux", "means --quux"), OPT_END(), }; int i; argc = parse_options(argc, argv, options, usage, 0); printf("boolean: %d\n", boolean); printf("integer: %d\n", integer); printf("string: %s\n", string ? string : "(not set)"); for (i = 0; i < argc; i++) printf("arg %02d: %s\n", i, argv[i]); return 0; }
static void parse_args(int argc, const char **argv) { const char * const * usage_str = revert_or_cherry_pick_usage(); int noop; #ifdef USE_CPLUSPLUS_FOR_INIT #pragma cplusplus on #endif struct option options[] = { OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"), OPT_BOOLEAN('e', "edit", &edit, "edit the commit message"), { OPTION_BOOLEAN, 'r', NULL, &noop, NULL, "no-op (backward compatibility)", PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 0 }, OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"), OPT_INTEGER('m', "mainline", &mainline, "parent number"), OPT_RERERE_AUTOUPDATE(&allow_rerere_auto), OPT_STRING(0, "strategy", &strategy, "strategy", "merge strategy"), OPT_CALLBACK('X', "strategy-option", &xopts, "option", "option for merge strategy", option_parse_x), OPT_END(), OPT_END(), OPT_END(), }; #ifdef USE_CPLUSPLUS_FOR_INIT #pragma cplusplus reset #endif if (action == CHERRY_PICK) { struct option cp_extra[] = { OPT_BOOLEAN('x', NULL, &no_replay, "append commit name"), OPT_BOOLEAN(0, "ff", &allow_ff, "allow fast-forward"), OPT_END(), }; if (parse_options_concat(options, ARRAY_SIZE(options), cp_extra)) die(_("program error")); } commit_argc = parse_options(argc, argv, NULL, options, usage_str, PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN); if (commit_argc < 2) usage_with_options(usage_str, options); commit_argv = argv; }
int main(int argc, const char **argv) { const char *prefix = "prefix/"; const char *usage[] = { "test-parse-options <options>", NULL }; struct option options[] = { OPT_BOOLEAN('b', "boolean", &boolean, "get a boolean"), OPT_BIT('4', "or4", &boolean, "bitwise-or boolean with ...0100", 4), OPT_NEGBIT(0, "neg-or4", &boolean, "same as --no-or4", 4), OPT_GROUP(""), OPT_INTEGER('i', "integer", &integer, "get a integer"), OPT_INTEGER('j', NULL, &integer, "get a integer, too"), OPT_SET_INT(0, "set23", &integer, "set integer to 23", 23), OPT_DATE('t', NULL, ×tamp, "get timestamp of <time>"), OPT_CALLBACK('L', "length", &integer, "str", "get length of <str>", length_callback), OPT_FILENAME('F', "file", &file, "set file to <FILE>"), OPT_GROUP("String options"), OPT_STRING('s', "string", &string, "string", "get a string"), OPT_STRING(0, "string2", &string, "str", "get another string"), OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"), OPT_STRING('o', NULL, &string, "str", "get another string"), OPT_SET_PTR(0, "default-string", &string, "set string to default", (unsigned long)"default"), OPT_GROUP("Magic arguments"), OPT_ARGUMENT("quux", "means --quux"), OPT_NUMBER_CALLBACK(&integer, "set integer to NUM", number_callback), { OPTION_BOOLEAN, '+', NULL, &boolean, NULL, "same as -b", PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH }, OPT_GROUP("Standard options"), OPT__ABBREV(&abbrev), OPT__VERBOSE(&verbose), OPT__DRY_RUN(&dry_run), OPT__QUIET(&quiet), OPT_END(), }; int i; argc = parse_options(argc, argv, prefix, options, usage, 0); printf("boolean: %d\n", boolean); printf("integer: %u\n", integer); printf("timestamp: %lu\n", timestamp); printf("string: %s\n", string ? string : "(not set)"); printf("abbrev: %d\n", abbrev); printf("verbose: %d\n", verbose); printf("quiet: %s\n", quiet ? "yes" : "no"); printf("dry run: %s\n", dry_run ? "yes" : "no"); printf("file: %s\n", file ? file : "(not set)"); for (i = 0; i < argc; i++) printf("arg %02d: %s\n", i, argv[i]); return 0; }
int main(int argc, const char *argv[]) { int RetVal; dbg_logger_stdout(); #if defined(CONF_FAMILY_UNIX) signal(SIGINT, ExitFunc); signal(SIGTERM, ExitFunc); signal(SIGQUIT, ExitFunc); signal(SIGHUP, ReloadFunc); #endif char aUsage[128]; CConfig Config; str_format(aUsage, sizeof(aUsage), "%s [options]", argv[0]); const char *pConfigFile = 0; const char *pWebDir = 0; const char *pBindAddr = 0; struct argparse_option aOptions[] = { OPT_HELP(), OPT_BOOLEAN('v', "verbose", &Config.m_Verbose, "Verbose output", 0), OPT_STRING('c', "config", &pConfigFile, "Config file to use", 0), OPT_STRING('d', "web-dir", &pWebDir, "Location of the web directory", 0), OPT_STRING('b', "bind", &pBindAddr, "Bind to address", 0), OPT_INTEGER('p', "port", &Config.m_Port, "Listen on port", 0), OPT_END(), }; struct argparse Argparse; argparse_init(&Argparse, aOptions, aUsage, 0); argc = argparse_parse(&Argparse, argc, argv); if(pConfigFile) str_copy(Config.m_aConfigFile, pConfigFile, sizeof(Config.m_aConfigFile)); if(pWebDir) str_copy(Config.m_aWebDir, pWebDir, sizeof(Config.m_aWebDir)); if(pBindAddr) str_copy(Config.m_aBindAddr, pBindAddr, sizeof(Config.m_aBindAddr)); if(Config.m_aWebDir[strlen(Config.m_aWebDir)-1] != '/') str_append(Config.m_aWebDir, "/", sizeof(Config.m_aWebDir)); if(!fs_is_dir(Config.m_aWebDir)) { dbg_msg("main", "ERROR: Can't find web directory: %s", Config.m_aWebDir); return 1; } char aTmp[1024]; str_format(aTmp, sizeof(aTmp), "%s%s", Config.m_aWebDir, Config.m_aJSONFile); str_copy(Config.m_aJSONFile, aTmp, sizeof(Config.m_aJSONFile)); CMain Main(Config); RetVal = Main.Run(); return RetVal; }
int cmd_prune(int argc, const char **argv, const char *prefix) { struct rev_info revs; const struct option options[] = { OPT_BOOLEAN('n', NULL, &show_only, "do not remove, show only"), OPT_BOOLEAN('v', NULL, &verbose, "report pruned objects"), OPT_DATE(0, "expire", &expire, "expire objects older than <time>"), OPT_END() }; char *s; expire = ULONG_MAX; save_commit_buffer = 0; read_replace_refs = 0; init_revisions(&revs, prefix); argc = parse_options(argc, argv, prefix, options, prune_usage, 0); while (argc--) { unsigned char sha1[20]; const char *name = *argv++; if (!get_sha1(name, sha1)) { struct object *object = parse_object(sha1); if (!object) die("bad object: %s", name); add_pending_object(&revs, object, ""); } else die("unrecognized argument: %s", name); } mark_reachable_objects(&revs, 1); prune_object_dir(get_object_directory()); prune_packed_objects(show_only); remove_temporary_files(get_object_directory()); s = xstrdup(mkpath("%s/pack", get_object_directory())); remove_temporary_files(s); free(s); return 0; }
static void parse_args(int argc, const char **argv) { const char * const * usage_str = revert_or_cherry_pick_usage(); int noop; struct option options[] = { OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"), OPT_BOOLEAN('e', "edit", &edit, "edit the commit message"), OPT_BOOLEAN('r', NULL, &noop, "no-op (backward compatibility)"), OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"), OPT_INTEGER('m', "mainline", &mainline, "parent number"), OPT_RERERE_AUTOUPDATE(&allow_rerere_auto), OPT_STRING(0, "strategy", &strategy, "strategy", "merge strategy"), OPT_END(), OPT_END(), OPT_END(), }; if (action == CHERRY_PICK) { struct option cp_extra[] = { OPT_BOOLEAN('x', NULL, &no_replay, "append commit name"), OPT_BOOLEAN(0, "ff", &allow_ff, "allow fast-forward"), OPT_END(), }; if (parse_options_concat(options, ARRAY_SIZE(options), cp_extra)) die("program error"); } commit_argc = parse_options(argc, argv, NULL, options, usage_str, PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN); if (commit_argc < 2) usage_with_options(usage_str, options); commit_argv = argv; }
int cmd_push(int argc, const char **argv, const char *prefix) { int flags = 0; int tags = 0; int rc; const char *repo = NULL; /* default repository */ struct option options[] = { OPT_BIT('q', "quiet", &flags, "be quiet", TRANSPORT_PUSH_QUIET), OPT_BIT('v', "verbose", &flags, "be verbose", TRANSPORT_PUSH_VERBOSE), OPT_STRING( 0 , "repo", &repo, "repository", "repository"), OPT_BIT( 0 , "all", &flags, "push all refs", TRANSPORT_PUSH_ALL), OPT_BIT( 0 , "mirror", &flags, "mirror all refs", (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)), OPT_BOOLEAN( 0 , "tags", &tags, "push tags"), OPT_BIT('n' , "dry-run", &flags, "dry run", TRANSPORT_PUSH_DRY_RUN), OPT_BIT( 0, "porcelain", &flags, "machine-readable output", TRANSPORT_PUSH_PORCELAIN), OPT_BIT('f', "force", &flags, "force updates", TRANSPORT_PUSH_FORCE), OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"), OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"), OPT_STRING( 0 , "exec", &receivepack, "receive-pack", "receive pack program"), OPT_END() }; argc = parse_options(argc, argv, prefix, options, push_usage, 0); if (tags) add_refspec("refs/tags/*"); if (argc > 0) { repo = argv[0]; set_refspecs(argv + 1, argc - 1); } rc = do_push(repo, flags); if (rc == -1) usage_with_options(push_usage, options); else return rc; }
int cmd_bisect__helper(int argc, const char **argv, const char *prefix) { int next_all = 0; struct option options[] = { OPT_BOOLEAN(0, "next-all", &next_all, "perform 'git bisect next'"), OPT_END() }; argc = parse_options(argc, argv, prefix, options, git_bisect_helper_usage, 0); if (!next_all) usage_with_options(git_bisect_helper_usage, options); /* next-all */ return bisect_next_all(prefix); }
int cmd_push(int argc, const char **argv, const char *prefix) { int flags = 0; int all = 0; int mirror = 0; int dry_run = 0; int force = 0; int tags = 0; int rc; const char *repo = NULL; /* default repository */ struct option options[] = { OPT__VERBOSE(&verbose), OPT_STRING( 0 , "repo", &repo, "repository", "repository"), OPT_BOOLEAN( 0 , "all", &all, "push all refs"), OPT_BOOLEAN( 0 , "mirror", &mirror, "mirror all refs"), OPT_BOOLEAN( 0 , "tags", &tags, "push tags"), OPT_BOOLEAN( 0 , "dry-run", &dry_run, "dry run"), OPT_BOOLEAN('f', "force", &force, "force updates"), OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"), OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"), OPT_STRING( 0 , "exec", &receivepack, "receive-pack", "receive pack program"), OPT_END() }; argc = parse_options(argc, argv, options, push_usage, 0); if (force) flags |= TRANSPORT_PUSH_FORCE; if (dry_run) flags |= TRANSPORT_PUSH_DRY_RUN; if (verbose) flags |= TRANSPORT_PUSH_VERBOSE; if (tags) add_refspec("refs/tags/*"); if (all) flags |= TRANSPORT_PUSH_ALL; if (mirror) flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE); if (argc > 0) { repo = argv[0]; set_refspecs(argv + 1, argc - 1); } rc = do_push(repo, flags); if (rc == -1) usage_with_options(push_usage, options); else return rc; }
int cmd_merge_base(int argc, const char **argv, const char *prefix) { struct commit **rev; int rev_nr = 0; int show_all = 0; struct option options[] = { OPT_BOOLEAN('a', "all", &show_all, "outputs all common ancestors"), OPT_END() }; git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, merge_base_usage, 0); if (argc < 2) usage_with_options(merge_base_usage, options); rev = xmalloc(argc * sizeof(*rev)); while (argc-- > 0) rev[rev_nr++] = get_commit_reference(*argv++); return show_merge_base(rev, rev_nr, show_all); }
static int remove_cmd(int argc, const char **argv, const char *prefix) { unsigned flag = 0; int from_stdin = 0; struct option options[] = { OPT_BIT(0, "ignore-missing", &flag, N_("attempt to remove non-existent note is not an error"), IGNORE_MISSING), OPT_BOOLEAN(0, "stdin", &from_stdin, N_("read object names from the standard input")), OPT_END() }; struct notes_tree *t; int retval = 0; argc = parse_options(argc, argv, prefix, options, git_notes_remove_usage, 0); t = init_notes_check("remove"); if (!argc && !from_stdin) { retval = remove_one_note(t, "HEAD", flag); } else { while (*argv) { retval |= remove_one_note(t, *argv, flag); argv++; } } if (from_stdin) { struct strbuf sb = STRBUF_INIT; while (strbuf_getwholeline(&sb, stdin, '\n') != EOF) { strbuf_rtrim(&sb); retval |= remove_one_note(t, sb.buf, flag); } strbuf_release(&sb); } if (!retval) commit_notes(t, "Notes removed by 'git notes remove'"); free_notes(t); return retval; }
static struct string_list option_reference; static int opt_parse_reference(const struct option *opt, const char *arg, int unset) { struct string_list *option_reference = opt->value; if (!arg) return -1; string_list_append(option_reference, arg); return 0; } static struct option builtin_clone_options[] = { OPT__VERBOSITY(&option_verbosity), OPT_BOOL(0, "progress", &option_progress, "force progress reporting"), OPT_BOOLEAN('n', "no-checkout", &option_no_checkout, "don't create a checkout"), OPT_BOOLEAN(0, "bare", &option_bare, "create a bare repository"), { OPTION_BOOLEAN, 0, "naked", &option_bare, NULL, "create a bare repository", PARSE_OPT_NOARG | PARSE_OPT_HIDDEN }, OPT_BOOLEAN(0, "mirror", &option_mirror, "create a mirror repository (implies bare)"), OPT_BOOLEAN('l', "local", &option_local, "to clone from a local repository"), OPT_BOOLEAN(0, "no-hardlinks", &option_no_hardlinks, "don't use local hardlinks, always copy"), OPT_BOOLEAN('s', "shared", &option_shared, "setup as shared repository"), OPT_BOOLEAN(0, "recursive", &option_recursive, "initialize submodules in the clone"), OPT_BOOLEAN(0, "recurse-submodules", &option_recursive,
#include "util/debug.h" #include "util/parse-options.h" #include "util/session.h" #include "util/symbol.h" static char const *input_name = "perf.data"; static bool force; static bool with_hits; static const char * const buildid_list_usage[] = { "perf buildid-list [<options>]", NULL }; static const struct option options[] = { OPT_BOOLEAN('H', "with-hits", &with_hits, "Show only DSOs with hits"), OPT_STRING('i', "input", &input_name, "file", "input file name"), OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), OPT_INCR('v', "verbose", &verbose, "be more verbose"), OPT_END() }; static int __cmd_buildid_list(void) { int err = -1; struct perf_session *session; session = perf_session__new(input_name, O_RDONLY, force); if (session == NULL)
int cmd_grep(int argc, const char **argv, const char *prefix) { int hit = 0; int cached = 0, untracked = 0, opt_exclude = -1; int seen_dashdash = 0; int external_grep_allowed__ignored; const char *show_in_pager = NULL, *default_pager = "dummy"; struct grep_opt opt; struct object_array list = OBJECT_ARRAY_INIT; const char **paths = NULL; struct pathspec pathspec; struct string_list path_list = STRING_LIST_INIT_NODUP; int i; int dummy; int use_index = 1; int pattern_type_arg = GREP_PATTERN_TYPE_UNSPECIFIED; struct option options[] = { OPT_BOOLEAN(0, "cached", &cached, N_("search in index instead of in the work tree")), OPT_NEGBIT(0, "no-index", &use_index, N_("find in contents not managed by git"), 1), OPT_BOOLEAN(0, "untracked", &untracked, N_("search in both tracked and untracked files")), OPT_SET_INT(0, "exclude-standard", &opt_exclude, N_("search also in ignored files"), 1), OPT_GROUP(""), OPT_BOOLEAN('v', "invert-match", &opt.invert, N_("show non-matching lines")), OPT_BOOLEAN('i', "ignore-case", &opt.ignore_case, N_("case insensitive matching")), OPT_BOOLEAN('w', "word-regexp", &opt.word_regexp, N_("match patterns only at word boundaries")), OPT_SET_INT('a', "text", &opt.binary, N_("process binary files as text"), GREP_BINARY_TEXT), OPT_SET_INT('I', NULL, &opt.binary, N_("don't match patterns in binary files"), GREP_BINARY_NOMATCH), { OPTION_INTEGER, 0, "max-depth", &opt.max_depth, N_("depth"), N_("descend at most <depth> levels"), PARSE_OPT_NONEG, NULL, 1 }, OPT_GROUP(""), OPT_SET_INT('E', "extended-regexp", &pattern_type_arg, N_("use extended POSIX regular expressions"), GREP_PATTERN_TYPE_ERE), OPT_SET_INT('G', "basic-regexp", &pattern_type_arg, N_("use basic POSIX regular expressions (default)"), GREP_PATTERN_TYPE_BRE), OPT_SET_INT('F', "fixed-strings", &pattern_type_arg, N_("interpret patterns as fixed strings"), GREP_PATTERN_TYPE_FIXED), OPT_SET_INT('P', "perl-regexp", &pattern_type_arg, N_("use Perl-compatible regular expressions"), GREP_PATTERN_TYPE_PCRE), OPT_GROUP(""), OPT_BOOLEAN('n', "line-number", &opt.linenum, N_("show line numbers")), OPT_NEGBIT('h', NULL, &opt.pathname, N_("don't show filenames"), 1), OPT_BIT('H', NULL, &opt.pathname, N_("show filenames"), 1), OPT_NEGBIT(0, "full-name", &opt.relative, N_("show filenames relative to top directory"), 1), OPT_BOOLEAN('l', "files-with-matches", &opt.name_only, N_("show only filenames instead of matching lines")), OPT_BOOLEAN(0, "name-only", &opt.name_only, N_("synonym for --files-with-matches")), OPT_BOOLEAN('L', "files-without-match", &opt.unmatch_name_only, N_("show only the names of files without match")), OPT_BOOLEAN('z', "null", &opt.null_following_name, N_("print NUL after filenames")), OPT_BOOLEAN('c', "count", &opt.count, N_("show the number of matches instead of matching lines")), OPT__COLOR(&opt.color, N_("highlight matches")), OPT_BOOLEAN(0, "break", &opt.file_break, N_("print empty line between matches from different files")), OPT_BOOLEAN(0, "heading", &opt.heading, N_("show filename only once above matches from same file")), OPT_GROUP(""), OPT_CALLBACK('C', "context", &opt, N_("n"), N_("show <n> context lines before and after matches"), context_callback), OPT_INTEGER('B', "before-context", &opt.pre_context, N_("show <n> context lines before matches")), OPT_INTEGER('A', "after-context", &opt.post_context, N_("show <n> context lines after matches")), OPT_NUMBER_CALLBACK(&opt, N_("shortcut for -C NUM"), context_callback), OPT_BOOLEAN('p', "show-function", &opt.funcname, N_("show a line with the function name before matches")), OPT_BOOLEAN('W', "function-context", &opt.funcbody, N_("show the surrounding function")), OPT_GROUP(""), OPT_CALLBACK('f', NULL, &opt, N_("file"), N_("read patterns from file"), file_callback), { OPTION_CALLBACK, 'e', NULL, &opt, N_("pattern"), N_("match <pattern>"), PARSE_OPT_NONEG, pattern_callback }, { OPTION_CALLBACK, 0, "and", &opt, NULL, N_("combine patterns specified with -e"), PARSE_OPT_NOARG | PARSE_OPT_NONEG, and_callback }, OPT_BOOLEAN(0, "or", &dummy, ""), { OPTION_CALLBACK, 0, "not", &opt, NULL, "", PARSE_OPT_NOARG | PARSE_OPT_NONEG, not_callback }, { OPTION_CALLBACK, '(', NULL, &opt, NULL, "", PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH, open_callback }, { OPTION_CALLBACK, ')', NULL, &opt, NULL, "", PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH, close_callback }, OPT__QUIET(&opt.status_only, N_("indicate hit with exit status without output")), OPT_BOOLEAN(0, "all-match", &opt.all_match, N_("show only matches from files that match all patterns")), { OPTION_SET_INT, 0, "debug", &opt.debug, NULL, N_("show parse tree for grep expression"), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1 }, OPT_GROUP(""), { OPTION_STRING, 'O', "open-files-in-pager", &show_in_pager, N_("pager"), N_("show matching files in the pager"), PARSE_OPT_OPTARG, NULL, (intptr_t)default_pager }, OPT_BOOLEAN(0, "ext-grep", &external_grep_allowed__ignored, N_("allow calling of grep(1) (ignored by this build)")), { OPTION_CALLBACK, 0, "help-all", &options, NULL, N_("show usage"), PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback }, OPT_END() }; /* * 'git grep -h', unlike 'git grep -h <pattern>', is a request * to show usage information and exit. */ if (argc == 2 && !strcmp(argv[1], "-h")) usage_with_options(grep_usage, options); init_grep_defaults(); git_config(grep_cmd_config, NULL); grep_init(&opt, prefix); /* * If there is no -- then the paths must exist in the working * tree. If there is no explicit pattern specified with -e or * -f, we take the first unrecognized non option to be the * pattern, but then what follows it must be zero or more * valid refs up to the -- (if exists), and then existing * paths. If there is an explicit pattern, then the first * unrecognized non option is the beginning of the refs list * that continues up to the -- (if exists), and then paths. */ argc = parse_options(argc, argv, prefix, options, grep_usage, PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_STOP_AT_NON_OPTION | PARSE_OPT_NO_INTERNAL_HELP); grep_commit_pattern_type(pattern_type_arg, &opt); if (use_index && !startup_info->have_repository) /* die the same way as if we did it at the beginning */ setup_git_directory(); /* * skip a -- separator; we know it cannot be * separating revisions from pathnames if * we haven't even had any patterns yet */ if (argc > 0 && !opt.pattern_list && !strcmp(argv[0], "--")) { argv++; argc--; } /* First unrecognized non-option token */ if (argc > 0 && !opt.pattern_list) { append_grep_pattern(&opt, argv[0], "command line", 0, GREP_PATTERN); argv++; argc--; } if (show_in_pager == default_pager) show_in_pager = git_pager(1); if (show_in_pager) { opt.color = 0; opt.name_only = 1; opt.null_following_name = 1; opt.output_priv = &path_list; opt.output = append_path; string_list_append(&path_list, show_in_pager); use_threads = 0; } if ((opt.binary & GREP_BINARY_NOMATCH)) use_threads = 0; if (!opt.pattern_list) die(_("no pattern given.")); if (!opt.fixed && opt.ignore_case) opt.regflags |= REG_ICASE; compile_grep_patterns(&opt); /* Check revs and then paths */ for (i = 0; i < argc; i++) { const char *arg = argv[i]; unsigned char sha1[20]; /* Is it a rev? */ if (!get_sha1(arg, sha1)) { struct object *object = parse_object(sha1); if (!object) die(_("bad object %s"), arg); add_object_array(object, arg, &list); continue; } if (!strcmp(arg, "--")) { i++; seen_dashdash = 1; } break; } #ifndef NO_PTHREADS if (list.nr || cached || online_cpus() == 1) use_threads = 0; #else use_threads = 0; #endif #ifndef NO_PTHREADS if (use_threads) { if (!(opt.name_only || opt.unmatch_name_only || opt.count) && (opt.pre_context || opt.post_context || opt.file_break || opt.funcbody)) skip_first_line = 1; start_threads(&opt); } #endif /* The rest are paths */ if (!seen_dashdash) { int j; for (j = i; j < argc; j++) verify_filename(prefix, argv[j], j == i); } paths = get_pathspec(prefix, argv + i); init_pathspec(&pathspec, paths); pathspec.max_depth = opt.max_depth; pathspec.recursive = 1; if (show_in_pager && (cached || list.nr)) die(_("--open-files-in-pager only works on the worktree")); if (show_in_pager && opt.pattern_list && !opt.pattern_list->next) { const char *pager = path_list.items[0].string; int len = strlen(pager); if (len > 4 && is_dir_sep(pager[len - 5])) pager += len - 4; if (opt.ignore_case && !strcmp("less", pager)) string_list_append(&path_list, "-i"); if (!strcmp("less", pager) || !strcmp("vi", pager)) { struct strbuf buf = STRBUF_INIT; strbuf_addf(&buf, "+/%s%s", strcmp("less", pager) ? "" : "*", opt.pattern_list->pattern); string_list_append(&path_list, buf.buf); strbuf_detach(&buf, NULL); } } if (!show_in_pager) setup_pager(); if (!use_index && (untracked || cached)) die(_("--cached or --untracked cannot be used with --no-index.")); if (!use_index || untracked) { int use_exclude = (opt_exclude < 0) ? use_index : !!opt_exclude; if (list.nr) die(_("--no-index or --untracked cannot be used with revs.")); hit = grep_directory(&opt, &pathspec, use_exclude); } else if (0 <= opt_exclude) { die(_("--[no-]exclude-standard cannot be used for tracked contents.")); } else if (!list.nr) { if (!cached) setup_work_tree(); hit = grep_cache(&opt, &pathspec, cached); } else { if (cached) die(_("both --cached and trees are given.")); hit = grep_objects(&opt, &pathspec, &list); } if (use_threads) hit |= wait_all(); if (hit && show_in_pager) run_pager(&opt, prefix); free_grep_patterns(&opt); return !hit; }
int cmd_show_branch(int ac, const char **av, const char *prefix) { struct commit *rev[MAX_REVS], *commit; char *reflog_msg[MAX_REVS]; struct commit_list *list = NULL, *seen = NULL; unsigned int rev_mask[MAX_REVS]; int num_rev, i, extra = 0; int all_heads = 0, all_remotes = 0; int all_mask, all_revs; int lifo = 1; char head[128]; const char *head_p; int head_len; unsigned char head_sha1[20]; int merge_base = 0; int independent = 0; int no_name = 0; int sha1_name = 0; int shown_merge_point = 0; int with_current_branch = 0; int head_at = -1; int topics = 0; int dense = 1; const char *reflog_base = NULL; struct option builtin_show_branch_options[] = { OPT_BOOLEAN('a', "all", &all_heads, "show remote-tracking and local branches"), OPT_BOOLEAN('r', "remotes", &all_remotes, "show remote-tracking branches"), OPT__COLOR(&showbranch_use_color, "color '*!+-' corresponding to the branch"), { OPTION_INTEGER, 0, "more", &extra, "n", "show <n> more commits after the common ancestor", PARSE_OPT_OPTARG, NULL, (intptr_t)1 }, OPT_SET_INT(0, "list", &extra, "synonym to more=-1", -1), OPT_BOOLEAN(0, "no-name", &no_name, "suppress naming strings"), OPT_BOOLEAN(0, "current", &with_current_branch, "include the current branch"), OPT_BOOLEAN(0, "sha1-name", &sha1_name, "name commits with their object names"), OPT_BOOLEAN(0, "merge-base", &merge_base, "show possible merge bases"), OPT_BOOLEAN(0, "independent", &independent, "show refs unreachable from any other ref"), OPT_BOOLEAN(0, "topo-order", &lifo, "show commits in topological order"), OPT_BOOLEAN(0, "topics", &topics, "show only commits not on the first branch"), OPT_SET_INT(0, "sparse", &dense, "show merges reachable from only one tip", 0), OPT_SET_INT(0, "date-order", &lifo, "show commits where no parent comes before its " "children", 0), { OPTION_CALLBACK, 'g', "reflog", &reflog_base, "<n>[,<base>]", "show <n> most recent ref-log entries starting at " "base", PARSE_OPT_OPTARG | PARSE_OPT_LITERAL_ARGHELP, parse_reflog_param }, OPT_END() }; git_config(git_show_branch_config, NULL); if (showbranch_use_color == -1) showbranch_use_color = git_use_color_default; /* If nothing is specified, try the default first */ if (ac == 1 && default_num) { ac = default_num; av = default_arg; } ac = parse_options(ac, av, prefix, builtin_show_branch_options, show_branch_usage, PARSE_OPT_STOP_AT_NON_OPTION); if (all_heads) all_remotes = 1; if (extra || reflog) { /* "listing" mode is incompatible with * independent nor merge-base modes. */ if (independent || merge_base) usage_with_options(show_branch_usage, builtin_show_branch_options); if (reflog && ((0 < extra) || all_heads || all_remotes)) /* * Asking for --more in reflog mode does not * make sense. --list is Ok. * * Also --all and --remotes do not make sense either. */ die("--reflog is incompatible with --all, --remotes, " "--independent or --merge-base"); } /* If nothing is specified, show all branches by default */ if (ac + all_heads + all_remotes == 0) all_heads = 1; if (reflog) { unsigned char sha1[20]; char nth_desc[256]; char *ref; int base = 0; if (ac == 0) { static const char *fake_av[2]; const char *refname; refname = resolve_ref("HEAD", sha1, 1, NULL); fake_av[0] = xstrdup(refname); fake_av[1] = NULL; av = fake_av; ac = 1; } if (ac != 1) die("--reflog option needs one branch name"); if (MAX_REVS < reflog) die("Only %d entries can be shown at one time.", MAX_REVS); if (!dwim_ref(*av, strlen(*av), sha1, &ref)) die("No such ref %s", *av); /* Has the base been specified? */ if (reflog_base) { char *ep; base = strtoul(reflog_base, &ep, 10); if (*ep) { /* Ah, that is a date spec... */ unsigned long at; at = approxidate(reflog_base); read_ref_at(ref, at, -1, sha1, NULL, NULL, NULL, &base); } } for (i = 0; i < reflog; i++) { char *logmsg, *m; const char *msg; unsigned long timestamp; int tz; if (read_ref_at(ref, 0, base+i, sha1, &logmsg, ×tamp, &tz, NULL)) { reflog = i; break; } msg = strchr(logmsg, '\t'); if (!msg) msg = "(none)"; else msg++; m = xmalloc(strlen(msg) + 200); sprintf(m, "(%s) %s", show_date(timestamp, tz, 1), msg); reflog_msg[i] = m; free(logmsg); sprintf(nth_desc, "%s@{%d}", *av, base+i); append_ref(nth_desc, sha1, 1); } } else if (all_heads + all_remotes) snarf_refs(all_heads, all_remotes); else { while (0 < ac) { append_one_rev(*av); ac--; av++; } } head_p = resolve_ref("HEAD", head_sha1, 1, NULL); if (head_p) { head_len = strlen(head_p); memcpy(head, head_p, head_len + 1); } else { head_len = 0; head[0] = 0; } if (with_current_branch && head_p) { int has_head = 0; for (i = 0; !has_head && i < ref_name_cnt; i++) { /* We are only interested in adding the branch * HEAD points at. */ if (rev_is_head(head, head_len, ref_name[i], head_sha1, NULL)) has_head++; } if (!has_head) { int offset = !prefixcmp(head, "refs/heads/") ? 11 : 0; append_one_rev(head + offset); } } if (!ref_name_cnt) { fprintf(stderr, "No revs to be shown.\n"); exit(0); } for (num_rev = 0; ref_name[num_rev]; num_rev++) { unsigned char revkey[20]; unsigned int flag = 1u << (num_rev + REV_SHIFT); if (MAX_REVS <= num_rev) die("cannot handle more than %d revs.", MAX_REVS); if (get_sha1(ref_name[num_rev], revkey)) die("'%s' is not a valid ref.", ref_name[num_rev]); commit = lookup_commit_reference(revkey); if (!commit) die("cannot find commit %s (%s)", ref_name[num_rev], revkey); parse_commit(commit); mark_seen(commit, &seen); /* rev#0 uses bit REV_SHIFT, rev#1 uses bit REV_SHIFT+1, * and so on. REV_SHIFT bits from bit 0 are used for * internal bookkeeping. */ commit->object.flags |= flag; if (commit->object.flags == flag) commit_list_insert_by_date(commit, &list); rev[num_rev] = commit; } for (i = 0; i < num_rev; i++) rev_mask[i] = rev[i]->object.flags; if (0 <= extra) join_revs(&list, &seen, num_rev, extra); commit_list_sort_by_date(&seen); if (merge_base) return show_merge_base(seen, num_rev); if (independent) return show_independent(rev, num_rev, ref_name, rev_mask); /* Show list; --more=-1 means list-only */ if (1 < num_rev || extra < 0) { for (i = 0; i < num_rev; i++) { int j; int is_head = rev_is_head(head, head_len, ref_name[i], head_sha1, rev[i]->object.sha1); if (extra < 0) printf("%c [%s] ", is_head ? '*' : ' ', ref_name[i]); else { for (j = 0; j < i; j++) putchar(' '); printf("%s%c%s [%s] ", get_color_code(i % COLUMN_COLORS_MAX), is_head ? '*' : '!', get_color_reset_code(), ref_name[i]); } if (!reflog) { /* header lines never need name */ show_one_commit(rev[i], 1); } else puts(reflog_msg[i]); if (is_head) head_at = i; } if (0 <= extra) { for (i = 0; i < num_rev; i++) putchar('-'); putchar('\n'); } } if (extra < 0) exit(0); /* Sort topologically */ sort_in_topological_order(&seen, lifo); /* Give names to commits */ if (!sha1_name && !no_name) name_commits(seen, rev, ref_name, num_rev); all_mask = ((1u << (REV_SHIFT + num_rev)) - 1); all_revs = all_mask & ~((1u << REV_SHIFT) - 1); while (seen) { struct commit *commit = pop_one_commit(&seen); int this_flag = commit->object.flags; int is_merge_point = ((this_flag & all_revs) == all_revs); shown_merge_point |= is_merge_point; if (1 < num_rev) { int is_merge = !!(commit->parents && commit->parents->next); if (topics && !is_merge_point && (this_flag & (1u << REV_SHIFT))) continue; if (dense && is_merge && omit_in_dense(commit, rev, num_rev)) continue; for (i = 0; i < num_rev; i++) { int mark; if (!(this_flag & (1u << (i + REV_SHIFT)))) mark = ' '; else if (is_merge) mark = '-'; else if (i == head_at) mark = '*'; else mark = '+'; printf("%s%c%s", get_color_code(i % COLUMN_COLORS_MAX), mark, get_color_reset_code()); } putchar(' '); } show_one_commit(commit, no_name); if (shown_merge_point && --extra < 0) break; } return 0; }
int cmd_format_patch(int argc, const char **argv, const char *prefix) { struct commit *commit; struct commit **list = NULL; struct rev_info rev; int nr = 0, total, i; int use_stdout = 0; int start_number = -1; int numbered_files = 0; /* _just_ numbers */ int ignore_if_in_upstream = 0; int cover_letter = 0; int boundary_count = 0; int no_binary_diff = 0; struct commit *origin = NULL, *head = NULL; const char *in_reply_to = NULL; struct patch_ids ids; char *add_signoff = NULL; struct strbuf buf = STRBUF_INIT; int use_patch_format = 0; const struct option builtin_format_patch_options[] = { { OPTION_CALLBACK, 'n', "numbered", &numbered, NULL, "use [PATCH n/m] even with a single patch", PARSE_OPT_NOARG, numbered_callback }, { OPTION_CALLBACK, 'N', "no-numbered", &numbered, NULL, "use [PATCH] even with multiple patches", PARSE_OPT_NOARG, no_numbered_callback }, OPT_BOOLEAN('s', "signoff", &do_signoff, "add Signed-off-by:"), OPT_BOOLEAN(0, "stdout", &use_stdout, "print patches to standard out"), OPT_BOOLEAN(0, "cover-letter", &cover_letter, "generate a cover letter"), OPT_BOOLEAN(0, "numbered-files", &numbered_files, "use simple number sequence for output file names"), OPT_STRING(0, "suffix", &fmt_patch_suffix, "sfx", "use <sfx> instead of '.patch'"), OPT_INTEGER(0, "start-number", &start_number, "start numbering patches at <n> instead of 1"), { OPTION_CALLBACK, 0, "subject-prefix", &rev, "prefix", "Use [<prefix>] instead of [PATCH]", PARSE_OPT_NONEG, subject_prefix_callback }, { OPTION_CALLBACK, 'o', "output-directory", &output_directory, "dir", "store resulting files in <dir>", PARSE_OPT_NONEG, output_directory_callback }, { OPTION_CALLBACK, 'k', "keep-subject", &rev, NULL, "don't strip/add [PATCH]", PARSE_OPT_NOARG | PARSE_OPT_NONEG, keep_callback }, OPT_BOOLEAN(0, "no-binary", &no_binary_diff, "don't output binary diffs"), OPT_BOOLEAN(0, "ignore-if-in-upstream", &ignore_if_in_upstream, "don't include a patch matching a commit upstream"), { OPTION_BOOLEAN, 'p', "no-stat", &use_patch_format, NULL, "show patch format instead of default (patch + stat)", PARSE_OPT_NONEG | PARSE_OPT_NOARG }, OPT_GROUP("Messaging"), { OPTION_CALLBACK, 0, "add-header", NULL, "header", "add email header", PARSE_OPT_NONEG, header_callback }, { OPTION_CALLBACK, 0, "cc", NULL, "email", "add Cc: header", PARSE_OPT_NONEG, cc_callback }, OPT_STRING(0, "in-reply-to", &in_reply_to, "message-id", "make first mail a reply to <message-id>"), { OPTION_CALLBACK, 0, "attach", &rev, "boundary", "attach the patch", PARSE_OPT_OPTARG, attach_callback }, { OPTION_CALLBACK, 0, "inline", &rev, "boundary", "inline the patch", PARSE_OPT_OPTARG | PARSE_OPT_NONEG, inline_callback }, { OPTION_CALLBACK, 0, "thread", &thread, "style", "enable message threading, styles: shallow, deep", PARSE_OPT_OPTARG, thread_callback }, OPT_END() }; git_config(git_format_config, NULL); init_revisions(&rev, prefix); rev.commit_format = CMIT_FMT_EMAIL; rev.verbose_header = 1; rev.diff = 1; rev.combine_merges = 0; rev.ignore_merges = 1; DIFF_OPT_SET(&rev.diffopt, RECURSIVE); rev.subject_prefix = fmt_patch_subject_prefix; if (default_attach) { rev.mime_boundary = default_attach; rev.no_inline = 1; } /* * Parse the arguments before setup_revisions(), or something * like "git format-patch -o a123 HEAD^.." may fail; a123 is * possibly a valid SHA1. */ argc = parse_options(argc, argv, prefix, builtin_format_patch_options, builtin_format_patch_usage, PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN | PARSE_OPT_KEEP_DASHDASH); if (do_signoff) { const char *committer; const char *endpos; committer = git_committer_info(IDENT_ERROR_ON_NO_NAME); endpos = strchr(committer, '>'); if (!endpos) die("bogus committer info %s", committer); add_signoff = xmemdupz(committer, endpos - committer + 1); } for (i = 0; i < extra_hdr_nr; i++) { strbuf_addstr(&buf, extra_hdr[i]); strbuf_addch(&buf, '\n'); } if (extra_to_nr) strbuf_addstr(&buf, "To: "); for (i = 0; i < extra_to_nr; i++) { if (i) strbuf_addstr(&buf, " "); strbuf_addstr(&buf, extra_to[i]); if (i + 1 < extra_to_nr) strbuf_addch(&buf, ','); strbuf_addch(&buf, '\n'); } if (extra_cc_nr) strbuf_addstr(&buf, "Cc: "); for (i = 0; i < extra_cc_nr; i++) { if (i) strbuf_addstr(&buf, " "); strbuf_addstr(&buf, extra_cc[i]); if (i + 1 < extra_cc_nr) strbuf_addch(&buf, ','); strbuf_addch(&buf, '\n'); } rev.extra_headers = strbuf_detach(&buf, NULL); if (start_number < 0) start_number = 1; /* * If numbered is set solely due to format.numbered in config, * and it would conflict with --keep-subject (-k) from the * command line, reset "numbered". */ if (numbered && keep_subject && !numbered_cmdline_opt) numbered = 0; if (numbered && keep_subject) die ("-n and -k are mutually exclusive."); if (keep_subject && subject_prefix) die ("--subject-prefix and -k are mutually exclusive."); argc = setup_revisions(argc, argv, &rev, "HEAD"); if (argc > 1) die ("unrecognized argument: %s", argv[1]); if (rev.diffopt.output_format & DIFF_FORMAT_NAME) die("--name-only does not make sense"); if (rev.diffopt.output_format & DIFF_FORMAT_NAME_STATUS) die("--name-status does not make sense"); if (rev.diffopt.output_format & DIFF_FORMAT_CHECKDIFF) die("--check does not make sense"); if (!use_patch_format && (!rev.diffopt.output_format || rev.diffopt.output_format == DIFF_FORMAT_PATCH)) rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY; /* Always generate a patch */ rev.diffopt.output_format |= DIFF_FORMAT_PATCH; if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff) DIFF_OPT_SET(&rev.diffopt, BINARY); if (!use_stdout) output_directory = set_outdir(prefix, output_directory); if (output_directory) { if (use_stdout) die("standard output, or directory, which one?"); if (mkdir(output_directory, 0777) < 0 && errno != EEXIST) die_errno("Could not create directory '%s'", output_directory); } if (rev.pending.nr == 1) { if (rev.max_count < 0 && !rev.show_root_diff) { /* * This is traditional behaviour of "git format-patch * origin" that prepares what the origin side still * does not have. */ rev.pending.objects[0].item->flags |= UNINTERESTING; add_head_to_pending(&rev); } /* * Otherwise, it is "format-patch -22 HEAD", and/or * "format-patch --root HEAD". The user wants * get_revision() to do the usual traversal. */ } /* * We cannot move this anywhere earlier because we do want to * know if --root was given explicitly from the comand line. */ rev.show_root_diff = 1; if (cover_letter) { /* remember the range */ int i; for (i = 0; i < rev.pending.nr; i++) { struct object *o = rev.pending.objects[i].item; if (!(o->flags & UNINTERESTING)) head = (struct commit *)o; } /* We can't generate a cover letter without any patches */ if (!head) return 0; } if (ignore_if_in_upstream) get_patch_ids(&rev, &ids, prefix); if (!use_stdout) realstdout = xfdopen(xdup(1), "w"); if (prepare_revision_walk(&rev)) die("revision walk setup failed"); rev.boundary = 1; while ((commit = get_revision(&rev)) != NULL) { if (commit->object.flags & BOUNDARY) { boundary_count++; origin = (boundary_count == 1) ? commit : NULL; continue; } /* ignore merges */ if (commit->parents && commit->parents->next) continue; if (ignore_if_in_upstream && has_commit_patch_id(commit, &ids)) continue; nr++; list = xrealloc(list, nr * sizeof(list[0])); list[nr - 1] = commit; } total = nr; if (!keep_subject && auto_number && total > 1) numbered = 1; if (numbered) rev.total = total + start_number - 1; if (in_reply_to || thread || cover_letter) rev.ref_message_ids = xcalloc(1, sizeof(struct string_list)); if (in_reply_to) { const char *msgid = clean_message_id(in_reply_to); string_list_append(msgid, rev.ref_message_ids); } rev.numbered_files = numbered_files; rev.patch_suffix = fmt_patch_suffix; if (cover_letter) { if (thread) gen_message_id(&rev, "cover"); make_cover_letter(&rev, use_stdout, numbered, numbered_files, origin, nr, list, head); total++; start_number--; } rev.add_signoff = add_signoff; while (0 <= --nr) { int shown; commit = list[nr]; rev.nr = total - nr + (start_number - 1); /* Make the second and subsequent mails replies to the first */ if (thread) { /* Have we already had a message ID? */ if (rev.message_id) { /* * For deep threading: make every mail * a reply to the previous one, no * matter what other options are set. * * For shallow threading: * * Without --cover-letter and * --in-reply-to, make every mail a * reply to the one before. * * With --in-reply-to but no * --cover-letter, make every mail a * reply to the <reply-to>. * * With --cover-letter, make every * mail but the cover letter a reply * to the cover letter. The cover * letter is a reply to the * --in-reply-to, if specified. */ if (thread == THREAD_SHALLOW && rev.ref_message_ids->nr > 0 && (!cover_letter || rev.nr > 1)) free(rev.message_id); else string_list_append(rev.message_id, rev.ref_message_ids); } gen_message_id(&rev, sha1_to_hex(commit->object.sha1)); } if (!use_stdout && reopen_stdout(numbered_files ? NULL : commit, &rev)) die("Failed to create output files"); shown = log_tree_commit(&rev, commit); free(commit->buffer); commit->buffer = NULL; /* We put one extra blank line between formatted * patches and this flag is used by log-tree code * to see if it needs to emit a LF before showing * the log; when using one file per patch, we do * not want the extra blank line. */ if (!use_stdout) rev.shown_one = 0; if (shown) { if (rev.mime_boundary) printf("\n--%s%s--\n\n\n", mime_boundary_leader, rev.mime_boundary); else printf("-- \n%s\n\n", git_version_string); } if (!use_stdout) fclose(stdout); } free(list); if (ignore_if_in_upstream) free_patch_ids(&ids); return 0; }
static int __cmd_record(int argc, const char **argv, struct perf_mem *mem) { int rec_argc, i = 0, j; const char **rec_argv; int ret; bool all_user = false, all_kernel = false; struct option options[] = { OPT_CALLBACK('e', "event", &mem, "event", "event selector. use 'perf mem record -e list' to list available events", parse_record_events), OPT_UINTEGER(0, "ldlat", &perf_mem_events__loads_ldlat, "mem-loads latency"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show counter open errors, etc)"), OPT_BOOLEAN('U', "all-user", &all_user, "collect only user level data"), OPT_BOOLEAN('K', "all-kernel", &all_kernel, "collect only kernel level data"), OPT_END() }; argc = parse_options(argc, argv, options, record_mem_usage, PARSE_OPT_KEEP_UNKNOWN); rec_argc = argc + 9; /* max number of arguments */ rec_argv = calloc(rec_argc + 1, sizeof(char *)); if (!rec_argv) return -1; rec_argv[i++] = "record"; if (mem->operation & MEM_OPERATION_LOAD) perf_mem_events[PERF_MEM_EVENTS__LOAD].record = true; if (mem->operation & MEM_OPERATION_STORE) perf_mem_events[PERF_MEM_EVENTS__STORE].record = true; if (perf_mem_events[PERF_MEM_EVENTS__LOAD].record) rec_argv[i++] = "-W"; rec_argv[i++] = "-d"; if (mem->phys_addr) rec_argv[i++] = "--phys-data"; for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) { if (!perf_mem_events[j].record) continue; if (!perf_mem_events[j].supported) { pr_err("failed: event '%s' not supported\n", perf_mem_events__name(j)); free(rec_argv); return -1; } rec_argv[i++] = "-e"; rec_argv[i++] = perf_mem_events__name(j); }; if (all_user) rec_argv[i++] = "--all-user"; if (all_kernel) rec_argv[i++] = "--all-kernel"; for (j = 0; j < argc; j++, i++) rec_argv[i] = argv[j]; if (verbose > 0) { pr_debug("calling: record "); while (rec_argv[j]) { pr_debug("%s ", rec_argv[j]); j++; } pr_debug("\n"); } ret = cmd_record(i, rec_argv); free(rec_argv); return ret; }
int cmd_grep(int argc, const char **argv, const char *prefix) { int hit = 0; int cached = 0; int seen_dashdash = 0; int external_grep_allowed__ignored; struct grep_opt opt; struct object_array list = { 0, 0, NULL }; const char **paths = NULL; int i; int dummy; int nongit = 0, use_index = 1; struct option options[] = { OPT_BOOLEAN(0, "cached", &cached, "search in index instead of in the work tree"), OPT_BOOLEAN(0, "index", &use_index, "--no-index finds in contents not managed by git"), OPT_GROUP(""), OPT_BOOLEAN('v', "invert-match", &opt.invert, "show non-matching lines"), OPT_BOOLEAN('i', "ignore-case", &opt.ignore_case, "case insensitive matching"), OPT_BOOLEAN('w', "word-regexp", &opt.word_regexp, "match patterns only at word boundaries"), OPT_SET_INT('a', "text", &opt.binary, "process binary files as text", GREP_BINARY_TEXT), OPT_SET_INT('I', NULL, &opt.binary, "don't match patterns in binary files", GREP_BINARY_NOMATCH), { OPTION_INTEGER, 0, "max-depth", &opt.max_depth, "depth", "descend at most <depth> levels", PARSE_OPT_NONEG, NULL, 1 }, OPT_GROUP(""), OPT_BIT('E', "extended-regexp", &opt.regflags, "use extended POSIX regular expressions", REG_EXTENDED), OPT_NEGBIT('G', "basic-regexp", &opt.regflags, "use basic POSIX regular expressions (default)", REG_EXTENDED), OPT_BOOLEAN('F', "fixed-strings", &opt.fixed, "interpret patterns as fixed strings"), OPT_GROUP(""), OPT_BOOLEAN('n', NULL, &opt.linenum, "show line numbers"), OPT_NEGBIT('h', NULL, &opt.pathname, "don't show filenames", 1), OPT_BIT('H', NULL, &opt.pathname, "show filenames", 1), OPT_NEGBIT(0, "full-name", &opt.relative, "show filenames relative to top directory", 1), OPT_BOOLEAN('l', "files-with-matches", &opt.name_only, "show only filenames instead of matching lines"), OPT_BOOLEAN(0, "name-only", &opt.name_only, "synonym for --files-with-matches"), OPT_BOOLEAN('L', "files-without-match", &opt.unmatch_name_only, "show only the names of files without match"), OPT_BOOLEAN('z', "null", &opt.null_following_name, "print NUL after filenames"), OPT_BOOLEAN('c', "count", &opt.count, "show the number of matches instead of matching lines"), OPT_SET_INT(0, "color", &opt.color, "highlight matches", 1), OPT_GROUP(""), OPT_CALLBACK('C', NULL, &opt, "n", "show <n> context lines before and after matches", context_callback), OPT_INTEGER('B', NULL, &opt.pre_context, "show <n> context lines before matches"), OPT_INTEGER('A', NULL, &opt.post_context, "show <n> context lines after matches"), OPT_NUMBER_CALLBACK(&opt, "shortcut for -C NUM", context_callback), OPT_BOOLEAN('p', "show-function", &opt.funcname, "show a line with the function name before matches"), OPT_GROUP(""), OPT_CALLBACK('f', NULL, &opt, "file", "read patterns from file", file_callback), { OPTION_CALLBACK, 'e', NULL, &opt, "pattern", "match <pattern>", PARSE_OPT_NONEG, pattern_callback }, { OPTION_CALLBACK, 0, "and", &opt, NULL, "combine patterns specified with -e", PARSE_OPT_NOARG | PARSE_OPT_NONEG, and_callback }, OPT_BOOLEAN(0, "or", &dummy, ""), { OPTION_CALLBACK, 0, "not", &opt, NULL, "", PARSE_OPT_NOARG | PARSE_OPT_NONEG, not_callback }, { OPTION_CALLBACK, '(', NULL, &opt, NULL, "", PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH, open_callback }, { OPTION_CALLBACK, ')', NULL, &opt, NULL, "", PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH, close_callback }, OPT_BOOLEAN('q', "quiet", &opt.status_only, "indicate hit with exit status without output"), OPT_BOOLEAN(0, "all-match", &opt.all_match, "show only matches from files that match all patterns"), OPT_GROUP(""), OPT_BOOLEAN(0, "ext-grep", &external_grep_allowed__ignored, "allow calling of grep(1) (ignored by this build)"), { OPTION_CALLBACK, 0, "help-all", &options, NULL, "show usage", PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback }, OPT_END() }; prefix = setup_git_directory_gently(&nongit); /* * 'git grep -h', unlike 'git grep -h <pattern>', is a request * to show usage information and exit. */ if (argc == 2 && !strcmp(argv[1], "-h")) usage_with_options(grep_usage, options); memset(&opt, 0, sizeof(opt)); opt.prefix = prefix; opt.prefix_length = (prefix && *prefix) ? strlen(prefix) : 0; opt.relative = 1; opt.pathname = 1; opt.pattern_tail = &opt.pattern_list; opt.regflags = REG_NEWLINE; opt.max_depth = -1; strcpy(opt.color_match, GIT_COLOR_RED GIT_COLOR_BOLD); opt.color = -1; git_config(grep_config, &opt); if (opt.color == -1) opt.color = git_use_color_default; /* * If there is no -- then the paths must exist in the working * tree. If there is no explicit pattern specified with -e or * -f, we take the first unrecognized non option to be the * pattern, but then what follows it must be zero or more * valid refs up to the -- (if exists), and then existing * paths. If there is an explicit pattern, then the first * unrecognized non option is the beginning of the refs list * that continues up to the -- (if exists), and then paths. */ argc = parse_options(argc, argv, prefix, options, grep_usage, PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_STOP_AT_NON_OPTION | PARSE_OPT_NO_INTERNAL_HELP); if (use_index && nongit) /* die the same way as if we did it at the beginning */ setup_git_directory(); /* * skip a -- separator; we know it cannot be * separating revisions from pathnames if * we haven't even had any patterns yet */ if (argc > 0 && !opt.pattern_list && !strcmp(argv[0], "--")) { argv++; argc--; } /* First unrecognized non-option token */ if (argc > 0 && !opt.pattern_list) { append_grep_pattern(&opt, argv[0], "command line", 0, GREP_PATTERN); argv++; argc--; } if (!opt.pattern_list) die("no pattern given."); if (!opt.fixed && opt.ignore_case) opt.regflags |= REG_ICASE; if ((opt.regflags != REG_NEWLINE) && opt.fixed) die("cannot mix --fixed-strings and regexp"); #ifndef NO_PTHREADS if (online_cpus() == 1 || !grep_threads_ok(&opt)) use_threads = 0; if (use_threads) start_threads(&opt); #else use_threads = 0; #endif compile_grep_patterns(&opt); /* Check revs and then paths */ for (i = 0; i < argc; i++) { const char *arg = argv[i]; unsigned char sha1[20]; /* Is it a rev? */ if (!get_sha1(arg, sha1)) { struct object *object = parse_object(sha1); if (!object) die("bad object %s", arg); add_object_array(object, arg, &list); continue; } if (!strcmp(arg, "--")) { i++; seen_dashdash = 1; } break; } /* The rest are paths */ if (!seen_dashdash) { int j; for (j = i; j < argc; j++) verify_filename(prefix, argv[j]); } if (i < argc) paths = get_pathspec(prefix, argv + i); else if (prefix) { paths = xcalloc(2, sizeof(const char *)); paths[0] = prefix; paths[1] = NULL; } if (!use_index) { int hit; if (cached) die("--cached cannot be used with --no-index."); if (list.nr) die("--no-index cannot be used with revs."); hit = grep_directory(&opt, paths); if (use_threads) hit |= wait_all(); return !hit; } if (!list.nr) { int hit; if (!cached) setup_work_tree(); hit = grep_cache(&opt, paths, cached); if (use_threads) hit |= wait_all(); return !hit; } if (cached) die("both --cached and trees are given."); for (i = 0; i < list.nr; i++) { struct object *real_obj; real_obj = deref_tag(list.objects[i].item, NULL, 0); if (grep_object(&opt, paths, real_obj, list.objects[i].name)) { hit = 1; if (opt.status_only) break; } } if (use_threads) hit |= wait_all(); free_grep_patterns(&opt); return !hit; }
static struct man_viewer_info_list { struct man_viewer_info_list *next; const char *info; char name[FLEX_ARRAY]; } *man_viewer_info_list; enum help_format { HELP_FORMAT_MAN, HELP_FORMAT_INFO, HELP_FORMAT_WEB, }; static int show_all = 0; static enum help_format help_format = HELP_FORMAT_MAN; static struct option builtin_help_options[] = { OPT_BOOLEAN('a', "all", &show_all, "print all available commands"), OPT_SET_INT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN), OPT_SET_INT('w', "web", &help_format, "show manual in web browser", HELP_FORMAT_WEB), OPT_SET_INT('i', "info", &help_format, "show info page", HELP_FORMAT_INFO), OPT_END(), }; static const char * const builtin_help_usage[] = { "git help [--all] [--man|--web|--info] [command]", NULL }; static enum help_format parse_help_format(const char *format) {
static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, struct rev_info *rev, struct setup_revision_opt *opt) { struct userformat_want w; int quiet = 0, source = 0; const struct option builtin_log_options[] = { OPT_BOOLEAN(0, "quiet", &quiet, N_("suppress diff output")), OPT_BOOLEAN(0, "source", &source, N_("show source")), { OPTION_CALLBACK, 0, "decorate", NULL, NULL, N_("decorate options"), PARSE_OPT_OPTARG, decorate_callback}, OPT_END() }; argc = parse_options(argc, argv, prefix, builtin_log_options, builtin_log_usage, PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN | PARSE_OPT_KEEP_DASHDASH); argc = setup_revisions(argc, argv, rev, opt); if (quiet) rev->diffopt.output_format |= DIFF_FORMAT_NO_OUTPUT; /* Any arguments at this point are not recognized */ if (argc > 1) die("unrecognized argument: %s", argv[1]); memset(&w, 0, sizeof(w)); userformat_find_requirements(NULL, &w); if (!rev->show_notes_given && (!rev->pretty_given || w.notes)) rev->show_notes = 1; if (rev->show_notes) init_display_notes(&rev->notes_opt); if (rev->diffopt.pickaxe || rev->diffopt.filter) rev->always_show_header = 0; if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) { rev->always_show_header = 0; if (rev->diffopt.pathspec.nr != 1) usage("git logs can only follow renames on one pathname at a time"); } if (source) rev->show_source = 1; if (rev->pretty_given && rev->commit_format == CMIT_FMT_RAW) { /* * "log --pretty=raw" is special; ignore UI oriented * configuration variables such as decoration. */ if (!decoration_given) decoration_style = 0; if (!rev->abbrev_commit_given) rev->abbrev_commit = 0; } if (decoration_style) { rev->show_decorations = 1; load_ref_decorations(decoration_style); } setup_pager(); }
int cmd_gc(int argc, const char **argv, const char *prefix) { int prune = 0; int aggressive = 0; int auto_gc = 0; int quiet = 0; char buf[80]; struct option builtin_gc_options[] = { OPT_BOOLEAN(0, "prune", &prune, "prune unreferenced objects (deprecated)"), OPT_BOOLEAN(0, "aggressive", &aggressive, "be more thorough (increased runtime)"), OPT_BOOLEAN(0, "auto", &auto_gc, "enable auto-gc mode"), OPT_BOOLEAN('q', "quiet", &quiet, "suppress progress reports"), OPT_END() }; git_config(gc_config, NULL); if (pack_refs < 0) pack_refs = !is_bare_repository(); argc = parse_options(argc, argv, builtin_gc_options, builtin_gc_usage, 0); if (argc > 0) usage_with_options(builtin_gc_usage, builtin_gc_options); if (aggressive) { append_option(argv_repack, "-f", MAX_ADD); if (aggressive_window > 0) { sprintf(buf, "--window=%d", aggressive_window); append_option(argv_repack, buf, MAX_ADD); } } if (quiet) append_option(argv_repack, "-q", MAX_ADD); if (auto_gc) { /* * Auto-gc should be least intrusive as possible. */ if (!need_to_gc()) return 0; fprintf(stderr, "Auto packing your repository for optimum " "performance. You may also\n" "run \"git gc\" manually. See " "\"git help gc\" for more information.\n"); } else append_option(argv_repack, "-A", MAX_ADD); if (pack_refs && run_command_v_opt(argv_pack_refs, RUN_GIT_CMD)) return error(FAILED_RUN, argv_pack_refs[0]); if (run_command_v_opt(argv_reflog, RUN_GIT_CMD)) return error(FAILED_RUN, argv_reflog[0]); if (run_command_v_opt(argv_repack, RUN_GIT_CMD)) return error(FAILED_RUN, argv_repack[0]); argv_prune[2] = prune_expire; if (run_command_v_opt(argv_prune, RUN_GIT_CMD)) return error(FAILED_RUN, argv_prune[0]); if (run_command_v_opt(argv_rerere, RUN_GIT_CMD)) return error(FAILED_RUN, argv_rerere[0]); if (auto_gc && too_many_loose_objects()) warning("There are too many unreachable loose objects; " "run 'git prune' to remove them."); return 0; }
static int cmd_parseopt(int argc, const char **argv, const char *prefix) { static int keep_dashdash = 0, stop_at_non_option = 0; static char const * const parseopt_usage[] = { N_("git rev-parse --parseopt [options] -- [<args>...]"), NULL }; static struct option parseopt_opts[] = { OPT_BOOLEAN(0, "keep-dashdash", &keep_dashdash, N_("keep the `--` passed as an arg")), OPT_BOOLEAN(0, "stop-at-non-option", &stop_at_non_option, N_("stop parsing after the " "first non-option argument")), OPT_END(), }; struct strbuf sb = STRBUF_INIT, parsed = STRBUF_INIT; const char **usage = NULL; struct option *opts = NULL; int onb = 0, osz = 0, unb = 0, usz = 0; strbuf_addstr(&parsed, "set --"); argc = parse_options(argc, argv, prefix, parseopt_opts, parseopt_usage, PARSE_OPT_KEEP_DASHDASH); if (argc < 1 || strcmp(argv[0], "--")) usage_with_options(parseopt_usage, parseopt_opts); /* get the usage up to the first line with a -- on it */ for (;;) { if (strbuf_getline(&sb, stdin, '\n') == EOF) die("premature end of input"); ALLOC_GROW(usage, unb + 1, usz); if (!strcmp("--", sb.buf)) { if (unb < 1) die("no usage string given before the `--' separator"); usage[unb] = NULL; break; } usage[unb++] = strbuf_detach(&sb, NULL); } /* parse: (<short>|<short>,<long>|<long>)[=?]? SP+ <help> */ while (strbuf_getline(&sb, stdin, '\n') != EOF) { const char *s; struct option *o; if (!sb.len) continue; ALLOC_GROW(opts, onb + 1, osz); memset(opts + onb, 0, sizeof(opts[onb])); o = &opts[onb++]; s = strchr(sb.buf, ' '); if (!s || *sb.buf == ' ') { o->type = OPTION_GROUP; o->help = xstrdup(skipspaces(sb.buf)); continue; } o->type = OPTION_CALLBACK; o->help = xstrdup(skipspaces(s)); o->value = &parsed; o->flags = PARSE_OPT_NOARG; o->callback = &parseopt_dump; while (s > sb.buf && strchr("*=?!", s[-1])) { switch (*--s) { case '=': o->flags &= ~PARSE_OPT_NOARG; break; case '?': o->flags &= ~PARSE_OPT_NOARG; o->flags |= PARSE_OPT_OPTARG; break; case '!': o->flags |= PARSE_OPT_NONEG; break; case '*': o->flags |= PARSE_OPT_HIDDEN; break; } } if (s - sb.buf == 1) /* short option only */ o->short_name = *sb.buf; else if (sb.buf[1] != ',') /* long option only */ o->long_name = xmemdupz(sb.buf, s - sb.buf); else { o->short_name = *sb.buf; o->long_name = xmemdupz(sb.buf + 2, s - sb.buf - 2); } } strbuf_release(&sb); /* put an OPT_END() */ ALLOC_GROW(opts, onb + 1, osz); memset(opts + onb, 0, sizeof(opts[onb])); argc = parse_options(argc, argv, prefix, opts, usage, (keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0) | (stop_at_non_option ? PARSE_OPT_STOP_AT_NON_OPTION : 0) | PARSE_OPT_SHELL_EVAL); strbuf_addf(&parsed, " --"); sq_quote_argv(&parsed, argv, 0); puts(parsed.buf); return 0; }
xopts[xopts_nr++] = xstrdup(arg); return 0; } static int option_parse_n(const struct option *opt, const char *arg, int unset) { show_diffstat = unset; return 0; } static struct option builtin_merge_options[] = { { OPTION_CALLBACK, 'n', NULL, NULL, NULL, N_("do not show a diffstat at the end of the merge"), PARSE_OPT_NOARG, option_parse_n }, OPT_BOOLEAN(0, "stat", &show_diffstat, N_("show a diffstat at the end of the merge")), OPT_BOOLEAN(0, "summary", &show_diffstat, N_("(synonym to --stat)")), { OPTION_INTEGER, 0, "log", &shortlog_len, N_("n"), N_("add (at most <n>) entries from shortlog to merge commit message"), PARSE_OPT_OPTARG, NULL, DEFAULT_MERGE_LOG_LEN }, OPT_BOOLEAN(0, "squash", &squash, N_("create a single commit instead of doing a merge")), OPT_BOOLEAN(0, "commit", &option_commit, N_("perform a commit if the merge succeeds (default)")), OPT_BOOL('e', "edit", &option_edit, N_("edit message before committing")), OPT_BOOLEAN(0, "ff", &allow_fast_forward, N_("allow fast-forward (default)")), OPT_BOOLEAN(0, "ff-only", &fast_forward_only, N_("abort if fast-forward is not possible")), OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),