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 */ 124 125 bool hasConflicts() 126 { 127 return git_index_has_conflicts(this.cHandle) != 0; 128 } 129 130 int conflictIterator(int delegate(GitIndexEntry ancestor, GitIndexEntry our, GitIndexEntry their) dg) 131 { 132 git_index_conflict_iterator* it; 133 require(git_index_conflict_iterator_new(&it, this.cHandle) == 0); 134 scope (exit) git_index_conflict_iterator_free(it); 135 while (true) { 136 const(git_index_entry)* ancestor, our, their; 137 auto ret = git_index_conflict_next(&ancestor, &our, &their, it); 138 if (ret == GIT_ITEROVER) break; 139 require(ret == 0); 140 ret = dg(GitIndexEntry(this, ancestor), GitIndexEntry(this, our), GitIndexEntry(this, their)); 141 if (ret) 142 return ret; 143 } 144 return 0; 145 } 146 147 /* 148 int git_index_conflict_iterator_new( 149 git_index_conflict_iterator **iterator_out, 150 git_index *index); 151 int git_index_conflict_next( 152 const(git_index_entry)** ancestor_out, 153 const(git_index_entry)** our_out, 154 const(git_index_entry)** their_out, 155 git_index_conflict_iterator *iterator); 156 void git_index_conflict_iterator_free( 157 git_index_conflict_iterator *iterator); 158 int git_index_entry_stage(const(git_index_entry)* entry);*/ 159 160 mixin RefCountedGitObject!(git_index, git_index_free); 161 private GitRepo _repo; 162 } 163 164 165 struct GitIndexEntry { 166 package this(GitIndex index, const(git_index_entry)* entry) 167 { 168 _index = index; 169 _entry = entry; 170 } 171 172 //@property SysTime ctime() const { return gitIndexTimeToSysTime(_entry.ctime); } 173 //@property SysTime mtime() const { return gitIndexTimeToSysTime(_entry.mtime); } 174 @property uint dev() const { return _entry.dev; } 175 @property uint ino() const { return _entry.ino; } 176 @property uint mode() const { return _entry.mode; } 177 @property uint uid() const { return _entry.uid; } 178 @property uint gid() const { return _entry.gid; } 179 @property ulong fileSize() const { return _entry.file_size; } 180 @property GitOid oid() const { return GitOid(_entry.oid); } 181 @property string path() const { return _entry.path.to!string; } 182 @property int stage() { return git_index_entry_stage(_entry); } 183 184 //ushort flags; 185 //ushort flags_extended; 186 187 package @property const(git_index_entry)* cHandle() const { return _entry; } 188 189 private const(git_index_entry)* _entry; 190 private GitIndex _index; 191 } 192 193 enum GitIndexCaps { 194 none = 0, 195 ignoreCase = GIT_INDEXCAP_IGNORE_CASE, 196 noFilemode = GIT_INDEXCAP_NO_FILEMODE, 197 noSymlinks = GIT_INDEXCAP_NO_SYMLINKS, 198 fromOwner = GIT_INDEXCAP_FROM_OWNER 199 } 200 201 /*struct git_index_time { 202 git_time_t seconds; 203 uint nanoseconds; 204 } 205 206 enum GIT_IDXENTRY_NAMEMASK = (0x0fff); 207 enum GIT_IDXENTRY_STAGEMASK = (0x3000); 208 enum GIT_IDXENTRY_EXTENDED = (0x4000); 209 enum GIT_IDXENTRY_VALID = (0x8000); 210 enum GIT_IDXENTRY_STAGESHIFT = 12; 211 212 auto GIT_IDXENTRY_STAGE(T)(T E) { return (((E).flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT); } 213 214 enum GIT_IDXENTRY_INTENT_TO_ADD = (1 << 13); 215 enum GIT_IDXENTRY_SKIP_WORKTREE = (1 << 14); 216 enum GIT_IDXENTRY_EXTENDED2 = (1 << 15); 217 enum GIT_IDXENTRY_EXTENDED_FLAGS = (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE); 218 219 enum GIT_IDXENTRY_UPDATE = (1 << 0); 220 enum GIT_IDXENTRY_REMOVE = (1 << 1); 221 enum GIT_IDXENTRY_UPTODATE = (1 << 2); 222 enum GIT_IDXENTRY_ADDED = (1 << 3); 223 224 enum GIT_IDXENTRY_HASHED = (1 << 4); 225 enum GIT_IDXENTRY_UNHASHED = (1 << 5); 226 enum GIT_IDXENTRY_WT_REMOVE = (1 << 6); 227 enum GIT_IDXENTRY_CONFLICTED = (1 << 7); 228 229 enum GIT_IDXENTRY_UNPACKED = (1 << 8); 230 enum GIT_IDXENTRY_NEW_SKIP_WORKTREE = (1 << 9); 231 232 233 alias git_index_matched_path_cb = int function( 234 const(char)* path, const(char)* matched_pathspec, void *payload); 235 236 enum git_index_add_option_t { 237 GIT_INDEX_ADD_DEFAULT = 0, 238 GIT_INDEX_ADD_FORCE = (1u << 0), 239 GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH = (1u << 1), 240 GIT_INDEX_ADD_CHECK_PATHSPEC = (1u << 2), 241 } 242 243 enum GIT_INDEX_STAGE_ANY = -1; 244 */