Skip to content

Commit 0c6f631

Browse files
authored
Merge pull request libgit2#4380 from cjhoward92/examples/ls-files
examples: ls-files: add ls-files to list paths in the index
2 parents 26a09a9 + 8aa437e commit 0c6f631

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

examples/ls-files.c

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
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"
16+
#include "array.h"
17+
18+
/**
19+
* This example demonstrates the libgit2 index APIs to roughly
20+
* simulate the output of `git ls-files`.
21+
* `git ls-files` has many options and this currently does not show them.
22+
*
23+
* `git ls-files` base command shows all paths in the index at that time.
24+
* This includes staged and committed files, but unstaged files will not display.
25+
*
26+
* This currently supports the default behavior and the `--error-unmatch` option.
27+
*/
28+
29+
typedef struct {
30+
int error_unmatch;
31+
char *files[1024];
32+
size_t file_count;
33+
} ls_options;
34+
35+
static void usage(const char *message, const char *arg)
36+
{
37+
if (message && arg)
38+
fprintf(stderr, "%s: %s\n", message, arg);
39+
else if (message)
40+
fprintf(stderr, "%s\n", message);
41+
fprintf(stderr, "usage: ls-files [--error-unmatch] [--] [<file>...]\n");
42+
exit(1);
43+
}
44+
45+
static int parse_options(ls_options *opts, int argc, char *argv[])
46+
{
47+
int parsing_files = 0;
48+
int i;
49+
50+
memset(opts, 0, sizeof(ls_options));
51+
52+
if (argc < 2)
53+
return 0;
54+
55+
for (i = 1; i < argc; ++i) {
56+
char *a = argv[i];
57+
58+
/* if it doesn't start with a '-' or is after the '--' then it is a file */
59+
if (a[0] != '-' || parsing_files) {
60+
parsing_files = 1;
61+
62+
/* watch for overflows (just in case) */
63+
if (opts->file_count == 1024) {
64+
fprintf(stderr, "ls-files can only support 1024 files at this time.\n");
65+
return -1;
66+
}
67+
68+
opts->files[opts->file_count++] = a;
69+
} else if (!strcmp(a, "--")) {
70+
parsing_files = 1;
71+
} else if (!strcmp(a, "--error-unmatch")) {
72+
opts->error_unmatch = 1;
73+
} else {
74+
usage("Unsupported argument", a);
75+
return -1;
76+
}
77+
}
78+
79+
return 0;
80+
}
81+
82+
static int print_paths(ls_options *opts, git_index *index)
83+
{
84+
size_t i;
85+
const git_index_entry *entry;
86+
87+
/* if there are no files explicitly listed by the user print all entries in the index */
88+
if (opts->file_count == 0) {
89+
size_t entry_count = git_index_entrycount(index);
90+
91+
for (i = 0; i < entry_count; i++) {
92+
entry = git_index_get_byindex(index, i);
93+
puts(entry->path);
94+
}
95+
return 0;
96+
}
97+
98+
/* loop through the files found in the args and print them if they exist */
99+
for (i = 0; i < opts->file_count; ++i) {
100+
const char *path = opts->files[i];
101+
102+
if ((entry = git_index_get_bypath(index, path, GIT_INDEX_STAGE_NORMAL)) != NULL) {
103+
puts(path);
104+
} else if (opts->error_unmatch) {
105+
fprintf(stderr, "error: pathspec '%s' did not match any file(s) known to git.\n", path);
106+
fprintf(stderr, "Did you forget to 'git add'?\n");
107+
return -1;
108+
}
109+
}
110+
111+
return 0;
112+
}
113+
114+
int main(int argc, char *argv[])
115+
{
116+
ls_options opts;
117+
git_repository *repo = NULL;
118+
git_index *index = NULL;
119+
int error;
120+
121+
if ((error = parse_options(&opts, argc, argv)) < 0)
122+
return error;
123+
124+
git_libgit2_init();
125+
126+
if ((error = git_repository_open_ext(&repo, ".", 0, NULL)) < 0)
127+
goto cleanup;
128+
129+
if ((error = git_repository_index(&index, repo)) < 0)
130+
goto cleanup;
131+
132+
error = print_paths(&opts, index);
133+
134+
cleanup:
135+
git_index_free(index);
136+
git_repository_free(repo);
137+
git_libgit2_shutdown();
138+
139+
return error;
140+
}

0 commit comments

Comments
 (0)