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

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/libgit2/git2go/stash.go')
-rw-r--r--vendor/github.com/libgit2/git2go/stash.go342
1 files changed, 342 insertions, 0 deletions
diff --git a/vendor/github.com/libgit2/git2go/stash.go b/vendor/github.com/libgit2/git2go/stash.go
new file mode 100644
index 000000000..8743da89e
--- /dev/null
+++ b/vendor/github.com/libgit2/git2go/stash.go
@@ -0,0 +1,342 @@
+package git
+
+/*
+#include <git2.h>
+
+extern void _go_git_setup_stash_apply_progress_callbacks(git_stash_apply_options *opts);
+extern int _go_git_stash_foreach(git_repository *repo, void *payload);
+*/
+import "C"
+import (
+ "runtime"
+ "unsafe"
+)
+
+// StashFlag are flags that affect the stash save operation.
+type StashFlag int
+
+const (
+ // StashDefault represents no option, default.
+ StashDefault StashFlag = C.GIT_STASH_DEFAULT
+
+ // StashKeepIndex leaves all changes already added to the
+ // index intact in the working directory.
+ StashKeepIndex StashFlag = C.GIT_STASH_KEEP_INDEX
+
+ // StashIncludeUntracked means all untracked files are also
+ // stashed and then cleaned up from the working directory.
+ StashIncludeUntracked StashFlag = C.GIT_STASH_INCLUDE_UNTRACKED
+
+ // StashIncludeIgnored means all ignored files are also
+ // stashed and then cleaned up from the working directory.
+ StashIncludeIgnored StashFlag = C.GIT_STASH_INCLUDE_IGNORED
+)
+
+// StashCollection represents the possible operations that can be
+// performed on the collection of stashes for a repository.
+type StashCollection struct {
+ repo *Repository
+}
+
+// Save saves the local modifications to a new stash.
+//
+// Stasher is the identity of the person performing the stashing.
+// Message is the optional description along with the stashed state.
+// Flags control the stashing process and are given as bitwise OR.
+func (c *StashCollection) Save(
+ stasher *Signature, message string, flags StashFlag) (*Oid, error) {
+
+ oid := new(Oid)
+
+ stasherC, err := stasher.toC()
+ if err != nil {
+ return nil, err
+ }
+ defer C.git_signature_free(stasherC)
+
+ messageC := C.CString(message)
+ defer C.free(unsafe.Pointer(messageC))
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C.git_stash_save(
+ oid.toC(), c.repo.ptr,
+ stasherC, messageC, C.uint32_t(flags))
+ runtime.KeepAlive(c)
+ if ret < 0 {
+ return nil, MakeGitError(ret)
+ }
+ return oid, nil
+}
+
+// StashApplyFlag are flags that affect the stash apply operation.
+type StashApplyFlag int
+
+const (
+ // StashApplyDefault is the default.
+ StashApplyDefault StashApplyFlag = C.GIT_STASH_APPLY_DEFAULT
+
+ // StashApplyReinstateIndex will try to reinstate not only the
+ // working tree's changes, but also the index's changes.
+ StashApplyReinstateIndex StashApplyFlag = C.GIT_STASH_APPLY_REINSTATE_INDEX
+)
+
+// StashApplyProgress are flags describing the progress of the apply operation.
+type StashApplyProgress int
+
+const (
+ // StashApplyProgressNone means loading the stashed data from the object store.
+ StashApplyProgressNone StashApplyProgress = C.GIT_STASH_APPLY_PROGRESS_NONE
+
+ // StashApplyProgressLoadingStash means the stored index is being analyzed.
+ StashApplyProgressLoadingStash StashApplyProgress = C.GIT_STASH_APPLY_PROGRESS_LOADING_STASH
+
+ // StashApplyProgressAnalyzeIndex means the stored index is being analyzed.
+ StashApplyProgressAnalyzeIndex StashApplyProgress = C.GIT_STASH_APPLY_PROGRESS_ANALYZE_INDEX
+
+ // StashApplyProgressAnalyzeModified means the modified files are being analyzed.
+ StashApplyProgressAnalyzeModified StashApplyProgress = C.GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED
+
+ // StashApplyProgressAnalyzeUntracked means the untracked and ignored files are being analyzed.
+ StashApplyProgressAnalyzeUntracked StashApplyProgress = C.GIT_STASH_APPLY_PROGRESS_ANALYZE_UNTRACKED
+
+ // StashApplyProgressCheckoutUntracked means the untracked files are being written to disk.
+ StashApplyProgressCheckoutUntracked StashApplyProgress = C.GIT_STASH_APPLY_PROGRESS_CHECKOUT_UNTRACKED
+
+ // StashApplyProgressCheckoutModified means the modified files are being written to disk.
+ StashApplyProgressCheckoutModified StashApplyProgress = C.GIT_STASH_APPLY_PROGRESS_CHECKOUT_MODIFIED
+
+ // StashApplyProgressDone means the stash was applied successfully.
+ StashApplyProgressDone StashApplyProgress = C.GIT_STASH_APPLY_PROGRESS_DONE
+)
+
+// StashApplyProgressCallback is the apply operation notification callback.
+type StashApplyProgressCallback func(progress StashApplyProgress) error
+
+type stashApplyProgressData struct {
+ Callback StashApplyProgressCallback
+ Error error
+}
+
+//export stashApplyProgressCb
+func stashApplyProgressCb(progress C.git_stash_apply_progress_t, handle unsafe.Pointer) int {
+ payload := pointerHandles.Get(handle)
+ data, ok := payload.(*stashApplyProgressData)
+ if !ok {
+ panic("could not retrieve data for handle")
+ }
+
+ if data != nil {
+ err := data.Callback(StashApplyProgress(progress))
+ if err != nil {
+ data.Error = err
+ return C.GIT_EUSER
+ }
+ }
+ return 0
+}
+
+// StashApplyOptions represents options to control the apply operation.
+type StashApplyOptions struct {
+ Flags StashApplyFlag
+ CheckoutOptions CheckoutOpts // options to use when writing files to the working directory
+ ProgressCallback StashApplyProgressCallback // optional callback to notify the consumer of application progress
+}
+
+// DefaultStashApplyOptions initializes the structure with default values.
+func DefaultStashApplyOptions() (StashApplyOptions, error) {
+ optsC := C.git_stash_apply_options{}
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ecode := C.git_stash_apply_init_options(&optsC, C.GIT_STASH_APPLY_OPTIONS_VERSION)
+ if ecode < 0 {
+ return StashApplyOptions{}, MakeGitError(ecode)
+ }
+ return StashApplyOptions{
+ Flags: StashApplyFlag(optsC.flags),
+ CheckoutOptions: checkoutOptionsFromC(&optsC.checkout_options),
+ }, nil
+}
+
+func (opts *StashApplyOptions) toC() (
+ optsC *C.git_stash_apply_options, progressData *stashApplyProgressData) {
+
+ if opts != nil {
+ progressData = &stashApplyProgressData{
+ Callback: opts.ProgressCallback,
+ }
+
+ optsC = &C.git_stash_apply_options{
+ version: C.GIT_STASH_APPLY_OPTIONS_VERSION,
+ flags: C.git_stash_apply_flags(opts.Flags),
+ }
+ populateCheckoutOpts(&optsC.checkout_options, &opts.CheckoutOptions)
+ if opts.ProgressCallback != nil {
+ C._go_git_setup_stash_apply_progress_callbacks(optsC)
+ optsC.progress_payload = pointerHandles.Track(progressData)
+ }
+ }
+ return
+}
+
+// should be called after every call to toC() as deferred.
+func untrackStashApplyOptionsCallback(optsC *C.git_stash_apply_options) {
+ if optsC != nil && optsC.progress_payload != nil {
+ pointerHandles.Untrack(optsC.progress_payload)
+ }
+}
+
+func freeStashApplyOptions(optsC *C.git_stash_apply_options) {
+ if optsC != nil {
+ freeCheckoutOpts(&optsC.checkout_options)
+ }
+}
+
+// Apply applies a single stashed state from the stash list.
+//
+// If local changes in the working directory conflict with changes in the
+// stash then ErrConflict will be returned. In this case, the index
+// will always remain unmodified and all files in the working directory will
+// remain unmodified. However, if you are restoring untracked files or
+// ignored files and there is a conflict when applying the modified files,
+// then those files will remain in the working directory.
+//
+// If passing the StashApplyReinstateIndex flag and there would be conflicts
+// when reinstating the index, the function will return ErrConflict
+// and both the working directory and index will be left unmodified.
+//
+// Note that a minimum checkout strategy of 'CheckoutSafe' is implied.
+//
+// 'index' is the position within the stash list. 0 points to the most
+// recent stashed state.
+//
+// Returns error code ErrNotFound if there's no stashed state for the given
+// index, error code ErrConflict if local changes in the working directory
+// conflict with changes in the stash, the user returned error from the
+// StashApplyProgressCallback, if any, or other error code.
+//
+// Error codes can be interogated with IsErrorCode(err, ErrNotFound).
+func (c *StashCollection) Apply(index int, opts StashApplyOptions) error {
+ optsC, progressData := opts.toC()
+ defer untrackStashApplyOptionsCallback(optsC)
+ defer freeStashApplyOptions(optsC)
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C.git_stash_apply(c.repo.ptr, C.size_t(index), optsC)
+ runtime.KeepAlive(c)
+ if ret == C.GIT_EUSER {
+ return progressData.Error
+ }
+ if ret < 0 {
+ return MakeGitError(ret)
+ }
+ return nil
+}
+
+// StashCallback is called per entry when interating over all
+// the stashed states.
+//
+// 'index' is the position of the current stash in the stash list,
+// 'message' is the message used when creating the stash and 'id'
+// is the commit id of the stash.
+type StashCallback func(index int, message string, id *Oid) error
+
+type stashCallbackData struct {
+ Callback StashCallback
+ Error error
+}
+
+//export stashForeachCb
+func stashForeachCb(index C.size_t, message *C.char, id *C.git_oid, handle unsafe.Pointer) int {
+ payload := pointerHandles.Get(handle)
+ data, ok := payload.(*stashCallbackData)
+ if !ok {
+ panic("could not retrieve data for handle")
+ }
+
+ err := data.Callback(int(index), C.GoString(message), newOidFromC(id))
+ if err != nil {
+ data.Error = err
+ return C.GIT_EUSER
+ }
+ return 0
+}
+
+// Foreach loops over all the stashed states and calls the callback
+// for each one.
+//
+// If callback returns an error, this will stop looping.
+func (c *StashCollection) Foreach(callback StashCallback) error {
+ data := stashCallbackData{
+ Callback: callback,
+ }
+
+ handle := pointerHandles.Track(&data)
+ defer pointerHandles.Untrack(handle)
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C._go_git_stash_foreach(c.repo.ptr, handle)
+ runtime.KeepAlive(c)
+ if ret == C.GIT_EUSER {
+ return data.Error
+ }
+ if ret < 0 {
+ return MakeGitError(ret)
+ }
+ return nil
+}
+
+// Drop removes a single stashed state from the stash list.
+//
+// 'index' is the position within the stash list. 0 points
+// to the most recent stashed state.
+//
+// Returns error code ErrNotFound if there's no stashed
+// state for the given index.
+func (c *StashCollection) Drop(index int) error {
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C.git_stash_drop(c.repo.ptr, C.size_t(index))
+ runtime.KeepAlive(c)
+ if ret < 0 {
+ return MakeGitError(ret)
+ }
+ return nil
+}
+
+// Pop applies a single stashed state from the stash list
+// and removes it from the list if successful.
+//
+// 'index' is the position within the stash list. 0 points
+// to the most recent stashed state.
+//
+// 'opts' controls how stashes are applied.
+//
+// Returns error code ErrNotFound if there's no stashed
+// state for the given index.
+func (c *StashCollection) Pop(index int, opts StashApplyOptions) error {
+ optsC, progressData := opts.toC()
+ defer untrackStashApplyOptionsCallback(optsC)
+ defer freeStashApplyOptions(optsC)
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ret := C.git_stash_pop(c.repo.ptr, C.size_t(index), optsC)
+ runtime.KeepAlive(c)
+ if ret == C.GIT_EUSER {
+ return progressData.Error
+ }
+ if ret < 0 {
+ return MakeGitError(ret)
+ }
+ return nil
+}