2016-08-06 23:40:59 -05:00
package git
/ *
# include < git2 . h >
* /
import "C"
import (
"errors"
"runtime"
"unsafe"
)
// RebaseOperationType is the type of rebase operation
type RebaseOperationType uint
const (
// RebaseOperationPick The given commit is to be cherry-picked. The client should commit the changes and continue if there are no conflicts.
RebaseOperationPick RebaseOperationType = C . GIT_REBASE_OPERATION_PICK
// RebaseOperationEdit The given commit is to be cherry-picked, but the client should stop to allow the user to edit the changes before committing them.
RebaseOperationEdit RebaseOperationType = C . GIT_REBASE_OPERATION_EDIT
// RebaseOperationSquash The given commit is to be squashed into the previous commit. The commit message will be merged with the previous message.
RebaseOperationSquash RebaseOperationType = C . GIT_REBASE_OPERATION_SQUASH
// RebaseOperationFixup No commit will be cherry-picked. The client should run the given command and (if successful) continue.
RebaseOperationFixup RebaseOperationType = C . GIT_REBASE_OPERATION_FIXUP
// RebaseOperationExec No commit will be cherry-picked. The client should run the given command and (if successful) continue.
RebaseOperationExec RebaseOperationType = C . GIT_REBASE_OPERATION_EXEC
)
// RebaseOperation describes a single instruction/operation to be performed during the rebase.
type RebaseOperation struct {
Type RebaseOperationType
ID * Oid
Exec string
}
func rebaseOperationFromC ( c * C . git_rebase_operation ) * RebaseOperation {
operation := & RebaseOperation { }
operation . Type = RebaseOperationType ( c . _type )
operation . ID = newOidFromC ( & c . id )
operation . Exec = C . GoString ( c . exec )
return operation
}
// RebaseOptions are used to tell the rebase machinery how to operate
type RebaseOptions struct { }
// Rebase object wrapper for C pointer
type Rebase struct {
ptr * C . git_rebase
}
2016-08-07 02:00:14 -05:00
// Abort aborts a rebase that is currently in progress, resetting the repository and working directory to their state before rebase began.
func ( rebase * Rebase ) Abort ( ) error {
err := C . git_rebase_abort ( rebase . ptr )
if err < 0 {
return MakeGitError ( err )
}
return nil
}
2016-08-06 23:40:59 -05:00
//RebaseInit initializes a rebase operation to rebase the changes in branch relative to upstream onto another branch.
func ( r * Repository ) RebaseInit ( branch * AnnotatedCommit , upstream * AnnotatedCommit , onto * AnnotatedCommit , opts * RebaseOptions ) ( * Rebase , error ) {
runtime . LockOSThread ( )
defer runtime . UnlockOSThread ( )
//TODO : use real rebase_options
if opts != nil {
return nil , errors . New ( "RebaseOptions Not implemented yet" )
}
if branch == nil {
branch = & AnnotatedCommit { ptr : nil }
}
if upstream == nil {
upstream = & AnnotatedCommit { ptr : nil }
}
if onto == nil {
onto = & AnnotatedCommit { ptr : nil }
}
var ptr * C . git_rebase
err := C . git_rebase_init ( & ptr , r . ptr , branch . ptr , upstream . ptr , onto . ptr , nil )
if err < 0 {
return nil , MakeGitError ( err )
}
return newRebaseFromC ( ptr ) , nil
}
// Next performs the next rebase operation and returns the information about it.
// If the operation is one that applies a patch (which is any operation except GIT_REBASE_OPERATION_EXEC)
// then the patch will be applied and the index and working directory will be updated with the changes.
// If there are conflicts, you will need to address those before committing the changes.
func ( rebase * Rebase ) Next ( ) ( * RebaseOperation , error ) {
runtime . LockOSThread ( )
defer runtime . UnlockOSThread ( )
var ptr * C . git_rebase_operation
err := C . git_rebase_next ( & ptr , rebase . ptr )
if err < 0 {
return nil , MakeGitError ( err )
}
return rebaseOperationFromC ( ptr ) , nil
}
// Commit commits the current patch.
// You must have resolved any conflicts that were introduced during the patch application from the git_rebase_next invocation.
func ( rebase * Rebase ) Commit ( ID * Oid , author , committer * Signature , message string ) error {
runtime . LockOSThread ( )
defer runtime . UnlockOSThread ( )
authorSig , err := author . toC ( )
if err != nil {
return err
}
defer C . git_signature_free ( authorSig )
committerSig , err := committer . toC ( )
if err != nil {
return err
}
cmsg := C . CString ( message )
defer C . free ( unsafe . Pointer ( cmsg ) )
cerr := C . git_rebase_commit ( ID . toC ( ) , rebase . ptr , authorSig , committerSig , nil , cmsg )
if cerr < 0 {
return MakeGitError ( cerr )
}
return nil
}
// Finish finishes a rebase that is currently in progress once all patches have been applied.
func ( rebase * Rebase ) Finish ( ) error {
runtime . LockOSThread ( )
defer runtime . UnlockOSThread ( )
err := C . git_rebase_finish ( rebase . ptr , nil )
if err < 0 {
return MakeGitError ( err )
}
return nil
}
2016-08-07 01:33:06 -05:00
// OperationCount gets the count of rebase operations that are to be applied.
func ( rebase * Rebase ) OperationCount ( ) uint {
return uint ( C . git_rebase_operation_entrycount ( rebase . ptr ) )
}
2016-08-06 23:40:59 -05:00
//Free frees the Rebase object and underlying git_rebase C pointer.
func ( rebase * Rebase ) Free ( ) {
runtime . SetFinalizer ( rebase , nil )
C . git_reference_free ( rebase . ptr )
}
func newRebaseFromC ( ptr * C . git_rebase ) * Rebase {
rebase := & Rebase { ptr : ptr }
runtime . SetFinalizer ( rebase , ( * Rebase ) . Free )
return rebase
}
2016-08-07 01:33:06 -05:00
/ * TODO -- Add last wrapper services and manage rebase_options
int git_rebase_init_options ( git_rebase_options * opts , unsigned int version ) ;
int git_rebase_open ( git_rebase * * out , git_repository * repo , const git_rebase_options * opts ) ;
git_rebase_operation * git_rebase_operation_byindex ( git_rebase * rebase , size_t idx ) ;
size_t git_rebase_operation_current ( git_rebase * rebase ) ;
* /