mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-30 00:04:03 +00:00
stash_apply: provide progress callbacks
This commit is contained in:
parent
19c80a6fd1
commit
4ea3eebf4b
@ -80,6 +80,40 @@ typedef enum {
|
||||
GIT_STASH_APPLY_REINSTATE_INDEX = (1 << 0),
|
||||
} git_stash_apply_flags;
|
||||
|
||||
typedef enum {
|
||||
GIT_STASH_APPLY_PROGRESS_NONE = 0,
|
||||
|
||||
/** Loading the stashed data from the object database. */
|
||||
GIT_STASH_APPLY_PROGRESS_LOADING_STASH,
|
||||
|
||||
/** The stored index is being analyzed. */
|
||||
GIT_STASH_APPLY_PROGRESS_ANALYZE_INDEX,
|
||||
|
||||
/** The modified files are being analyzed. */
|
||||
GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED,
|
||||
|
||||
/** The untracked and ignored files are being analyzed. */
|
||||
GIT_STASH_APPLY_PROGRESS_ANALYZE_UNTRACKED,
|
||||
|
||||
/** The untracked files are being written to disk. */
|
||||
GIT_STASH_APPLY_PROGRESS_CHECKOUT_UNTRACKED,
|
||||
|
||||
/** The modified files are being written to disk. */
|
||||
GIT_STASH_APPLY_PROGRESS_CHECKOUT_MODIFIED,
|
||||
|
||||
/** The stash was applied successfully. */
|
||||
GIT_STASH_APPLY_PROGRESS_DONE,
|
||||
} git_stash_apply_progress_t;
|
||||
|
||||
/**
|
||||
* Stash application progress notification function.
|
||||
* Return 0 to continue processing, or a negative value to
|
||||
* abort the stash application.
|
||||
*/
|
||||
typedef int (*git_stash_apply_progress_cb)(
|
||||
git_stash_apply_progress_t progress,
|
||||
void *payload);
|
||||
|
||||
/** Stash application options structure.
|
||||
*
|
||||
* Initialize with the `GIT_STASH_APPLY_OPTIONS_INIT` macro to set
|
||||
@ -95,6 +129,10 @@ typedef struct git_stash_apply_options {
|
||||
|
||||
/** Options to use when writing files to the working directory. */
|
||||
git_checkout_options checkout_options;
|
||||
|
||||
/** Optional callback to notify the consumer of application progress. */
|
||||
git_stash_apply_progress_cb progress_cb;
|
||||
void *progress_payload;
|
||||
} git_stash_apply_options;
|
||||
|
||||
#define GIT_STASH_APPLY_OPTIONS_VERSION 1
|
||||
|
24
src/stash.c
24
src/stash.c
@ -701,6 +701,11 @@ int git_stash_apply_init_options(git_stash_apply_options *opts, unsigned int ver
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define NOTIFY_PROGRESS(opts, progress_type) \
|
||||
if ((opts).progress_cb && \
|
||||
(error = (opts).progress_cb((progress_type), (opts).progress_payload))) \
|
||||
return (error < 0) ? error : -1;
|
||||
|
||||
int git_stash_apply(
|
||||
git_repository *repo,
|
||||
size_t index,
|
||||
@ -725,6 +730,8 @@ int git_stash_apply(
|
||||
normalize_apply_options(&opts, given_opts);
|
||||
checkout_strategy = opts.checkout_options.checkout_strategy;
|
||||
|
||||
NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_LOADING_STASH);
|
||||
|
||||
/* Retrieve commit corresponding to the given stash */
|
||||
if ((error = retrieve_stash_commit(&stash_commit, repo, index)) < 0)
|
||||
goto cleanup;
|
||||
@ -739,6 +746,8 @@ int git_stash_apply(
|
||||
if ((error = git_repository_index(&repo_index, repo)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_ANALYZE_INDEX);
|
||||
|
||||
/* Restore index if required */
|
||||
if ((opts.flags & GIT_STASH_APPLY_REINSTATE_INDEX) &&
|
||||
git_oid_cmp(git_tree_id(stash_parent_tree), git_tree_id(index_tree))) {
|
||||
@ -753,19 +762,26 @@ int git_stash_apply(
|
||||
}
|
||||
}
|
||||
|
||||
NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED);
|
||||
|
||||
/* Restore modified files in workdir */
|
||||
if ((error = merge_index_and_tree(
|
||||
&modified_index, repo, stash_parent_tree, repo_index, stash_tree)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* If applicable, restore untracked / ignored files in workdir */
|
||||
if (untracked_tree &&
|
||||
(error = merge_index_and_tree(&untracked_index, repo, NULL, repo_index, untracked_tree)) < 0)
|
||||
if (untracked_tree) {
|
||||
NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_ANALYZE_UNTRACKED);
|
||||
|
||||
if ((error = merge_index_and_tree(&untracked_index, repo, NULL, repo_index, untracked_tree)) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (untracked_index) {
|
||||
opts.checkout_options.checkout_strategy |= GIT_CHECKOUT_DONT_UPDATE_INDEX;
|
||||
|
||||
NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_CHECKOUT_UNTRACKED);
|
||||
|
||||
if ((error = git_checkout_index(repo, untracked_index, &opts.checkout_options)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
@ -787,6 +803,8 @@ int git_stash_apply(
|
||||
*/
|
||||
opts.checkout_options.baseline_index = repo_index;
|
||||
|
||||
NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_CHECKOUT_MODIFIED);
|
||||
|
||||
if ((error = git_checkout_index(repo, modified_index, &opts.checkout_options)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
@ -795,6 +813,8 @@ int git_stash_apply(
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_DONE);
|
||||
|
||||
cleanup:
|
||||
git_index_free(untracked_index);
|
||||
git_index_free(modified_index);
|
||||
|
@ -286,3 +286,48 @@ void test_stash_apply__executes_notify_cb(void)
|
||||
cl_assert_equal_b(true, seen_paths.who);
|
||||
cl_assert_equal_b(true, seen_paths.when);
|
||||
}
|
||||
|
||||
int progress_cb(
|
||||
git_stash_apply_progress_t progress,
|
||||
void *payload)
|
||||
{
|
||||
git_stash_apply_progress_t *p = (git_stash_apply_progress_t *)payload;
|
||||
|
||||
cl_assert_equal_i((*p)+1, progress);
|
||||
|
||||
*p = progress;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_stash_apply__calls_progress_cb(void)
|
||||
{
|
||||
git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
|
||||
git_stash_apply_progress_t progress = GIT_STASH_APPLY_PROGRESS_NONE;
|
||||
|
||||
opts.progress_cb = progress_cb;
|
||||
opts.progress_payload = &progress;
|
||||
|
||||
cl_git_pass(git_stash_apply(repo, 0, &opts));
|
||||
cl_assert_equal_i(progress, GIT_STASH_APPLY_PROGRESS_DONE);
|
||||
}
|
||||
|
||||
int aborting_progress_cb(
|
||||
git_stash_apply_progress_t progress,
|
||||
void *payload)
|
||||
{
|
||||
if (progress == GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED)
|
||||
return -44;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_stash_apply__progress_cb_can_abort(void)
|
||||
{
|
||||
git_stash_apply_options opts = GIT_STASH_APPLY_OPTIONS_INIT;
|
||||
git_stash_apply_progress_t progress = GIT_STASH_APPLY_PROGRESS_NONE;
|
||||
|
||||
opts.progress_cb = aborting_progress_cb;
|
||||
|
||||
cl_git_fail_with(-44, git_stash_apply(repo, 0, &opts));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user