1 /* 2 * libgit2 "rev-list" example - shows how to transform a rev-spec into a list 3 * of commit ids 4 * 5 * Written by the libgit2 contributors 6 * 7 * To the extent possible under law, the author(s) have dedicated all copyright 8 * and related and neighboring rights to this software to the public domain 9 * worldwide. This software is distributed without any warranty. 10 * 11 * You should have received a copy of the CC0 Public Domain Dedication along 12 * with this software. If not, see 13 * <http://creativecommons.org/publicdomain/zero/1.0/>. 14 */ 15 module libgit2_d.example.rev_list; 16 17 18 private static import core.stdc.stdio; 19 private static import core.stdc.stdlib; 20 private static import core.stdc.string; 21 private static import libgit2_d.errors; 22 private static import libgit2_d.example.args; 23 private static import libgit2_d.example.common; 24 private static import libgit2_d.object; 25 private static import libgit2_d.oid; 26 private static import libgit2_d.revparse; 27 private static import libgit2_d.revwalk; 28 private static import libgit2_d.types; 29 30 package: 31 32 //private int revwalk_parseopts(libgit2_d.types.git_repository* repo, libgit2_d.types.git_revwalk* walk, int nopts, char** opts); 33 34 extern (C) 35 nothrow @nogc 36 public int lg2_rev_list(libgit2_d.types.git_repository* repo, int argc, char** argv) 37 38 in 39 { 40 } 41 42 do 43 { 44 libgit2_d.example.args.args_info args = libgit2_d.example.args.ARGS_INFO_INIT(argc, argv); 45 libgit2_d.types.git_revwalk* walk; 46 libgit2_d.revwalk.git_sort_t sort; 47 48 libgit2_d.example.common.check_lg2(.revwalk_parse_options(&sort, &args), "parsing options", null); 49 50 libgit2_d.example.common.check_lg2(libgit2_d.revwalk.git_revwalk_new(&walk, repo), "allocating revwalk", null); 51 libgit2_d.revwalk.git_revwalk_sorting(walk, sort); 52 libgit2_d.example.common.check_lg2(.revwalk_parse_revs(repo, walk, &args), "parsing revs", null); 53 54 libgit2_d.oid.git_oid oid; 55 char[libgit2_d.oid.GIT_OID_HEXSZ + 1] buf; 56 57 while (!libgit2_d.revwalk.git_revwalk_next(&oid, walk)) { 58 libgit2_d.oid.git_oid_fmt(&(buf[0]), &oid); 59 buf[libgit2_d.oid.GIT_OID_HEXSZ] = '\0'; 60 core.stdc.stdio.printf("%s\n", &(buf[0])); 61 } 62 63 libgit2_d.revwalk.git_revwalk_free(walk); 64 65 return 0; 66 } 67 68 nothrow @nogc 69 private int push_commit(libgit2_d.types.git_revwalk* walk, const (libgit2_d.oid.git_oid)* oid, int hide) 70 71 in 72 { 73 } 74 75 do 76 { 77 if (hide) { 78 return libgit2_d.revwalk.git_revwalk_hide(walk, oid); 79 } else { 80 return libgit2_d.revwalk.git_revwalk_push(walk, oid); 81 } 82 } 83 84 nothrow @nogc 85 private int push_spec(libgit2_d.types.git_repository* repo, libgit2_d.types.git_revwalk* walk, const (char)* spec, int hide) 86 87 in 88 { 89 } 90 91 do 92 { 93 libgit2_d.types.git_object* obj; 94 int error = libgit2_d.revparse.git_revparse_single(&obj, repo, spec); 95 96 if (error < 0) { 97 return error; 98 } 99 100 error = .push_commit(walk, libgit2_d.object.git_object_id(obj), hide); 101 libgit2_d.object.git_object_free(obj); 102 103 return error; 104 } 105 106 nothrow @nogc 107 private int push_range(libgit2_d.types.git_repository* repo, libgit2_d.types.git_revwalk* walk, const (char)* range, int hide) 108 109 in 110 { 111 } 112 113 do 114 { 115 libgit2_d.revparse.git_revspec revspec; 116 int error = libgit2_d.revparse.git_revparse(&revspec, repo, range); 117 118 if (error) { 119 return error; 120 } 121 122 scope (exit) { 123 libgit2_d.object.git_object_free(revspec.from); 124 libgit2_d.object.git_object_free(revspec.to); 125 } 126 127 if (revspec.flags & libgit2_d.revparse.git_revparse_mode_t.GIT_REVPARSE_MERGE_BASE) { 128 /* TODO: support "<commit>...<commit>" */ 129 return libgit2_d.errors.git_error_code.GIT_EINVALIDSPEC; 130 } 131 132 error = .push_commit(walk, libgit2_d.object.git_object_id(revspec.from), !hide); 133 134 if (error) { 135 return error; 136 } 137 138 error = .push_commit(walk, libgit2_d.object.git_object_id(revspec.to), hide); 139 140 return error; 141 } 142 143 nothrow @nogc 144 private void print_usage() 145 146 do 147 { 148 core.stdc.stdio.fprintf(core.stdc.stdio.stderr, "rev-list [--git-dir=dir] [--topo-order|--date-order] [--reverse] <revspec>\n"); 149 core.stdc.stdlib.exit(-1); 150 } 151 152 nothrow @nogc 153 private int revwalk_parse_options(libgit2_d.revwalk.git_sort_t* sort, libgit2_d.example.args.args_info* args) 154 155 in 156 { 157 assert((sort) && (args)); 158 } 159 160 do 161 { 162 *sort = libgit2_d.revwalk.git_sort_t.GIT_SORT_NONE; 163 164 if (args.argc < 1) { 165 .print_usage(); 166 } 167 168 for (args.pos = 1; args.pos < args.argc; ++args.pos) { 169 const (char)* curr = args.argv[args.pos]; 170 171 if (!core.stdc..string.strcmp(curr, "--topo-order")) { 172 *sort |= libgit2_d.revwalk.git_sort_t.GIT_SORT_TOPOLOGICAL; 173 } else if (!core.stdc..string.strcmp(curr, "--date-order")) { 174 *sort |= libgit2_d.revwalk.git_sort_t.GIT_SORT_TIME; 175 } else if (!core.stdc..string.strcmp(curr, "--reverse")) { 176 *sort |= (*sort & ~libgit2_d.revwalk.git_sort_t.GIT_SORT_REVERSE) ^ libgit2_d.revwalk.git_sort_t.GIT_SORT_REVERSE; 177 } else { 178 break; 179 } 180 } 181 182 return 0; 183 } 184 185 nothrow @nogc 186 private int revwalk_parse_revs(libgit2_d.types.git_repository* repo, libgit2_d.types.git_revwalk* walk, libgit2_d.example.args.args_info* args) 187 188 in 189 { 190 } 191 192 do 193 { 194 int hide = 0; 195 int error; 196 libgit2_d.oid.git_oid oid; 197 198 for (; args.pos < args.argc; ++args.pos) { 199 const (char)* curr = args.argv[args.pos]; 200 201 if (!core.stdc..string.strcmp(curr, "--not")) { 202 hide = !hide; 203 } else if (curr[0] == '^') { 204 error = .push_spec(repo, walk, curr + 1, !hide); 205 206 if (error) { 207 return error; 208 } 209 } else if (core.stdc..string.strstr(curr, "..")) { 210 error = .push_range(repo, walk, curr, hide); 211 212 if (error) { 213 return error; 214 } 215 } else { 216 if (.push_spec(repo, walk, curr, hide) == 0) { 217 continue; 218 } 219 220 error = libgit2_d.oid.git_oid_fromstr(&oid, curr); 221 222 if (error) { 223 return error; 224 } 225 226 error = .push_commit(walk, &oid, hide); 227 228 if (error) { 229 return error; 230 } 231 } 232 } 233 234 return 0; 235 }