1313 */
1414
1515#include "common.h"
16- #include <assert.h>
1716
1817/**
1918 * The following example demonstrates how to add files with libgit2.
2726 * -u/--update: update the index instead of adding to it.
2827 */
2928
30- enum print_options {
31- SKIP = 1 ,
32- VERBOSE = 2 ,
33- UPDATE = 4 ,
29+ enum index_mode {
30+ INDEX_NONE ,
31+ INDEX_ADD ,
3432};
3533
36- struct print_payload {
37- enum print_options options ;
34+ struct index_options {
35+ int dry_run ;
36+ int verbose ;
3837 git_repository * repo ;
38+ enum index_mode mode ;
39+ int add_update ;
3940};
4041
4142/* Forward declarations for helpers */
42- static void parse_opts (int * options , int * count , int argc , char * argv []);
43- void init_array (git_strarray * array , int argc , char * * argv );
43+ static void parse_opts (const char * * repo_path , struct index_options * opts , struct args_info * args );
4444int print_matched_cb (const char * path , const char * matched_pathspec , void * payload );
4545
46- int lg2_add (git_repository * repo , int argc , char * * argv )
46+ int lg2_add (git_repository * repo , int argc , char * * argv )
4747{
4848 git_index_matched_path_cb matched_cb = NULL ;
4949 git_index * index ;
5050 git_strarray array = {0 };
51- int options = 0 , count = 0 ;
52- struct print_payload payload = { 0 } ;
51+ struct index_options options ;
52+ struct args_info args = ARGS_INFO_INIT ;
5353
54- parse_opts (& options , & count , argc , argv );
55- init_array (& array , argc - count , argv + count );
54+ /* Parse the options & arguments. */
55+ parse_opts (NULL , & options , & args );
56+ strarray_from_args (& array , & args );
5657
58+ /* Grab the repository's index. */
5759 check_lg2 (git_repository_index (& index , repo ), "Could not open repository index" , NULL );
5860
5961 /* Setup a callback if the requested options need it */
60- if (( options & VERBOSE ) || ( options & SKIP ) ) {
62+ if (options . verbose || options . dry_run ) {
6163 matched_cb = & print_matched_cb ;
6264 }
6365
64- /* Perform the requested action with the index and files */
65- payload .options = options ;
66- payload .repo = repo ;
66+ options .repo = repo ;
6767
68- if (options & UPDATE ) {
69- git_index_update_all (index , & array , matched_cb , & payload );
68+ /* Perform the requested action with the index and files */
69+ if (options .add_update ) {
70+ git_index_update_all (index , & array , matched_cb , & options );
7071 } else {
71- git_index_add_all (index , & array , 0 , matched_cb , & payload );
72+ git_index_add_all (index , & array , 0 , matched_cb , & options );
7273 }
7374
7475 /* Cleanup memory */
@@ -85,15 +86,14 @@ int lg2_add(git_repository *repo, int argc, char** argv)
8586 */
8687int print_matched_cb (const char * path , const char * matched_pathspec , void * payload )
8788{
88- struct print_payload p = * (struct print_payload * )(payload );
89+ struct index_options * opts = (struct index_options * )(payload );
8990 int ret ;
9091 unsigned status ;
9192 (void )matched_pathspec ;
9293
9394 /* Get the file status */
94- if (git_status_file (& status , p . repo , path )) {
95+ if (git_status_file (& status , opts -> repo , path ) < 0 )
9596 return -1 ;
96- }
9797
9898 if ((status & GIT_STATUS_WT_MODIFIED ) || (status & GIT_STATUS_WT_NEW )) {
9999 printf ("add '%s'\n" , path );
@@ -102,9 +102,8 @@ int print_matched_cb(const char *path, const char *matched_pathspec, void *paylo
102102 ret = 1 ;
103103 }
104104
105- if (( p . options & SKIP )) {
105+ if (opts -> dry_run )
106106 ret = 1 ;
107- }
108107
109108 return ret ;
110109}
@@ -133,33 +132,39 @@ void print_usage(void)
133132 exit (1 );
134133}
135134
136- static void parse_opts (int * options , int * count , int argc , char * argv [] )
135+ static void parse_opts (const char * * repo_path , struct index_options * opts , struct args_info * args )
137136{
138- int i ;
137+ if (args -> argc <= 1 )
138+ print_usage ();
139139
140- for (i = 1 ; i < argc ; ++ i ) {
141- if (argv [i ][0 ] != '-' )
142- break ;
143- else if (!strcmp (argv [i ], "--verbose" ) || !strcmp (argv [i ], "-v" ))
144- * options |= VERBOSE ;
145- else if (!strcmp (argv [i ], "--dry-run" ) || !strcmp (argv [i ], "-n" ))
146- * options |= SKIP ;
147- else if (!strcmp (argv [i ], "--update" ) || !strcmp (argv [i ], "-u" ))
148- * options |= UPDATE ;
149- else if (!strcmp (argv [i ], "-h" )) {
140+ for (args -> pos = 1 ; args -> pos < args -> argc ; ++ args -> pos ) {
141+ const char * curr = args -> argv [args -> pos ];
142+
143+ if (curr [0 ] != '-' ) {
144+ if (!strcmp ("add" , curr )) {
145+ opts -> mode = INDEX_ADD ;
146+ continue ;
147+ } else if (opts -> mode == INDEX_NONE ) {
148+ fprintf (stderr , "missing command: %s" , curr );
149+ print_usage ();
150+ break ;
151+ } else {
152+ /* We might be looking at a filename */
153+ break ;
154+ }
155+ } else if (match_bool_arg (& opts -> verbose , args , "--verbose" ) ||
156+ match_bool_arg (& opts -> dry_run , args , "--dry-run" ) ||
157+ match_str_arg (repo_path , args , "--git-dir" ) ||
158+ (opts -> mode == INDEX_ADD && match_bool_arg (& opts -> add_update , args , "--update" ))) {
159+ continue ;
160+ } else if (match_bool_arg (NULL , args , "--help" )) {
150161 print_usage ();
151162 break ;
152- } else if (!strcmp (argv [i ], "--" )) {
153- i ++ ;
163+ } else if (match_arg_separator (args )) {
154164 break ;
155165 } else {
156- fprintf (stderr , "Unsupported option %s.\n" , argv [ i ] );
166+ fprintf (stderr , "Unsupported option %s.\n" , curr );
157167 print_usage ();
158168 }
159169 }
160-
161- if (argc <= i )
162- print_usage ();
163-
164- * count = i ;
165170}
0 commit comments