Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornulltoken <emeric.fermas@gmail.com>2012-10-04 17:13:43 +0400
committernulltoken <emeric.fermas@gmail.com>2012-10-27 00:11:09 +0400
commit233884131d123432d2e1ad7236ad3c6ef7b2b518 (patch)
tree7badf8a263468f8cba00a1568b4fc06cf25b17c1
parent590fb68be087ed8a60323026dc2501c456ede945 (diff)
stash: add git_stash_foreach()
-rw-r--r--include/git2/stash.h40
-rw-r--r--src/stash.c42
-rw-r--r--tests-clar/stash/foreach.c119
3 files changed, 201 insertions, 0 deletions
diff --git a/include/git2/stash.h b/include/git2/stash.h
index cadc65673..6ebf89ed1 100644
--- a/include/git2/stash.h
+++ b/include/git2/stash.h
@@ -62,6 +62,46 @@ GIT_EXTERN(int) git_stash_save(
const char *message,
uint32_t flags);
+/**
+ * When iterating over all the stashed states, callback that will be
+ * issued per entry.
+ *
+ * @param index The position within the stash list. 0 points to the
+ * most recent stashed state.
+ *
+ * @param message The stash message.
+ *
+ * @param stash_oid The commit oid of the stashed state.
+ *
+ * @param payload Extra parameter to callback function.
+ *
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ */
+typedef int (*stash_cb)(
+ size_t index,
+ const char* message,
+ const git_oid *stash_oid,
+ void *payload);
+
+/**
+ * Loop over all the stashed states and issue a callback for each one.
+ *
+ * If the callback returns a non-zero value, this will stop looping.
+ *
+ * @param repo Repository where to find the stash.
+ *
+ * @param callabck Callback to invoke per found stashed state. The most recent
+ * stash state will be enumerated first.
+ *
+ * @param payload Extra parameter to callback function.
+ *
+ * @return 0 on success, GIT_EUSER on non-zero callback, or error code
+ */
+GIT_EXTERN(int) git_stash_foreach(
+ git_repository *repo,
+ stash_cb callback,
+ void *payload);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/src/stash.c b/src/stash.c
index e63ee99e3..ed0b20f93 100644
--- a/src/stash.c
+++ b/src/stash.c
@@ -575,3 +575,45 @@ cleanup:
git_index_free(index);
return error;
}
+
+int git_stash_foreach(
+ git_repository *repo,
+ stash_cb callback,
+ void *payload)
+{
+ git_reference *stash;
+ git_reflog *reflog = NULL;
+ int error;
+ size_t i, max;
+ const git_reflog_entry *entry;
+
+ error = git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE);
+ if (error == GIT_ENOTFOUND)
+ return 0;
+
+ if (error < 0)
+ goto cleanup;
+
+ if ((error = git_reflog_read(&reflog, stash)) < 0)
+ goto cleanup;
+
+ max = git_reflog_entrycount(reflog);
+ for (i = 0; i < max; i++) {
+ entry = git_reflog_entry_byindex(reflog, max - i - 1);
+
+ if (callback(i,
+ git_reflog_entry_msg(entry),
+ git_reflog_entry_oidnew(entry),
+ payload)) {
+ error = GIT_EUSER;
+ goto cleanup;
+ }
+ }
+
+ error = 0;
+
+cleanup:
+ git_reference_free(stash);
+ git_reflog_free(reflog);
+ return error;
+}
diff --git a/tests-clar/stash/foreach.c b/tests-clar/stash/foreach.c
new file mode 100644
index 000000000..808650786
--- /dev/null
+++ b/tests-clar/stash/foreach.c
@@ -0,0 +1,119 @@
+#include "clar_libgit2.h"
+#include "fileops.h"
+#include "stash_helpers.h"
+
+struct callback_data
+{
+ char **oids;
+ int invokes;
+};
+
+static git_repository *repo;
+static git_signature *signature;
+static git_oid stash_tip_oid;
+struct callback_data data;
+
+#define REPO_NAME "stash"
+
+void test_stash_foreach__initialize(void)
+{
+ cl_git_pass(git_signature_new(
+ &signature,
+ "nulltoken",
+ "emeric.fermas@gmail.com",
+ 1323847743, 60)); /* Wed Dec 14 08:29:03 2011 +0100 */
+
+ memset(&data, 0, sizeof(struct callback_data));
+}
+
+void test_stash_foreach__cleanup(void)
+{
+ git_signature_free(signature);
+ git_repository_free(repo);
+ cl_git_pass(git_futils_rmdir_r(REPO_NAME, NULL, GIT_DIRREMOVAL_FILES_AND_DIRS));
+}
+
+static int callback_cb(
+ size_t index,
+ const char* message,
+ const git_oid *stash_oid,
+ void *payload)
+{
+ int i = 0;
+ bool found = false;
+ struct callback_data *data = (struct callback_data *)payload;
+
+ cl_assert_equal_i(0, git_oid_streq(stash_oid, data->oids[data->invokes++]));
+
+ return 0;
+}
+
+void test_stash_foreach__enumerating_a_empty_repository_doesnt_fail(void)
+{
+ char *oids[] = { NULL };
+
+ data.oids = oids;
+
+ cl_git_pass(git_repository_init(&repo, REPO_NAME, 0));
+
+ cl_git_pass(git_stash_foreach(repo, callback_cb, &data));
+
+ cl_assert_equal_i(0, data.invokes);
+}
+
+void test_stash_foreach__can_enumerate_a_repository(void)
+{
+ char *oids_default[] = {
+ "1d91c842a7cdfc25872b3a763e5c31add8816c25", NULL };
+
+ char *oids_untracked[] = {
+ "7f89a8b15c878809c5c54d1ff8f8c9674154017b",
+ "1d91c842a7cdfc25872b3a763e5c31add8816c25", NULL };
+
+ char *oids_ignored[] = {
+ "c95599a8fef20a7e57582c6727b1a0d02e0a5828",
+ "7f89a8b15c878809c5c54d1ff8f8c9674154017b",
+ "1d91c842a7cdfc25872b3a763e5c31add8816c25", NULL };
+
+ cl_git_pass(git_repository_init(&repo, REPO_NAME, 0));
+
+ setup_stash(repo, signature);
+
+ cl_git_pass(git_stash_save(
+ &stash_tip_oid,
+ repo,
+ signature,
+ NULL,
+ GIT_STASH_DEFAULT));
+
+ data.oids = oids_default;
+
+ cl_git_pass(git_stash_foreach(repo, callback_cb, &data));
+ cl_assert_equal_i(1, data.invokes);
+
+ data.oids = oids_untracked;
+ data.invokes = 0;
+
+ cl_git_pass(git_stash_save(
+ &stash_tip_oid,
+ repo,
+ signature,
+ NULL,
+ GIT_STASH_INCLUDE_UNTRACKED));
+
+ cl_git_pass(git_stash_foreach(repo, callback_cb, &data));
+ cl_assert_equal_i(2, data.invokes);
+
+ data.oids = oids_ignored;
+ data.invokes = 0;
+
+ cl_git_pass(git_stash_save(
+ &stash_tip_oid,
+ repo,
+ signature,
+ NULL,
+ GIT_STASH_INCLUDE_IGNORED));
+
+ cl_git_pass(git_stash_foreach(repo, callback_cb, &data));
+ cl_assert_equal_i(3, data.invokes);
+}