summaryrefslogtreecommitdiff
path: root/diff-lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'diff-lib.c')
-rw-r--r--diff-lib.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/diff-lib.c b/diff-lib.c
index 5848e4f9ca..3cf353946f 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -1,8 +1,10 @@
/*
* Copyright (C) 2005 Junio C Hamano
*/
+
+#define USE_THE_REPOSITORY_VARIABLE
+
#include "git-compat-util.h"
-#include "quote.h"
#include "commit.h"
#include "diff.h"
#include "diffcore.h"
@@ -38,7 +40,13 @@
*/
static int check_removed(const struct cache_entry *ce, struct stat *st)
{
- if (lstat(ce->name, st) < 0) {
+ int stat_err;
+
+ if (!(ce->ce_flags & CE_FSMONITOR_VALID))
+ stat_err = lstat(ce->name, st);
+ else
+ stat_err = fake_lstat(ce, st);
+ if (stat_err < 0) {
if (!is_missing_file_error(errno))
return -1;
return 1;
@@ -61,7 +69,8 @@ static int check_removed(const struct cache_entry *ce, struct stat *st)
* a directory --- the blob was removed!
*/
if (!S_ISGITLINK(ce->ce_mode) &&
- resolve_gitlink_ref(ce->name, "HEAD", &sub))
+ repo_resolve_gitlink_ref(the_repository, ce->name,
+ "HEAD", &sub))
return 1;
}
return 0;
@@ -122,7 +131,16 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
if (diff_can_quit_early(&revs->diffopt))
break;
- if (!ce_path_match(istate, ce, &revs->prune_data, NULL))
+ /*
+ * NEEDSWORK:
+ * Here we filter with pathspec but the result is further
+ * filtered out when --relative is in effect. To end-users,
+ * a pathspec element that matched only to paths outside the
+ * current directory is like not matching anything at all;
+ * the handling of ps_matched[] here may become problematic
+ * if/when we add the "--error-unmatch" option to "git diff".
+ */
+ if (!ce_path_match(istate, ce, &revs->prune_data, revs->ps_matched))
continue;
if (revs->diffopt.prefix &&
@@ -145,7 +163,7 @@ void run_diff_files(struct rev_info *revs, unsigned int option)
dpath->next = NULL;
memcpy(dpath->path, ce->name, path_len);
dpath->path[path_len] = '\0';
- oidclr(&dpath->oid);
+ oidclr(&dpath->oid, the_repository->hash_algo);
memset(&(dpath->parent[0]), 0,
sizeof(struct combine_diff_parent)*5);
@@ -290,8 +308,7 @@ static void diff_index_show_file(struct rev_info *revs,
oid, oid_valid, ce->name, dirty_submodule);
}
-static int get_stat_data(const struct index_state *istate,
- const struct cache_entry *ce,
+static int get_stat_data(const struct cache_entry *ce,
const struct object_id **oidp,
unsigned int *modep,
int cached, int match_missing,
@@ -334,7 +351,6 @@ static void show_new_file(struct rev_info *revs,
const struct object_id *oid;
unsigned int mode;
unsigned dirty_submodule = 0;
- struct index_state *istate = revs->diffopt.repo->index;
if (new_file && S_ISSPARSEDIR(new_file->ce_mode)) {
diff_tree_oid(NULL, &new_file->oid, new_file->name, &revs->diffopt);
@@ -345,7 +361,7 @@ static void show_new_file(struct rev_info *revs,
* New file in the index: it might actually be different in
* the working tree.
*/
- if (get_stat_data(istate, new_file, &oid, &mode, cached, match_missing,
+ if (get_stat_data(new_file, &oid, &mode, cached, match_missing,
&dirty_submodule, &revs->diffopt) < 0)
return;
@@ -361,7 +377,6 @@ static int show_modified(struct rev_info *revs,
unsigned int mode, oldmode;
const struct object_id *oid;
unsigned dirty_submodule = 0;
- struct index_state *istate = revs->diffopt.repo->index;
assert(S_ISSPARSEDIR(old_entry->ce_mode) ==
S_ISSPARSEDIR(new_entry->ce_mode));
@@ -377,7 +392,7 @@ static int show_modified(struct rev_info *revs,
return 0;
}
- if (get_stat_data(istate, new_entry, &oid, &mode, cached, match_missing,
+ if (get_stat_data(new_entry, &oid, &mode, cached, match_missing,
&dirty_submodule, &revs->diffopt) < 0) {
if (report_missing)
diff_index_show_file(revs, "-", old_entry,
@@ -397,7 +412,7 @@ static int show_modified(struct rev_info *revs,
memcpy(p->path, new_entry->name, pathlen);
p->path[pathlen] = 0;
p->mode = mode;
- oidclr(&p->oid);
+ oidclr(&p->oid, the_repository->hash_algo);
memset(p->parent, 0, 2 * sizeof(struct combine_diff_parent));
p->parent[0].status = DIFF_STATUS_MODIFIED;
p->parent[0].mode = new_entry->ce_mode;
@@ -557,7 +572,7 @@ static int diff_cache(struct rev_info *revs,
opts.pathspec = &revs->diffopt.pathspec;
opts.pathspec->recursive = 1;
- init_tree_desc(&t, tree->buffer, tree->size);
+ init_tree_desc(&t, &tree->object.oid, tree->buffer, tree->size);
return unpack_trees(1, &t, &opts);
}
@@ -565,14 +580,12 @@ void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb)
{
int i;
struct commit *mb_child[2] = {0};
- struct commit_list *merge_bases;
+ struct commit_list *merge_bases = NULL;
for (i = 0; i < revs->pending.nr; i++) {
struct object *obj = revs->pending.objects[i].item;
if (obj->flags)
die(_("--merge-base does not work with ranges"));
- if (obj->type != OBJ_COMMIT)
- die(_("--merge-base only works with commits"));
}
/*
@@ -594,7 +607,8 @@ void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb)
mb_child[1] = lookup_commit_reference(the_repository, &oid);
}
- merge_bases = repo_get_merge_bases(the_repository, mb_child[0], mb_child[1]);
+ if (repo_get_merge_bases(the_repository, mb_child[0], mb_child[1], &merge_bases) < 0)
+ exit(128);
if (!merge_bases)
die(_("no merge base found"));
if (merge_bases->next)
@@ -647,11 +661,13 @@ int do_diff_cache(const struct object_id *tree_oid, struct diff_options *opt)
repo_init_revisions(opt->repo, &revs, NULL);
copy_pathspec(&revs.prune_data, &opt->pathspec);
- diff_setup_done(&revs.diffopt);
+ diff_free(&revs.diffopt);
revs.diffopt = *opt;
+ revs.diffopt.no_free = 1;
if (diff_cache(&revs, tree_oid, NULL, 1))
exit(128);
+
release_revisions(&revs);
return 0;
}
@@ -686,7 +702,7 @@ int index_differs_from(struct repository *r,
return (has_changes != 0);
}
-static struct strbuf *idiff_prefix_cb(struct diff_options *opt UNUSED, void *data)
+static const char *idiff_prefix_cb(struct diff_options *opt UNUSED, void *data)
{
return data;
}
@@ -701,7 +717,7 @@ void show_interdiff(const struct object_id *oid1, const struct object_id *oid2,
opts.output_format = DIFF_FORMAT_PATCH;
opts.output_prefix = idiff_prefix_cb;
strbuf_addchars(&prefix, ' ', indent);
- opts.output_prefix_data = &prefix;
+ opts.output_prefix_data = prefix.buf;
diff_setup_done(&opts);
diff_tree_oid(oid1, oid2, "", &opts);