diff: return diff_filepair from diff queue helpers

The `diff_addremove()` and `diff_change()` functions set up and queue
diffs, but do not return the `diff_filepair` added to the queue. In a
subsequent commit, modifications to `diff_filepair` need to occur in
certain cases after being queued.

Since the existing `diff_addremove()` and `diff_change()` are also used
for callbacks in `diff_options` as types `add_remove_fn_t` and
`change_fn_t`, modifying the existing function signatures requires
further changes. The diff options for pruning use `file_add_remove()`
and `file_change()` where file pairs do not even get queued. Thus,
separate functions are implemented instead.

Split out the queuing operations into `diff_queue_addremove()` and
`diff_queue_change()` which also return a handle to the queued
`diff_filepair`. Both `diff_addremove()` and `diff_change()` are
reimplemented as thin wrappers around the new functions.

Signed-off-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Justin Tobler 2025-02-28 15:33:43 -06:00 committed by Junio C Hamano
parent 08bdfd4535
commit 7c67d2a070
2 changed files with 75 additions and 20 deletions

70
diff.c
View File

@ -7161,16 +7161,19 @@ void compute_diffstat(struct diff_options *options,
options->found_changes = !!diffstat->nr;
}

void diff_addremove(struct diff_options *options,
int addremove, unsigned mode,
const struct object_id *oid,
int oid_valid,
const char *concatpath, unsigned dirty_submodule)
struct diff_filepair *diff_queue_addremove(struct diff_queue_struct *queue,
struct diff_options *options,
int addremove, unsigned mode,
const struct object_id *oid,
int oid_valid,
const char *concatpath,
unsigned dirty_submodule)
{
struct diff_filespec *one, *two;
struct diff_filepair *pair;

if (S_ISGITLINK(mode) && is_submodule_ignored(concatpath, options))
return;
return NULL;

/* This may look odd, but it is a preparation for
* feeding "there are unchanged files which should
@ -7190,7 +7193,7 @@ void diff_addremove(struct diff_options *options,

if (options->prefix &&
strncmp(concatpath, options->prefix, options->prefix_length))
return;
return NULL;

one = alloc_filespec(concatpath);
two = alloc_filespec(concatpath);
@ -7202,25 +7205,29 @@ void diff_addremove(struct diff_options *options,
two->dirty_submodule = dirty_submodule;
}

diff_queue(&diff_queued_diff, one, two);
pair = diff_queue(queue, one, two);
if (!options->flags.diff_from_contents)
options->flags.has_changes = 1;

return pair;
}

void diff_change(struct diff_options *options,
unsigned old_mode, unsigned new_mode,
const struct object_id *old_oid,
const struct object_id *new_oid,
int old_oid_valid, int new_oid_valid,
const char *concatpath,
unsigned old_dirty_submodule, unsigned new_dirty_submodule)
struct diff_filepair *diff_queue_change(struct diff_queue_struct *queue,
struct diff_options *options,
unsigned old_mode, unsigned new_mode,
const struct object_id *old_oid,
const struct object_id *new_oid,
int old_oid_valid, int new_oid_valid,
const char *concatpath,
unsigned old_dirty_submodule,
unsigned new_dirty_submodule)
{
struct diff_filespec *one, *two;
struct diff_filepair *p;

if (S_ISGITLINK(old_mode) && S_ISGITLINK(new_mode) &&
is_submodule_ignored(concatpath, options))
return;
return NULL;

if (options->flags.reverse_diff) {
SWAP(old_mode, new_mode);
@ -7231,7 +7238,7 @@ void diff_change(struct diff_options *options,

if (options->prefix &&
strncmp(concatpath, options->prefix, options->prefix_length))
return;
return NULL;

one = alloc_filespec(concatpath);
two = alloc_filespec(concatpath);
@ -7239,19 +7246,42 @@ void diff_change(struct diff_options *options,
fill_filespec(two, new_oid, new_oid_valid, new_mode);
one->dirty_submodule = old_dirty_submodule;
two->dirty_submodule = new_dirty_submodule;
p = diff_queue(&diff_queued_diff, one, two);
p = diff_queue(queue, one, two);

if (options->flags.diff_from_contents)
return;
return p;

if (options->flags.quick && options->skip_stat_unmatch &&
!diff_filespec_check_stat_unmatch(options->repo, p)) {
diff_free_filespec_data(p->one);
diff_free_filespec_data(p->two);
return;
return p;
}

options->flags.has_changes = 1;

return p;
}

void diff_addremove(struct diff_options *options, int addremove, unsigned mode,
const struct object_id *oid, int oid_valid,
const char *concatpath, unsigned dirty_submodule)
{
diff_queue_addremove(&diff_queued_diff, options, addremove, mode, oid,
oid_valid, concatpath, dirty_submodule);
}

void diff_change(struct diff_options *options,
unsigned old_mode, unsigned new_mode,
const struct object_id *old_oid,
const struct object_id *new_oid,
int old_oid_valid, int new_oid_valid,
const char *concatpath,
unsigned old_dirty_submodule, unsigned new_dirty_submodule)
{
diff_queue_change(&diff_queued_diff, options, old_mode, new_mode,
old_oid, new_oid, old_oid_valid, new_oid_valid,
concatpath, old_dirty_submodule, new_dirty_submodule);
}

struct diff_filepair *diff_unmerge(struct diff_options *options, const char *path)

25
diff.h
View File

@ -508,6 +508,31 @@ void diff_set_default_prefix(struct diff_options *options);

int diff_can_quit_early(struct diff_options *);

/*
* Stages changes in the provided diff queue for file additions and deletions.
* If a file pair gets queued, it is returned.
*/
struct diff_filepair *diff_queue_addremove(struct diff_queue_struct *queue,
struct diff_options *,
int addremove, unsigned mode,
const struct object_id *oid,
int oid_valid, const char *fullpath,
unsigned dirty_submodule);

/*
* Stages changes in the provided diff queue for file modifications.
* If a file pair gets queued, it is returned.
*/
struct diff_filepair *diff_queue_change(struct diff_queue_struct *queue,
struct diff_options *,
unsigned mode1, unsigned mode2,
const struct object_id *old_oid,
const struct object_id *new_oid,
int old_oid_valid, int new_oid_valid,
const char *fullpath,
unsigned dirty_submodule1,
unsigned dirty_submodule2);

void diff_addremove(struct diff_options *,
int addremove,
unsigned mode,