Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions src/egit-stash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include <string.h>

#include "git2.h"

#include "egit.h"
#include "egit-util.h"
#include "interface.h"
#include "egit-stash.h"


static int foreach_callback(size_t index, const char *msg, const git_oid *id, void *payload)
{
egit_generic_payload *ctx = (egit_generic_payload*) payload;
emacs_env *env = ctx->env;

emacs_value args[3];
args[0] = EM_INTEGER(index);
args[1] = EM_STRING(msg);

const char *oid_s = git_oid_tostr_s(id);
args[2] = EM_STRING(oid_s);

env->funcall(env, ctx->func, 3, args);

EM_RETURN_IF_NLE(GIT_EUSER);
return 0;
}


EGIT_DOC(stash_drop, "REPO N", "Drop the Nth stash from REPO.");
emacs_value egit_stash_drop(emacs_env *env, emacs_value _repo, emacs_value _index)
{
EGIT_ASSERT_REPOSITORY(_repo);
EM_ASSERT_INTEGER(_index);

git_repository *repo = EGIT_EXTRACT(_repo);
size_t index = EM_EXTRACT_INTEGER(_index);

int retval = git_stash_drop(repo, index);
EGIT_CHECK_ERROR(retval);

return esym_nil;
}


EGIT_DOC(stash_foreach, "REPO FUNC",
"Call FUNC for each stashed state in REPO.\n"
"FUNC is called with three arguments: the stash index, message and commit ID.");
emacs_value egit_stash_foreach(emacs_env *env, emacs_value _repo, emacs_value func)
{
EGIT_ASSERT_REPOSITORY(_repo);
EM_ASSERT_FUNCTION(func);

git_repository *repo = EGIT_EXTRACT(_repo);
egit_generic_payload ctx = {.env = env, .func = func};

int retval = git_stash_foreach(repo, foreach_callback, &ctx);

EM_RETURN_NIL_IF_NLE();
if (retval == GIT_EUSER)
return esym_nil;
EGIT_CHECK_ERROR(retval);
return esym_nil;
}


EGIT_DOC(stash_save, "REPO STASHER &optional MSG FLAGS",
"Save the local modifications to a new stash.\n"
"STASHER must be a valid signature object. MSG, if given, a description.\n"
"FLAGS is a list with any of the following symbols:\n"
" - `keep-index': changes already added to the index are left intact in the WD\n"
" - `include-untracked': untracked files are also stashed and cleaned up\n"
" - `include-ignored': ignored files are also stashed and cleaned up");
emacs_value egit_stash_save(emacs_env *env, emacs_value _repo, emacs_value _stasher,
emacs_value _msg, emacs_value _flags)
{
EGIT_ASSERT_REPOSITORY(_repo);
EGIT_ASSERT_SIGNATURE(_stasher);
EM_ASSERT_STRING_OR_NIL(_msg);

uint32_t flags = GIT_STASH_DEFAULT;
if (!em_setflags_list(&flags, env, _flags, true, em_setflag_stash_flags))
return esym_nil;

git_repository *repo = EGIT_EXTRACT(_repo);
git_signature *stasher = EGIT_EXTRACT(_stasher);
char *msg = EM_EXTRACT_STRING_OR_NULL(_msg);

git_oid oid;
int retval = git_stash_save(&oid, repo, stasher, msg, flags);
EGIT_CHECK_ERROR(retval);

const char *oid_s = git_oid_tostr_s(&oid);
return EM_STRING(oid_s);
}
10 changes: 10 additions & 0 deletions src/egit-stash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "egit.h"

#ifndef EGIT_STASH_H
#define EGIT_STASH_H

EGIT_DEFUN(stash_drop, emacs_value _repo, emacs_value _index);
EGIT_DEFUN(stash_foreach, emacs_value _repo, emacs_value func);
EGIT_DEFUN(stash_save, emacs_value _repo, emacs_value _stasher, emacs_value _msg, emacs_value _flags);

#endif /* EGIT_STASH_H */
6 changes: 6 additions & 0 deletions src/egit.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "egit-revert.h"
#include "egit-revwalk.h"
#include "egit-signature.h"
#include "egit-stash.h"
#include "egit-status.h"
#include "egit-submodule.h"
#include "egit-tag.h"
Expand Down Expand Up @@ -760,6 +761,11 @@ void egit_init(emacs_env *env)
DEFUN("libgit-signature-email", signature_email, 1, 1);
DEFUN("libgit-signature-time", signature_time, 1, 1);

// Stash
DEFUN("libgit-stash-drop", stash_drop, 2, 2);
DEFUN("libgit-stash-foreach", stash_foreach, 2, 2);
DEFUN("libgit-stash-save", stash_foreach, 2, 4);

