mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-31 00:08:32 +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_REINSTATE_INDEX = (1 << 0),
|
||||||
} git_stash_apply_flags;
|
} 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.
|
/** Stash application options structure.
|
||||||
*
|
*
|
||||||
* Initialize with the `GIT_STASH_APPLY_OPTIONS_INIT` macro to set
|
* 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. */
|
/** Options to use when writing files to the working directory. */
|
||||||
git_checkout_options checkout_options;
|
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;
|
} git_stash_apply_options;
|
||||||
|
|
||||||
#define GIT_STASH_APPLY_OPTIONS_VERSION 1
|
#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;
|
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(
|
int git_stash_apply(
|
||||||
git_repository *repo,
|
git_repository *repo,
|
||||||
size_t index,
|
size_t index,
|
||||||
@ -725,6 +730,8 @@ int git_stash_apply(
|
|||||||
normalize_apply_options(&opts, given_opts);
|
normalize_apply_options(&opts, given_opts);
|
||||||
checkout_strategy = opts.checkout_options.checkout_strategy;
|
checkout_strategy = opts.checkout_options.checkout_strategy;
|
||||||
|
|
||||||
|
NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_LOADING_STASH);
|
||||||
|
|
||||||
/* Retrieve commit corresponding to the given stash */
|
/* Retrieve commit corresponding to the given stash */
|
||||||
if ((error = retrieve_stash_commit(&stash_commit, repo, index)) < 0)
|
if ((error = retrieve_stash_commit(&stash_commit, repo, index)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -739,6 +746,8 @@ int git_stash_apply(
|
|||||||
if ((error = git_repository_index(&repo_index, repo)) < 0)
|
if ((error = git_repository_index(&repo_index, repo)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_ANALYZE_INDEX);
|
||||||
|
|
||||||
/* Restore index if required */
|
/* Restore index if required */
|
||||||
if ((opts.flags & GIT_STASH_APPLY_REINSTATE_INDEX) &&
|
if ((opts.flags & GIT_STASH_APPLY_REINSTATE_INDEX) &&
|
||||||
git_oid_cmp(git_tree_id(stash_parent_tree), git_tree_id(index_tree))) {
|
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 */
|
/* Restore modified files in workdir */
|
||||||
if ((error = merge_index_and_tree(
|
if ((error = merge_index_and_tree(
|
||||||
&modified_index, repo, stash_parent_tree, repo_index, stash_tree)) < 0)
|
&modified_index, repo, stash_parent_tree, repo_index, stash_tree)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* If applicable, restore untracked / ignored files in workdir */
|
/* If applicable, restore untracked / ignored files in workdir */
|
||||||
if (untracked_tree &&
|
if (untracked_tree) {
|
||||||
(error = merge_index_and_tree(&untracked_index, repo, NULL, repo_index, untracked_tree)) < 0)
|
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;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (untracked_index) {
|
if (untracked_index) {
|
||||||
opts.checkout_options.checkout_strategy |= GIT_CHECKOUT_DONT_UPDATE_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)
|
if ((error = git_checkout_index(repo, untracked_index, &opts.checkout_options)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -787,6 +803,8 @@ int git_stash_apply(
|
|||||||
*/
|
*/
|
||||||
opts.checkout_options.baseline_index = repo_index;
|
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)
|
if ((error = git_checkout_index(repo, modified_index, &opts.checkout_options)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -795,6 +813,8 @@ int git_stash_apply(
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NOTIFY_PROGRESS(opts, GIT_STASH_APPLY_PROGRESS_DONE);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
git_index_free(untracked_index);
|
git_index_free(untracked_index);
|
||||||
git_index_free(modified_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.who);
|
||||||
cl_assert_equal_b(true, seen_paths.when);
|
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