2 * libgit2 "add" example - shows how to modify the index
4 * Written by the libgit2 contributors
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.
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/>.
18 * The following example demonstrates how to add files with libgit2.
20 * It will use the repository in the current working directory, and act
21 * on files passed as its parameters.
23 * Recognized options are:
24 * -v/--verbose: show the file's status after acting on it.
25 * -n/--dry-run: do not actually change the index.
26 * -u/--update: update the index instead of adding to it.
34 struct index_options
{
42 /* Forward declarations for helpers */
43 static void parse_opts(const char **repo_path
, struct index_options
*opts
, struct args_info
*args
);
44 int print_matched_cb(const char *path
, const char *matched_pathspec
, void *payload
);
46 int lg2_add(git_repository
*repo
, int argc
, char **argv
)
48 git_index_matched_path_cb matched_cb
= NULL
;
50 git_strarray array
= {0};
51 struct index_options options
= {0};
52 struct args_info args
= ARGS_INFO_INIT
;
54 options
.mode
= INDEX_ADD
;
56 /* Parse the options & arguments. */
57 parse_opts(NULL
, &options
, &args
);
58 strarray_from_args(&array
, &args
);
60 /* Grab the repository's index. */
61 check_lg2(git_repository_index(&index
, repo
), "Could not open repository index", NULL
);
63 /* Setup a callback if the requested options need it */
64 if (options
.verbose
|| options
.dry_run
) {
65 matched_cb
= &print_matched_cb
;
70 /* Perform the requested action with the index and files */
71 if (options
.add_update
) {
72 git_index_update_all(index
, &array
, matched_cb
, &options
);
74 git_index_add_all(index
, &array
, 0, matched_cb
, &options
);
78 git_index_write(index
);
79 git_index_free(index
);
85 * This callback is called for each file under consideration by
86 * git_index_(update|add)_all above.
87 * It makes uses of the callback's ability to abort the action.
89 int print_matched_cb(const char *path
, const char *matched_pathspec
, void *payload
)
91 struct index_options
*opts
= (struct index_options
*)(payload
);
94 (void)matched_pathspec
;
96 /* Get the file status */
97 if (git_status_file(&status
, opts
->repo
, path
) < 0)
100 if ((status
& GIT_STATUS_WT_MODIFIED
) || (status
& GIT_STATUS_WT_NEW
)) {
101 printf("add '%s'\n", path
);
113 void init_array(git_strarray
*array
, int argc
, char **argv
)
118 array
->strings
= calloc(array
->count
, sizeof(char *));
119 assert(array
->strings
!= NULL
);
121 for (i
= 0; i
< array
->count
; i
++) {
122 array
->strings
[i
] = argv
[i
];
128 void print_usage(void)
130 fprintf(stderr
, "usage: add [options] [--] file-spec [file-spec] [...]\n\n");
131 fprintf(stderr
, "\t-n, --dry-run dry run\n");
132 fprintf(stderr
, "\t-v, --verbose be verbose\n");
133 fprintf(stderr
, "\t-u, --update update tracked files\n");
137 static void parse_opts(const char **repo_path
, struct index_options
*opts
, struct args_info
*args
)
142 for (args
->pos
= 1; args
->pos
< args
->argc
; ++args
->pos
) {
143 const char *curr
= args
->argv
[args
->pos
];
145 if (curr
[0] != '-') {
146 if (!strcmp("add", curr
)) {
147 opts
->mode
= INDEX_ADD
;
149 } else if (opts
->mode
== INDEX_NONE
) {
150 fprintf(stderr
, "missing command: %s", curr
);
154 /* We might be looking at a filename */
157 } else if (match_bool_arg(&opts
->verbose
, args
, "--verbose") ||
158 match_bool_arg(&opts
->dry_run
, args
, "--dry-run") ||
159 match_str_arg(repo_path
, args
, "--git-dir") ||
160 (opts
->mode
== INDEX_ADD
&& match_bool_arg(&opts
->add_update
, args
, "--update"))) {
162 } else if (match_bool_arg(NULL
, args
, "--help")) {
165 } else if (match_arg_separator(args
)) {
168 fprintf(stderr
, "Unsupported option %s.\n", curr
);