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