7
7
#include "refs.h"
8
8
#include "prefix-map.h"
9
9
#include "lockfile.h"
10
+ #include "pathspec.h"
11
+ #include "dir.h"
10
12
11
13
struct add_i_state {
12
14
struct repository * r ;
@@ -455,6 +457,7 @@ static int is_valid_prefix(const char *prefix, size_t prefix_len)
455
457
struct print_file_item_data {
456
458
const char * modified_fmt , * color , * reset ;
457
459
struct strbuf buf , name , index , worktree ;
460
+ unsigned only_names :1 ;
458
461
};
459
462
460
463
static void print_file_item (int i , int selected , struct prefix_item * item ,
@@ -478,6 +481,12 @@ static void print_file_item(int i, int selected, struct prefix_item *item,
478
481
highlighted = d -> name .buf ;
479
482
}
480
483
484
+ if (d -> only_names ) {
485
+ printf ("%c%2d: %s" , selected ? '*' : ' ' , i + 1 ,
486
+ highlighted ? highlighted : item -> name );
487
+ return ;
488
+ }
489
+
481
490
populate_wi_changes (& d -> worktree , & c -> worktree , _ ("nothing" ));
482
491
populate_wi_changes (& d -> index , & c -> index , _ ("unchanged" ));
483
492
strbuf_addf (& d -> buf , d -> modified_fmt ,
@@ -672,6 +681,92 @@ static int run_revert(struct add_i_state *s, const struct pathspec *ps,
672
681
return res ;
673
682
}
674
683
684
+ static int get_untracked_files (struct repository * r , struct file_list * list ,
685
+ const struct pathspec * ps )
686
+ {
687
+ struct dir_struct dir = { 0 };
688
+ size_t i ;
689
+
690
+ if (repo_read_index (r ) < 0 )
691
+ return error (_ ("could not read index" ));
692
+
693
+ setup_standard_excludes (& dir );
694
+ add_exclude_list (& dir , EXC_CMDL , "--exclude option" );
695
+ fill_directory (& dir , r -> index , ps );
696
+
697
+ for (i = 0 ; i < dir .nr ; i ++ ) {
698
+ struct dir_entry * ent = dir .entries [i ];
699
+
700
+ if (index_name_is_other (r -> index , ent -> name , ent -> len )) {
701
+ struct file_item * item ;
702
+
703
+ FLEXPTR_ALLOC_MEM (item , item .name , ent -> name , ent -> len );
704
+
705
+ ALLOC_GROW (list -> file , list -> nr + 1 , list -> alloc );
706
+ list -> file [list -> nr ++ ] = item ;
707
+ }
708
+ }
709
+
710
+ return 0 ;
711
+ }
712
+
713
+ static int run_add_untracked (struct add_i_state * s , const struct pathspec * ps ,
714
+ struct file_list * files ,
715
+ struct list_and_choose_options * opts )
716
+ {
717
+ struct print_file_item_data * d = opts -> list_opts .print_item_data ;
718
+ int res = 0 , fd , * selected = NULL ;
719
+ size_t count , i ;
720
+
721
+ struct lock_file index_lock ;
722
+
723
+ reset_file_list (files );
724
+ if (get_untracked_files (s -> r , files , ps ) < 0 )
725
+ return -1 ;
726
+
727
+ if (!files -> nr ) {
728
+ printf (_ ("No untracked files.\n" ));
729
+ goto finish_add_untracked ;
730
+ }
731
+
732
+ opts -> prompt = N_ ("Add untracked" );
733
+ CALLOC_ARRAY (selected , files -> nr );
734
+
735
+ d -> only_names = 1 ;
736
+ count = list_and_choose ((struct prefix_item * * )files -> file ,
737
+ selected , files -> nr , s , opts );
738
+ d -> only_names = 0 ;
739
+ if (count <= 0 )
740
+ goto finish_add_untracked ;
741
+
742
+ fd = repo_hold_locked_index (s -> r , & index_lock , LOCK_REPORT_ON_ERROR );
743
+ if (fd < 0 ) {
744
+ res = -1 ;
745
+ goto finish_add_untracked ;
746
+ }
747
+
748
+ for (i = 0 ; i < files -> nr ; i ++ ) {
749
+ const char * name = files -> file [i ]-> item .name ;
750
+ if (selected [i ] &&
751
+ add_file_to_index (s -> r -> index , name , 0 ) < 0 ) {
752
+ res = error (_ ("could not stage '%s'" ), name );
753
+ break ;
754
+ }
755
+ }
756
+
757
+ if (!res && write_locked_index (s -> r -> index , & index_lock , COMMIT_LOCK ) < 0 )
758
+ res = error (_ ("could not write index" ));
759
+
760
+ if (!res )
761
+ printf (Q_ ("added %d path\n" ,
762
+ "added %d paths\n" , count ), (int )count );
763
+
764
+ finish_add_untracked :
765
+ putchar ('\n' );
766
+ free (selected );
767
+ return res ;
768
+ }
769
+
675
770
static int run_help (struct add_i_state * s , const struct pathspec * ps ,
676
771
struct file_list * files ,
677
772
struct list_and_choose_options * opts )
@@ -764,9 +859,10 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
764
859
status = { { "status" }, run_status },
765
860
update = { { "update" }, run_update },
766
861
revert = { { "revert" }, run_revert },
862
+ add_untracked = { { "add untracked" }, run_add_untracked },
767
863
help = { { "help" }, run_help };
768
864
struct command_item * commands [] = {
769
- & status , & update , & revert ,
865
+ & status , & update , & revert , & add_untracked ,
770
866
& help
771
867
};
772
868
0 commit comments