From: Junio C Hamano Date: Wed, 30 Jun 2010 18:55:38 +0000 (-0700) Subject: Merge branch 'jp/string-list-api-cleanup' X-Git-Tag: v1.7.2-rc1~8 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/a53deac89eb6c65cd953c730f33b86ac3f72d647?ds=inline;hp=-c Merge branch 'jp/string-list-api-cleanup' * jp/string-list-api-cleanup: string_list: Fix argument order for string_list_append string_list: Fix argument order for string_list_lookup string_list: Fix argument order for string_list_insert_at_index string_list: Fix argument order for string_list_insert string_list: Fix argument order for for_each_string_list string_list: Fix argument order for print_string_list --- a53deac89eb6c65cd953c730f33b86ac3f72d647 diff --combined builtin/apply.c index 562e5345fc,03639282e1..12ef9ea8af --- a/builtin/apply.c +++ b/builtin/apply.c @@@ -56,7 -56,7 +56,7 @@@ static enum ws_error_action nowarn_ws_error, warn_on_ws_error, die_on_ws_error, - correct_ws_error, + correct_ws_error } ws_error_action = warn_on_ws_error; static int whitespace_error; static int squelch_whitespace_errors = 5; @@@ -64,7 -64,7 +64,7 @@@ static int applied_after_fixing_ws static enum ws_ignore { ignore_ws_none, - ignore_ws_change, + ignore_ws_change } ws_ignore_action = ignore_ws_none; @@@ -2628,7 -2628,7 +2628,7 @@@ static struct patch *in_fn_table(const if (name == NULL) return NULL; - item = string_list_lookup(name, &fn_table); + item = string_list_lookup(&fn_table, name); if (item != NULL) return (struct patch *)item->util; @@@ -2664,7 -2664,7 +2664,7 @@@ static void add_to_fn_table(struct patc * file creations and copies */ if (patch->new_name != NULL) { - item = string_list_insert(patch->new_name, &fn_table); + item = string_list_insert(&fn_table, patch->new_name); item->util = patch; } @@@ -2673,7 -2673,7 +2673,7 @@@ * later chunks shouldn't patch old names */ if ((patch->new_name == NULL) || (patch->is_rename)) { - item = string_list_insert(patch->old_name, &fn_table); + item = string_list_insert(&fn_table, patch->old_name); item->util = PATH_WAS_DELETED; } } @@@ -2686,7 -2686,7 +2686,7 @@@ static void prepare_fn_table(struct pat while (patch) { if ((patch->new_name == NULL) || (patch->is_rename)) { struct string_list_item *item; - item = string_list_insert(patch->old_name, &fn_table); + item = string_list_insert(&fn_table, patch->old_name); item->util = PATH_TO_BE_DELETED; } patch = patch->next; @@@ -3394,7 -3394,7 +3394,7 @@@ static void add_name_limit(const char * { struct string_list_item *it; - it = string_list_append(name, &limit_by_name); + it = string_list_append(&limit_by_name, name); it->util = exclude ? NULL : (void *) 1; } diff --combined builtin/commit.c index 3d99cf9158,763fe74b90..c6b053a508 --- a/builtin/commit.c +++ b/builtin/commit.c @@@ -48,11 -48,6 +48,11 @@@ static const char implicit_ident_advice "\n" " git commit --amend --author='Your Name '\n"; +static const char empty_amend_advice[] = +"You asked to amend the most recent commit, but doing so would make\n" +"it empty. You can repeat your command with --allow-empty, or you can\n" +"remove the commit entirely with \"git reset HEAD^\".\n"; + static unsigned char head_sha1[20]; static char *use_message_buffer; @@@ -62,7 -57,7 +62,7 @@@ static struct lock_file false_lock; /* static enum { COMMIT_AS_IS = 1, COMMIT_NORMAL, - COMMIT_PARTIAL, + COMMIT_PARTIAL } commit_style; static const char *logfile, *force_author; @@@ -83,7 -78,7 +83,7 @@@ static char *untracked_files_arg, *forc static enum { CLEANUP_SPACE, CLEANUP_NONE, - CLEANUP_ALL, + CLEANUP_ALL } cleanup_mode; static char *cleanup_arg; @@@ -96,9 -91,8 +96,9 @@@ static int null_termination static enum { STATUS_FORMAT_LONG, STATUS_FORMAT_SHORT, - STATUS_FORMAT_PORCELAIN, + STATUS_FORMAT_PORCELAIN } status_format = STATUS_FORMAT_LONG; +static int status_show_branch; static int opt_parse_m(const struct option *opt, const char *arg, int unset) { @@@ -140,7 -134,6 +140,7 @@@ static struct option builtin_commit_opt OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"), OPT_SET_INT(0, "short", &status_format, "show status concisely", STATUS_FORMAT_SHORT), + OPT_BOOLEAN(0, "branch", &status_show_branch, "show branch information"), OPT_SET_INT(0, "porcelain", &status_format, "show porcelain output format", STATUS_FORMAT_PORCELAIN), OPT_BOOLEAN('z', "null", &null_termination, @@@ -219,7 -212,7 +219,7 @@@ static int list_paths(struct string_lis continue; if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m)) continue; - item = string_list_insert(ce->name, list); + item = string_list_insert(list, ce->name); if (ce_skip_worktree(ce)) item->util = item; /* better a valid pointer than a fake one */ } @@@ -431,7 -424,7 +431,7 @@@ static int run_status(FILE *fp, const c switch (status_format) { case STATUS_FORMAT_SHORT: - wt_shortstatus_print(s, null_termination); + wt_shortstatus_print(s, null_termination, status_show_branch); break; case STATUS_FORMAT_PORCELAIN: wt_porcelain_print(s, null_termination); @@@ -469,21 -462,15 +469,21 @@@ static void determine_author_info(void if (!a) die("invalid commit: %s", use_message); - lb = strstr(a + 8, " <"); - rb = strstr(a + 8, "> "); - eol = strchr(a + 8, '\n'); - if (!lb || !rb || !eol) + lb = strchrnul(a + strlen("\nauthor "), '<'); + rb = strchrnul(lb, '>'); + eol = strchrnul(rb, '\n'); + if (!*lb || !*rb || !*eol) die("invalid commit: %s", use_message); - name = xstrndup(a + 8, lb - (a + 8)); - email = xstrndup(lb + 2, rb - (lb + 2)); - date = xstrndup(rb + 2, eol - (rb + 2)); + if (lb == a + strlen("\nauthor ")) + /* \nauthor */ + name = xcalloc(1, 1); + else + name = xmemdupz(a + strlen("\nauthor "), + (lb - strlen(" ") - + (a + strlen("\nauthor ")))); + email = xmemdupz(lb + strlen("<"), rb - (lb + strlen("<"))); + date = xmemdupz(rb + strlen("> "), eol - (rb + strlen("> "))); } if (force_author) { @@@ -713,8 -700,6 +713,8 @@@ static int prepare_to_commit(const cha if (!commitable && !in_merge && !allow_empty && !(amend && is_a_merge(head_sha1))) { run_status(stdout, index_file, prefix, 0, s); + if (amend) + fputs(empty_amend_advice, stderr); return 0; } @@@ -739,8 -724,7 +739,8 @@@ if (use_editor) { char index[PATH_MAX]; - const char *env[2] = { index, NULL }; + const char *env[2] = { NULL }; + env[0] = index; snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file); if (launch_editor(git_path(commit_editmsg), NULL, env)) { fprintf(stderr, @@@ -1046,8 -1030,6 +1046,8 @@@ int cmd_status(int argc, const char **a OPT__VERBOSE(&verbose), OPT_SET_INT('s', "short", &status_format, "show status concisely", STATUS_FORMAT_SHORT), + OPT_BOOLEAN('b', "branch", &status_show_branch, + "show branch information"), OPT_SET_INT(0, "porcelain", &status_format, "show porcelain output format", STATUS_FORMAT_PORCELAIN), @@@ -1100,7 -1082,7 +1100,7 @@@ switch (status_format) { case STATUS_FORMAT_SHORT: - wt_shortstatus_print(&s, null_termination); + wt_shortstatus_print(&s, null_termination, status_show_branch); break; case STATUS_FORMAT_PORCELAIN: wt_porcelain_print(&s, null_termination); @@@ -1175,11 -1157,13 +1175,11 @@@ static void print_summary(const char *p initial_commit ? " (root-commit)" : ""); if (!log_tree_commit(&rev, commit)) { - struct pretty_print_context ctx = {0}; - struct strbuf buf = STRBUF_INIT; - ctx.date_mode = DATE_NORMAL; - format_commit_message(commit, format.buf + 7, &buf, &ctx); - printf("%s\n", buf.buf); - strbuf_release(&buf); + rev.always_show_header = 1; + rev.use_terminator = 1; + log_tree_commit(&rev, commit); } + strbuf_release(&format); } @@@ -1267,16 -1251,13 +1267,16 @@@ int cmd_commit(int argc, const char **a } /* Determine parents */ + reflog_msg = getenv("GIT_REFLOG_ACTION"); if (initial_commit) { - reflog_msg = "commit (initial)"; + if (!reflog_msg) + reflog_msg = "commit (initial)"; } else if (amend) { struct commit_list *c; struct commit *commit; - reflog_msg = "commit (amend)"; + if (!reflog_msg) + reflog_msg = "commit (amend)"; commit = lookup_commit(head_sha1); if (!commit || parse_commit(commit)) die("could not parse HEAD commit"); @@@ -1287,8 -1268,7 +1287,8 @@@ struct strbuf m = STRBUF_INIT; FILE *fp; - reflog_msg = "commit (merge)"; + if (!reflog_msg) + reflog_msg = "commit (merge)"; pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next; fp = fopen(git_path("MERGE_HEAD"), "r"); if (fp == NULL) @@@ -1311,8 -1291,7 +1311,8 @@@ if (allow_fast_forward) parents = reduce_heads(parents); } else { - reflog_msg = "commit"; + if (!reflog_msg) + reflog_msg = "commit"; pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next; } diff --combined builtin/fetch.c index 5cb369cfd1,c5e24b50ec..6eb1dfea09 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@@ -528,7 -528,7 +528,7 @@@ static int add_existing(const char *ref int flag, void *cbdata) { struct string_list *list = (struct string_list *)cbdata; - struct string_list_item *item = string_list_insert(refname, list); + struct string_list_item *item = string_list_insert(list, refname); item->util = (void *)sha1; return 0; } @@@ -574,10 -574,9 +574,10 @@@ static void find_non_local_tags(struct { struct string_list existing_refs = { NULL, 0, 0, 0 }; struct string_list remote_refs = { NULL, 0, 0, 0 }; - struct tag_data data = {head, tail}; + struct tag_data data; const struct ref *ref; struct string_list_item *item = NULL; + data.head = head; data.tail = tail; for_each_ref(add_existing, &existing_refs); for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) { @@@ -617,7 -616,7 +617,7 @@@ string_list_has_string(&existing_refs, ref->name)) continue; - item = string_list_insert(ref->name, &remote_refs); + item = string_list_insert(&remote_refs, ref->name); item->util = (void *)ref->old_sha1; } string_list_clear(&existing_refs, 0); @@@ -634,7 -633,7 +634,7 @@@ * For all the tags in the remote_refs string list, call * add_to_tail to add them to the list of refs to be fetched */ - for_each_string_list(add_to_tail, &remote_refs, &data); + for_each_string_list(&remote_refs, add_to_tail, &data); string_list_clear(&remote_refs, 0); } @@@ -696,8 -695,8 +696,8 @@@ static int do_fetch(struct transport *t for (rm = ref_map; rm; rm = rm->next) { if (rm->peer_ref) { - peer_item = string_list_lookup(rm->peer_ref->name, - &existing_refs); + peer_item = string_list_lookup(&existing_refs, + rm->peer_ref->name); if (peer_item) hashcpy(rm->peer_ref->old_sha1, peer_item->util); @@@ -746,7 -745,7 +746,7 @@@ static int get_one_remote_for_fetch(str { struct string_list *list = priv; if (!remote->skip_default_update) - string_list_append(remote->name, list); + string_list_append(list, remote->name); return 0; } @@@ -765,8 -764,8 +765,8 @@@ static int get_remote_group(const char int space = strcspn(value, " \t\n"); while (*value) { if (space > 1) { - string_list_append(xstrndup(value, space), - g->list); + string_list_append(g->list, + xstrndup(value, space)); } value += space + (value[space] != '\0'); space = strcspn(value, " \t\n"); @@@ -779,8 -778,7 +779,8 @@@ static int add_remote_or_group(const char *name, struct string_list *list) { int prev_nr = list->nr; - struct remote_group_data g = { name, list }; + struct remote_group_data g; + g.name = name; g.list = list; git_config(get_remote_group, &g); if (list->nr == prev_nr) { @@@ -788,7 -786,7 +788,7 @@@ if (!remote_is_configured(name)) return 0; remote = remote_get(name); - string_list_append(remote->name, list); + string_list_append(list, remote->name); } return 1; } diff --combined builtin/fmt-merge-msg.c index 44204257c7,601201264e..bc3c5e6d3e --- a/builtin/fmt-merge-msg.c +++ b/builtin/fmt-merge-msg.c @@@ -82,7 -82,7 +82,7 @@@ static int handle_line(char *line item = unsorted_string_list_lookup(&srcs, src); if (!item) { - item = string_list_append(src, &srcs); + item = string_list_append(&srcs, src); item->util = xcalloc(1, sizeof(struct src_data)); init_src_data(item->util); } @@@ -93,19 -93,19 +93,19 @@@ src_data->head_status |= 1; } else if (!prefixcmp(line, "branch ")) { origin = line + 7; - string_list_append(origin, &src_data->branch); + string_list_append(&src_data->branch, origin); src_data->head_status |= 2; } else if (!prefixcmp(line, "tag ")) { origin = line; - string_list_append(origin + 4, &src_data->tag); + string_list_append(&src_data->tag, origin + 4); src_data->head_status |= 2; } else if (!prefixcmp(line, "remote branch ")) { origin = line + 14; - string_list_append(origin, &src_data->r_branch); + string_list_append(&src_data->r_branch, origin); src_data->head_status |= 2; } else { origin = src; - string_list_append(line, &src_data->generic); + string_list_append(&src_data->generic, line); src_data->head_status |= 2; } @@@ -118,7 -118,7 +118,7 @@@ sprintf(new_origin, "%s of %s", origin, src); origin = new_origin; } - string_list_append(origin, &origins)->util = sha1; + string_list_append(&origins, origin)->util = sha1; return 0; } @@@ -176,10 -176,10 +176,10 @@@ static void shortlog(const char *name, strbuf_ltrim(&sb); if (!sb.len) - string_list_append(sha1_to_hex(commit->object.sha1), - &subjects); + string_list_append(&subjects, + sha1_to_hex(commit->object.sha1)); else - string_list_append(strbuf_detach(&sb, NULL), &subjects); + string_list_append(&subjects, strbuf_detach(&sb, NULL)); } if (count > limit) @@@ -202,10 -202,35 +202,10 @@@ string_list_clear(&subjects, 0); } -int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) { - int limit = 20, i = 0, pos = 0; +static void do_fmt_merge_msg_title(struct strbuf *out, + const char *current_branch) { + int i = 0; char *sep = ""; - unsigned char head_sha1[20]; - const char *current_branch; - - /* get current branch */ - current_branch = resolve_ref("HEAD", head_sha1, 1, NULL); - if (!current_branch) - die("No current branch"); - if (!prefixcmp(current_branch, "refs/heads/")) - current_branch += 11; - - /* get a line */ - while (pos < in->len) { - int len; - char *newline, *p = in->buf + pos; - - newline = strchr(p, '\n'); - len = newline ? newline - p : strlen(p); - pos += len + !!newline; - i++; - p[len] = 0; - if (handle_line(p)) - die ("Error in line %d: %.*s", i, len, p); - } - - if (!srcs.nr) - return 0; strbuf_addstr(out, "Merge "); for (i = 0; i < srcs.nr; i++) { @@@ -253,40 -278,6 +253,40 @@@ strbuf_addch(out, '\n'); else strbuf_addf(out, " into %s\n", current_branch); +} + +static int do_fmt_merge_msg(int merge_title, int merge_summary, + struct strbuf *in, struct strbuf *out) { + int limit = 20, i = 0, pos = 0; + unsigned char head_sha1[20]; + const char *current_branch; + + /* get current branch */ + current_branch = resolve_ref("HEAD", head_sha1, 1, NULL); + if (!current_branch) + die("No current branch"); + if (!prefixcmp(current_branch, "refs/heads/")) + current_branch += 11; + + /* get a line */ + while (pos < in->len) { + int len; + char *newline, *p = in->buf + pos; + + newline = strchr(p, '\n'); + len = newline ? newline - p : strlen(p); + pos += len + !!newline; + i++; + p[len] = 0; + if (handle_line(p)) + die ("Error in line %d: %.*s", i, len, p); + } + + if (!srcs.nr) + return 0; + + if (merge_title) + do_fmt_merge_msg_title(out, current_branch); if (merge_summary) { struct commit *head; @@@ -298,9 -289,6 +298,9 @@@ rev.ignore_merges = 1; rev.limited = 1; + if (suffixcmp(out->buf, "\n")) + strbuf_addch(out, '\n'); + for (i = 0; i < origins.nr; i++) shortlog(origins.items[i].string, origins.items[i].util, head, &rev, limit, out); @@@ -308,14 -296,6 +308,14 @@@ return 0; } +int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) { + return do_fmt_merge_msg(1, merge_summary, in, out); +} + +int fmt_merge_msg_shortlog(struct strbuf *in, struct strbuf *out) { + return do_fmt_merge_msg(0, 1, in, out); +} + int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) { const char *inpath = NULL; diff --combined builtin/log.c index f068583618,40bdd01e82..7cb9317af7 --- a/builtin/log.c +++ b/builtin/log.c @@@ -535,13 -535,13 +535,13 @@@ static void add_header(const char *valu len--; if (!strncasecmp(value, "to: ", 4)) { - item = string_list_append(value + 4, &extra_to); + item = string_list_append(&extra_to, value + 4); len -= 4; } else if (!strncasecmp(value, "cc: ", 4)) { - item = string_list_append(value + 4, &extra_cc); + item = string_list_append(&extra_cc, value + 4); len -= 4; } else { - item = string_list_append(value, &extra_hdr); + item = string_list_append(&extra_hdr, value); } item->string[len] = '\0'; @@@ -549,9 -549,8 +549,9 @@@ #define THREAD_SHALLOW 1 #define THREAD_DEEP 2 -static int thread = 0; -static int do_signoff = 0; +static int thread; +static int do_signoff; +static const char *signature = git_version_string; static int git_format_config(const char *var, const char *value, void *cb) { @@@ -566,13 -565,13 +566,13 @@@ if (!strcmp(var, "format.to")) { if (!value) return config_error_nonbool(var); - string_list_append(value, &extra_to); + string_list_append(&extra_to, value); return 0; } if (!strcmp(var, "format.cc")) { if (!value) return config_error_nonbool(var); - string_list_append(value, &extra_cc); + string_list_append(&extra_cc, value); return 0; } if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) { @@@ -610,8 -609,6 +610,8 @@@ do_signoff = git_config_bool(var, value); return 0; } + if (!strcmp(var, "format.signature")) + return git_config_string(&signature, var, value); return git_log_config(var, value, cb); } @@@ -706,12 -703,6 +706,12 @@@ static void gen_message_id(struct rev_i info->message_id = strbuf_detach(&buf, NULL); } +static void print_signature(void) +{ + if (signature && *signature) + printf("-- \n%s\n\n", signature); +} + static void make_cover_letter(struct rev_info *rev, int use_stdout, int numbered, int numbered_files, struct commit *origin, @@@ -805,7 -796,6 +805,7 @@@ diff_flush(&opts); printf("\n"); + print_signature(); } static const char *clean_message_id(const char *msg_id) @@@ -959,7 -949,7 +959,7 @@@ static int to_callback(const struct opt if (unset) string_list_clear(&extra_to, 0); else - string_list_append(arg, &extra_to); + string_list_append(&extra_to, arg); return 0; } @@@ -968,7 -958,7 +968,7 @@@ static int cc_callback(const struct opt if (unset) string_list_clear(&extra_cc, 0); else - string_list_append(arg, &extra_cc); + string_list_append(&extra_cc, arg); return 0; } @@@ -1045,8 -1035,6 +1045,8 @@@ int cmd_format_patch(int argc, const ch { OPTION_CALLBACK, 0, "thread", &thread, "style", "enable message threading, styles: shallow, deep", PARSE_OPT_OPTARG, thread_callback }, + OPT_STRING(0, "signature", &signature, "signature", + "add a signature"), OPT_END() }; @@@ -1251,7 -1239,7 +1251,7 @@@ 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); + string_list_append(rev.ref_message_ids, msgid); } rev.numbered_files = numbered_files; rev.patch_suffix = fmt_patch_suffix; @@@ -1298,8 -1286,8 +1298,8 @@@ && (!cover_letter || rev.nr > 1)) free(rev.message_id); else - string_list_append(rev.message_id, - rev.ref_message_ids); + string_list_append(rev.ref_message_ids, + rev.message_id); } gen_message_id(&rev, sha1_to_hex(commit->object.sha1)); } @@@ -1325,7 -1313,7 +1325,7 @@@ mime_boundary_leader, rev.mime_boundary); else - printf("-- \n%s\n\n", git_version_string); + print_signature(); } if (!use_stdout) fclose(stdout); diff --combined builtin/ls-files.c index 0804047693,3eeacdc699..1b9b8a8b4a --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@@ -26,9 -26,8 +26,9 @@@ static int show_killed static int show_valid_bit; static int line_terminator = '\n'; +static const char *prefix; +static int max_prefix_len; static int prefix_len; -static int prefix_offset; static const char **pathspec; static int error_unmatch; static char *ps_matched; @@@ -44,15 -43,10 +44,15 @@@ static const char *tag_modified = "" static const char *tag_skip_worktree = ""; static const char *tag_resolve_undo = ""; +static void write_name(const char* name, size_t len) +{ + write_name_quoted_relative(name, len, prefix, prefix_len, stdout, + line_terminator); +} + static void show_dir_entry(const char *tag, struct dir_entry *ent) { - int len = prefix_len; - int offset = prefix_offset; + int len = max_prefix_len; if (len >= ent->len) die("git ls-files: internal error - directory entry not superset of prefix"); @@@ -61,7 -55,7 +61,7 @@@ return; fputs(tag, stdout); - write_name_quoted(ent->name + offset, stdout, line_terminator); + write_name(ent->name, ent->len); } static void show_other_files(struct dir_struct *dir) @@@ -127,7 -121,8 +127,7 @@@ static void show_killed_files(struct di static void show_ce_entry(const char *tag, struct cache_entry *ce) { - int len = prefix_len; - int offset = prefix_offset; + int len = max_prefix_len; if (len >= ce_namelen(ce)) die("git ls-files: internal error - cache entry not superset of prefix"); @@@ -161,19 -156,20 +161,19 @@@ find_unique_abbrev(ce->sha1,abbrev), ce_stage(ce)); } - write_name_quoted(ce->name + offset, stdout, line_terminator); + write_name(ce->name, ce_namelen(ce)); } static int show_one_ru(struct string_list_item *item, void *cbdata) { - int offset = prefix_offset; const char *path = item->string; struct resolve_undo_info *ui = item->util; int i, len; len = strlen(path); - if (len < prefix_len) + if (len < max_prefix_len) return 0; /* outside of the prefix */ - if (!match_pathspec(pathspec, path, len, prefix_len, ps_matched)) + if (!match_pathspec(pathspec, path, len, max_prefix_len, ps_matched)) return 0; /* uninterested */ for (i = 0; i < 3; i++) { if (!ui->mode[i]) @@@ -181,19 -177,19 +181,19 @@@ printf("%s%06o %s %d\t", tag_resolve_undo, ui->mode[i], find_unique_abbrev(ui->sha1[i], abbrev), i + 1); - write_name_quoted(path + offset, stdout, line_terminator); + write_name(path, len); } return 0; } -static void show_ru_info(const char *prefix) +static void show_ru_info(void) { if (!the_index.resolve_undo) return; - for_each_string_list(show_one_ru, the_index.resolve_undo, NULL); + for_each_string_list(the_index.resolve_undo, show_one_ru, NULL); } -static void show_files(struct dir_struct *dir, const char *prefix) +static void show_files(struct dir_struct *dir) { int i; @@@ -247,7 -243,7 +247,7 @@@ */ static void prune_cache(const char *prefix) { - int pos = cache_name_pos(prefix, prefix_len); + int pos = cache_name_pos(prefix, max_prefix_len); unsigned int first, last; if (pos < 0) @@@ -260,7 -256,7 +260,7 @@@ while (last > first) { int next = (last + first) >> 1; struct cache_entry *ce = active_cache[next]; - if (!strncmp(ce->name, prefix, prefix_len)) { + if (!strncmp(ce->name, prefix, max_prefix_len)) { first = next+1; continue; } @@@ -269,16 -265,11 +269,16 @@@ active_nr = last; } -static const char *verify_pathspec(const char *prefix) +static const char *pathspec_prefix(const char *prefix) { const char **p, *n, *prev; unsigned long max; + if (!pathspec) { + max_prefix_len = prefix ? strlen(prefix) : 0; + return prefix; + } + prev = NULL; max = PATH_MAX; for (p = pathspec; (n = *p) != NULL; p++) { @@@ -300,7 -291,10 +300,7 @@@ } } - if (prefix_offset > max || memcmp(prev, prefix, prefix_offset)) - die("git ls-files: cannot generate relative filenames containing '..'"); - - prefix_len = max; + max_prefix_len = max; return max ? xmemdupz(prev, max) : NULL; } @@@ -380,7 -374,7 +380,7 @@@ void overlay_tree_on_cache(const char * } } -int report_path_error(const char *ps_matched, const char **pathspec, int prefix_offset) +int report_path_error(const char *ps_matched, const char **pathspec, int prefix_len) { /* * Make sure all pathspec matched; otherwise it is an error. @@@ -410,7 -404,7 +410,7 @@@ continue; error("pathspec '%s' did not match any file(s) known to git.", - pathspec[num] + prefix_offset); + pathspec[num] + prefix_len); errors++; } return errors; @@@ -462,10 -456,9 +462,10 @@@ static int option_parse_exclude_standar return 0; } -int cmd_ls_files(int argc, const char **argv, const char *prefix) +int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) { int require_work_tree = 0, show_tag = 0; + const char *max_prefix; struct dir_struct dir; struct option builtin_ls_files_options[] = { { OPTION_CALLBACK, 'z', NULL, NULL, NULL, @@@ -511,7 -504,7 +511,7 @@@ { OPTION_CALLBACK, 0, "exclude-standard", &dir, NULL, "add the standard git exclusions", PARSE_OPT_NOARG, option_parse_exclude_standard }, - { OPTION_SET_INT, 0, "full-name", &prefix_offset, NULL, + { OPTION_SET_INT, 0, "full-name", &prefix_len, NULL, "make the output relative to the project top directory", PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL }, OPT_BOOLEAN(0, "error-unmatch", &error_unmatch, @@@ -523,9 -516,8 +523,9 @@@ }; memset(&dir, 0, sizeof(dir)); + prefix = cmd_prefix; if (prefix) - prefix_offset = strlen(prefix); + prefix_len = strlen(prefix); git_config(git_default_config, NULL); if (read_cache() < 0) @@@ -563,8 -555,9 +563,8 @@@ if (pathspec) strip_trailing_slash_from_submodules(); - /* Verify that the pathspec matches the prefix */ - if (pathspec) - prefix = verify_pathspec(prefix); + /* Find common prefix for all pathspec's */ + max_prefix = pathspec_prefix(prefix); /* Treat unmatching pathspec elements as errors */ if (pathspec && error_unmatch) { @@@ -582,8 -575,8 +582,8 @@@ show_killed | show_modified | show_resolve_undo)) show_cached = 1; - if (prefix) - prune_cache(prefix); + if (max_prefix) + prune_cache(max_prefix); if (with_tree) { /* * Basic sanity check; show-stages and show-unmerged @@@ -591,15 -584,15 +591,15 @@@ */ if (show_stage || show_unmerged) die("ls-files --with-tree is incompatible with -s or -u"); - overlay_tree_on_cache(with_tree, prefix); + overlay_tree_on_cache(with_tree, max_prefix); } - show_files(&dir, prefix); + show_files(&dir); if (show_resolve_undo) - show_ru_info(prefix); + show_ru_info(); if (ps_matched) { int bad; - bad = report_path_error(ps_matched, pathspec, prefix_offset); + bad = report_path_error(ps_matched, pathspec, prefix_len); if (bad) fprintf(stderr, "Did you forget to 'git add'?\n"); diff --combined builtin/receive-pack.c index 29bc8d50bb,5170abf2a0..d634b5a3d5 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@@ -17,7 -17,7 +17,7 @@@ enum deny_action DENY_UNCONFIGURED, DENY_IGNORE, DENY_WARN, - DENY_REFUSE, + DENY_REFUSE }; static int deny_deletes; @@@ -501,7 -501,7 +501,7 @@@ static void check_aliased_update(struc if (!(flag & REF_ISSYMREF)) return; - if ((item = string_list_lookup(dst_name, list)) == NULL) + if ((item = string_list_lookup(list, dst_name)) == NULL) return; cmd->skip_update = 1; @@@ -515,9 -515,9 +515,9 @@@ dst_cmd->skip_update = 1; strcpy(cmd_oldh, find_unique_abbrev(cmd->old_sha1, DEFAULT_ABBREV)); - strcat(cmd_newh, find_unique_abbrev(cmd->new_sha1, DEFAULT_ABBREV)); + strcpy(cmd_newh, find_unique_abbrev(cmd->new_sha1, DEFAULT_ABBREV)); strcpy(dst_oldh, find_unique_abbrev(dst_cmd->old_sha1, DEFAULT_ABBREV)); - strcat(dst_newh, find_unique_abbrev(dst_cmd->new_sha1, DEFAULT_ABBREV)); + strcpy(dst_newh, find_unique_abbrev(dst_cmd->new_sha1, DEFAULT_ABBREV)); rp_error("refusing inconsistent update between symref '%s' (%s..%s) and" " its target '%s' (%s..%s)", cmd->ref_name, cmd_oldh, cmd_newh, @@@ -534,7 -534,7 +534,7 @@@ static void check_aliased_updates(struc for (cmd = commands; cmd; cmd = cmd->next) { struct string_list_item *item = - string_list_append(cmd->ref_name, &ref_list); + string_list_append(&ref_list, cmd->ref_name); item->util = (void *)cmd; } sort_string_list(&ref_list); diff --combined builtin/remote.c index 0a52667e0f,03d90cde02..6699bc5712 --- a/builtin/remote.c +++ b/builtin/remote.c @@@ -16,7 -16,6 +16,7 @@@ static const char * const builtin_remot "git remote [-v | --verbose] show [-n] ", "git remote prune [-n | --dry-run] ", "git remote [-v | --verbose] update [-p | --prune] [group | remote]", + "git remote set-branches [--add] ...", "git remote set-url []", "git remote set-url --add ", "git remote set-url --delete ", @@@ -43,12 -42,6 +43,12 @@@ static const char * const builtin_remot NULL }; +static const char * const builtin_remote_setbranches_usage[] = { + "git remote set-branches ...", + "git remote set-branches --add ...", + NULL +}; + static const char * const builtin_remote_show_usage[] = { "git remote show [] ", NULL @@@ -94,7 -87,7 +94,7 @@@ static int opt_parse_track(const struc if (not) string_list_clear(list, 0); else - string_list_append(arg, list); + string_list_append(list, arg); return 0; } @@@ -117,20 -110,6 +117,20 @@@ enum TAGS_SET = 2 }; +static int add_branch(const char *key, const char *branchname, + const char *remotename, int mirror, struct strbuf *tmp) +{ + strbuf_reset(tmp); + strbuf_addch(tmp, '+'); + if (mirror) + strbuf_addf(tmp, "refs/%s:refs/%s", + branchname, branchname); + else + strbuf_addf(tmp, "refs/heads/%s:refs/remotes/%s/%s", + branchname, remotename, branchname); + return git_config_set_multivar(key, tmp->buf, "^$", 0); +} + static int add(int argc, const char **argv) { int fetch = 0, mirror = 0, fetch_tags = TAGS_DEFAULT; @@@ -181,10 -160,19 +181,10 @@@ strbuf_addf(&buf, "remote.%s.fetch", name); if (track.nr == 0) - string_list_append("*", &track); + string_list_append(&track, "*"); for (i = 0; i < track.nr; i++) { - struct string_list_item *item = track.items + i; - - strbuf_reset(&buf2); - strbuf_addch(&buf2, '+'); - if (mirror) - strbuf_addf(&buf2, "refs/%s:refs/%s", - item->string, item->string); - else - strbuf_addf(&buf2, "refs/heads/%s:refs/remotes/%s/%s", - item->string, name, item->string); - if (git_config_set_multivar(buf.buf, buf2.buf, "^$", 0)) + if (add_branch(buf.buf, track.items[i].string, + name, mirror, &buf2)) return 1; } @@@ -263,7 -251,7 +263,7 @@@ static int config_read_branches(const c } else return 0; - item = string_list_insert(name, &branch_list); + item = string_list_insert(&branch_list, name); if (!item->util) item->util = xcalloc(sizeof(struct branch_info), 1); @@@ -278,11 -266,11 +278,11 @@@ while (space) { char *merge; merge = xstrndup(value, space - value); - string_list_append(merge, &info->merge); + string_list_append(&info->merge, merge); value = abbrev_branch(space + 1); space = strchr(value, ' '); } - string_list_append(xstrdup(value), &info->merge); + string_list_append(&info->merge, xstrdup(value)); } else info->rebase = git_config_bool(orig_key, value); } @@@ -319,14 -307,14 +319,14 @@@ static int get_ref_states(const struct for (ref = fetch_map; ref; ref = ref->next) { unsigned char sha1[20]; if (!ref->peer_ref || read_ref(ref->peer_ref->name, sha1)) - string_list_append(abbrev_branch(ref->name), &states->new); + string_list_append(&states->new, abbrev_branch(ref->name)); else - string_list_append(abbrev_branch(ref->name), &states->tracked); + string_list_append(&states->tracked, abbrev_branch(ref->name)); } stale_refs = get_stale_heads(states->remote, fetch_map); for (ref = stale_refs; ref; ref = ref->next) { struct string_list_item *item = - string_list_append(abbrev_branch(ref->name), &states->stale); + string_list_append(&states->stale, abbrev_branch(ref->name)); item->util = xstrdup(ref->name); } free_refs(stale_refs); @@@ -348,7 -336,7 +348,7 @@@ struct push_info PUSH_STATUS_UPTODATE, PUSH_STATUS_FASTFORWARD, PUSH_STATUS_OUTOFDATE, - PUSH_STATUS_NOTQUERIED, + PUSH_STATUS_NOTQUERIED } status; }; @@@ -375,8 -363,8 +375,8 @@@ static int get_push_ref_states(const st continue; hashcpy(ref->new_sha1, ref->peer_ref->new_sha1); - item = string_list_append(abbrev_branch(ref->peer_ref->name), - &states->push); + item = string_list_append(&states->push, + abbrev_branch(ref->peer_ref->name)); item->util = xcalloc(sizeof(struct push_info), 1); info = item->util; info->forced = ref->force; @@@ -411,7 -399,7 +411,7 @@@ static int get_push_ref_states_noquery( states->push.strdup_strings = 1; if (!remote->push_refspec_nr) { - item = string_list_append("(matching)", &states->push); + item = string_list_append(&states->push, "(matching)"); info = item->util = xcalloc(sizeof(struct push_info), 1); info->status = PUSH_STATUS_NOTQUERIED; info->dest = xstrdup(item->string); @@@ -419,11 -407,11 +419,11 @@@ for (i = 0; i < remote->push_refspec_nr; i++) { struct refspec *spec = remote->push + i; if (spec->matching) - item = string_list_append("(matching)", &states->push); + item = string_list_append(&states->push, "(matching)"); else if (strlen(spec->src)) - item = string_list_append(spec->src, &states->push); + item = string_list_append(&states->push, spec->src); else - item = string_list_append("(delete)", &states->push); + item = string_list_append(&states->push, "(delete)"); info = item->util = xcalloc(sizeof(struct push_info), 1); info->forced = spec->force; @@@ -447,7 -435,7 +447,7 @@@ static int get_head_names(const struct matches = guess_remote_head(find_ref_by_name(remote_refs, "HEAD"), fetch_map, 1); for (ref = matches; ref; ref = ref->next) - string_list_append(abbrev_branch(ref->name), &states->heads); + string_list_append(&states->heads, abbrev_branch(ref->name)); free_refs(fetch_map); free_refs(matches); @@@ -511,8 -499,8 +511,8 @@@ static int add_branch_for_removal(cons if (prefixcmp(refname, "refs/remotes")) { /* advise user how to delete local branches */ if (!prefixcmp(refname, "refs/heads/")) - string_list_append(abbrev_branch(refname), - branches->skipped); + string_list_append(branches->skipped, + abbrev_branch(refname)); /* silently skip over other non-remote refs */ return 0; } @@@ -521,7 -509,7 +521,7 @@@ if (flags & REF_ISSYMREF) return unlink(git_path("%s", refname)); - item = string_list_append(refname, branches->branches); + item = string_list_append(branches->branches, refname); item->util = xmalloc(20); hashcpy(item->util, sha1); @@@ -546,7 -534,7 +546,7 @@@ static int read_remote_branches(const c strbuf_addf(&buf, "refs/remotes/%s", rename->old); if (!prefixcmp(refname, buf.buf)) { - item = string_list_append(xstrdup(refname), rename->remote_branches); + item = string_list_append(rename->remote_branches, xstrdup(refname)); symref = resolve_ref(refname, orig_sha1, 1, &flag); if (flag & REF_ISSYMREF) item->util = xstrdup(symref); @@@ -736,14 -724,11 +736,14 @@@ static int rm(int argc, const char **ar struct known_remotes known_remotes = { NULL, NULL }; struct string_list branches = { NULL, 0, 0, 1 }; struct string_list skipped = { NULL, 0, 0, 1 }; - struct branches_for_remote cb_data = { - NULL, &branches, &skipped, &known_remotes - }; + struct branches_for_remote cb_data; int i, result; + memset(&cb_data, 0, sizeof(cb_data)); + cb_data.branches = &branches; + cb_data.skipped = &skipped; + cb_data.keep = &known_remotes; + if (argc != 2) usage_with_options(builtin_remote_rm_usage, options); @@@ -832,7 -817,7 +832,7 @@@ static int append_ref_to_tracked_list(c memset(&refspec, 0, sizeof(refspec)); refspec.dst = (char *)refname; if (!remote_find_tracking(states->remote, &refspec)) - string_list_append(abbrev_branch(refspec.src), &states->tracked); + string_list_append(&states->tracked, abbrev_branch(refspec.src)); return 0; } @@@ -885,7 -870,7 +885,7 @@@ static int add_remote_to_show_info(stru int n = strlen(item->string); if (n > info->width) info->width = n; - string_list_insert(item->string, info->list); + string_list_insert(info->list, item->string); return 0; } @@@ -932,7 -917,7 +932,7 @@@ static int add_local_to_show_info(struc if (branch_info->rebase) show_info->any_rebase = 1; - item = string_list_insert(branch_item->string, show_info->list); + item = string_list_insert(show_info->list, branch_item->string); item->util = branch_info; return 0; @@@ -980,7 -965,7 +980,7 @@@ static int add_push_to_show_info(struc show_info->width = n; if ((n = strlen(push_info->dest)) > show_info->width2) show_info->width2 = n; - item = string_list_append(push_item->string, show_info->list); + item = string_list_append(show_info->list, push_item->string); item->util = push_item->util; return 0; } @@@ -1096,24 -1081,24 +1096,24 @@@ static int show(int argc, const char ** /* remote branch info */ info.width = 0; - for_each_string_list(add_remote_to_show_info, &states.new, &info); - for_each_string_list(add_remote_to_show_info, &states.tracked, &info); - for_each_string_list(add_remote_to_show_info, &states.stale, &info); + for_each_string_list(&states.new, add_remote_to_show_info, &info); + for_each_string_list(&states.tracked, add_remote_to_show_info, &info); + for_each_string_list(&states.stale, add_remote_to_show_info, &info); if (info.list->nr) printf(" Remote branch%s:%s\n", info.list->nr > 1 ? "es" : "", no_query ? " (status not queried)" : ""); - for_each_string_list(show_remote_info_item, info.list, &info); + for_each_string_list(info.list, show_remote_info_item, &info); string_list_clear(info.list, 0); /* git pull info */ info.width = 0; info.any_rebase = 0; - for_each_string_list(add_local_to_show_info, &branch_list, &info); + for_each_string_list(&branch_list, add_local_to_show_info, &info); if (info.list->nr) printf(" Local branch%s configured for 'git pull':\n", info.list->nr > 1 ? "es" : ""); - for_each_string_list(show_local_info_item, info.list, &info); + for_each_string_list(info.list, show_local_info_item, &info); string_list_clear(info.list, 0); /* git push info */ @@@ -1121,14 -1106,14 +1121,14 @@@ printf(" Local refs will be mirrored by 'git push'\n"); info.width = info.width2 = 0; - for_each_string_list(add_push_to_show_info, &states.push, &info); + for_each_string_list(&states.push, add_push_to_show_info, &info); qsort(info.list->items, info.list->nr, sizeof(*info.list->items), cmp_string_with_push); if (info.list->nr) printf(" Local ref%s configured for 'git push'%s:\n", info.list->nr > 1 ? "s" : "", no_query ? " (status not queried)" : ""); - for_each_string_list(show_push_info_item, info.list, &info); + for_each_string_list(info.list, show_push_info_item, &info); string_list_clear(info.list, 0); free_remote_ref_states(&states); @@@ -1299,72 -1284,6 +1299,72 @@@ static int update(int argc, const char return run_command_v_opt(fetch_argv, RUN_GIT_CMD); } +static int remove_all_fetch_refspecs(const char *remote, const char *key) +{ + return git_config_set_multivar(key, NULL, NULL, 1); +} + +static int add_branches(struct remote *remote, const char **branches, + const char *key) +{ + const char *remotename = remote->name; + int mirror = remote->mirror; + struct strbuf refspec = STRBUF_INIT; + + for (; *branches; branches++) + if (add_branch(key, *branches, remotename, mirror, &refspec)) { + strbuf_release(&refspec); + return 1; + } + + strbuf_release(&refspec); + return 0; +} + +static int set_remote_branches(const char *remotename, const char **branches, + int add_mode) +{ + struct strbuf key = STRBUF_INIT; + struct remote *remote; + + strbuf_addf(&key, "remote.%s.fetch", remotename); + + if (!remote_is_configured(remotename)) + die("No such remote '%s'", remotename); + remote = remote_get(remotename); + + if (!add_mode && remove_all_fetch_refspecs(remotename, key.buf)) { + strbuf_release(&key); + return 1; + } + if (add_branches(remote, branches, key.buf)) { + strbuf_release(&key); + return 1; + } + + strbuf_release(&key); + return 0; +} + +static int set_branches(int argc, const char **argv) +{ + int add_mode = 0; + struct option options[] = { + OPT_BOOLEAN('\0', "add", &add_mode, "add branch"), + OPT_END() + }; + + argc = parse_options(argc, argv, NULL, options, + builtin_remote_setbranches_usage, 0); + if (argc == 0) { + error("no remote specified"); + usage_with_options(builtin_remote_seturl_usage, options); + } + argv[argc] = NULL; + + return set_remote_branches(argv[0], argv + 1, add_mode); +} + static int set_url(int argc, const char **argv) { int i, push_mode = 0, add_mode = 0, delete_mode = 0; @@@ -1460,10 -1379,10 +1460,10 @@@ static int get_one_entry(struct remote if (remote->url_nr > 0) { strbuf_addf(&url_buf, "%s (fetch)", remote->url[0]); - string_list_append(remote->name, list)->util = + string_list_append(list, remote->name)->util = strbuf_detach(&url_buf, NULL); } else - string_list_append(remote->name, list)->util = NULL; + string_list_append(list, remote->name)->util = NULL; if (remote->pushurl_nr) { url = remote->pushurl; url_nr = remote->pushurl_nr; @@@ -1474,7 -1393,7 +1474,7 @@@ for (i = 0; i < url_nr; i++) { strbuf_addf(&url_buf, "%s (push)", url[i]); - string_list_append(remote->name, list)->util = + string_list_append(list, remote->name)->util = strbuf_detach(&url_buf, NULL); } @@@ -1530,8 -1449,6 +1530,8 @@@ int cmd_remote(int argc, const char **a result = rm(argc, argv); else if (!strcmp(argv[0], "set-head")) result = set_head(argc, argv); + else if (!strcmp(argv[0], "set-branches")) + result = set_branches(argc, argv); else if (!strcmp(argv[0], "set-url")) result = set_url(argc, argv); else if (!strcmp(argv[0], "show")) diff --combined builtin/rerere.c index 0048f9ef7f,73610b6bc2..980d5421ee --- a/builtin/rerere.c +++ b/builtin/rerere.c @@@ -59,7 -59,7 +59,7 @@@ static void garbage_collect(struct stri cutoff = (has_rerere_resolution(e->d_name) ? cutoff_resolve : cutoff_noresolve); if (then < now - cutoff * 86400) - string_list_append(e->d_name, &to_remove); + string_list_append(&to_remove, e->d_name); } for (i = 0; i < to_remove.nr; i++) unlink_rr_item(to_remove.items[i].string); @@@ -89,7 -89,7 +89,7 @@@ static int diff_two(const char *file1, printf("--- a/%s\n+++ b/%s\n", label1, label2); fflush(stdout); memset(&xpp, 0, sizeof(xpp)); - xpp.flags = XDF_NEED_MINIMAL; + xpp.flags = 0; memset(&xecfg, 0, sizeof(xecfg)); xecfg.ctxlen = 3; ecb.outf = outf; diff --combined http-backend.c index 44ce6bb32b,8ec15f99c0..14c90c2e84 --- a/http-backend.c +++ b/http-backend.c @@@ -6,7 -6,6 +6,7 @@@ #include "exec_cmd.h" #include "run-command.h" #include "string-list.h" +#include "url.h" static const char content_type[] = "Content-Type"; static const char content_length[] = "Content-Length"; @@@ -26,6 -25,60 +26,6 @@@ static struct rpc_service rpc_service[ { "receive-pack", "receivepack", -1 }, }; -static int decode_char(const char *q) -{ - int i; - unsigned char val = 0; - for (i = 0; i < 2; i++) { - unsigned char c = *q++; - val <<= 4; - if (c >= '0' && c <= '9') - val += c - '0'; - else if (c >= 'a' && c <= 'f') - val += c - 'a' + 10; - else if (c >= 'A' && c <= 'F') - val += c - 'A' + 10; - else - return -1; - } - return val; -} - -static char *decode_parameter(const char **query, int is_name) -{ - const char *q = *query; - struct strbuf out; - - strbuf_init(&out, 16); - do { - unsigned char c = *q; - - if (!c) - break; - if (c == '&' || (is_name && c == '=')) { - q++; - break; - } - - if (c == '%') { - int val = decode_char(q + 1); - if (0 <= val) { - strbuf_addch(&out, val); - q += 3; - continue; - } - } - - if (c == '+') - strbuf_addch(&out, ' '); - else - strbuf_addch(&out, c); - q++; - } while (1); - *query = q; - return strbuf_detach(&out, NULL); -} - static struct string_list *get_parameters(void) { if (!query_params) { @@@ -33,13 -86,13 +33,13 @@@ query_params = xcalloc(1, sizeof(*query_params)); while (query && *query) { - char *name = decode_parameter(&query, 1); - char *value = decode_parameter(&query, 0); + char *name = url_decode_parameter_name(&query); + char *value = url_decode_parameter_value(&query); struct string_list_item *i; - i = string_list_lookup(name, query_params); + i = string_list_lookup(query_params, name); if (!i) - i = string_list_insert(name, query_params); + i = string_list_insert(query_params, name); else free(i->util); i->util = value; @@@ -51,7 -104,7 +51,7 @@@ static const char *get_parameter(const char *name) { struct string_list_item *i; - i = string_list_lookup(name, get_parameters()); + i = string_list_lookup(get_parameters(), name); return i ? i->util : NULL; } @@@ -488,12 -541,14 +488,12 @@@ static NORETURN void die_webcgi(const c static int dead; if (!dead) { - char buffer[1000]; dead = 1; - - vsnprintf(buffer, sizeof(buffer), err, params); - fprintf(stderr, "fatal: %s\n", buffer); http_status(500, "Internal Server Error"); hdr_nocache(); end_headers(); + + vreportf("fatal: ", err, params); } exit(0); /* we successfully reported a failure ;-) */ } diff --combined notes.c index 30d6ded78e,4a541e4371..1978244398 --- a/notes.c +++ b/notes.c @@@ -716,7 -716,7 +716,7 @@@ static int write_each_non_note_until(co struct write_each_note_data *d) { struct non_note *n = d->next_non_note; - int cmp, ret; + int cmp = 0, ret; while (n && (!note_path || (cmp = strcmp(n->path, note_path)) <= 0)) { if (note_path && cmp == 0) ; /* do nothing, prefer note to non-note */ @@@ -838,7 -838,7 +838,7 @@@ static int string_list_add_one_ref(cons { struct string_list *refs = cb; if (!unsorted_string_list_has_string(refs, path)) - string_list_append(path, refs); + string_list_append(refs, path); return 0; } @@@ -851,7 -851,7 +851,7 @@@ void string_list_add_refs_by_glob(struc if (get_sha1(glob, sha1)) warning("notes ref %s is invalid", glob); if (!unsorted_string_list_has_string(list, glob)) - string_list_append(glob, list); + string_list_append(list, glob); } } @@@ -969,7 -969,7 +969,7 @@@ struct notes_tree **load_notes_trees(st trees = xmalloc((refs->nr+1) * sizeof(struct notes_tree *)); cb_data.counter = 0; cb_data.trees = trees; - for_each_string_list(load_one_display_note_ref, refs, &cb_data); + for_each_string_list(refs, load_one_display_note_ref, &cb_data); trees[cb_data.counter] = NULL; return trees; } @@@ -983,7 -983,7 +983,7 @@@ void init_display_notes(struct display_ assert(!display_notes_trees); if (!opt || !opt->suppress_default_notes) { - string_list_append(default_notes_ref(), &display_notes_refs); + string_list_append(&display_notes_refs, default_notes_ref()); display_ref_env = getenv(GIT_NOTES_DISPLAY_REF_ENVIRONMENT); if (display_ref_env) { string_list_add_refs_from_colon_sep(&display_notes_refs, @@@ -996,8 -996,8 +996,8 @@@ git_config(notes_display_config, &load_config_refs); if (opt && opt->extra_notes_refs) - for_each_string_list(string_list_add_refs_from_list, - opt->extra_notes_refs, + for_each_string_list(opt->extra_notes_refs, + string_list_add_refs_from_list, &display_notes_refs); display_notes_trees = load_notes_trees(&display_notes_refs); @@@ -1083,7 -1083,7 +1083,7 @@@ int write_notes_tree(struct notes_tree return ret; } -void prune_notes(struct notes_tree *t) +void prune_notes(struct notes_tree *t, int flags) { struct note_delete_list *l = NULL; @@@ -1094,10 -1094,7 +1094,10 @@@ for_each_note(t, 0, prune_notes_helper, &l); while (l) { - remove_note(t, l->sha1); + if (flags & NOTES_PRUNE_VERBOSE) + printf("%s\n", sha1_to_hex(l->sha1)); + if (!(flags & NOTES_PRUNE_DRYRUN)) + remove_note(t, l->sha1); l = l->next; } } diff --combined remote.c index e51cd22d6b,9f0c6ef8f5..afbba47460 --- a/remote.c +++ b/remote.c @@@ -478,7 -478,7 +478,7 @@@ static void read_config(void unsigned char sha1[20]; const char *head_ref; int flag; - if (default_remote_name) // did this already + if (default_remote_name) /* did this already */ return; default_remote_name = xstrdup("origin"); current_branch = NULL; @@@ -659,9 -659,10 +659,9 @@@ static struct refspec *parse_refspec_in int valid_fetch_refspec(const char *fetch_refspec_str) { - const char *fetch_refspec[] = { fetch_refspec_str }; struct refspec *refspec; - refspec = parse_refspec_internal(1, fetch_refspec, 1, 1); + refspec = parse_refspec_internal(1, &fetch_refspec_str, 1, 1); free_refspecs(refspec, 1); return !!refspec; } @@@ -762,7 -763,7 +762,7 @@@ void ref_remove_duplicates(struct ref * if (!ref_map->peer_ref) continue; - item = string_list_lookup(ref_map->peer_ref->name, &refs); + item = string_list_lookup(&refs, ref_map->peer_ref->name); if (item) { if (strcmp(((struct ref *)item->util)->name, ref_map->name)) @@@ -777,7 -778,7 +777,7 @@@ continue; } - item = string_list_insert(ref_map->peer_ref->name, &refs); + item = string_list_insert(&refs, ref_map->peer_ref->name); item->util = ref_map; } string_list_clear(&refs, 0); @@@ -1710,7 -1711,7 +1710,7 @@@ struct ref *get_stale_heads(struct remo info.ref_names = &ref_names; info.stale_refs_tail = &stale_refs; for (ref = fetch_map; ref; ref = ref->next) - string_list_append(ref->name, &ref_names); + string_list_append(&ref_names, ref->name); sort_string_list(&ref_names); for_each_ref(get_stale_heads_cb, &info); string_list_clear(&ref_names, 0); diff --combined rerere.c index 2197890982,910cfd963d..d03a69634b --- a/rerere.c +++ b/rerere.c @@@ -46,7 -46,7 +46,7 @@@ static void read_rr(struct string_list ; /* do nothing */ if (i == sizeof(buf)) die("filename too long"); - string_list_insert(buf, rr)->util = name; + string_list_insert(rr, buf)->util = name; } fclose(in); } @@@ -153,7 -153,7 +153,7 @@@ static int handle_path(unsigned char *s git_SHA_CTX ctx; int hunk_no = 0; enum { - RR_CONTEXT = 0, RR_SIDE_1, RR_SIDE_2, RR_ORIGINAL, + RR_CONTEXT = 0, RR_SIDE_1, RR_SIDE_2, RR_ORIGINAL } hunk = RR_CONTEXT; struct strbuf one = STRBUF_INIT, two = STRBUF_INIT; struct strbuf buf = STRBUF_INIT; @@@ -354,7 -354,7 +354,7 @@@ static int find_conflict(struct string_ ce_same_name(e2, e3) && S_ISREG(e2->ce_mode) && S_ISREG(e3->ce_mode)) { - string_list_insert((const char *)e2->name, conflict); + string_list_insert(conflict, (const char *)e2->name); i++; /* skip over both #2 and #3 */ } } @@@ -449,7 -449,7 +449,7 @@@ static int do_plain_rerere(struct strin if (ret < 1) continue; hex = xstrdup(sha1_to_hex(sha1)); - string_list_insert(path, rr)->util = hex; + string_list_insert(rr, path)->util = hex; if (mkdir(git_path("rr-cache/%s", hex), 0755)) continue; handle_file(path, NULL, rerere_path(hex, "preimage")); @@@ -471,7 -471,7 +471,7 @@@ if (has_rerere_resolution(name)) { if (!merge(name, path)) { if (rerere_autoupdate) - string_list_insert(path, &update); + string_list_insert(&update, path); fprintf(stderr, "%s '%s' using previous resolution.\n", rerere_autoupdate @@@ -577,7 -577,7 +577,7 @@@ static int rerere_forget_one_path(cons fprintf(stderr, "Updated preimage for '%s'\n", path); - string_list_insert(path, rr)->util = hex; + string_list_insert(rr, path)->util = hex; fprintf(stderr, "Forgot resolution for %s\n", path); return 0; } diff --combined revision.c index 527ec34e63,28f1c6d014..7e82efd932 --- a/revision.c +++ b/revision.c @@@ -646,93 -646,6 +646,93 @@@ static int still_interesting(struct com return slop-1; } +/* + * "rev-list --ancestry-path A..B" computes commits that are ancestors + * of B but not ancestors of A but further limits the result to those + * that are descendants of A. This takes the list of bottom commits and + * the result of "A..B" without --ancestry-path, and limits the latter + * further to the ones that can reach one of the commits in "bottom". + */ +static void limit_to_ancestry(struct commit_list *bottom, struct commit_list *list) +{ + struct commit_list *p; + struct commit_list *rlist = NULL; + int made_progress; + + /* + * Reverse the list so that it will be likely that we would + * process parents before children. + */ + for (p = list; p; p = p->next) + commit_list_insert(p->item, &rlist); + + for (p = bottom; p; p = p->next) + p->item->object.flags |= TMP_MARK; + + /* + * Mark the ones that can reach bottom commits in "list", + * in a bottom-up fashion. + */ + do { + made_progress = 0; + for (p = rlist; p; p = p->next) { + struct commit *c = p->item; + struct commit_list *parents; + if (c->object.flags & (TMP_MARK | UNINTERESTING)) + continue; + for (parents = c->parents; + parents; + parents = parents->next) { + if (!(parents->item->object.flags & TMP_MARK)) + continue; + c->object.flags |= TMP_MARK; + made_progress = 1; + break; + } + } + } while (made_progress); + + /* + * NEEDSWORK: decide if we want to remove parents that are + * not marked with TMP_MARK from commit->parents for commits + * in the resulting list. We may not want to do that, though. + */ + + /* + * The ones that are not marked with TMP_MARK are uninteresting + */ + for (p = list; p; p = p->next) { + struct commit *c = p->item; + if (c->object.flags & TMP_MARK) + continue; + c->object.flags |= UNINTERESTING; + } + + /* We are done with the TMP_MARK */ + for (p = list; p; p = p->next) + p->item->object.flags &= ~TMP_MARK; + for (p = bottom; p; p = p->next) + p->item->object.flags &= ~TMP_MARK; + free_commit_list(rlist); +} + +/* + * Before walking the history, keep the set of "negative" refs the + * caller has asked to exclude. + * + * This is used to compute "rev-list --ancestry-path A..B", as we need + * to filter the result of "A..B" further to the ones that can actually + * reach A. + */ +static struct commit_list *collect_bottom_commits(struct commit_list *list) +{ + struct commit_list *elem, *bottom = NULL; + for (elem = list; elem; elem = elem->next) + if (elem->item->object.flags & UNINTERESTING) + commit_list_insert(elem->item, &bottom); + return bottom; +} + static int limit_list(struct rev_info *revs) { int slop = SLOP; @@@ -740,13 -653,6 +740,13 @@@ struct commit_list *list = revs->commits; struct commit_list *newlist = NULL; struct commit_list **p = &newlist; + struct commit_list *bottom = NULL; + + if (revs->ancestry_path) { + bottom = collect_bottom_commits(list); + if (!bottom) + die("--ancestry-path given but there are no bottom commits"); + } while (list) { struct commit_list *entry = list; @@@ -788,11 -694,6 +788,11 @@@ if (revs->cherry_pick) cherry_pick_list(newlist, revs); + if (bottom) { + limit_to_ancestry(bottom, newlist); + free_commit_list(bottom); + } + revs->commits = newlist; return 0; } @@@ -1162,22 -1063,18 +1162,22 @@@ static int handle_revision_opt(struct r if (!prefixcmp(arg, "--max-count=")) { revs->max_count = atoi(arg + 12); + revs->no_walk = 0; } else if (!prefixcmp(arg, "--skip=")) { revs->skip_count = atoi(arg + 7); } else if ((*arg == '-') && isdigit(arg[1])) { /* accept -, like traditional "head" */ revs->max_count = atoi(arg + 1); + revs->no_walk = 0; } else if (!strcmp(arg, "-n")) { if (argc <= 1) return error("-n requires an argument"); revs->max_count = atoi(argv[1]); + revs->no_walk = 0; return 2; } else if (!prefixcmp(arg, "-n")) { revs->max_count = atoi(arg + 2); + revs->no_walk = 0; } else if (!prefixcmp(arg, "--max-age=")) { revs->max_age = atoi(arg + 10); } else if (!prefixcmp(arg, "--since=")) { @@@ -1192,10 -1089,6 +1192,10 @@@ revs->min_age = approxidate(arg + 8); } else if (!strcmp(arg, "--first-parent")) { revs->first_parent_only = 1; + } else if (!strcmp(arg, "--ancestry-path")) { + revs->ancestry_path = 1; + revs->simplify_history = 0; + revs->limited = 1; } else if (!strcmp(arg, "-g") || !strcmp(arg, "--walk-reflogs")) { init_reflog_walk(&revs->reflog_info); } else if (!strcmp(arg, "--default")) { @@@ -1253,8 -1146,6 +1253,8 @@@ revs->boundary = 1; } else if (!strcmp(arg, "--left-right")) { revs->left_right = 1; + } else if (!strcmp(arg, "--count")) { + revs->count = 1; } else if (!strcmp(arg, "--cherry-pick")) { revs->cherry_pick = 1; revs->limited = 1; @@@ -1314,8 -1205,8 +1314,8 @@@ else strbuf_addstr(&buf, "refs/notes/"); strbuf_addstr(&buf, arg+13); - string_list_append(strbuf_detach(&buf, NULL), - revs->notes_opt.extra_notes_refs); + string_list_append(revs->notes_opt.extra_notes_refs, + strbuf_detach(&buf, NULL)); } else if (!strcmp(arg, "--no-notes")) { revs->show_notes = 0; revs->show_notes_given = 1; @@@ -1890,7 -1781,7 +1890,7 @@@ int prepare_revision_walk(struct rev_in enum rewrite_result { rewrite_one_ok, rewrite_one_noparents, - rewrite_one_error, + rewrite_one_error }; static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp) diff --combined wt-status.c index 9d9cb95562,1653cfa9d6..38754ad735 --- a/wt-status.c +++ b/wt-status.c @@@ -9,7 -9,6 +9,7 @@@ #include "quote.h" #include "run-command.h" #include "remote.h" +#include "refs.h" static char default_wt_status_colors[][COLOR_MAXLEN] = { GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */ @@@ -18,8 -17,6 +18,8 @@@ GIT_COLOR_RED, /* WT_STATUS_UNTRACKED */ GIT_COLOR_RED, /* WT_STATUS_NOBRANCH */ GIT_COLOR_RED, /* WT_STATUS_UNMERGED */ + GIT_COLOR_GREEN, /* WT_STATUS_LOCAL_BRANCH */ + GIT_COLOR_RED, /* WT_STATUS_REMOTE_BRANCH */ }; static const char *color(int slot, struct wt_status *s) @@@ -235,7 -232,7 +235,7 @@@ static void wt_status_collect_changed_c struct wt_status_change_data *d; p = q->queue[i]; - it = string_list_insert(p->one->path, &s->change); + it = string_list_insert(&s->change, p->one->path); d = it->util; if (!d) { d = xcalloc(1, sizeof(*d)); @@@ -282,7 -279,7 +282,7 @@@ static void wt_status_collect_updated_c struct wt_status_change_data *d; p = q->queue[i]; - it = string_list_insert(p->two->path, &s->change); + it = string_list_insert(&s->change, p->two->path); d = it->util; if (!d) { d = xcalloc(1, sizeof(*d)); @@@ -349,7 -346,7 +349,7 @@@ static void wt_status_collect_changes_i if (!ce_path_match(ce, s->pathspec)) continue; - it = string_list_insert(ce->name, &s->change); + it = string_list_insert(&s->change, ce->name); d = it->util; if (!d) { d = xcalloc(1, sizeof(*d)); @@@ -384,7 -381,7 +384,7 @@@ static void wt_status_collect_untracked continue; if (!match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL)) continue; - string_list_insert(ent->name, &s->untracked); + string_list_insert(&s->untracked, ent->name); free(ent); } @@@ -398,7 -395,7 +398,7 @@@ continue; if (!match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL)) continue; - string_list_insert(ent->name, &s->ignored); + string_list_insert(&s->ignored, ent->name); free(ent); } } @@@ -521,18 -518,17 +521,18 @@@ static void wt_status_print_submodule_s struct child_process sm_summary; char summary_limit[64]; char index[PATH_MAX]; - const char *env[] = { index, NULL }; - const char *argv[] = { - "submodule", - "summary", - uncommitted ? "--files" : "--cached", - "--for-status", - "--summary-limit", - summary_limit, - uncommitted ? NULL : (s->amend ? "HEAD^" : "HEAD"), - NULL - }; + const char *env[] = { NULL, NULL }; + const char *argv[8]; + + env[0] = index; + argv[0] = "submodule"; + argv[1] = "summary"; + argv[2] = uncommitted ? "--files" : "--cached"; + argv[3] = "--for-status"; + argv[4] = "--summary-limit"; + argv[5] = summary_limit; + argv[6] = uncommitted ? NULL : (s->amend ? "HEAD^" : "HEAD"); + argv[7] = NULL; sprintf(summary_limit, "%d", s->submodule_summary); snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", s->index_file); @@@ -760,69 -756,9 +760,69 @@@ static void wt_shortstatus_other(int nu } } -void wt_shortstatus_print(struct wt_status *s, int null_termination) +static void wt_shortstatus_print_tracking(struct wt_status *s) +{ + struct branch *branch; + const char *header_color = color(WT_STATUS_HEADER, s); + const char *branch_color_local = color(WT_STATUS_LOCAL_BRANCH, s); + const char *branch_color_remote = color(WT_STATUS_REMOTE_BRANCH, s); + + const char *base; + const char *branch_name; + int num_ours, num_theirs; + + color_fprintf(s->fp, color(WT_STATUS_HEADER, s), "## "); + + if (!s->branch) + return; + branch_name = s->branch; + + if (!prefixcmp(branch_name, "refs/heads/")) + branch_name += 11; + else if (!strcmp(branch_name, "HEAD")) { + branch_name = "HEAD (no branch)"; + branch_color_local = color(WT_STATUS_NOBRANCH, s); + } + + branch = branch_get(s->branch + 11); + if (s->is_initial) + color_fprintf(s->fp, header_color, "Initial commit on "); + if (!stat_tracking_info(branch, &num_ours, &num_theirs)) { + color_fprintf_ln(s->fp, branch_color_local, + "%s", branch_name); + return; + } + + base = branch->merge[0]->dst; + base = shorten_unambiguous_ref(base, 0); + color_fprintf(s->fp, branch_color_local, "%s", branch_name); + color_fprintf(s->fp, header_color, "..."); + color_fprintf(s->fp, branch_color_remote, "%s", base); + + color_fprintf(s->fp, header_color, " ["); + if (!num_ours) { + color_fprintf(s->fp, header_color, "behind "); + color_fprintf(s->fp, branch_color_remote, "%d", num_theirs); + } else if (!num_theirs) { + color_fprintf(s->fp, header_color, "ahead "); + color_fprintf(s->fp, branch_color_local, "%d", num_ours); + } else { + color_fprintf(s->fp, header_color, "ahead "); + color_fprintf(s->fp, branch_color_local, "%d", num_ours); + color_fprintf(s->fp, header_color, ", behind "); + color_fprintf(s->fp, branch_color_remote, "%d", num_theirs); + } + + color_fprintf_ln(s->fp, header_color, "]"); +} + +void wt_shortstatus_print(struct wt_status *s, int null_termination, int show_branch) { int i; + + if (show_branch) + wt_shortstatus_print_tracking(s); + for (i = 0; i < s->change.nr; i++) { struct wt_status_change_data *d; struct string_list_item *it; @@@ -853,5 -789,5 +853,5 @@@ void wt_porcelain_print(struct wt_statu s->use_color = 0; s->relative_paths = 0; s->prefix = NULL; - wt_shortstatus_print(s, null_termination); + wt_shortstatus_print(s, null_termination, 0); }