- Notifications
You must be signed in to change notification settings - Fork 324
/
Copy pathstatus.go
194 lines (163 loc) · 5.3 KB
/
status.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
package git
/*
#include <git2.h>
*/
import"C"
import (
"errors"
"runtime"
"unsafe"
)
typeStatusint
const (
StatusCurrentStatus=C.GIT_STATUS_CURRENT
StatusIndexNewStatus=C.GIT_STATUS_INDEX_NEW
StatusIndexModifiedStatus=C.GIT_STATUS_INDEX_MODIFIED
StatusIndexDeletedStatus=C.GIT_STATUS_INDEX_DELETED
StatusIndexRenamedStatus=C.GIT_STATUS_INDEX_RENAMED
StatusIndexTypeChangeStatus=C.GIT_STATUS_INDEX_TYPECHANGE
StatusWtNewStatus=C.GIT_STATUS_WT_NEW
StatusWtModifiedStatus=C.GIT_STATUS_WT_MODIFIED
StatusWtDeletedStatus=C.GIT_STATUS_WT_DELETED
StatusWtTypeChangeStatus=C.GIT_STATUS_WT_TYPECHANGE
StatusWtRenamedStatus=C.GIT_STATUS_WT_RENAMED
StatusIgnoredStatus=C.GIT_STATUS_IGNORED
StatusConflictedStatus=C.GIT_STATUS_CONFLICTED
)
typeStatusEntrystruct {
StatusStatus
HeadToIndexDiffDelta
IndexToWorkdirDiffDelta
}
funcstatusEntryFromC(statusEntry*C.git_status_entry) StatusEntry {
varheadToIndexDiffDelta=DiffDelta{}
varindexToWorkdirDiffDelta=DiffDelta{}
// Based on the libgit2 status example, head_to_index can be null in some cases
ifstatusEntry.head_to_index!=nil {
headToIndex=diffDeltaFromC(statusEntry.head_to_index)
}
ifstatusEntry.index_to_workdir!=nil {
indexToWorkdir=diffDeltaFromC(statusEntry.index_to_workdir)
}
returnStatusEntry{
Status: Status(statusEntry.status),
HeadToIndex: headToIndex,
IndexToWorkdir: indexToWorkdir,
}
}
typeStatusListstruct {
doNotCompare
ptr*C.git_status_list
r*Repository
}
funcnewStatusListFromC(ptr*C.git_status_list, r*Repository) *StatusList {
ifptr==nil {
returnnil
}
statusList:=&StatusList{
ptr: ptr,
r: r,
}
runtime.SetFinalizer(statusList, (*StatusList).Free)
returnstatusList
}
func (statusList*StatusList) Free() {
ifstatusList.ptr==nil {
return
}
runtime.SetFinalizer(statusList, nil)
C.git_status_list_free(statusList.ptr)
statusList.ptr=nil
}
func (statusList*StatusList) ByIndex(indexint) (StatusEntry, error) {
ifstatusList.ptr==nil {
returnStatusEntry{}, ErrInvalid
}
ptr:=C.git_status_byindex(statusList.ptr, C.size_t(index))
ifptr==nil {
returnStatusEntry{}, errors.New("index out of Bounds")
}
entry:=statusEntryFromC(ptr)
runtime.KeepAlive(statusList)
returnentry, nil
}
func (statusList*StatusList) EntryCount() (int, error) {
ifstatusList.ptr==nil {
return-1, ErrInvalid
}
ret:=int(C.git_status_list_entrycount(statusList.ptr))
runtime.KeepAlive(statusList)
returnret, nil
}
typeStatusOptint
const (
StatusOptIncludeUntrackedStatusOpt=C.GIT_STATUS_OPT_INCLUDE_UNTRACKED
StatusOptIncludeIgnoredStatusOpt=C.GIT_STATUS_OPT_INCLUDE_IGNORED
StatusOptIncludeUnmodifiedStatusOpt=C.GIT_STATUS_OPT_INCLUDE_UNMODIFIED
StatusOptExcludeSubmodulesStatusOpt=C.GIT_STATUS_OPT_EXCLUDE_SUBMODULES
StatusOptRecurseUntrackedDirsStatusOpt=C.GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS
StatusOptDisablePathspecMatchStatusOpt=C.GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH
StatusOptRecurseIgnoredDirsStatusOpt=C.GIT_STATUS_OPT_RECURSE_IGNORED_DIRS
StatusOptRenamesHeadToIndexStatusOpt=C.GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX
StatusOptRenamesIndexToWorkdirStatusOpt=C.GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR
StatusOptSortCaseSensitivelyStatusOpt=C.GIT_STATUS_OPT_SORT_CASE_SENSITIVELY
StatusOptSortCaseInsensitivelyStatusOpt=C.GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY
StatusOptRenamesFromRewritesStatusOpt=C.GIT_STATUS_OPT_RENAMES_FROM_REWRITES
StatusOptNoRefreshStatusOpt=C.GIT_STATUS_OPT_NO_REFRESH
StatusOptUpdateIndexStatusOpt=C.GIT_STATUS_OPT_UPDATE_INDEX
)
typeStatusShowint
const (
StatusShowIndexAndWorkdirStatusShow=C.GIT_STATUS_SHOW_INDEX_AND_WORKDIR
StatusShowIndexOnlyStatusShow=C.GIT_STATUS_SHOW_INDEX_ONLY
StatusShowWorkdirOnlyStatusShow=C.GIT_STATUS_SHOW_WORKDIR_ONLY
)
typeStatusOptionsstruct {
ShowStatusShow
FlagsStatusOpt
Pathspec []string
}
func (v*Repository) StatusList(opts*StatusOptions) (*StatusList, error) {
varptr*C.git_status_list
varcopts*C.git_status_options
ifopts!=nil {
cpathspec:= C.git_strarray{}
ifopts.Pathspec!=nil {
cpathspec.count=C.size_t(len(opts.Pathspec))
cpathspec.strings=makeCStringsFromStrings(opts.Pathspec)
deferfreeStrarray(&cpathspec)
}
copts=&C.git_status_options{
version: C.GIT_STATUS_OPTIONS_VERSION,
show: C.git_status_show_t(opts.Show),
flags: C.uint(opts.Flags),
pathspec: cpathspec,
}
} else {
copts=&C.git_status_options{}
ret:=C.git_status_options_init(copts, C.GIT_STATUS_OPTIONS_VERSION)
ifret<0 {
returnnil, MakeGitError(ret)
}
}
runtime.LockOSThread()
deferruntime.UnlockOSThread()
ret:=C.git_status_list_new(&ptr, v.ptr, copts)
ifret<0 {
returnnil, MakeGitError(ret)
}
returnnewStatusListFromC(ptr, v), nil
}
func (v*Repository) StatusFile(pathstring) (Status, error) {
varstatusFlags C.uint
cPath:=C.CString(path)
deferC.free(unsafe.Pointer(cPath))
runtime.LockOSThread()
deferruntime.UnlockOSThread()
ret:=C.git_status_file(&statusFlags, v.ptr, cPath)
runtime.KeepAlive(v)
ifret<0 {
return0, MakeGitError(ret)
}
returnStatus(statusFlags), nil
}