From: Junio C Hamano Date: Mon, 8 May 2006 23:40:23 +0000 (-0700) Subject: Merge branch 'fix' X-Git-Tag: v1.4.0-rc1~161 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/45f75a0167b4a4693f2c6005bf7db231ca91ecc8?ds=inline;hp=-c Merge branch 'fix' * fix: Separate object name errors from usage errors Documentation: {caret} fixes (git-rev-list.txt) Fix "git diff --stat" with long filenames Fix repo-config set-multivar error return path. --- 45f75a0167b4a4693f2c6005bf7db231ca91ecc8 diff --combined config.c index 61eacefbee,adb5ce476a..0f518c957c --- a/config.c +++ b/config.c @@@ -336,10 -336,8 +336,10 @@@ static int store_aux(const char* key, c store.state = KEY_SEEN; store.seen++; } else if (strrchr(key, '.') - key == store.baselen && - !strncmp(key, store.key, store.baselen)) + !strncmp(key, store.key, store.baselen)) { store.state = SECTION_SEEN; + store.offset[store.seen] = ftell(config_file); + } } return 0; } @@@ -422,7 -420,7 +422,7 @@@ int git_config_set_multivar(const char const char* value_regex, int multi_replace) { int i; - int fd, in_fd; + int fd = -1, in_fd; int ret; char* config_filename = strdup(git_path("config")); char* lock_file = strdup(git_path("config.lock")); @@@ -480,15 -478,11 +480,11 @@@ if ( ENOENT != errno ) { error("opening %s: %s", config_filename, strerror(errno)); - close(fd); - unlink(lock_file); ret = 3; /* same as "invalid config file" */ goto out_free; } /* if nothing to unset, error out */ if (value == NULL) { - close(fd); - unlink(lock_file); ret = 5; goto out_free; } @@@ -516,8 -510,6 +512,6 @@@ fprintf(stderr, "Invalid pattern: %s\n", value_regex); free(store.value_regex); - close(fd); - unlink(lock_file); ret = 6; goto out_free; } @@@ -553,8 -545,6 +547,6 @@@ /* if nothing to unset, or too many matches, error out */ if ((store.seen == 0 && value == NULL) || (store.seen > 1 && multi_replace == 0)) { - close(fd); - unlink(lock_file); ret = 5; goto out_free; } @@@ -603,8 -593,6 +595,6 @@@ unlink(config_filename); } - close(fd); - if (rename(lock_file, config_filename) < 0) { fprintf(stderr, "Could not rename the lock file?\n"); ret = 4; @@@ -614,10 -602,14 +604,14 @@@ ret = 0; out_free: + if (0 <= fd) + close(fd); if (config_filename) free(config_filename); - if (lock_file) + if (lock_file) { + unlink(lock_file); free(lock_file); + } return ret; } diff --combined diff.c index c845c87113,afaa648dbb..5315270601 --- a/diff.c +++ b/diff.c @@@ -195,56 -195,6 +195,56 @@@ static int fn_out(void *priv, mmbuffer_ return 0; } +static char *pprint_rename(const char *a, const char *b) +{ + const char *old = a; + const char *new = b; + char *name = NULL; + int pfx_length, sfx_length; + int len_a = strlen(a); + int len_b = strlen(b); + + /* Find common prefix */ + pfx_length = 0; + while (*old && *new && *old == *new) { + if (*old == '/') + pfx_length = old - a + 1; + old++; + new++; + } + + /* Find common suffix */ + old = a + len_a; + new = b + len_b; + sfx_length = 0; + while (a <= old && b <= new && *old == *new) { + if (*old == '/') + sfx_length = len_a - (old - a); + old--; + new--; + } + + /* + * pfx{mid-a => mid-b}sfx + * {pfx-a => pfx-b}sfx + * pfx{sfx-a => sfx-b} + * name-a => name-b + */ + if (pfx_length + sfx_length) { + name = xmalloc(len_a + len_b - pfx_length - sfx_length + 7); + sprintf(name, "%.*s{%.*s => %.*s}%s", + pfx_length, a, + len_a - pfx_length - sfx_length, a + pfx_length, + len_b - pfx_length - sfx_length, b + pfx_length, + a + len_a - sfx_length); + } + else { + name = xmalloc(len_a + len_b + 5); + sprintf(name, "%s => %s", a, b); + } + return name; +} + struct diffstat_t { struct xdiff_emit_state xm; @@@ -254,14 -204,12 +254,14 @@@ char *name; unsigned is_unmerged:1; unsigned is_binary:1; + unsigned is_renamed:1; unsigned int added, deleted; } **files; }; static struct diffstat_file *diffstat_add(struct diffstat_t *diffstat, - const char *name) + const char *name_a, + const char *name_b) { struct diffstat_file *x; x = xcalloc(sizeof (*x), 1); @@@ -271,12 -219,7 +271,12 @@@ diffstat->alloc * sizeof(x)); } diffstat->files[diffstat->nr++] = x; - x->name = strdup(name); + if (name_b) { + x->name = pprint_rename(name_a, name_b); + x->is_renamed = 1; + } + else + x->name = strdup(name_a); return x; } @@@ -296,7 -239,6 +296,6 @@@ static const char minuses[]= "--------- static void show_stats(struct diffstat_t* data) { - char *prefix = ""; int i, len, add, del, total, adds = 0, dels = 0; int max, max_change = 0, max_len = 0; int total_files = data->nr; @@@ -318,6 -260,7 +317,7 @@@ } for (i = 0; i < data->nr; i++) { + char *prefix = ""; char *name = data->files[i]->name; int added = data->files[i]->added; int deleted = data->files[i]->deleted; @@@ -362,8 -305,7 +362,8 @@@ printf(" %s%-*s | Unmerged\n", prefix, len, name); goto free_diffstat_file; } - else if (added + deleted == 0) { + else if (!data->files[i]->is_renamed && + (added + deleted == 0)) { total_files--; goto free_diffstat_file; } @@@ -483,27 -425,19 +483,27 @@@ static void builtin_diff(const char *na } static void builtin_diffstat(const char *name_a, const char *name_b, - struct diff_filespec *one, struct diff_filespec *two, - struct diffstat_t *diffstat) + struct diff_filespec *one, + struct diff_filespec *two, + struct diffstat_t *diffstat, + int complete_rewrite) { mmfile_t mf1, mf2; struct diffstat_file *data; - data = diffstat_add(diffstat, name_a ? name_a : name_b); + data = diffstat_add(diffstat, name_a, name_b); if (!one || !two) { data->is_unmerged = 1; return; } - + if (complete_rewrite) { + diff_populate_filespec(one, 0); + diff_populate_filespec(two, 0); + data->deleted = count_lines(one->data, one->size); + data->added = count_lines(two->data, two->size); + return; + } if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) die("unable to read files to diff"); @@@ -1018,12 -952,14 +1018,12 @@@ static void run_diff(struct diff_filepa } if (memcmp(one->sha1, two->sha1, 20)) { - char one_sha1[41]; int abbrev = o->full_index ? 40 : DEFAULT_ABBREV; - memcpy(one_sha1, sha1_to_hex(one->sha1), 41); len += snprintf(msg + len, sizeof(msg) - len, "index %.*s..%.*s", - abbrev, one_sha1, abbrev, - sha1_to_hex(two->sha1)); + abbrev, sha1_to_hex(one->sha1), + abbrev, sha1_to_hex(two->sha1)); if (one->mode == two->mode) len += snprintf(msg + len, sizeof(msg) - len, " %06o", one->mode); @@@ -1056,15 -992,14 +1056,15 @@@ } static void run_diffstat(struct diff_filepair *p, struct diff_options *o, - struct diffstat_t *diffstat) + struct diffstat_t *diffstat) { const char *name; const char *other; + int complete_rewrite = 0; if (DIFF_PAIR_UNMERGED(p)) { /* unmerged */ - builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat); + builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, 0); return; } @@@ -1074,9 -1009,7 +1074,9 @@@ diff_fill_sha1_info(p->one); diff_fill_sha1_info(p->two); - builtin_diffstat(name, other, p->one, p->two, diffstat); + if (p->status == DIFF_STATUS_MODIFIED && p->score) + complete_rewrite = 1; + builtin_diffstat(name, other, p->one, p->two, diffstat, complete_rewrite); } void diff_setup(struct diff_options *options) @@@ -1103,7 -1036,8 +1103,7 @@@ int diff_setup_done(struct diff_option * recursive bits for other formats here. */ if ((options->output_format == DIFF_FORMAT_PATCH) || - (options->output_format == DIFF_FORMAT_DIFFSTAT) || - (options->with_stat)) + (options->output_format == DIFF_FORMAT_DIFFSTAT)) options->recursive = 1; if (options->detect_rename && options->rename_limit < 0) @@@ -1441,7 -1375,7 +1441,7 @@@ static void diff_flush_patch(struct dif } static void diff_flush_stat(struct diff_filepair *p, struct diff_options *o, - struct diffstat_t *diffstat) + struct diffstat_t *diffstat) { if (diff_unmodified_pair(p)) return; @@@ -1626,7 -1560,7 +1626,7 @@@ void diff_flush(struct diff_options *op for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; flush_one_pair(p, DIFF_FORMAT_DIFFSTAT, options, - diffstat); + diffstat); } show_stats(diffstat); free(diffstat); diff --combined merge-tree.c index cc7b5bd891,47181d422c..9dcaab7a85 --- a/merge-tree.c +++ b/merge-tree.c @@@ -24,14 -24,16 +24,14 @@@ static const char *sha1_to_hex_zero(con static void resolve(const char *base, struct name_entry *branch1, struct name_entry *result) { - char branch1_sha1[50]; - /* If it's already branch1, don't bother showing it */ if (!branch1) return; - memcpy(branch1_sha1, sha1_to_hex_zero(branch1->sha1), 41); printf("0 %06o->%06o %s->%s %s%s\n", branch1->mode, result->mode, - branch1_sha1, sha1_to_hex_zero(result->sha1), + sha1_to_hex_zero(branch1->sha1), + sha1_to_hex_zero(result->sha1), base, result->path); } @@@ -149,7 -151,7 +149,7 @@@ static void *get_tree_descriptor(struc unsigned char sha1[20]; void *buf; - if (get_sha1(rev, sha1) < 0) + if (get_sha1(rev, sha1)) die("unknown rev %s", rev); buf = fill_tree_descriptor(desc, sha1); if (!buf) diff --combined revision.c index f8ee38e54d,d41e59b9cc..2294b16ea2 --- a/revision.c +++ b/revision.c @@@ -116,27 -116,21 +116,27 @@@ static void add_pending_object(struct r add_object(obj, &revs->pending_objects, NULL, name); } -static struct commit *get_commit_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags) +static struct object *get_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags) { struct object *object; object = parse_object(sha1); if (!object) die("bad object %s", name); + object->flags |= flags; + return object; +} + +static struct commit *handle_commit(struct rev_info *revs, struct object *object, const char *name) +{ + unsigned long flags = object->flags; /* * Tag object? Look what it points to.. */ while (object->type == tag_type) { struct tag *tag = (struct tag *) object; - object->flags |= flags; - if (revs->tag_objects && !(object->flags & UNINTERESTING)) + if (revs->tag_objects && !(flags & UNINTERESTING)) add_pending_object(revs, object, tag->tag); object = parse_object(tag->tagged->sha1); if (!object) @@@ -149,10 -143,10 +149,10 @@@ */ if (object->type == commit_type) { struct commit *commit = (struct commit *)object; - object->flags |= flags; if (parse_commit(commit) < 0) die("unable to parse commit %s", name); if (flags & UNINTERESTING) { + commit->object.flags |= UNINTERESTING; mark_parents_uninteresting(commit); revs->limited = 1; } @@@ -247,7 -241,7 +247,7 @@@ int rev_compare_tree(struct rev_info *r return REV_TREE_DIFFERENT; tree_difference = REV_TREE_SAME; if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "", - &revs->diffopt) < 0) + &revs->pruning) < 0) return REV_TREE_DIFFERENT; return tree_difference; } @@@ -270,7 -264,7 +270,7 @@@ int rev_same_tree_as_empty(struct rev_i empty.size = 0; tree_difference = 0; - retval = diff_tree(&empty, &real, "", &revs->diffopt); + retval = diff_tree(&empty, &real, "", &revs->pruning); free(tree); return retval >= 0 && !tree_difference; @@@ -381,9 -375,6 +381,9 @@@ static void add_parents_to_list(struct if (revs->prune_fn) revs->prune_fn(revs, commit); + if (revs->no_walk) + return; + parent = commit->parents; while (parent) { struct commit *p = parent->item; @@@ -460,13 -451,21 +460,13 @@@ static void limit_list(struct rev_info revs->commits = newlist; } -static void add_one_commit(struct commit *commit, struct rev_info *revs) -{ - if (!commit || (commit->object.flags & SEEN)) - return; - commit->object.flags |= SEEN; - commit_list_insert(commit, &revs->commits); -} - static int all_flags; static struct rev_info *all_revs; static int handle_one_ref(const char *path, const unsigned char *sha1) { - struct commit *commit = get_commit_reference(all_revs, path, sha1, all_flags); - add_one_commit(commit, all_revs); + struct object *object = get_reference(all_revs, path, sha1, all_flags); + add_pending_object(all_revs, object, ""); return 0; } @@@ -477,45 -476,12 +477,45 @@@ static void handle_all(struct rev_info for_each_ref(handle_one_ref); } +static int add_parents_only(struct rev_info *revs, const char *arg, int flags) +{ + unsigned char sha1[20]; + struct object *it; + struct commit *commit; + struct commit_list *parents; + + if (*arg == '^') { + flags ^= UNINTERESTING; + arg++; + } + if (get_sha1(arg, sha1)) + return 0; + while (1) { + it = get_reference(revs, arg, sha1, 0); + if (strcmp(it->type, tag_type)) + break; + memcpy(sha1, ((struct tag*)it)->tagged->sha1, 20); + } + if (strcmp(it->type, commit_type)) + return 0; + commit = (struct commit *)it; + for (parents = commit->parents; parents; parents = parents->next) { + it = &parents->item->object; + it->flags |= flags; + add_pending_object(revs, it, arg); + } + return 1; +} + void init_revisions(struct rev_info *revs) { memset(revs, 0, sizeof(*revs)); - revs->diffopt.recursive = 1; - revs->diffopt.add_remove = file_add_remove; - revs->diffopt.change = file_change; + + revs->abbrev = DEFAULT_ABBREV; + revs->ignore_merges = 1; + revs->pruning.recursive = 1; + revs->pruning.add_remove = file_add_remove; + revs->pruning.change = file_change; revs->lifo = 1; revs->dense = 1; revs->prefix = setup_git_directory(); @@@ -528,10 -494,6 +528,10 @@@ revs->topo_setter = topo_sort_default_setter; revs->topo_getter = topo_sort_default_getter; + + revs->commit_format = CMIT_FMT_DEFAULT; + + diff_setup(&revs->diffopt); } /* @@@ -547,6 -509,8 +547,6 @@@ int setup_revisions(int argc, const cha const char **unrecognized = argv + 1; int left = 1; - init_revisions(revs); - /* First, search for "--" */ seen_dashdash = 0; for (i = 1; i < argc; i++) { @@@ -562,14 -526,13 +562,14 @@@ flags = 0; for (i = 1; i < argc; i++) { - struct commit *commit; + struct object *object; const char *arg = argv[i]; unsigned char sha1[20]; char *dotdot; int local_flags; if (*arg == '-') { + int opts; if (!strncmp(arg, "--max-count=", 12)) { revs->max_count = atoi(arg + 12); continue; @@@ -677,77 -640,6 +677,77 @@@ revs->unpacked = 1; continue; } + if (!strcmp(arg, "-r")) { + revs->diff = 1; + revs->diffopt.recursive = 1; + continue; + } + if (!strcmp(arg, "-t")) { + revs->diff = 1; + revs->diffopt.recursive = 1; + revs->diffopt.tree_in_recursive = 1; + continue; + } + if (!strcmp(arg, "-m")) { + revs->ignore_merges = 0; + continue; + } + if (!strcmp(arg, "-c")) { + revs->diff = 1; + revs->dense_combined_merges = 0; + revs->combine_merges = 1; + continue; + } + if (!strcmp(arg, "--cc")) { + revs->diff = 1; + revs->dense_combined_merges = 1; + revs->combine_merges = 1; + continue; + } + if (!strcmp(arg, "-v")) { + revs->verbose_header = 1; + continue; + } + if (!strncmp(arg, "--pretty", 8)) { + revs->verbose_header = 1; + revs->commit_format = get_commit_format(arg+8); + continue; + } + if (!strcmp(arg, "--root")) { + revs->show_root_diff = 1; + continue; + } + if (!strcmp(arg, "--no-commit-id")) { + revs->no_commit_id = 1; + continue; + } + if (!strcmp(arg, "--always")) { + revs->always_show_header = 1; + continue; + } + if (!strcmp(arg, "--no-abbrev")) { + revs->abbrev = 0; + continue; + } + if (!strcmp(arg, "--abbrev")) { + revs->abbrev = DEFAULT_ABBREV; + continue; + } + if (!strcmp(arg, "--abbrev-commit")) { + revs->abbrev_commit = 1; + continue; + } + if (!strcmp(arg, "--full-diff")) { + revs->diff = 1; + revs->full_diff = 1; + continue; + } + opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i); + if (opts > 0) { + revs->diff = 1; + i += opts - 1; + continue; + } *unrecognized++ = arg; left++; continue; @@@ -764,108 -656,63 +764,108 @@@ this = "HEAD"; if (!get_sha1(this, from_sha1) && !get_sha1(next, sha1)) { - struct commit *exclude; - struct commit *include; + struct object *exclude; + struct object *include; - exclude = get_commit_reference(revs, this, from_sha1, flags ^ UNINTERESTING); - include = get_commit_reference(revs, next, sha1, flags); + exclude = get_reference(revs, this, from_sha1, flags ^ UNINTERESTING); + include = get_reference(revs, next, sha1, flags); if (!exclude || !include) die("Invalid revision range %s..%s", arg, next); - add_one_commit(exclude, revs); - add_one_commit(include, revs); + + if (!seen_dashdash) { + *dotdot = '.'; + verify_non_filename(revs->prefix, arg); + } + add_pending_object(revs, exclude, this); + add_pending_object(revs, include, next); continue; } *dotdot = '.'; } + dotdot = strstr(arg, "^@"); + if (dotdot && !dotdot[2]) { + *dotdot = 0; + if (add_parents_only(revs, arg, flags)) + continue; + *dotdot = '^'; + } local_flags = 0; if (*arg == '^') { local_flags = UNINTERESTING; arg++; } - if (get_sha1(arg, sha1) < 0) { + if (get_sha1(arg, sha1)) { int j; if (seen_dashdash || local_flags) die("bad revision '%s'", arg); - /* If we didn't have a "--", all filenames must exist */ + /* If we didn't have a "--": + * (1) all filenames must exist; + * (2) all rev-args must not be interpretable + * as a valid filename. + * but the latter we have checked in the main loop. + */ for (j = i; j < argc; j++) verify_filename(revs->prefix, argv[j]); revs->prune_data = get_pathspec(revs->prefix, argv + i); break; } - commit = get_commit_reference(revs, arg, sha1, flags ^ local_flags); - add_one_commit(commit, revs); + if (!seen_dashdash) + verify_non_filename(revs->prefix, arg); + object = get_reference(revs, arg, sha1, flags ^ local_flags); + add_pending_object(revs, object, arg); } - if (def && !revs->commits) { + if (def && !revs->pending_objects) { unsigned char sha1[20]; - struct commit *commit; + struct object *object; - if (get_sha1(def, sha1) < 0) + if (get_sha1(def, sha1)) die("bad default revision '%s'", def); - commit = get_commit_reference(revs, def, sha1, 0); - add_one_commit(commit, revs); + object = get_reference(revs, def, sha1, 0); + add_pending_object(revs, object, def); } if (revs->topo_order || revs->unpacked) revs->limited = 1; if (revs->prune_data) { - diff_tree_setup_paths(revs->prune_data, &revs->diffopt); + diff_tree_setup_paths(revs->prune_data, &revs->pruning); revs->prune_fn = try_to_simplify_commit; + if (!revs->full_diff) + diff_tree_setup_paths(revs->prune_data, &revs->diffopt); + } + if (revs->combine_merges) { + revs->ignore_merges = 0; + if (revs->dense_combined_merges && + (revs->diffopt.output_format != DIFF_FORMAT_DIFFSTAT)) + revs->diffopt.output_format = DIFF_FORMAT_PATCH; } + revs->diffopt.abbrev = revs->abbrev; + diff_setup_done(&revs->diffopt); return left; } void prepare_revision_walk(struct rev_info *revs) { - sort_by_date(&revs->commits); + struct object_list *list; + + list = revs->pending_objects; + revs->pending_objects = NULL; + while (list) { + struct commit *commit = handle_commit(revs, list->item, list->name); + if (commit) { + if (!(commit->object.flags & SEEN)) { + commit->object.flags |= SEEN; + insert_by_date(commit, &revs->commits); + } + } + list = list->next; + } + + if (revs->no_walk) + return; if (revs->limited) limit_list(revs); if (revs->topo_order)