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
}
2016-08-07 02:31:42 -05:00
func newRebaseOperationFromC ( c * C . git_rebase_operation ) * RebaseOperation {
2016-08-06 23:40:59 -05:00
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
}
//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 {
2016-08-07 02:31:42 -05:00
return nil , errors . New ( "RebaseOptions Not implemented yet, use nil for default opts" )
2016-08-06 23:40:59 -05:00
}
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
}
2016-09-05 23:15:10 -05:00
//RebaseOpen opens an existing rebase that was previously started by either an invocation of git_rebase_init or by another client.
func ( r * Repository ) RebaseOpen ( 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, use nil for default opts" )
}
var ptr * C . git_rebase
err := C . git_rebase_open ( & ptr , r . ptr , nil )
if err < 0 {
return nil , MakeGitError ( err )
}
return newRebaseFromC ( ptr ) , nil
}
2016-08-07 02:31:42 -05:00
// OperationAt gets the rebase operation specified by the given index.
func ( rebase * Rebase ) OperationAt ( index uint ) * RebaseOperation {
operation := C . git_rebase_operation_byindex ( rebase . ptr , C . size_t ( index ) )
return newRebaseOperationFromC ( operation )
}
// CurrentOperationIndex gets the index of the rebase operation that is currently being applied.
// If the first operation has not yet been applied then this returns -1 (C.GIT_REBASE_NO_OPERATION).
func ( rebase * Rebase ) CurrentOperationIndex ( ) int {
return int ( C . git_rebase_operation_current ( rebase . ptr ) )
}
// 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
// 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 )
}
2016-08-07 02:31:42 -05:00
return newRebaseOperationFromC ( ptr ) , nil
2016-08-06 23:40:59 -05:00
}
// 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 02:31:42 -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 {
runtime . LockOSThread ( )
defer runtime . UnlockOSThread ( )
err := C . git_rebase_abort ( rebase . ptr )
if err < 0 {
return MakeGitError ( err )
}
return nil
2016-08-07 01:33:06 -05:00
}
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 )
2016-08-07 19:49:40 -05:00
C . git_rebase_free ( rebase . ptr )
2016-08-06 23:40:59 -05:00
}
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 ) ;
* /