summaryrefslogtreecommitdiff
path: root/builtin/diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/diff.c')
-rw-r--r--builtin/diff.c65
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;
}