@@ -140,8 +140,6 @@ static void refresh(int verbose, const char **pathspec)
140140 for (specs = 0 ; pathspec [specs ]; specs ++ )
141141 /* nothing */ ;
142142 seen = xcalloc (specs , 1 );
143- if (read_cache () < 0 )
144- die ("index file corrupt" );
145143 refresh_index (& the_index , verbose ? REFRESH_SAY_CHANGED : REFRESH_QUIET ,
146144 pathspec , seen );
147145 for (i = 0 ; i < specs ; i ++ ) {
@@ -193,7 +191,7 @@ static const char ignore_error[] =
193191"The following paths are ignored by one of your .gitignore files:\n" ;
194192
195193static int verbose = 0 , show_only = 0 , ignored_too = 0 , refresh_only = 0 ;
196- static int ignore_add_errors ;
194+ static int ignore_add_errors , addremove ;
197195
198196static struct option builtin_add_options [] = {
199197 OPT__DRY_RUN (& show_only ),
@@ -203,6 +201,7 @@ static struct option builtin_add_options[] = {
203201 OPT_BOOLEAN ('p' , "patch" , & patch_interactive , "interactive patching" ),
204202 OPT_BOOLEAN ('f' , "force" , & ignored_too , "allow adding otherwise ignored files" ),
205203 OPT_BOOLEAN ('u' , "update" , & take_worktree_changes , "update tracked files" ),
204+ OPT_BOOLEAN ('A' , "all" , & addremove , "add all, noticing removal of tracked files" ),
206205 OPT_BOOLEAN ( 0 , "refresh" , & refresh_only , "don't add, only refresh the index" ),
207206 OPT_BOOLEAN ( 0 , "ignore-errors" , & ignore_add_errors , "just skip files which cannot be added because of errors" ),
208207 OPT_END (),
@@ -217,13 +216,36 @@ static int add_config(const char *var, const char *value, void *cb)
217216 return git_default_config (var , value , cb );
218217}
219218
219+ static int add_files (struct dir_struct * dir , int flags )
220+ {
221+ int i , exit_status = 0 ;
222+
223+ if (dir -> ignored_nr ) {
224+ fprintf (stderr , ignore_error );
225+ for (i = 0 ; i < dir -> ignored_nr ; i ++ )
226+ fprintf (stderr , "%s\n" , dir -> ignored [i ]-> name );
227+ fprintf (stderr , "Use -f if you really want to add them.\n" );
228+ die ("no files added" );
229+ }
230+
231+ for (i = 0 ; i < dir -> nr ; i ++ )
232+ if (add_file_to_cache (dir -> entries [i ]-> name , flags )) {
233+ if (!ignore_add_errors )
234+ die ("adding files failed" );
235+ exit_status = 1 ;
236+ }
237+ return exit_status ;
238+ }
239+
220240int cmd_add (int argc , const char * * argv , const char * prefix )
221241{
222242 int exit_status = 0 ;
223- int i , newfd ;
243+ int newfd ;
224244 const char * * pathspec ;
225245 struct dir_struct dir ;
226246 int flags ;
247+ int add_new_files ;
248+ int require_pathspec ;
227249
228250 argc = parse_options (argc , argv , builtin_add_options ,
229251 builtin_add_usage , 0 );
@@ -234,53 +256,51 @@ int cmd_add(int argc, const char **argv, const char *prefix)
234256
235257 git_config (add_config , NULL );
236258
259+ if (addremove && take_worktree_changes )
260+ die ("-A and -u are mutually incompatible" );
261+ if (addremove && !argc ) {
262+ static const char * here [2 ] = { "." , NULL };
263+ argc = 1 ;
264+ argv = here ;
265+ }
266+
267+ add_new_files = !take_worktree_changes && !refresh_only ;
268+ require_pathspec = !take_worktree_changes ;
269+
237270 newfd = hold_locked_index (& lock_file , 1 );
238271
239272 flags = ((verbose ? ADD_CACHE_VERBOSE : 0 ) |
240273 (show_only ? ADD_CACHE_PRETEND : 0 ) |
241274 (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0 ));
242275
243- if (take_worktree_changes ) {
244- const char * * pathspec ;
245- if (read_cache () < 0 )
246- die ("index file corrupt" );
247- pathspec = get_pathspec (prefix , argv );
248- exit_status = add_files_to_cache (prefix , pathspec , flags );
249- goto finish ;
250- }
251-
252- if (argc == 0 ) {
276+ if (require_pathspec && argc == 0 ) {
253277 fprintf (stderr , "Nothing specified, nothing added.\n" );
254278 fprintf (stderr , "Maybe you wanted to say 'git add .'?\n" );
255279 return 0 ;
256280 }
257281 pathspec = get_pathspec (prefix , argv );
258282
259- if (refresh_only ) {
260- refresh (verbose , pathspec );
261- goto finish ;
262- }
263-
264- fill_directory (& dir , pathspec , ignored_too );
283+ /*
284+ * If we are adding new files, we need to scan the working
285+ * tree to find the ones that match pathspecs; this needs
286+ * to be done before we read the index.
287+ */
288+ if (add_new_files )
289+ fill_directory (& dir , pathspec , ignored_too );
265290
266291 if (read_cache () < 0 )
267292 die ("index file corrupt" );
268293
269- if (dir .ignored_nr ) {
270- fprintf (stderr , ignore_error );
271- for (i = 0 ; i < dir .ignored_nr ; i ++ ) {
272- fprintf (stderr , "%s\n" , dir .ignored [i ]-> name );
273- }
274- fprintf (stderr , "Use -f if you really want to add them.\n" );
275- die ("no files added" );
294+ if (refresh_only ) {
295+ refresh (verbose , pathspec );
296+ goto finish ;
276297 }
277298
278- for (i = 0 ; i < dir .nr ; i ++ )
279- if (add_file_to_cache (dir .entries [i ]-> name , flags )) {
280- if (!ignore_add_errors )
281- die ("adding files failed" );
282- exit_status = 1 ;
283- }
299+ if (take_worktree_changes || addremove )
300+ exit_status |= add_files_to_cache (prefix , pathspec , flags );
301+
302+ if (add_new_files )
303+ exit_status |= add_files (& dir , flags );
284304
285305 finish :
286306 if (active_cache_changed ) {
0 commit comments