merge(3p/git): Merge git upstream at v2.26.2

This commit is contained in:
Vincent Ambo 2020-05-22 17:46:45 +01:00
commit 5229c9b232
1006 changed files with 149006 additions and 60819 deletions

148
third_party/git/diff.c vendored
View file

@ -25,7 +25,7 @@
#include "packfile.h"
#include "parse-options.h"
#include "help.h"
#include "fetch-object.h"
#include "promisor-remote.h"
#ifdef NO_FAST_WORKING_DIRECTORY
#define FAST_WORKING_DIRECTORY 0
@ -414,14 +414,6 @@ int git_diff_ui_config(const char *var, const char *value, void *cb)
return 0;
}
if (!strcmp(var, "diff.wserrorhighlight")) {
int val = parse_ws_error_highlight(value);
if (val < 0)
return -1;
ws_error_highlight_default = val;
return 0;
}
if (git_color_config(var, value, cb) < 0)
return -1;
@ -450,6 +442,14 @@ int git_diff_basic_config(const char *var, const char *value, void *cb)
return color_parse(value, diff_colors[slot]);
}
if (!strcmp(var, "diff.wserrorhighlight")) {
int val = parse_ws_error_highlight(value);
if (val < 0)
return -1;
ws_error_highlight_default = val;
return 0;
}
/* like GNU diff's --suppress-blank-empty option */
if (!strcmp(var, "diff.suppressblankempty") ||
/* for backwards compatibility */
@ -933,16 +933,18 @@ static int cmp_in_block_with_wsd(const struct diff_options *o,
}
static int moved_entry_cmp(const void *hashmap_cmp_fn_data,
const void *entry,
const void *entry_or_key,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *keydata)
{
const struct diff_options *diffopt = hashmap_cmp_fn_data;
const struct moved_entry *a = entry;
const struct moved_entry *b = entry_or_key;
const struct moved_entry *a, *b;
unsigned flags = diffopt->color_moved_ws_handling
& XDF_WHITESPACE_FLAGS;
a = container_of(eptr, const struct moved_entry, ent);
b = container_of(entry_or_key, const struct moved_entry, ent);
if (diffopt->color_moved_ws_handling &
COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE)
/*
@ -964,8 +966,9 @@ static struct moved_entry *prepare_entry(struct diff_options *o,
struct moved_entry *ret = xmalloc(sizeof(*ret));
struct emitted_diff_symbol *l = &o->emitted_symbols->buf[line_no];
unsigned flags = o->color_moved_ws_handling & XDF_WHITESPACE_FLAGS;
unsigned int hash = xdiff_hash_string(l->line, l->len, flags);
ret->ent.hash = xdiff_hash_string(l->line, l->len, flags);
hashmap_entry_init(&ret->ent, hash);
ret->es = l;
ret->next_line = NULL;
@ -1002,7 +1005,7 @@ static void add_lines_to_move_detection(struct diff_options *o,
if (prev_line && prev_line->es->s == o->emitted_symbols->buf[n].s)
prev_line->next_line = key;
hashmap_add(hm, key);
hashmap_add(hm, &key->ent);
prev_line = key;
}
}
@ -1018,7 +1021,7 @@ static void pmb_advance_or_null(struct diff_options *o,
struct moved_entry *prev = pmb[i].match;
struct moved_entry *cur = (prev && prev->next_line) ?
prev->next_line : NULL;
if (cur && !hm->cmpfn(o, cur, match, NULL)) {
if (cur && !hm->cmpfn(o, &cur->ent, &match->ent, NULL)) {
pmb[i].match = cur;
} else {
pmb[i].match = NULL;
@ -1035,7 +1038,7 @@ static void pmb_advance_or_null_multi_match(struct diff_options *o,
int i;
char *got_match = xcalloc(1, pmb_nr);
for (; match; match = hashmap_get_next(hm, match)) {
hashmap_for_each_entry_from(hm, match, ent) {
for (i = 0; i < pmb_nr; i++) {
struct moved_entry *prev = pmb[i].match;
struct moved_entry *cur = (prev && prev->next_line) ?
@ -1143,13 +1146,13 @@ static void mark_color_as_moved(struct diff_options *o,
case DIFF_SYMBOL_PLUS:
hm = del_lines;
key = prepare_entry(o, n);
match = hashmap_get(hm, key, NULL);
match = hashmap_get_entry(hm, key, ent, NULL);
free(key);
break;
case DIFF_SYMBOL_MINUS:
hm = add_lines;
key = prepare_entry(o, n);
match = hashmap_get(hm, key, NULL);
match = hashmap_get_entry(hm, key, ent, NULL);
free(key);
break;
default:
@ -1188,7 +1191,7 @@ static void mark_color_as_moved(struct diff_options *o,
* The current line is the start of a new block.
* Setup the set of potential blocks.
*/
for (; match; match = hashmap_get_next(hm, match)) {
hashmap_for_each_entry_from(hm, match, ent) {
ALLOC_GROW(pmb, pmb_nr + 1, pmb_alloc);
if (o->color_moved_ws_handling &
COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE) {
@ -2492,22 +2495,6 @@ static void pprint_rename(struct strbuf *name, const char *a, const char *b)
}
}
struct diffstat_t {
int nr;
int alloc;
struct diffstat_file {
char *from_name;
char *name;
char *print_name;
const char *comments;
unsigned is_unmerged:1;
unsigned is_binary:1;
unsigned is_renamed:1;
unsigned is_interesting:1;
uintmax_t added, deleted;
} **files;
};
static struct diffstat_file *diffstat_add(struct diffstat_t *diffstat,
const char *name_a,
const char *name_b)
@ -2548,7 +2535,7 @@ static int scale_linear(int it, int width, int max_change)
/*
* make sure that at least one '-' or '+' is printed if
* there is any change to this path. The easiest way is to
* scale linearly as if the alloted width is one column shorter
* scale linearly as if the allotted width is one column shorter
* than it is, and then add 1 to the result.
*/
return 1 + (it * (width - 1) / max_change);
@ -3154,7 +3141,7 @@ static void show_dirstat_by_line(struct diffstat_t *data, struct diff_options *o
gather_dirstat(options, &dir, changed, "", 0);
}
static void free_diffstat_info(struct diffstat_t *diffstat)
void free_diffstat_info(struct diffstat_t *diffstat)
{
int i;
for (i = 0; i < diffstat->nr; i++) {
@ -3193,7 +3180,7 @@ static int is_conflict_marker(const char *line, int marker_size, unsigned long l
for (cnt = 1; cnt < marker_size; cnt++)
if (line[cnt] != firstchar)
return 0;
/* line[1] thru line[marker_size-1] are same as firstchar */
/* line[1] through line[marker_size-1] are same as firstchar */
if (len < marker_size + 1 || !isspace(line[marker_size]))
return 0;
return 1;
@ -4037,7 +4024,7 @@ int diff_populate_filespec(struct repository *r,
return 0;
}
}
s->data = read_object_file(&s->oid, &type, &s->size);
s->data = repo_read_object_file(r, &s->oid, &type, &s->size);
if (!s->data)
die("unable to read %s", oid_to_hex(&s->oid));
s->should_free = 1;
@ -5978,7 +5965,7 @@ static void diff_summary(struct diff_options *opt, struct diff_filepair *p)
}
struct patch_id_t {
git_SHA_CTX *ctx;
git_hash_ctx *ctx;
int patchlen;
};
@ -5995,16 +5982,16 @@ static int remove_space(char *line, int len)
return dst - line;
}
void flush_one_hunk(struct object_id *result, git_SHA_CTX *ctx)
void flush_one_hunk(struct object_id *result, git_hash_ctx *ctx)
{
unsigned char hash[GIT_MAX_RAWSZ];
unsigned short carry = 0;
int i;
git_SHA1_Final(hash, ctx);
git_SHA1_Init(ctx);
the_hash_algo->final_fn(hash, ctx);
the_hash_algo->init_fn(ctx);
/* 20-byte sum, with carry */
for (i = 0; i < GIT_SHA1_RAWSZ; ++i) {
for (i = 0; i < the_hash_algo->rawsz; ++i) {
carry += result->hash[i] + hash[i];
result->hash[i] = carry;
carry >>= 8;
@ -6018,21 +6005,21 @@ static void patch_id_consume(void *priv, char *line, unsigned long len)
new_len = remove_space(line, len);
git_SHA1_Update(data->ctx, line, new_len);
the_hash_algo->update_fn(data->ctx, line, new_len);
data->patchlen += new_len;
}
static void patch_id_add_string(git_SHA_CTX *ctx, const char *str)
static void patch_id_add_string(git_hash_ctx *ctx, const char *str)
{
git_SHA1_Update(ctx, str, strlen(str));
the_hash_algo->update_fn(ctx, str, strlen(str));
}
static void patch_id_add_mode(git_SHA_CTX *ctx, unsigned mode)
static void patch_id_add_mode(git_hash_ctx *ctx, unsigned mode)
{
/* large enough for 2^32 in octal */
char buf[12];
int len = xsnprintf(buf, sizeof(buf), "%06o", mode);
git_SHA1_Update(ctx, buf, len);
the_hash_algo->update_fn(ctx, buf, len);
}
/* returns 0 upon success, and writes result into oid */
@ -6040,10 +6027,10 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid
{
struct diff_queue_struct *q = &diff_queued_diff;
int i;
git_SHA_CTX ctx;
git_hash_ctx ctx;
struct patch_id_t data;
git_SHA1_Init(&ctx);
the_hash_algo->init_fn(&ctx);
memset(&data, 0, sizeof(struct patch_id_t));
data.ctx = &ctx;
oidclr(oid);
@ -6076,27 +6063,27 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid
len2 = remove_space(p->two->path, strlen(p->two->path));
patch_id_add_string(&ctx, "diff--git");
patch_id_add_string(&ctx, "a/");
git_SHA1_Update(&ctx, p->one->path, len1);
the_hash_algo->update_fn(&ctx, p->one->path, len1);
patch_id_add_string(&ctx, "b/");
git_SHA1_Update(&ctx, p->two->path, len2);
the_hash_algo->update_fn(&ctx, p->two->path, len2);
if (p->one->mode == 0) {
patch_id_add_string(&ctx, "newfilemode");
patch_id_add_mode(&ctx, p->two->mode);
patch_id_add_string(&ctx, "---/dev/null");
patch_id_add_string(&ctx, "+++b/");
git_SHA1_Update(&ctx, p->two->path, len2);
the_hash_algo->update_fn(&ctx, p->two->path, len2);
} else if (p->two->mode == 0) {
patch_id_add_string(&ctx, "deletedfilemode");
patch_id_add_mode(&ctx, p->one->mode);
patch_id_add_string(&ctx, "---a/");
git_SHA1_Update(&ctx, p->one->path, len1);
the_hash_algo->update_fn(&ctx, p->one->path, len1);
patch_id_add_string(&ctx, "+++/dev/null");
} else {
patch_id_add_string(&ctx, "---a/");
git_SHA1_Update(&ctx, p->one->path, len1);
the_hash_algo->update_fn(&ctx, p->one->path, len1);
patch_id_add_string(&ctx, "+++b/");
git_SHA1_Update(&ctx, p->two->path, len2);
the_hash_algo->update_fn(&ctx, p->two->path, len2);
}
if (diff_header_only)
@ -6108,10 +6095,10 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid
if (diff_filespec_is_binary(options->repo, p->one) ||
diff_filespec_is_binary(options->repo, p->two)) {
git_SHA1_Update(&ctx, oid_to_hex(&p->one->oid),
GIT_SHA1_HEXSZ);
git_SHA1_Update(&ctx, oid_to_hex(&p->two->oid),
GIT_SHA1_HEXSZ);
the_hash_algo->update_fn(&ctx, oid_to_hex(&p->one->oid),
the_hash_algo->hexsz);
the_hash_algo->update_fn(&ctx, oid_to_hex(&p->two->oid),
the_hash_algo->hexsz);
continue;
}
@ -6128,7 +6115,7 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid
}
if (!stable)
git_SHA1_Final(oid->hash, &ctx);
the_hash_algo->final_fn(oid->hash, &ctx);
return 0;
}
@ -6230,8 +6217,10 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o)
if (o->color_moved == COLOR_MOVED_ZEBRA_DIM)
dim_moved_lines(o);
hashmap_free(&add_lines, 1);
hashmap_free(&del_lines, 1);
hashmap_free_entries(&add_lines, struct moved_entry,
ent);
hashmap_free_entries(&del_lines, struct moved_entry,
ent);
}
for (i = 0; i < esm.nr; i++)
@ -6278,12 +6267,7 @@ void diff_flush(struct diff_options *options)
dirstat_by_line) {
struct diffstat_t diffstat;
memset(&diffstat, 0, sizeof(struct diffstat_t));
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
if (check_pair_status(p))
diff_flush_stat(p, options, &diffstat);
}
compute_diffstat(options, &diffstat, q);
if (output_format & DIFF_FORMAT_NUMSTAT)
show_numstat(&diffstat, options);
if (output_format & DIFF_FORMAT_DIFFSTAT)
@ -6512,6 +6496,7 @@ static void add_if_missing(struct repository *r,
const struct diff_filespec *filespec)
{
if (filespec && filespec->oid_valid &&
!S_ISGITLINK(filespec->mode) &&
oid_object_info_extended(r, &filespec->oid, NULL,
OBJECT_INFO_FOR_PREFETCH))
oid_array_append(to_fetch, &filespec->oid);
@ -6519,8 +6504,7 @@ static void add_if_missing(struct repository *r,
void diffcore_std(struct diff_options *options)
{
if (options->repo == the_repository &&
repository_format_partial_clone) {
if (options->repo == the_repository && has_promisor_remote()) {
/*
* Prefetch the diff pairs that are about to be flushed.
*/
@ -6537,8 +6521,8 @@ void diffcore_std(struct diff_options *options)
/*
* NEEDSWORK: Consider deduplicating the OIDs sent.
*/
fetch_objects(repository_format_partial_clone,
to_fetch.oid, to_fetch.nr);
promisor_remote_get_direct(options->repo,
to_fetch.oid, to_fetch.nr);
oid_array_clear(&to_fetch);
}
@ -6616,6 +6600,20 @@ static int is_submodule_ignored(const char *path, struct diff_options *options)
return ignored;
}
void compute_diffstat(struct diff_options *options,
struct diffstat_t *diffstat,
struct diff_queue_struct *q)
{
int i;
memset(diffstat, 0, sizeof(struct diffstat_t));
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
if (check_pair_status(p))
diff_flush_stat(p, options, diffstat);
}
}
void diff_addremove(struct diff_options *options,
int addremove, unsigned mode,
const struct object_id *oid,