|
1 | | -#include <common.h> |
| 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 | + * <http://creativecommons.org/publicdomain/zero/1.0/>. |
| 13 | + */ |
2 | 14 |
|
3 | | -typedef struct ls_files_state { |
| 15 | +#include "common.h" |
| 16 | + |
| 17 | +/** |
| 18 | + * This example demonstrates the libgit2 index APIs to roughly |
| 19 | + * simulate the output of `git ls-files`. |
| 20 | + * `git ls-files` has many options and this currently does not show them. |
| 21 | + * |
| 22 | + * `git ls-files` base command shows all paths in the index at that time. |
| 23 | + * This includes staged and committed files, but unstaged files will not display. |
| 24 | + */ |
| 25 | + |
| 26 | +#define MAX_FILES 64 |
| 27 | + |
| 28 | +typedef struct ls_options { |
| 29 | + int error_unmatch; |
| 30 | + char *files[MAX_FILES]; |
| 31 | + int file_count; |
| 32 | +} ls_options; |
| 33 | + |
| 34 | +void parse_options(ls_options *opts, int argc, char *argv[]); |
| 35 | + |
| 36 | +int main(int argc, char *argv[]) { |
| 37 | + ls_options opts; |
4 | 38 | git_repository *repo; |
5 | 39 | git_index *index; |
6 | | - char **files; |
7 | | - size_t num_entries; |
8 | | -} ls_files; |
9 | | - |
10 | | -void create_ls_files(ls_files **ls); |
| 40 | + const git_index_entry *entry; |
| 41 | + size_t entry_count; |
| 42 | + size_t i = 0; |
| 43 | + int error; |
11 | 44 |
|
12 | | -int main(int argc, char[] *argv) { |
13 | | - ls_files *ls; |
14 | | - git_index_entry *entry; |
15 | | - size_t i; |
| 45 | + parse_options(&opts, argc, argv); |
16 | 46 |
|
| 47 | + /* we need to initialize libgit2 */ |
17 | 48 | git_libgit2_init(); |
18 | 49 |
|
19 | | - ls = git__malloc(sizeof(ls_files)); |
| 50 | + /* we need to open the repo */ |
| 51 | + if ((error = git_repository_open_ext(&repo, ".", 0, NULL)) != 0) |
| 52 | + goto cleanup; |
20 | 53 |
|
21 | | - // TODO err |
22 | | - git_repository_open_ext(&ls->repo, ".", 0, NULL); |
| 54 | + /* we need to load the repo's index */ |
| 55 | + if ((error = git_repository_index(&index, repo)) != 0) |
| 56 | + goto cleanup; |
23 | 57 |
|
24 | | - // TODO err |
25 | | - git_repository_index__weakptr(&ls->index, ls->repo); |
| 58 | + if (opts.error_unmatch) { |
| 59 | + for (i = 0; i < opts.file_count; i++) { |
| 60 | + const char *path = opts.files[i]; |
| 61 | + printf("Checking first path '%s'\n", path); |
| 62 | + entry = git_index_get_bypath(index, path, GIT_INDEX_STAGE_NORMAL); |
| 63 | + if (!entry) { |
| 64 | + printf("Could not find path '%s'\n", path); |
| 65 | + return -1; |
| 66 | + } |
| 67 | + } |
| 68 | + goto cleanup; |
| 69 | + } |
26 | 70 |
|
| 71 | + /* we need to know how many entries exist in the index */ |
| 72 | + entry_count = git_index_entrycount(index); |
27 | 73 |
|
28 | | - git_vector_foreach(&ls->index->entries, i, entry) { |
| 74 | + /* loop through the entries by index and display their pathes */ |
| 75 | + for (i = 0; i < entry_count; i++) { |
| 76 | + entry = git_index_get_byindex(index, i); |
29 | 77 | printf("%s\n", entry->path); |
30 | 78 | } |
31 | 79 |
|
32 | | - git_repository_free(ls->repo); |
33 | | - git__free(ls); |
| 80 | +cleanup: |
| 81 | + /* free our allocated resources */ |
| 82 | + git_index_free(index); |
| 83 | + git_repository_free(repo); |
| 84 | + |
| 85 | + /* we need to shutdown libgit2 */ |
34 | 86 | git_libgit2_shutdown(); |
35 | 87 |
|
36 | | - return 0; |
| 88 | + return error; |
37 | 89 | } |
| 90 | + |
| 91 | +void parse_options(ls_options *opts, int argc, char *argv[]) { |
| 92 | + int parsing_files = 0; |
| 93 | + int file_idx = 0; |
| 94 | + struct args_info args = ARGS_INFO_INIT; |
| 95 | + |
| 96 | + memset(opts, 0, sizeof(ls_options)); |
| 97 | + opts->error_unmatch = 0; |
| 98 | + opts->file_count = 0; |
| 99 | + |
| 100 | + if (argc < 2) |
| 101 | + return; |
| 102 | + |
| 103 | + for (args.pos = 1; args.pos < argc; ++args.pos) { |
| 104 | + char *a = argv[args.pos]; |
| 105 | + |
| 106 | + if (a[0] != '-' || !strcmp(a, "--")) { |
| 107 | + if (parsing_files) { |
| 108 | + printf("%s\n", a); |
| 109 | + opts->files[opts->file_count++] = a; |
| 110 | + } else { |
| 111 | + parsing_files = 1; |
| 112 | + } |
| 113 | + } else if (!strcmp(a, "--error-unmatch")) { |
| 114 | + opts->error_unmatch = 1; |
| 115 | + parsing_files = 1; |
| 116 | + } else { |
| 117 | + printf("Bad command\n"); |
| 118 | + } |
| 119 | + } |
| 120 | + |
| 121 | + printf("file count: %d\n", opts->file_count); |
| 122 | + int i; |
| 123 | + for (i = 0; i < opts->file_count; i++) { |
| 124 | + printf("Path ids %d: %s\n", i, opts->files[i]); |
| 125 | + } |
| 126 | + } |
0 commit comments