]>
Commit | Line | Data |
---|---|---|
ac3d33df JK |
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 | */ | |
14 | ||
15 | #include "common.h" | |
ac3d33df JK |
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 | * This currently supports the default behavior and the `--error-unmatch` option. | |
26 | */ | |
27 | ||
0c9c969a | 28 | struct ls_options { |
ac3d33df JK |
29 | int error_unmatch; |
30 | char *files[1024]; | |
31 | size_t file_count; | |
0c9c969a | 32 | }; |
ac3d33df JK |
33 | |
34 | static void usage(const char *message, const char *arg) | |
35 | { | |
36 | if (message && arg) | |
37 | fprintf(stderr, "%s: %s\n", message, arg); | |
38 | else if (message) | |
39 | fprintf(stderr, "%s\n", message); | |
40 | fprintf(stderr, "usage: ls-files [--error-unmatch] [--] [<file>...]\n"); | |
41 | exit(1); | |
42 | } | |
43 | ||
0c9c969a | 44 | static int parse_options(struct ls_options *opts, int argc, char *argv[]) |
ac3d33df JK |
45 | { |
46 | int parsing_files = 0; | |
47 | int i; | |
48 | ||
0c9c969a | 49 | memset(opts, 0, sizeof(struct ls_options)); |
ac3d33df JK |
50 | |
51 | if (argc < 2) | |
52 | return 0; | |
53 | ||
54 | for (i = 1; i < argc; ++i) { | |
55 | char *a = argv[i]; | |
56 | ||
57 | /* if it doesn't start with a '-' or is after the '--' then it is a file */ | |
58 | if (a[0] != '-' || parsing_files) { | |
59 | parsing_files = 1; | |
60 | ||
61 | /* watch for overflows (just in case) */ | |
62 | if (opts->file_count == 1024) { | |
63 | fprintf(stderr, "ls-files can only support 1024 files at this time.\n"); | |
64 | return -1; | |
65 | } | |
66 | ||
67 | opts->files[opts->file_count++] = a; | |
68 | } else if (!strcmp(a, "--")) { | |
69 | parsing_files = 1; | |
70 | } else if (!strcmp(a, "--error-unmatch")) { | |
71 | opts->error_unmatch = 1; | |
72 | } else { | |
73 | usage("Unsupported argument", a); | |
74 | return -1; | |
75 | } | |
76 | } | |
77 | ||
78 | return 0; | |
79 | } | |
80 | ||
0c9c969a | 81 | static int print_paths(struct ls_options *opts, git_index *index) |
ac3d33df JK |
82 | { |
83 | size_t i; | |
84 | const git_index_entry *entry; | |
85 | ||
86 | /* if there are no files explicitly listed by the user print all entries in the index */ | |
87 | if (opts->file_count == 0) { | |
88 | size_t entry_count = git_index_entrycount(index); | |
89 | ||
90 | for (i = 0; i < entry_count; i++) { | |
91 | entry = git_index_get_byindex(index, i); | |
92 | puts(entry->path); | |
93 | } | |
94 | return 0; | |
95 | } | |
96 | ||
97 | /* loop through the files found in the args and print them if they exist */ | |
98 | for (i = 0; i < opts->file_count; ++i) { | |
99 | const char *path = opts->files[i]; | |
100 | ||
101 | if ((entry = git_index_get_bypath(index, path, GIT_INDEX_STAGE_NORMAL)) != NULL) { | |
102 | puts(path); | |
103 | } else if (opts->error_unmatch) { | |
104 | fprintf(stderr, "error: pathspec '%s' did not match any file(s) known to git.\n", path); | |
105 | fprintf(stderr, "Did you forget to 'git add'?\n"); | |
106 | return -1; | |
107 | } | |
108 | } | |
109 | ||
110 | return 0; | |
111 | } | |
112 | ||
0c9c969a | 113 | int lg2_ls_files(git_repository *repo, int argc, char *argv[]) |
ac3d33df | 114 | { |
ac3d33df | 115 | git_index *index = NULL; |
0c9c969a | 116 | struct ls_options opts; |
ac3d33df JK |
117 | int error; |
118 | ||
119 | if ((error = parse_options(&opts, argc, argv)) < 0) | |
120 | return error; | |
121 | ||
ac3d33df JK |
122 | if ((error = git_repository_index(&index, repo)) < 0) |
123 | goto cleanup; | |
124 | ||
125 | error = print_paths(&opts, index); | |
126 | ||
127 | cleanup: | |
128 | git_index_free(index); | |
ac3d33df JK |
129 | |
130 | return error; | |
131 | } |