Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3138ad9

Browse files
hackhaslamEdward Thomson
authored and
Edward Thomson
committed
Add diff progress callback.
1 parent db1edf9 commit 3138ad9

File tree

5 files changed

+74
-9
lines changed

5 files changed

+74
-9
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ v0.23 + 1
1717
the opportunity for concurrent operations and not committing any
1818
changes until the unlock.
1919

20+
* `git_diff_options` added a new callback `progress_cb` to report on the
21+
progress of the diff as files are being compared. The documentation of
22+
the existing callback `notify_cb` was updated to reflect that it only
23+
gets called when new deltas are added to the diff.
24+
2025
### API removals
2126

2227
### Breaking API changes
@@ -36,6 +41,9 @@ v0.23 + 1
3641
it existed in the index. This does not affect the higher-level
3742
`git_index_add_bypath` or `git_index_add_frombuffer` functions.
3843

44+
* The `notify_payload` field of `git_diff_options` was renamed to `payload`
45+
to reflect that it's also the payload for the new progress callback.
46+
3947
v0.23
4048
------
4149

include/git2/diff.h

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,22 @@ typedef int (*git_diff_notify_cb)(
350350
const char *matched_pathspec,
351351
void *payload);
352352

353+
/**
354+
* Diff progress callback.
355+
*
356+
* Called before each file comparison.
357+
*
358+
* @param diff_so_far The diff being generated.
359+
* @param old_path The path to the old file or NULL.
360+
* @param new_path The path to the new file or NULL.
361+
* @return Non-zero to abort the diff.
362+
*/
363+
typedef int (*git_diff_progress_cb)(
364+
const git_diff *diff_so_far,
365+
const char *old_path,
366+
const char *new_path,
367+
void *payload);
368+
353369
/**
354370
* Structure describing options about how the diff should be executed.
355371
*
@@ -370,8 +386,10 @@ typedef int (*git_diff_notify_cb)(
370386
* - `max_size` is a file size (in bytes) above which a blob will be marked
371387
* as binary automatically; pass a negative value to disable.
372388
* - `notify_cb` is an optional callback function, notifying the consumer of
373-
* which files are being examined as the diff is generated
374-
* - `notify_payload` is the payload data to pass to the `notify_cb` function
389+
* changes to the diff as new deltas are added.
390+
* - `progress_cb` is an optional callback function, notifying the consumer of
391+
* which files are being examined as the diff is generated.
392+
* - `payload` is the payload to pass to the callback functions.
375393
* - `ignore_submodules` overrides the submodule ignore setting for all
376394
* submodules in the diff.
377395
*/
@@ -383,8 +401,9 @@ typedef struct {
383401

384402
git_submodule_ignore_t ignore_submodules; /**< submodule ignore rule */
385403
git_strarray pathspec; /**< defaults to include all paths */
386-
git_diff_notify_cb notify_cb;
387-
void *notify_payload;
404+
git_diff_notify_cb notify_cb;
405+
git_diff_progress_cb progress_cb;
406+
void *payload;
388407

389408
/* options controlling how to diff text is generated */
390409

@@ -403,7 +422,7 @@ typedef struct {
403422
* `git_diff_options_init` programmatic initialization.
404423
*/
405424
#define GIT_DIFF_OPTIONS_INIT \
406-
{GIT_DIFF_OPTIONS_VERSION, 0, GIT_SUBMODULE_IGNORE_UNSPECIFIED, {NULL,0}, NULL, NULL, 3}
425+
{GIT_DIFF_OPTIONS_VERSION, 0, GIT_SUBMODULE_IGNORE_UNSPECIFIED, {NULL,0}, NULL, NULL, NULL, 3}
407426

408427
/**
409428
* Initializes a `git_diff_options` with default values. Equivalent to

src/diff.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static int diff_insert_delta(
5656

5757
if (diff->opts.notify_cb) {
5858
error = diff->opts.notify_cb(
59-
diff, delta, matched_pathspec, diff->opts.notify_payload);
59+
diff, delta, matched_pathspec, diff->opts.payload);
6060

6161
if (error) {
6262
git__free(delta);
@@ -1260,7 +1260,18 @@ int git_diff__from_iterators(
12601260

12611261
/* run iterators building diffs */
12621262
while (!error && (info.oitem || info.nitem)) {
1263-
int cmp = info.oitem ?
1263+
int cmp;
1264+
1265+
/* report progress */
1266+
if (opts && opts->progress_cb) {
1267+
if ((error = opts->progress_cb(diff,
1268+
info.oitem ? info.oitem->path : NULL,
1269+
info.nitem ? info.nitem->path : NULL,
1270+
opts->payload)))
1271+
break;
1272+
}
1273+
1274+
cmp = info.oitem ?
12641275
(info.nitem ? diff->entrycomp(info.oitem, info.nitem) : -1) : 1;
12651276

12661277
/* create DELETED records for old items not matched in new */

tests/diff/notify.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static void test_notify(
5555
opts.pathspec.strings = searched_pathspecs;
5656
opts.pathspec.count = pathspecs_count;
5757

58-
opts.notify_payload = expected_matched_pathspecs;
58+
opts.payload = expected_matched_pathspecs;
5959
memset(&exp, 0, sizeof(exp));
6060

6161
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
@@ -228,3 +228,30 @@ void test_diff_notify__notify_cb_can_be_used_as_filtering_function(void)
228228

229229
git_diff_free(diff);
230230
}
231+
232+
static int progress_abort_diff(
233+
const git_diff *diff_so_far,
234+
const char *old_path,
235+
const char *new_path,
236+
void *payload)
237+
{
238+
GIT_UNUSED(old_path);
239+
GIT_UNUSED(new_path);
240+
GIT_UNUSED(payload);
241+
242+
return -42;
243+
}
244+
245+
void test_diff_notify__progress_cb_can_abort_diff(void)
246+
{
247+
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
248+
git_diff *diff = NULL;
249+
250+
g_repo = cl_git_sandbox_init("status");
251+
252+
opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
253+
opts.progress_cb = progress_abort_diff;
254+
255+
cl_git_fail_with(
256+
git_diff_index_to_workdir(&diff, g_repo, NULL, &opts), -42);
257+
}

tests/diff/tree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void test_diff_tree__0(void)
9090

9191
#define DIFF_OPTS(FLAGS, CTXT) \
9292
{GIT_DIFF_OPTIONS_VERSION, (FLAGS), GIT_SUBMODULE_IGNORE_UNSPECIFIED, \
93-
{NULL,0}, NULL, NULL, (CTXT), 1}
93+
{NULL,0}, NULL, NULL, NULL, (CTXT), 1}
9494

9595
void test_diff_tree__options(void)
9696
{

0 commit comments

Comments
 (0)