diff options
Diffstat (limited to 'builtin/diff.c')
-rw-r--r-- | builtin/diff.c | 65 |
1 files changed, 43 insertions, 22 deletions
diff --git a/builtin/diff.c b/builtin/diff.c index 54bb3de964..7b64659fe7 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -3,7 +3,7 @@ * * Copyright (c) 2006 Junio C Hamano */ -#define USE_THE_INDEX_COMPATIBILITY_MACROS +#define USE_THE_INDEX_VARIABLE #include "cache.h" #include "config.h" #include "ewah/ewok.h" @@ -11,6 +11,7 @@ #include "color.h" #include "commit.h" #include "blob.h" +#include "gettext.h" #include "tag.h" #include "diff.h" #include "diff-merges.h" @@ -18,8 +19,10 @@ #include "revision.h" #include "log-tree.h" #include "builtin.h" +#include "setup.h" #include "submodule.h" #include "oid-array.h" +#include "tree.h" #define DIFF_NO_INDEX_EXPLICIT 1 #define DIFF_NO_INDEX_IMPLICIT 2 @@ -30,7 +33,8 @@ static const char builtin_diff_usage[] = " or: git diff [<options>] [--merge-base] <commit> [<commit>...] <commit> [--] [<path>...]\n" " or: git diff [<options>] <commit>...<commit> [--] [<path>...]\n" " or: git diff [<options>] <blob> <blob>\n" -" or: git diff [<options>] --no-index [--] <path> <path>\n" +" or: git diff [<options>] --no-index [--] <path> <path>" +"\n" COMMON_DIFF_OPTIONS_HELP; static const char *blob_path(struct object_array_entry *entry) @@ -73,7 +77,7 @@ static void stuff_change(struct diff_options *opt, } static int builtin_diff_b_f(struct rev_info *revs, - int argc, const char **argv, + int argc, const char **argv UNUSED, struct object_array_entry **blob) { /* Blob vs file in the working tree*/ @@ -108,7 +112,7 @@ static int builtin_diff_b_f(struct rev_info *revs, } static int builtin_diff_blobs(struct rev_info *revs, - int argc, const char **argv, + int argc, const char **argv UNUSED, struct object_array_entry **blob) { const unsigned mode = canon_mode(S_IFREG | 0644); @@ -156,12 +160,13 @@ static int builtin_diff_index(struct rev_info *revs, usage(builtin_diff_usage); if (!(option & DIFF_INDEX_CACHED)) { setup_work_tree(); - if (read_cache_preload(&revs->diffopt.pathspec) < 0) { - perror("read_cache_preload"); + if (repo_read_index_preload(the_repository, + &revs->diffopt.pathspec, 0) < 0) { + perror("repo_read_index_preload"); return -1; } - } else if (read_cache() < 0) { - perror("read_cache"); + } else if (repo_read_index(the_repository) < 0) { + perror("repo_read_cache"); return -1; } return run_diff_index(revs, option); @@ -207,9 +212,9 @@ static int builtin_diff_tree(struct rev_info *revs, } static int builtin_diff_combined(struct rev_info *revs, - int argc, const char **argv, + int argc, const char **argv UNUSED, struct object_array_entry *ent, - int ents) + int ents, int first_non_parent) { struct oid_array parents = OID_ARRAY_INIT; int i; @@ -217,11 +222,18 @@ static int builtin_diff_combined(struct rev_info *revs, if (argc > 1) usage(builtin_diff_usage); + if (first_non_parent < 0) + die(_("no merge given, only parents.")); + if (first_non_parent >= ents) + BUG("first_non_parent out of range: %d", first_non_parent); + diff_merges_set_dense_combined_if_unset(revs); - for (i = 1; i < ents; i++) - oid_array_append(&parents, &ent[i].item->oid); - diff_tree_combined(&ent[0].item->oid, &parents, revs); + for (i = 0; i < ents; i++) { + if (i != first_non_parent) + oid_array_append(&parents, &ent[i].item->oid); + } + diff_tree_combined(&ent[first_non_parent].item->oid, &parents, revs); oid_array_clear(&parents); return 0; } @@ -231,12 +243,13 @@ static void refresh_index_quietly(void) struct lock_file lock_file = LOCK_INIT; int fd; - fd = hold_locked_index(&lock_file, 0); + fd = repo_hold_locked_index(the_repository, &lock_file, 0); if (fd < 0) return; - discard_cache(); - read_cache(); - refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED); + discard_index(&the_index); + repo_read_index(the_repository); + refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, NULL, NULL, + NULL); repo_update_index_if_able(the_repository, &lock_file); } @@ -271,8 +284,9 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv diff_merges_set_dense_combined_if_unset(revs); setup_work_tree(); - if (read_cache_preload(&revs->diffopt.pathspec) < 0) { - perror("read_cache_preload"); + if (repo_read_index_preload(the_repository, &revs->diffopt.pathspec, + 0) < 0) { + perror("repo_read_index_preload"); return -1; } return run_diff_files(revs, options); @@ -385,6 +399,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) int i; struct rev_info rev; struct object_array ent = OBJECT_ARRAY_INIT; + int first_non_parent = -1; int blobs = 0, paths = 0; struct object_array_entry *blob[2]; int nongit = 0, no_index = 0; @@ -536,13 +551,18 @@ int cmd_diff(int argc, const char **argv, const char *prefix) if (!obj) die(_("invalid object '%s' given."), name); if (obj->type == OBJ_COMMIT) - obj = &get_commit_tree(((struct commit *)obj))->object; + obj = &repo_get_commit_tree(the_repository, + ((struct commit *)obj))->object; if (obj->type == OBJ_TREE) { if (sdiff.skip && bitmap_get(sdiff.skip, i)) continue; obj->flags |= flags; add_object_array(obj, name, &ent); + if (first_non_parent < 0 && + (i >= rev.cmdline.nr || /* HEAD by hand. */ + rev.cmdline.rev[i].whence != REV_CMD_PARENTS_ONLY)) + first_non_parent = ent.nr - 1; } else if (obj->type == OBJ_BLOB) { if (2 <= blobs) die(_("more than two blobs given: '%s'"), name); @@ -590,12 +610,13 @@ int cmd_diff(int argc, const char **argv, const char *prefix) &ent.objects[0], &ent.objects[1]); } else result = builtin_diff_combined(&rev, argc, argv, - ent.objects, ent.nr); + ent.objects, ent.nr, + first_non_parent); result = diff_result_code(&rev.diffopt, result); if (1 < rev.diffopt.skip_stat_unmatch) refresh_index_quietly(); release_revisions(&rev); - UNLEAK(ent); + object_array_clear(&ent); UNLEAK(blob); return result; } |