int cmd_interpret_trailers(int argc, const char **argv, const char *prefix) { int trim_empty = 0; struct string_list trailers = STRING_LIST_INIT_DUP; struct option options[] = { OPT_BOOL(0, "trim-empty", &trim_empty, N_("trim empty trailers")), OPT_STRING_LIST(0, "trailer", &trailers, N_("trailer"), N_("trailer(s) to add")), OPT_END() }; argc = parse_options(argc, argv, prefix, options, git_interpret_trailers_usage, 0); if (argc) { int i; for (i = 0; i < argc; i++) process_trailers(argv[i], trim_empty, &trailers); } else process_trailers(NULL, trim_empty, &trailers); string_list_clear(&trailers, 0); return 0; }
int main(int argc, char **argv) { const char *prefix = "prefix/"; const char *usage[] = { "test-parse-options <options>", NULL }; struct string_list expect = STRING_LIST_INIT_NODUP; struct option options[] = { OPT_BOOL(0, "yes", &boolean, "get a boolean"), OPT_BOOL('D', "no-doubt", &boolean, "begins with 'no-'"), { OPTION_SET_INT, 'B', "no-fear", &boolean, NULL, "be brave", PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 }, OPT_COUNTUP('b', "boolean", &boolean, "increment by one"), 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_MAGNITUDE('m', "magnitude", &magnitude, "get a magnitude"), 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_NOOP_NOARG(0, "obsolete"), OPT_STRING_LIST(0, "list", &list, "str", "add str to list"), OPT_GROUP("Magic arguments"), OPT_ARGUMENT("quux", "means --quux"), OPT_NUMBER_CALLBACK(&integer, "set integer to NUM", number_callback), { OPTION_COUNTUP, '+', NULL, &boolean, NULL, "same as -b", PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH }, { OPTION_COUNTUP, 0, "ambiguous", &ambiguous, NULL, "positive ambiguity", PARSE_OPT_NOARG | PARSE_OPT_NONEG }, { OPTION_COUNTUP, 0, "no-ambiguous", &ambiguous, NULL, "negative ambiguity", PARSE_OPT_NOARG | PARSE_OPT_NONEG }, OPT_GROUP("Standard options"), OPT__ABBREV(&abbrev), OPT__VERBOSE(&verbose, "be verbose"), OPT__DRY_RUN(&dry_run, "dry run"), OPT__QUIET(&quiet, "be quiet"), OPT_CALLBACK(0, "expect", &expect, "string", "expected output in the variable dump", collect_expect), OPT_END(), }; int i; int ret = 0; argc = parse_options(argc, (const char **)argv, prefix, options, usage, 0); if (length_cb.called) { const char *arg = length_cb.arg; int unset = length_cb.unset; show(&expect, &ret, "Callback: \"%s\", %d", (arg ? arg : "not set"), unset); } show(&expect, &ret, "boolean: %d", boolean); show(&expect, &ret, "integer: %d", integer); show(&expect, &ret, "magnitude: %lu", magnitude); show(&expect, &ret, "timestamp: %lu", timestamp); show(&expect, &ret, "string: %s", string ? string : "(not set)"); show(&expect, &ret, "abbrev: %d", abbrev); show(&expect, &ret, "verbose: %d", verbose); show(&expect, &ret, "quiet: %d", quiet); show(&expect, &ret, "dry run: %s", dry_run ? "yes" : "no"); show(&expect, &ret, "file: %s", file ? file : "(not set)"); for (i = 0; i < list.nr; i++) show(&expect, &ret, "list: %s", list.items[i].string); for (i = 0; i < argc; i++) show(&expect, &ret, "arg %02d: %s", i, argv[i]); return ret; }
N_("reference repository"), &opt_parse_reference), OPT_STRING('o', "origin", &option_origin, N_("name"), N_("use <name> instead of 'origin' to track upstream")), OPT_STRING('b', "branch", &option_branch, N_("branch"), N_("checkout <branch> instead of the remote's HEAD")), OPT_STRING('u', "upload-pack", &option_upload_pack, N_("path"), N_("path to git-upload-pack on the remote")), OPT_STRING(0, "depth", &option_depth, N_("depth"), N_("create a shallow clone of that depth")), OPT_BOOL(0, "single-branch", &option_single_branch, N_("clone only one branch, HEAD or --branch")), OPT_BOOL(0, "dissociate", &option_dissociate, N_("use --reference only while cloning")), OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"), N_("separate git dir from working tree")), OPT_STRING_LIST('c', "config", &option_config, N_("key=value"), N_("set config inside the new repository")), OPT_END() }; static const char *argv_submodule[] = { "submodule", "update", "--init", "--recursive", NULL }; static char *get_repo_path(const char *repo, int *is_bundle) { static char *suffix[] = { "/.git", "", ".git/.git", ".git" }; static char *bundle_suffix[] = { ".bundle", "" }; struct stat st; int i; for (i = 0; i < ARRAY_SIZE(suffix); i++) {
N_("create a mirror repository (implies bare)")), OPT_BOOL('l', "local", &option_local, N_("to clone from a local repository")), OPT_BOOL(0, "no-hardlinks", &option_no_hardlinks, N_("don't use local hardlinks, always copy")), OPT_BOOL('s', "shared", &option_shared, N_("setup as shared repository")), OPT_BOOL(0, "recursive", &option_recursive, N_("initialize submodules in the clone")), OPT_BOOL(0, "recurse-submodules", &option_recursive, N_("initialize submodules in the clone")), OPT_INTEGER('j', "jobs", &max_jobs, N_("number of submodules cloned in parallel")), OPT_STRING(0, "template", &option_template, N_("template-directory"), N_("directory from which templates will be used")), OPT_STRING_LIST(0, "reference", &option_required_reference, N_("repo"), N_("reference repository")), OPT_STRING_LIST(0, "reference-if-able", &option_optional_reference, N_("repo"), N_("reference repository")), OPT_BOOL(0, "dissociate", &option_dissociate, N_("use --reference only while cloning")), OPT_STRING('o', "origin", &option_origin, N_("name"), N_("use <name> instead of 'origin' to track upstream")), OPT_STRING('b', "branch", &option_branch, N_("branch"), N_("checkout <branch> instead of the remote's HEAD")), OPT_STRING('u', "upload-pack", &option_upload_pack, N_("path"), N_("path to git-upload-pack on the remote")), OPT_STRING(0, "depth", &option_depth, N_("depth"), N_("create a shallow clone of that depth")), OPT_STRING(0, "shallow-since", &option_since, N_("time"), N_("create a shallow clone since a specific time")), OPT_STRING_LIST(0, "shallow-exclude", &option_not, N_("revision"),
N_("create a bare repository")), OPT_BOOL(0, "mirror", &option_mirror, N_("create a mirror repository (implies bare)")), OPT_BOOL('l', "local", &option_local, N_("to clone from a local repository")), OPT_BOOL(0, "no-hardlinks", &option_no_hardlinks, N_("don't use local hardlinks, always copy")), OPT_BOOL('s', "shared", &option_shared, N_("setup as shared repository")), OPT_BOOL(0, "recursive", &option_recursive, N_("initialize submodules in the clone")), OPT_BOOL(0, "recurse-submodules", &option_recursive, N_("initialize submodules in the clone")), OPT_STRING(0, "template", &option_template, N_("template-directory"), N_("directory from which templates will be used")), OPT_STRING_LIST(0, "reference", &option_reference, N_("repo"), N_("reference repository")), OPT_BOOL(0, "dissociate", &option_dissociate, N_("use --reference only while cloning")), OPT_STRING('o', "origin", &option_origin, N_("name"), N_("use <name> instead of 'origin' to track upstream")), OPT_STRING('b', "branch", &option_branch, N_("branch"), N_("checkout <branch> instead of the remote's HEAD")), OPT_STRING('u', "upload-pack", &option_upload_pack, N_("path"), N_("path to git-upload-pack on the remote")), OPT_STRING(0, "depth", &option_depth, N_("depth"), N_("create a shallow clone of that depth")), OPT_BOOL(0, "single-branch", &option_single_branch, N_("clone only one branch, HEAD or --branch")), OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"), N_("separate git dir from working tree")), OPT_STRING_LIST('c', "config", &option_config, N_("key=value"),
static int update_clone(int argc, const char **argv, const char *prefix) { const char *update = NULL; int max_jobs = -1; struct string_list_item *item; struct pathspec pathspec; struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; struct option module_update_clone_options[] = { OPT_STRING(0, "prefix", &prefix, N_("path"), N_("path into the working tree")), OPT_STRING(0, "recursive-prefix", &suc.recursive_prefix, N_("path"), N_("path into the working tree, across nested " "submodule boundaries")), OPT_STRING(0, "update", &update, N_("string"), N_("rebase, merge, checkout or none")), OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"), N_("reference repository")), OPT_STRING(0, "depth", &suc.depth, "<depth>", N_("Create a shallow clone truncated to the " "specified number of revisions")), OPT_INTEGER('j', "jobs", &max_jobs, N_("parallel jobs")), OPT_BOOL(0, "recommend-shallow", &suc.recommend_shallow, N_("whether the initial clone should follow the shallow recommendation")), OPT__QUIET(&suc.quiet, N_("don't print cloning progress")), OPT_BOOL(0, "progress", &suc.progress, N_("force cloning progress")), OPT_END() }; const char *const git_submodule_helper_usage[] = { N_("git submodule--helper update_clone [--prefix=<path>] [<path>...]"), NULL }; suc.prefix = prefix; argc = parse_options(argc, argv, prefix, module_update_clone_options, git_submodule_helper_usage, 0); if (update) if (parse_submodule_update_strategy(update, &suc.update) < 0) die(_("bad value for update parameter")); if (module_list_compute(argc, argv, prefix, &pathspec, &suc.list) < 0) return 1; if (pathspec.nr) suc.warn_if_uninitialized = 1; /* Overlay the parsed .gitmodules file with .git/config */ gitmodules_config(); git_config(submodule_config, NULL); if (max_jobs < 0) max_jobs = parallel_submodules(); run_processes_parallel(max_jobs, update_clone_get_next_task, update_clone_start_failure, update_clone_task_finished, &suc); /* * We saved the output and put it out all at once now. * That means: * - the listener does not have to interleave their (checkout) * work with our fetching. The writes involved in a * checkout involve more straightforward sequential I/O. * - the listener can avoid doing any work if fetching failed. */ if (suc.quickstop) return 1; for_each_string_list_item(item, &suc.projectlines) utf8_fprintf(stdout, "%s", item->string); return 0; }
static int module_clone(int argc, const char **argv, const char *prefix) { const char *name = NULL, *url = NULL, *depth = NULL; int quiet = 0; int progress = 0; char *p, *path = NULL, *sm_gitdir; struct strbuf sb = STRBUF_INIT; struct string_list reference = STRING_LIST_INIT_NODUP; char *sm_alternate = NULL, *error_strategy = NULL; struct option module_clone_options[] = { OPT_STRING(0, "prefix", &prefix, N_("path"), N_("alternative anchor for relative paths")), OPT_STRING(0, "path", &path, N_("path"), N_("where the new submodule will be cloned to")), OPT_STRING(0, "name", &name, N_("string"), N_("name of the new submodule")), OPT_STRING(0, "url", &url, N_("string"), N_("url where to clone the submodule from")), OPT_STRING_LIST(0, "reference", &reference, N_("repo"), N_("reference repository")), OPT_STRING(0, "depth", &depth, N_("string"), N_("depth for shallow clones")), OPT__QUIET(&quiet, "Suppress output for cloning a submodule"), OPT_BOOL(0, "progress", &progress, N_("force cloning progress")), OPT_END() }; const char *const git_submodule_helper_usage[] = { N_("git submodule--helper clone [--prefix=<path>] [--quiet] " "[--reference <repository>] [--name <name>] [--depth <depth>] " "--url <url> --path <path>"), NULL }; argc = parse_options(argc, argv, prefix, module_clone_options, git_submodule_helper_usage, 0); if (argc || !url || !path || !*path) usage_with_options(git_submodule_helper_usage, module_clone_options); strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name); sm_gitdir = absolute_pathdup(sb.buf); strbuf_reset(&sb); if (!is_absolute_path(path)) { strbuf_addf(&sb, "%s/%s", get_git_work_tree(), path); path = strbuf_detach(&sb, NULL); } else path = xstrdup(path); if (!file_exists(sm_gitdir)) { if (safe_create_leading_directories_const(sm_gitdir) < 0) die(_("could not create directory '%s'"), sm_gitdir); prepare_possible_alternates(name, &reference); if (clone_submodule(path, sm_gitdir, url, depth, &reference, quiet, progress)) die(_("clone of '%s' into submodule path '%s' failed"), url, path); } else { if (safe_create_leading_directories_const(path) < 0) die(_("could not create directory '%s'"), path); strbuf_addf(&sb, "%s/index", sm_gitdir); unlink_or_warn(sb.buf); strbuf_reset(&sb); } /* Connect module worktree and git dir */ connect_work_tree_and_git_dir(path, sm_gitdir); p = git_pathdup_submodule(path, "config"); if (!p) die(_("could not get submodule directory for '%s'"), path); /* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */ git_config_get_string("submodule.alternateLocation", &sm_alternate); if (sm_alternate) git_config_set_in_file(p, "submodule.alternateLocation", sm_alternate); git_config_get_string("submodule.alternateErrorStrategy", &error_strategy); if (error_strategy) git_config_set_in_file(p, "submodule.alternateErrorStrategy", error_strategy); free(sm_alternate); free(error_strategy); strbuf_release(&sb); free(sm_gitdir); free(path); free(p); return 0; }
int cmd_blame(int argc, const char **argv, const char *prefix) { struct rev_info revs; const char *path; struct blame_scoreboard sb; struct blame_origin *o; struct blame_entry *ent = NULL; long dashdash_pos, lno; struct progress_info pi = { NULL, 0 }; struct string_list range_list = STRING_LIST_INIT_NODUP; int output_option = 0, opt = 0; int show_stats = 0; const char *revs_file = NULL; const char *contents_from = NULL; const struct option options[] = { OPT_BOOL(0, "incremental", &incremental, N_("Show blame entries as we find them, incrementally")), OPT_BOOL('b', NULL, &blank_boundary, N_("Show blank SHA-1 for boundary commits (Default: off)")), OPT_BOOL(0, "root", &show_root, N_("Do not treat root commits as boundaries (Default: off)")), OPT_BOOL(0, "show-stats", &show_stats, N_("Show work cost statistics")), OPT_BOOL(0, "progress", &show_progress, N_("Force progress reporting")), OPT_BIT(0, "score-debug", &output_option, N_("Show output score for blame entries"), OUTPUT_SHOW_SCORE), OPT_BIT('f', "show-name", &output_option, N_("Show original filename (Default: auto)"), OUTPUT_SHOW_NAME), OPT_BIT('n', "show-number", &output_option, N_("Show original linenumber (Default: off)"), OUTPUT_SHOW_NUMBER), OPT_BIT('p', "porcelain", &output_option, N_("Show in a format designed for machine consumption"), OUTPUT_PORCELAIN), OPT_BIT(0, "line-porcelain", &output_option, N_("Show porcelain format with per-line commit information"), OUTPUT_PORCELAIN|OUTPUT_LINE_PORCELAIN), OPT_BIT('c', NULL, &output_option, N_("Use the same output mode as git-annotate (Default: off)"), OUTPUT_ANNOTATE_COMPAT), OPT_BIT('t', NULL, &output_option, N_("Show raw timestamp (Default: off)"), OUTPUT_RAW_TIMESTAMP), OPT_BIT('l', NULL, &output_option, N_("Show long commit SHA1 (Default: off)"), OUTPUT_LONG_OBJECT_NAME), OPT_BIT('s', NULL, &output_option, N_("Suppress author name and timestamp (Default: off)"), OUTPUT_NO_AUTHOR), OPT_BIT('e', "show-email", &output_option, N_("Show author email instead of name (Default: off)"), OUTPUT_SHOW_EMAIL), OPT_BIT('w', NULL, &xdl_opts, N_("Ignore whitespace differences"), XDF_IGNORE_WHITESPACE), /* * The following two options are parsed by parse_revision_opt() * and are only included here to get included in the "-h" * output: */ { OPTION_LOWLEVEL_CALLBACK, 0, "indent-heuristic", NULL, NULL, N_("Use an experimental heuristic to improve diffs"), PARSE_OPT_NOARG, parse_opt_unknown_cb }, OPT_BIT(0, "minimal", &xdl_opts, N_("Spend extra cycles to find better match"), XDF_NEED_MINIMAL), OPT_STRING('S', NULL, &revs_file, N_("file"), N_("Use revisions from <file> instead of calling git-rev-list")), OPT_STRING(0, "contents", &contents_from, N_("file"), N_("Use <file>'s contents as the final image")), { OPTION_CALLBACK, 'C', NULL, &opt, N_("score"), N_("Find line copies within and across files"), PARSE_OPT_OPTARG, blame_copy_callback }, { OPTION_CALLBACK, 'M', NULL, &opt, N_("score"), N_("Find line movements within and across files"), PARSE_OPT_OPTARG, blame_move_callback }, OPT_STRING_LIST('L', NULL, &range_list, N_("n,m"), N_("Process only line range n,m, counting from 1")), OPT__ABBREV(&abbrev), OPT_END() }; struct parse_opt_ctx_t ctx; int cmd_is_annotate = !strcmp(argv[0], "annotate"); struct range_set ranges; unsigned int range_i; long anchor; git_config(git_blame_config, &output_option); init_revisions(&revs, NULL); revs.date_mode = blame_date_mode; revs.diffopt.flags.allow_textconv = 1; revs.diffopt.flags.follow_renames = 1; save_commit_buffer = 0; dashdash_pos = 0; show_progress = -1; parse_options_start(&ctx, argc, argv, prefix, options, PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0); for (;;) { switch (parse_options_step(&ctx, options, blame_opt_usage)) { case PARSE_OPT_HELP: exit(129); case PARSE_OPT_DONE: if (ctx.argv[0]) dashdash_pos = ctx.cpidx; goto parse_done; } if (!strcmp(ctx.argv[0], "--reverse")) { ctx.argv[0] = "--children"; reverse = 1; } parse_revision_opt(&revs, &ctx, options, blame_opt_usage); } parse_done: no_whole_file_rename = !revs.diffopt.flags.follow_renames; xdl_opts |= revs.diffopt.xdl_opts & XDF_INDENT_HEURISTIC; revs.diffopt.flags.follow_renames = 0; argc = parse_options_end(&ctx); if (incremental || (output_option & OUTPUT_PORCELAIN)) { if (show_progress > 0) die(_("--progress can't be used with --incremental or porcelain formats")); show_progress = 0; } else if (show_progress < 0) show_progress = isatty(2); if (0 < abbrev && abbrev < GIT_SHA1_HEXSZ) /* one more abbrev length is needed for the boundary commit */ abbrev++; else if (!abbrev) abbrev = GIT_SHA1_HEXSZ; if (revs_file && read_ancestry(revs_file)) die_errno("reading graft file '%s' failed", revs_file); if (cmd_is_annotate) { output_option |= OUTPUT_ANNOTATE_COMPAT; blame_date_mode.type = DATE_ISO8601; } else { blame_date_mode = revs.date_mode; } /* The maximum width used to show the dates */ switch (blame_date_mode.type) { case DATE_RFC2822: blame_date_width = sizeof("Thu, 19 Oct 2006 16:00:04 -0700"); break; case DATE_ISO8601_STRICT: blame_date_width = sizeof("2006-10-19T16:00:04-07:00"); break; case DATE_ISO8601: blame_date_width = sizeof("2006-10-19 16:00:04 -0700"); break; case DATE_RAW: blame_date_width = sizeof("1161298804 -0700"); break; case DATE_UNIX: blame_date_width = sizeof("1161298804"); break; case DATE_SHORT: blame_date_width = sizeof("2006-10-19"); break; case DATE_RELATIVE: /* * TRANSLATORS: This string is used to tell us the * maximum display width for a relative timestamp in * "git blame" output. For C locale, "4 years, 11 * months ago", which takes 22 places, is the longest * among various forms of relative timestamps, but * your language may need more or fewer display * columns. */ blame_date_width = utf8_strwidth(_("4 years, 11 months ago")) + 1; /* add the null */ break; case DATE_NORMAL: blame_date_width = sizeof("Thu Oct 19 16:00:04 2006 -0700"); break; case DATE_STRFTIME: blame_date_width = strlen(show_date(0, 0, &blame_date_mode)) + 1; /* add the null */ break; } blame_date_width -= 1; /* strip the null */ if (revs.diffopt.flags.find_copies_harder) opt |= (PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE | PICKAXE_BLAME_COPY_HARDER); /* * We have collected options unknown to us in argv[1..unk] * which are to be passed to revision machinery if we are * going to do the "bottom" processing. * * The remaining are: * * (1) if dashdash_pos != 0, it is either * "blame [revisions] -- <path>" or * "blame -- <path> <rev>" * * (2) otherwise, it is one of the two: * "blame [revisions] <path>" * "blame <path> <rev>" * * Note that we must strip out <path> from the arguments: we do not * want the path pruning but we may want "bottom" processing. */ if (dashdash_pos) { switch (argc - dashdash_pos - 1) { case 2: /* (1b) */ if (argc != 4) usage_with_options(blame_opt_usage, options); /* reorder for the new way: <rev> -- <path> */ argv[1] = argv[3]; argv[3] = argv[2]; argv[2] = "--"; /* FALLTHROUGH */ case 1: /* (1a) */ path = add_prefix(prefix, argv[--argc]); argv[argc] = NULL; break; default: usage_with_options(blame_opt_usage, options); } } else { if (argc < 2) usage_with_options(blame_opt_usage, options); if (argc == 3 && is_a_rev(argv[argc - 1])) { /* (2b) */ path = add_prefix(prefix, argv[1]); argv[1] = argv[2]; } else { /* (2a) */ if (argc == 2 && is_a_rev(argv[1]) && !get_git_work_tree()) die("missing <path> to blame"); path = add_prefix(prefix, argv[argc - 1]); } argv[argc - 1] = "--"; } revs.disable_stdin = 1; setup_revisions(argc, argv, &revs, NULL); init_scoreboard(&sb); sb.revs = &revs; sb.contents_from = contents_from; sb.reverse = reverse; setup_scoreboard(&sb, path, &o); lno = sb.num_lines; if (lno && !range_list.nr) string_list_append(&range_list, "1"); anchor = 1; range_set_init(&ranges, range_list.nr); for (range_i = 0; range_i < range_list.nr; ++range_i) { long bottom, top; if (parse_range_arg(range_list.items[range_i].string, nth_line_cb, &sb, lno, anchor, &bottom, &top, sb.path)) usage(blame_usage); if (lno < top || ((lno || bottom) && lno < bottom)) die(Q_("file %s has only %lu line", "file %s has only %lu lines", lno), path, lno); if (bottom < 1) bottom = 1; if (top < 1) top = lno; bottom--; range_set_append_unsafe(&ranges, bottom, top); anchor = top + 1; } sort_and_merge_range_set(&ranges); for (range_i = ranges.nr; range_i > 0; --range_i) { const struct range *r = &ranges.ranges[range_i - 1]; ent = blame_entry_prepend(ent, r->start, r->end, o); } o->suspects = ent; prio_queue_put(&sb.commits, o->commit); blame_origin_decref(o); range_set_release(&ranges); string_list_clear(&range_list, 0); sb.ent = NULL; sb.path = path; if (blame_move_score) sb.move_score = blame_move_score; if (blame_copy_score) sb.copy_score = blame_copy_score; sb.debug = DEBUG; sb.on_sanity_fail = &sanity_check_on_fail; sb.show_root = show_root; sb.xdl_opts = xdl_opts; sb.no_whole_file_rename = no_whole_file_rename; read_mailmap(&mailmap, NULL); sb.found_guilty_entry = &found_guilty_entry; sb.found_guilty_entry_data = π if (show_progress) pi.progress = start_delayed_progress(_("Blaming lines"), sb.num_lines); assign_blame(&sb, opt); stop_progress(&pi.progress); if (!incremental) setup_pager(); else return 0; blame_sort_final(&sb); blame_coalesce(&sb); if (!(output_option & OUTPUT_PORCELAIN)) find_alignment(&sb, &output_option); output(&sb, output_option); free((void *)sb.final_buf); for (ent = sb.ent; ent; ) { struct blame_entry *e = ent->next; free(ent); ent = e; } if (show_stats) { printf("num read blob: %d\n", sb.num_read_blob); printf("num get patch: %d\n", sb.num_get_patch); printf("num commits: %d\n", sb.num_commits); } return 0; }
int cmd_push(int argc, const char **argv, const char *prefix) { int flags = 0; int tags = 0; int push_cert = -1; int rc; const char *repo = NULL; /* default repository */ struct string_list push_options = STRING_LIST_INIT_DUP; const struct string_list_item *item; 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_BOOL('d', "delete", &deleterefs, N_("delete refs")), OPT_BOOL( 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, CAS_OPT_NAME, &cas, N_("refname>:<expect"), N_("require old value of ref to be at this value"), PARSE_OPT_OPTARG, parseopt_push_cas_option }, { OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules, "check|on-demand|no", N_("control recursive pushing of submodules"), PARSE_OPT_OPTARG, option_parse_recurse_submodules }, OPT_BOOL( 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), { OPTION_CALLBACK, 0, "signed", &push_cert, "yes|no|if-asked", N_("GPG sign the push"), PARSE_OPT_OPTARG, option_parse_push_signed }, OPT_BIT(0, "atomic", &flags, N_("request atomic transaction on remote side"), TRANSPORT_PUSH_ATOMIC), OPT_STRING_LIST('o', "push-option", &push_options, N_("server-specific"), N_("option to transmit")), OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"), TRANSPORT_FAMILY_IPV4), OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"), TRANSPORT_FAMILY_IPV6), OPT_END() }; packet_trace_identity("push"); git_config(git_push_config, &flags); argc = parse_options(argc, argv, prefix, options, push_usage, 0); set_push_cert_flags(&flags, push_cert); 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 (recurse_submodules == RECURSE_SUBMODULES_CHECK) flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK; else if (recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) flags |= TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND; else if (recurse_submodules == RECURSE_SUBMODULES_ONLY) flags |= TRANSPORT_RECURSE_SUBMODULES_ONLY; if (tags) add_refspec("refs/tags/*"); if (argc > 0) { repo = argv[0]; set_refspecs(argv + 1, argc - 1, repo); } for_each_string_list_item(item, &push_options) if (strchr(item->string, '\n')) die(_("push options must not have new line characters")); rc = do_push(repo, flags, &push_options); string_list_clear(&push_options, 0); if (rc == -1) usage_with_options(push_usage, options); else return rc; }