1 /* 2 * libgit2 "add" example - shows how to modify the index 3 * 4 * Written by the libgit2 contributors 5 * 6 * To the extent possible under law, the author(s) have dedicated all copyright 7 * and related and neighboring rights to this software to the public domain 8 * worldwide. This software is distributed without any warranty. 9 * 10 * You should have received a copy of the CC0 Public Domain Dedication along 11 * with this software. If not, see 12 * <http://creativecommons.org/publicdomain/zero/1.0/>. 13 */ 14 module libgit2_d.example.add; 15 16 17 private static import core.stdc.stdio; 18 private static import core.stdc.stdlib; 19 private static import core.stdc.string; 20 private static import libgit2_d.example.args; 21 private static import libgit2_d.example.common; 22 private static import libgit2_d.index; 23 private static import libgit2_d.repository; 24 private static import libgit2_d.status; 25 private static import libgit2_d.strarray; 26 private static import libgit2_d.types; 27 28 package: 29 30 /** 31 * The following example demonstrates how to add files with libgit2. 32 * 33 * It will use the repository in the current working directory, and act 34 * on files passed as its parameters. 35 * 36 * Recognized options are: 37 * -v/--verbose: show the file's status after acting on it. 38 * -n/--dry-run: do not actually change the index. 39 * -u/--update: update the index instead of adding to it. 40 */ 41 42 public enum index_mode 43 { 44 INDEX_NONE, 45 INDEX_ADD, 46 } 47 48 public struct index_options 49 { 50 int dry_run; 51 int verbose; 52 libgit2_d.types.git_repository* repo; 53 .index_mode mode; 54 int add_update; 55 } 56 57 /* Forward declarations for helpers */ 58 //private void parse_opts(int* options, int* count, int argc, char*[] argv); 59 //void init_array(libgit2_d.strarray.git_strarray* array, int argc, char** argv); 60 //int print_matched_cb(const (char)* path, const (char)* matched_pathspec, void* payload); 61 62 extern (C) 63 nothrow @nogc 64 public int lg2_add(libgit2_d.types.git_repository* repo, int argc, char** argv) 65 66 in 67 { 68 } 69 70 do 71 { 72 libgit2_d.example.args.args_info args = libgit2_d.example.args.ARGS_INFO_INIT(argc, argv); 73 74 /* Parse the options & arguments. */ 75 .index_options options; 76 .parse_opts(null, &options, &args); 77 78 libgit2_d.strarray.git_strarray array = libgit2_d.strarray.git_strarray.init; 79 libgit2_d.example.args.strarray_from_args(&array, &args); 80 81 /* Grab the repository's index. */ 82 libgit2_d.types.git_index* index; 83 libgit2_d.example.common.check_lg2(libgit2_d.repository.git_repository_index(&index, repo), "Could not open repository index", null); 84 85 libgit2_d.index.git_index_matched_path_cb matched_cb = null; 86 87 /* Setup a callback if the requested options need it */ 88 if ((options.verbose) || (options.dry_run)) { 89 matched_cb = &.print_matched_cb; 90 } 91 92 options.repo = repo; 93 94 if (options.add_update) { 95 libgit2_d.index.git_index_update_all(index, &array, matched_cb, &options); 96 } else { 97 libgit2_d.index.git_index_add_all(index, &array, 0, matched_cb, &options); 98 } 99 100 /* Cleanup memory */ 101 libgit2_d.index.git_index_write(index); 102 libgit2_d.index.git_index_free(index); 103 104 return 0; 105 } 106 107 /* 108 * This callback is called for each file under consideration by 109 * git_index_(update|add)_all above. 110 * It makes uses of the callback's ability to abort the action. 111 */ 112 extern (C) 113 nothrow @nogc 114 public int print_matched_cb(const (char)* path, const (char)* matched_pathspec, void* payload) 115 116 in 117 { 118 } 119 120 do 121 { 122 .index_options opts = *cast(.index_options*)(payload); 123 uint status; 124 //cast(void)(matched_pathspec); 125 126 /* Get the file status */ 127 if (libgit2_d.status.git_status_file(&status, opts.repo, path) < 0) { 128 return -1; 129 } 130 131 int ret; 132 133 if ((status & libgit2_d.status.git_status_t.GIT_STATUS_WT_MODIFIED) || (status & libgit2_d.status.git_status_t.GIT_STATUS_WT_NEW)) { 134 core.stdc.stdio.printf("add '%s'\n", path); 135 ret = 0; 136 } else { 137 ret = 1; 138 } 139 140 if (opts.dry_run) { 141 ret = 1; 142 } 143 144 return ret; 145 } 146 147 nothrow @nogc 148 public void init_array(libgit2_d.strarray.git_strarray* array, int argc, char** argv) 149 150 in 151 { 152 } 153 154 do 155 { 156 array.count = argc; 157 array.strings = cast(char**)(core.stdc.stdlib.calloc(array.count, (char*).sizeof)); 158 assert(array.strings != null); 159 160 for (uint i = 0; i < array.count; i++) { 161 array.strings[i] = argv[i]; 162 } 163 164 return; 165 } 166 167 nothrow @nogc 168 public void print_usage() 169 170 in 171 { 172 } 173 174 do 175 { 176 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "usage: add [options] [--] file-spec [file-spec] [...]\n\n"); 177 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "\t-n, --dry-run dry run\n"); 178 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "\t-v, --verbose be verbose\n"); 179 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "\t-u, --update update tracked files\n"); 180 core.stdc.stdlib.exit(1); 181 } 182 183 nothrow @nogc 184 private void parse_opts(const (char)** repo_path, .index_options* opts, libgit2_d.example.args.args_info* args) 185 186 in 187 { 188 } 189 190 do 191 { 192 if (args.argc <= 1) { 193 .print_usage(); 194 } 195 196 for (args.pos = 1; args.pos < args.argc; ++args.pos) { 197 const (char)* curr = args.argv[args.pos]; 198 199 if (curr[0] != '-') { 200 if (!core.stdc..string.strcmp("add", curr)) { 201 opts.mode = .index_mode.INDEX_ADD; 202 203 continue; 204 } else if (opts.mode == .index_mode.INDEX_NONE) { 205 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "missing command: %s", curr); 206 .print_usage(); 207 208 break; 209 } else { 210 /* We might be looking at a filename */ 211 break; 212 } 213 } else if ((libgit2_d.example.args.match_bool_arg(&opts.verbose, args, "--verbose")) || (libgit2_d.example.args.match_bool_arg(&opts.dry_run, args, "--dry-run")) || (libgit2_d.example.args.match_str_arg(repo_path, args, "--git-dir")) || ((opts.mode == .index_mode.INDEX_ADD) && (libgit2_d.example.args.match_bool_arg(&opts.add_update, args, "--update")))) { 214 continue; 215 } else if (libgit2_d.example.args.match_bool_arg(null, args, "--help")) { 216 .print_usage(); 217 218 break; 219 } else if (libgit2_d.example.args.match_arg_separator(args)) { 220 break; 221 } else { 222 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "Unsupported option %s.\n", curr); 223 .print_usage(); 224 } 225 } 226 }