1 /*
2  *             Copyright Sönke Ludwig 2014.
3  *  Distributed under the Boost Software License, Version 1.0.
4  *     (See accompanying file LICENSE_1_0.txt or copy at
5  *           http://www.boost.org/LICENSE_1_0.txt)
6  */
7 module git.index;
8 
9 import git.commit;
10 import git.oid;
11 import git.tree;
12 import git.repository;
13 import git.types;
14 import git.util;
15 import git.version_;
16 
17 import deimos.git2.index;
18 import deimos.git2.errors;
19 import deimos.git2.types;
20 
21 import std.conv : to;
22 import std.string : toStringz;
23 
24 
25 GitIndex openIndex(string index_path)
26 {
27 	git_index* dst;
28 	require(git_index_open(&dst, index_path.toStringz) == 0);
29 	return GitIndex(dst);
30 }
31 
32 GitIndex createIndex()
33 {
34 	git_index* dst;
35 	require(git_index_new(&dst) == 0);
36 	return GitIndex(dst);
37 }
38 
39 struct GitIndex {
40 	this(git_index* index)
41 	{
42 		_repo = GitRepo.init;
43 		_data = Data(index);
44 	}
45 
46 	this(GitRepo repo, git_index* index)
47 	{
48 		_repo = repo;
49 		_data = Data(index);
50 	}
51 
52 	@property inout(GitRepo) owner() inout { return _repo; }
53 
54 	@property GitIndexCaps caps() { return cast(GitIndexCaps)git_index_caps(this.cHandle); }
55 	@property void caps(GitIndexCaps caps) { require(git_index_set_caps(this.cHandle, caps) == 0); }
56 
57 	static if (targetLibGitVersion >= VersionInfo(0, 20, 0))
58 		@property string path() { return git_index_path(this.cHandle).to!string; }
59 
60 	@property size_t entryCount() { return git_index_entrycount(this.cHandle); }
61 
62 	static if (targetLibGitVersion >= VersionInfo(0, 20, 0))
63 		void read(bool force) { require(git_index_read(this.cHandle, force) == 0); }
64 	else void read() { require(git_index_read(this.cHandle) == 0); }
65 	void write() { require(git_index_write(this.cHandle) == 0); }
66 
67 	void readTree(in GitTree tree) { require(git_index_read_tree(this.cHandle, tree.cHandle) == 0); }
68 	GitOid writeTree()
69 	{
70 		GitOid ret;
71 		require(git_index_write_tree(&ret._get_oid(), this.cHandle) == 0);
72 		return ret;
73 	}
74 	GitOid writeTree(GitRepo repo)
75 	{
76 		GitOid ret;
77 		require(git_index_write_tree_to(&ret._get_oid(), this.cHandle, repo.cHandle) == 0);
78 		return ret;
79 	}
80 
81 	void clear() { git_index_clear(this.cHandle); }
82 
83 	GitIndexEntry get(size_t n) { return GitIndexEntry(this, git_index_get_byindex(this.cHandle, n)); }
84 	GitIndexEntry get(string path, int stage) { return GitIndexEntry(this, git_index_get_bypath(this.cHandle, path.toStringz, stage)); }
85 
86 	void remove(string path, int stage) { require(git_index_remove(this.cHandle, path.toStringz, stage) == 0); }
87 	void removeDirectory(string dir, int stage) { require(git_index_remove_directory(this.cHandle, dir.toStringz, stage) == 0); }
88 	void add(GitIndexEntry source_entry) { require(git_index_add(this.cHandle, source_entry.cHandle) == 0); }
89 	void addByPath(string path) { require(git_index_add_bypath(this.cHandle, path.toStringz) == 0); }
90 	void removeByPath(string path) { require(git_index_remove_bypath(this.cHandle, path.toStringz) == 0); }
91 
92 /*
93 int git_index_add_all(
94 	git_index *index,
95 	const(git_strarray)* pathspec,
96 	uint flags,
97 	git_index_matched_path_cb callback,
98 	void *payload);
99 int git_index_remove_all(
100 	git_index *index,
101 	const(git_strarray)* pathspec,
102 	git_index_matched_path_cb callback,
103 	void *payload);
104 int git_index_update_all(
105 	git_index *index,
106 	const(git_strarray)* pathspec,
107 	git_index_matched_path_cb callback,
108 	void *payload);
109 int git_index_find(size_t *at_pos, git_index *index, const(char)* path);
110 int git_index_conflict_add(
111 	git_index *index,
112 	const(git_index_entry)* ancestor_entry,
113 	const(git_index_entry)* our_entry,
114 	const(git_index_entry)* their_entry);
115 int git_index_conflict_get(
116 	const(git_index_entry)** ancestor_out,
117 	const(git_index_entry)** our_out,
118 	const(git_index_entry)** their_out,
119 	git_index *index,
120 	const(char)* path);
121 int git_index_conflict_remove(git_index *index, const(char)* path);
122 void git_index_conflict_cleanup(git_index *index);
123 int git_index_has_conflicts(const(git_index)* index);
124 int git_index_conflict_iterator_new(
125 	git_index_conflict_iterator **iterator_out,
126 	git_index *index);
127 int git_index_conflict_next(
128 	const(git_index_entry)** ancestor_out,
129 	const(git_index_entry)** our_out,
130 	const(git_index_entry)** their_out,
131 	git_index_conflict_iterator *iterator);
132 void git_index_conflict_iterator_free(
133 	git_index_conflict_iterator *iterator);
134 int git_index_entry_stage(const(git_index_entry)* entry);*/
135 
136 	mixin RefCountedGitObject!(git_index, git_index_free);
137 	private GitRepo _repo;
138 }
139 
140 struct GitIndexEntry {
141 	package this(GitIndex index, const(git_index_entry)* entry)
142 	{
143 		_index = index;
144 		_entry = entry;
145 	}
146 
147 	//@property SysTime ctime() const { return gitIndexTimeToSysTime(_entry.ctime); }
148 	//@property SysTime mtime() const { return gitIndexTimeToSysTime(_entry.mtime); }
149 	@property uint dev() const { return _entry.dev; }
150 	@property uint ino() const { return _entry.ino; }
151 	@property uint mode() const { return _entry.mode; }
152 	@property uint uid() const { return _entry.uid; }
153 	@property uint gid() const { return _entry.gid; }
154 	@property ulong fileSize() const { return _entry.file_size; }
155 	@property GitOid oid() const { return GitOid(_entry.oid); }
156 	@property string path() const { return _entry.path.to!string; }
157 	@property int stage() { return git_index_entry_stage(_entry); }
158 
159 	//ushort flags;
160 	//ushort flags_extended;
161 
162 	package @property const(git_index_entry)* cHandle() const { return _entry; }
163 
164 	private const(git_index_entry)* _entry;
165 	private GitIndex _index;
166 }
167 
168 enum GitIndexCaps {
169 	none = 0,
170 	ignoreCase = GIT_INDEXCAP_IGNORE_CASE,
171 	noFilemode = GIT_INDEXCAP_NO_FILEMODE,
172 	noSymlinks = GIT_INDEXCAP_NO_SYMLINKS,
173 	fromOwner = GIT_INDEXCAP_FROM_OWNER
174 }
175 
176 /*struct git_index_time {
177 	git_time_t seconds;
178 	uint nanoseconds;
179 }
180 
181 enum GIT_IDXENTRY_NAMEMASK   = (0x0fff);
182 enum GIT_IDXENTRY_STAGEMASK  = (0x3000);
183 enum GIT_IDXENTRY_EXTENDED   = (0x4000);
184 enum GIT_IDXENTRY_VALID      = (0x8000);
185 enum GIT_IDXENTRY_STAGESHIFT = 12;
186 
187 auto GIT_IDXENTRY_STAGE(T)(T E) { return (((E).flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT); }
188 
189 enum GIT_IDXENTRY_INTENT_TO_ADD     = (1 << 13);
190 enum GIT_IDXENTRY_SKIP_WORKTREE     = (1 << 14);
191 enum GIT_IDXENTRY_EXTENDED2         = (1 << 15);
192 enum GIT_IDXENTRY_EXTENDED_FLAGS = (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE);
193 
194 enum GIT_IDXENTRY_UPDATE            = (1 << 0);
195 enum GIT_IDXENTRY_REMOVE            = (1 << 1);
196 enum GIT_IDXENTRY_UPTODATE          = (1 << 2);
197 enum GIT_IDXENTRY_ADDED             = (1 << 3);
198 
199 enum GIT_IDXENTRY_HASHED            = (1 << 4);
200 enum GIT_IDXENTRY_UNHASHED          = (1 << 5);
201 enum GIT_IDXENTRY_WT_REMOVE         = (1 << 6);
202 enum GIT_IDXENTRY_CONFLICTED        = (1 << 7);
203 
204 enum GIT_IDXENTRY_UNPACKED          = (1 << 8);
205 enum GIT_IDXENTRY_NEW_SKIP_WORKTREE = (1 << 9);
206 
207 
208 alias git_index_matched_path_cb = int function(
209 	const(char)* path, const(char)* matched_pathspec, void *payload);
210 
211 enum git_index_add_option_t {
212 	GIT_INDEX_ADD_DEFAULT = 0,
213 	GIT_INDEX_ADD_FORCE = (1u << 0),
214 	GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH = (1u << 1),
215 	GIT_INDEX_ADD_CHECK_PATHSPEC = (1u << 2),
216 }
217 
218 enum GIT_INDEX_STAGE_ANY = -1;
219 */