/
index.jl
218 lines (191 loc) · 8.05 KB
/
index.jl
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# This file is a part of Julia. License is MIT: https://julialang.org/license
"""
GitIndex(repo::GitRepo)
Load the index file for the repository `repo`.
"""
function GitIndex(repo::GitRepo)
ensure_initialized()
idx_ptr_ptr = Ref{Ptr{Cvoid}}(C_NULL)
@check ccall((:git_repository_index, :libgit2), Cint,
(Ptr{Ptr{Cvoid}}, Ptr{Cvoid}), idx_ptr_ptr, repo.ptr)
return GitIndex(repo, idx_ptr_ptr[])
end
"""
read!(idx::GitIndex, force::Bool = false) -> GitIndex
Update the contents of `idx` by reading changes made on disk. For example, `idx`
might be updated if a file has been added to the repository since it was created.
If `force` is `true`, any changes in memory (any changes in `idx` since its last
[`write!`](@ref), or since its creation if no writes have occurred) are discarded.
If `force` is `false`, the index data is only updated from disk if the data on disk
has changed since the last time it was loaded into `idx`.
"""
function read!(idx::GitIndex, force::Bool = false)
ensure_initialized()
@check ccall((:git_index_read, :libgit2), Cint, (Ptr{Cvoid}, Cint), idx.ptr, Cint(force))
return idx
end
"""
write!(idx::GitIndex) -> GitIndex
Write the state of index `idx` to disk using a file lock.
"""
function write!(idx::GitIndex)
ensure_initialized()
@check ccall((:git_index_write, :libgit2), Cint, (Ptr{Cvoid},), idx.ptr)
return idx
end
"""
write_tree!(idx::GitIndex) -> GitHash
Write the index `idx` as a [`GitTree`](@ref) on disk. Trees will be recursively
created for each subtree in `idx`. The returned [`GitHash`](@ref) can be used to
create a [`GitCommit`](@ref). `idx` must have a parent repository and this
repository cannot be bare. `idx` must not contain any files with conflicts.
"""
function write_tree!(idx::GitIndex)
ensure_initialized()
oid_ptr = Ref(GitHash())
@check ccall((:git_index_write_tree, :libgit2), Cint,
(Ptr{GitHash}, Ptr{Cvoid}), oid_ptr, idx.ptr)
return oid_ptr[]
end
function repository(idx::GitIndex)
if idx.owner === nothing
throw(GitError(Error.Index, Error.ENOTFOUND, "Index does not have an owning repository."))
else
return idx.owner
end
end
"""
LibGit2.read_tree!(idx::GitIndex, tree::GitTree)
LibGit2.read_tree!(idx::GitIndex, treehash::AbstractGitHash)
Read the tree `tree` (or the tree pointed to by `treehash` in the repository owned by
`idx`) into the index `idx`. The current index contents will be replaced.
"""
function read_tree!(idx::GitIndex, tree::GitTree)
ensure_initialized()
@check ccall((:git_index_read_tree, :libgit2), Cint,
(Ptr{Cvoid}, Ptr{Cvoid}), idx.ptr, tree.ptr)
end
read_tree!(idx::GitIndex, hash::AbstractGitHash) =
read_tree!(idx, GitTree(repository(idx), hash))
"""
add!(repo::GitRepo, files::AbstractString...; flags::Cuint = Consts.INDEX_ADD_DEFAULT)
add!(idx::GitIndex, files::AbstractString...; flags::Cuint = Consts.INDEX_ADD_DEFAULT)
Add all the files with paths specified by `files` to the index `idx` (or the index
of the `repo`). If the file already exists, the index entry will be updated.
If the file does not exist already, it will be newly added into the index.
`files` may contain glob patterns which will be expanded and any matching files will
be added (unless `INDEX_ADD_DISABLE_PATHSPEC_MATCH` is set, see below).
If a file has been ignored (in `.gitignore` or in the config), it *will not* be
added, *unless* it is already being tracked in the index, in which case it *will* be
updated. The keyword argument `flags` is a set of bit-flags which control the behavior
with respect to ignored files:
* `Consts.INDEX_ADD_DEFAULT` - default, described above.
* `Consts.INDEX_ADD_FORCE` - disregard the existing ignore rules and force addition of
the file to the index even if it is already ignored.
* `Consts.INDEX_ADD_CHECK_PATHSPEC` - cannot be used at the same time as `INDEX_ADD_FORCE`.
Check that each file in `files` which exists on disk is not in the ignore list. If one
of the files *is* ignored, the function will return `EINVALIDSPEC`.
* `Consts.INDEX_ADD_DISABLE_PATHSPEC_MATCH` - turn off glob matching, and only add files
to the index which exactly match the paths specified in `files`.
"""
function add!(idx::GitIndex, files::AbstractString...;
flags::Cuint = Consts.INDEX_ADD_DEFAULT)
ensure_initialized()
@check ccall((:git_index_add_all, :libgit2), Cint,
(Ptr{Cvoid}, Ptr{StrArrayStruct}, Cuint, Ptr{Cvoid}, Ptr{Cvoid}),
idx.ptr, collect(files), flags, C_NULL, C_NULL)
end
"""
update!(repo::GitRepo, files::AbstractString...)
update!(idx::GitIndex, files::AbstractString...)
Update all the files with paths specified by `files` in the index `idx` (or the index
of the `repo`). Match the state of each file in the index with the current state on
disk, removing it if it has been removed on disk, or updating its entry in the object
database.
"""
function update!(idx::GitIndex, files::AbstractString...)
ensure_initialized()
@check ccall((:git_index_update_all, :libgit2), Cint,
(Ptr{Cvoid}, Ptr{StrArrayStruct}, Ptr{Cvoid}, Ptr{Cvoid}),
idx.ptr, collect(files), C_NULL, C_NULL)
end
"""
remove!(repo::GitRepo, files::AbstractString...)
remove!(idx::GitIndex, files::AbstractString...)
Remove all the files with paths specified by `files` in the index `idx` (or the index
of the `repo`).
"""
function remove!(idx::GitIndex, files::AbstractString...)
ensure_initialized()
@check ccall((:git_index_remove_all, :libgit2), Cint,
(Ptr{Cvoid}, Ptr{StrArrayStruct}, Ptr{Cvoid}, Ptr{Cvoid}),
idx.ptr, collect(files), C_NULL, C_NULL)
end
function add!(repo::GitRepo, files::AbstractString...;
flags::Cuint = Consts.INDEX_ADD_DEFAULT)
with(GitIndex, repo) do idx
add!(idx, files..., flags = flags)
write!(idx)
end
return
end
function update!(repo::GitRepo, files::AbstractString...)
with(GitIndex, repo) do idx
update!(idx, files...)
write!(idx)
end
return
end
function remove!(repo::GitRepo, files::AbstractString...)
with(GitIndex, repo) do idx
remove!(idx, files...)
write!(idx)
end
return
end
function read!(repo::GitRepo, force::Bool = false)
with(GitIndex, repo) do idx
read!(idx, force)
end
return
end
function count(idx::GitIndex)
ensure_initialized()
return ccall((:git_index_entrycount, :libgit2), Csize_t, (Ptr{Cvoid},), idx.ptr)
end
function Base.getindex(idx::GitIndex, i::Integer)
ensure_initialized()
GC.@preserve idx begin
ie_ptr = ccall((:git_index_get_byindex, :libgit2),
Ptr{IndexEntry},
(Ptr{Cvoid}, Csize_t), idx.ptr, i-1)
ie_ptr == C_NULL && return nothing
elem = unsafe_load(ie_ptr)
end
return elem
end
function Base.findall(path::String, idx::GitIndex)
ensure_initialized()
pos_ref = Ref{Csize_t}(0)
ret = ccall((:git_index_find, :libgit2), Cint,
(Ref{Csize_t}, Ptr{Cvoid}, Cstring), pos_ref, idx.ptr, path)
ret == Cint(Error.ENOTFOUND) && return nothing
return pos_ref[]+1
end
"""
stage(ie::IndexEntry) -> Cint
Get the stage number of `ie`. The stage number `0` represents the current state
of the working tree, but other numbers can be used in the case of a merge conflict.
In such a case, the various stage numbers on an `IndexEntry` describe which side(s)
of the conflict the current state of the file belongs to. Stage `0` is the state
before the attempted merge, stage `1` is the changes which have been made locally,
stages `2` and larger are for changes from other branches (for instance, in the case
of a multi-branch "octopus" merge, stages `2`, `3`, and `4` might be used).
"""
function stage(ie::IndexEntry)
ensure_initialized()
return ccall((:git_index_entry_stage, :libgit2), Cint, (Ptr{IndexEntry},), Ref(ie))
end
function Base.show(io::IO, idx::GitIndex)
println(io, "GitIndex:\nRepository: ", repository(idx), "\nNumber of elements: ", count(idx))
end