// Status
DEFUN("libgit-status-decode", status_decode, 1, 1);
DEFUN("libgit-status-file", status_file, 2, 2);
Expand Down
1 change: 1 addition & 0 deletions src/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ MKSETFLAG(git_index_add_option_t, index_add_option);
MKSETFLAG(git_merge_file_flag_t, merge_file_flag);
MKSETFLAG(git_merge_flag_t, merge_flag);
MKSETFLAG(git_sort_t, sort);
MKSETFLAG(git_stash_flags, stash_flags);
MKSETFLAG(git_status_opt_t, status_opt);

#undef MKSETFLAG
Expand Down
1 change: 1 addition & 0 deletions src/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ setter em_setflag_index_add_option;
setter em_setflag_merge_file_flag;
setter em_setflag_merge_flag;
setter em_setflag_sort;
setter em_setflag_stash_flags;
setter em_setflag_status_opt;

bool em_setflags_list(void *out, emacs_env *env, emacs_value list, bool required, setter *setter);
Expand Down
9 changes: 9 additions & 0 deletions src/symbols.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ emacs_value esym_index_typechange;
emacs_value esym_insert;
emacs_value esym_integerp;
emacs_value esym_interhunk_lines;
emacs_value esym_keep_index;
emacs_value esym_last;
emacs_value esym_length;
emacs_value esym_libgit_annotated_commit_p;
Expand Down Expand Up @@ -626,6 +627,13 @@ esym_map esym_reset_map[4] = {
{&esym_hard, {.reset = GIT_RESET_HARD}},
{NULL, {0}}
};
esym_map esym_stash_flags_map[5] = {
{&esym_default, {.stash_flags = GIT_STASH_DEFAULT}},
{&esym_keep_index, {.stash_flags = GIT_STASH_KEEP_INDEX}},
{&esym_include_untracked, {.stash_flags = GIT_STASH_INCLUDE_UNTRACKED}},
{&esym_include_ignored, {.stash_flags = GIT_STASH_INCLUDE_IGNORED}},
{NULL, {0}}
};
esym_map esym_status_opt_map[17] = {
{&esym_include_untracked, {.status_opt = GIT_STATUS_OPT_INCLUDE_UNTRACKED}},
{&esym_include_ignored, {.status_opt = GIT_STATUS_OPT_INCLUDE_IGNORED}},
Expand Down Expand Up @@ -871,6 +879,7 @@ void esyms_init(emacs_env *env)
esym_insert = env->make_global_ref(env, env->intern(env, "insert"));
esym_integerp = env->make_global_ref(env, env->intern(env, "integerp"));
esym_interhunk_lines = env->make_global_ref(env, env->intern(env, "interhunk-lines"));
esym_keep_index = env->make_global_ref(env, env->intern(env, "keep-index"));
esym_last = env->make_global_ref(env, env->intern(env, "last"));
esym_length = env->make_global_ref(env, env->intern(env, "length"));
esym_libgit_annotated_commit_p = env->make_global_ref(env, env->intern(env, "libgit-annotated-commit-p"));
Expand Down
3 changes: 3 additions & 0 deletions src/symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ typedef union {
git_remote_autotag_option_t remote_autotag_option;
git_repository_state_t repository_state;
git_reset_t reset;
git_stash_flags stash_flags;
git_status_opt_t status_opt;
git_status_show_t status_show;
git_status_t status;
Expand Down Expand Up @@ -83,6 +84,7 @@ extern esym_map esym_proxy_map[5];
extern esym_map esym_remote_autotag_option_map[5];
extern esym_map esym_repository_state_map[13];
extern esym_map esym_reset_map[4];
extern esym_map esym_stash_flags_map[5];
extern esym_map esym_status_opt_map[17];
extern esym_map esym_status_show_map[5];
extern esym_map esym_status_map[15];
Expand Down Expand Up @@ -239,6 +241,7 @@ extern emacs_value esym_index_typechange;
extern emacs_value esym_insert;
extern emacs_value esym_integerp;
extern emacs_value esym_interhunk_lines;
extern emacs_value esym_keep_index;
extern emacs_value esym_last;
extern emacs_value esym_length;
extern emacs_value esym_libgit_annotated_commit_p;
Expand Down
7 changes: 7 additions & 0 deletions symbols.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,13 @@ soft
mixed
hard

[git_stash_flags]
__prefix = GIT_STASH_
default
keep-index
include-untracked
include-ignored

[git_status_opt_t]
__prefix = GIT_STATUS_OPT_
include-untracked
Expand Down