1 /* 2 * libgit2 "ls-files" example - shows how to view all files currently in 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 * This example demonstrates the libgit2 index APIs to roughly 16 * simulate the output of `git ls-files`. 17 * `git ls-files` has many options and this currently does not show them. 18 * 19 * `git ls-files` base command shows all paths in the index at that time. 20 * This includes staged and committed files, but unstaged files will not display. 21 * 22 * This currently supports the default behavior and the `--error-unmatch` option. 23 * 24 * License: $(LINK2 https://creativecommons.org/publicdomain/zero/1.0/, CC0 1.0 Universal) 25 */ 26 module libgit2.example.ls_files; 27 28 29 private static import core.stdc.stdio; 30 private static import core.stdc.stdlib; 31 private static import core.stdc.string; 32 private static import libgit2.index; 33 private static import libgit2.repository; 34 private static import libgit2.types; 35 36 extern (C) 37 public struct ls_options 38 { 39 int error_unmatch; 40 char*[1024] files; 41 size_t file_count; 42 } 43 44 nothrow @nogc 45 private void usage(const (char)* message, const (char)* arg) 46 47 in 48 { 49 } 50 51 do 52 { 53 if ((message != null) && (arg != null)) { 54 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "%s: %s\n", message, arg); 55 } else if (message != null) { 56 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "%s\n", message); 57 } 58 59 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "usage: ls-files [--error-unmatch] [--] [<file>...]\n"); 60 core.stdc.stdlib.exit(1); 61 } 62 63 nothrow @nogc 64 private int parse_options(.ls_options* opts, int argc, char** argv) 65 66 in 67 { 68 } 69 70 do 71 { 72 core.stdc..string.memset(opts, 0, .ls_options.sizeof); 73 74 if (argc < 2) { 75 return 0; 76 } 77 78 int parsing_files = 0; 79 80 for (int i = 1; i < argc; ++i) { 81 char* a = argv[i]; 82 83 /* if it doesn't start with a '-' or is after the '--' then it is a file */ 84 if ((a[0] != '-') || (parsing_files)) { 85 parsing_files = 1; 86 87 /* watch for overflows (just in case) */ 88 if (opts.file_count == 1024) { 89 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "ls-files can only support 1024 files at this time.\n"); 90 91 return -1; 92 } 93 94 opts.files[opts.file_count++] = a; 95 } else if (!core.stdc..string.strcmp(a, "--")) { 96 parsing_files = 1; 97 } else if (!core.stdc..string.strcmp(a, "--error-unmatch")) { 98 opts.error_unmatch = 1; 99 } else { 100 .usage("Unsupported argument", a); 101 102 return -1; 103 } 104 } 105 106 return 0; 107 } 108 109 nothrow @nogc 110 private int print_paths(.ls_options* opts, libgit2.types.git_index* index) 111 112 in 113 { 114 } 115 116 do 117 { 118 const (libgit2.index.git_index_entry)* entry; 119 120 /* if there are no files explicitly listed by the user print all entries in the index */ 121 if (opts.file_count == 0) { 122 size_t entry_count = libgit2.index.git_index_entrycount(index); 123 124 for (size_t i = 0; i < entry_count; i++) { 125 entry = libgit2.index.git_index_get_byindex(index, i); 126 core.stdc.stdio.puts(entry.path); 127 } 128 129 return 0; 130 } 131 132 /* loop through the files found in the args and print them if they exist */ 133 for (size_t i = 0; i < opts.file_count; ++i) { 134 const (char)* path = opts.files[i]; 135 entry = libgit2.index.git_index_get_bypath(index, path, libgit2.index.git_index_stage_t.GIT_INDEX_STAGE_NORMAL); 136 137 if (entry != null) { 138 core.stdc.stdio.puts(path); 139 } else if (opts.error_unmatch) { 140 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "error: pathspec '%s' did not match any file(s) known to git.\n", path); 141 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "Did you forget to 'git add'?\n"); 142 143 return -1; 144 } 145 } 146 147 return 0; 148 } 149 150 extern (C) 151 nothrow @nogc 152 public int lg2_ls_files(libgit2.types.git_repository* repo, int argc, char** argv) 153 154 in 155 { 156 } 157 158 do 159 { 160 .ls_options opts; 161 int error = .parse_options(&opts, argc, argv); 162 163 if (error < 0) { 164 return error; 165 } 166 167 libgit2.types.git_index* index = null; 168 169 scope (exit) { 170 libgit2.index.git_index_free(index); 171 } 172 173 error = libgit2.repository.git_repository_index(&index, repo); 174 175 if (error < 0) { 176 return error; 177 } 178 179 error = .print_paths(&opts, index); 180 181 return error; 182 }