1 /* 2 * Copyright David Nadlinger 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.checkout; 8 9 // Note: This file includes none of the original comments, as they might 10 // be copyrightable material. 11 12 import git.object_; 13 import git.repository; 14 import git.tree; 15 import git.util; 16 17 import deimos.git2.checkout; 18 import deimos.git2.common; 19 import deimos.git2.diff; 20 import deimos.git2.strarray; 21 import deimos.git2.types; 22 import deimos.git2.util; 23 24 /// 25 enum GitCheckoutStrategy 26 { 27 /// 28 none = GIT_CHECKOUT_NONE, 29 30 /// 31 safe = GIT_CHECKOUT_SAFE, 32 33 /// 34 safeCreate = GIT_CHECKOUT_SAFE_CREATE, 35 36 /// 37 force = GIT_CHECKOUT_FORCE, 38 39 /// 40 allowConflicts = GIT_CHECKOUT_ALLOW_CONFLICTS, 41 42 /// 43 removeUntracked = GIT_CHECKOUT_REMOVE_UNTRACKED, 44 45 /// 46 removeIgnored = GIT_CHECKOUT_REMOVE_IGNORED, 47 48 /// 49 updateOnly = GIT_CHECKOUT_UPDATE_ONLY, 50 51 /// 52 dontUpdateIndex = GIT_CHECKOUT_DONT_UPDATE_INDEX, 53 54 /// 55 noRefresh = GIT_CHECKOUT_NO_REFRESH, 56 57 /// 58 disablePathspecMatch = GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH, 59 60 /// 61 skipLockedDirs = GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES, 62 63 /// Not implemented yet! 64 skipUnmerged = GIT_CHECKOUT_SKIP_UNMERGED, 65 66 /// ditto 67 useOurs = GIT_CHECKOUT_USE_OURS, 68 69 /// ditto 70 useTheirs = GIT_CHECKOUT_USE_THEIRS, 71 72 /// ditto 73 updateSubmods = GIT_CHECKOUT_UPDATE_SUBMODULES, 74 75 /// ditto 76 updateSubmodsIfChanged = GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED, 77 } 78 79 /// 80 enum GitCheckoutNotify 81 { 82 /// 83 none = GIT_CHECKOUT_NOTIFY_NONE, 84 85 /// 86 conflict = GIT_CHECKOUT_NOTIFY_CONFLICT, 87 88 /// 89 dirty = GIT_CHECKOUT_NOTIFY_DIRTY, 90 91 /// 92 updated = GIT_CHECKOUT_NOTIFY_UPDATED, 93 94 /// 95 untracked = GIT_CHECKOUT_NOTIFY_UNTRACKED, 96 97 /// 98 notify_ignored = GIT_CHECKOUT_NOTIFY_IGNORED, 99 100 /// 101 notify_all = GIT_CHECKOUT_NOTIFY_ALL, 102 } 103 104 alias GitCheckoutNotifyDelegate = void delegate( 105 GitCheckoutNotify why, 106 const(char)[] path, 107 const(git_diff_file)* baseline, 108 const(git_diff_file)* target, 109 const(git_diff_file)* workdir); 110 111 extern(C) int cCheckoutNotifyCallback( 112 git_checkout_notify_t why, 113 const(char)* path, 114 const(git_diff_file)* baseline, 115 const(git_diff_file)* target, 116 const(git_diff_file)* workdir, 117 void *payload) 118 { 119 auto dg = (cast(GitCheckoutOptions*)payload).notifyCallback; 120 dg(cast(GitCheckoutNotify)why, toSlice(path), baseline, target, workdir); 121 return 0; // TODO: What does this return value indicate? 122 } 123 124 alias GitCheckoutProgressDelegate = void delegate( 125 const(char)[] path, 126 size_t completed_steps, 127 size_t total_steps 128 ); 129 130 extern(C) void cCheckoutProgressCallback( 131 const(char)* path, 132 size_t completed_steps, 133 size_t total_steps, 134 void *payload) 135 { 136 auto dg = (cast(GitCheckoutOptions*)payload).progressCallback; 137 dg(toSlice(path), completed_steps, total_steps); 138 } 139 140 struct GitCheckoutOptions 141 { 142 uint version_ = git_checkout_opts.init.version_; 143 144 GitCheckoutStrategy strategy; 145 146 int disableFilters; 147 uint dirMode; 148 uint fileMode; 149 int fileOpenFlags; 150 151 uint notifyFlags; 152 153 GitCheckoutNotifyDelegate notifyCallback; 154 GitCheckoutProgressDelegate progressCallback; 155 156 git_strarray paths; // TODO: Translate. 157 git_tree* baseline; // TODO: Translate. 158 159 string targetDir; 160 } 161 162 package void toCCheckoutOpts(ref GitCheckoutOptions dOpts, ref git_checkout_opts cOpts) 163 { 164 with (dOpts) 165 { 166 cOpts.version_ = version_; 167 cOpts.checkout_strategy = cast(uint)strategy; 168 cOpts.disable_filters = disableFilters; 169 cOpts.dir_mode = fileMode; 170 cOpts.file_mode = fileMode; 171 cOpts.file_open_flags = fileOpenFlags; 172 cOpts.notify_flags = notifyFlags; 173 if (notifyCallback) 174 { 175 cOpts.notify_cb = &cCheckoutNotifyCallback; 176 cOpts.notify_payload = cast(void*)&dOpts; 177 } 178 if (progressCallback) 179 { 180 cOpts.progress_cb = &cCheckoutProgressCallback; 181 cOpts.progress_payload = cast(void*)&dOpts; 182 } 183 cOpts.paths = paths; 184 cOpts.baseline = baseline; 185 cOpts.target_directory = targetDir.gitStr; 186 } 187 } 188 189 void checkoutHead(GitRepo repo, GitCheckoutOptions opts = GitCheckoutOptions.init) 190 { 191 git_checkout_opts cOpts; 192 opts.toCCheckoutOpts(cOpts); 193 require(git_checkout_head(repo.cHandle, &cOpts) == 0); 194 } 195 196 void checkout(GitRepo repo, git_index* index, GitCheckoutOptions opts = GitCheckoutOptions.init) // TODO: Convert. 197 { 198 git_checkout_opts cOpts; 199 opts.toCCheckoutOpts(cOpts); 200 require(git_checkout_index(repo.cHandle, index, &cOpts) == 0); 201 } 202 203 void checkout(GitRepo repo, GitObject treeish, GitCheckoutOptions opts = GitCheckoutOptions.init) 204 { 205 git_checkout_opts cOpts; 206 opts.toCCheckoutOpts(cOpts); 207 require(git_checkout_tree(repo.cHandle, treeish.cHandle, &cOpts) == 0); 208 } 209 210 void checkout(GitRepo repo, GitTree treeish, GitCheckoutOptions opts = GitCheckoutOptions.init) 211 { 212 git_checkout_opts cOpts; 213 opts.toCCheckoutOpts(cOpts); 214 require(git_checkout_tree(repo.cHandle, cast(git_object*)treeish.cHandle, &cOpts) == 0); 215 }