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 ;
@@ -462,6 +464,7 @@ static int is_valid_prefix(const char *prefix, size_t prefix_len)
462
464
struct print_file_item_data {
463
465
const char * modified_fmt , * color , * reset ;
464
466
struct strbuf buf , name , index , worktree ;
467
+ unsigned only_names :1 ;
465
468
};
466
469
467
470
static void print_file_item (int i , int selected , struct prefix_item * item ,
@@ -485,6 +488,12 @@ static void print_file_item(int i, int selected, struct prefix_item *item,
485
488
highlighted = d -> name .buf ;
486
489
}
487
490
491
+ if (d -> only_names ) {
492
+ printf ("%c%2d: %s" , selected ? '*' : ' ' , i + 1 ,
493
+ highlighted ? highlighted : item -> name );
494
+ return ;
495
+ }
496
+
488
497
populate_wi_changes (& d -> worktree , & c -> worktree , _ ("nothing" ));
489
498
populate_wi_changes (& d -> index , & c -> index , _ ("unchanged" ));
490
499
strbuf_addf (& d -> buf , d -> modified_fmt ,
@@ -679,6 +688,92 @@ static int run_revert(struct add_i_state *s, const struct pathspec *ps,
679
688
return res ;
680
689
}
681
690
691
+ static int get_untracked_files (struct repository * r , struct file_list * list ,
692
+ const struct pathspec * ps )
693
+ {
694
+ struct dir_struct dir = { 0 };
695
+ size_t i ;
696
+
697
+ if (repo_read_index (r ) < 0 )
698
+ return error (_ ("could not read index" ));
699
+
700
+ setup_standard_excludes (& dir );
701
+ add_exclude_list (& dir , EXC_CMDL , "--exclude option" );
702
+ fill_directory (& dir , r -> index , ps );
703
+
704
+ for (i = 0 ; i < dir .nr ; i ++ ) {
705
+ struct dir_entry * ent = dir .entries [i ];
706
+
707
+ if (index_name_is_other (r -> index , ent -> name , ent -> len )) {
708
+ struct file_item * item ;
709
+
710
+ FLEXPTR_ALLOC_MEM (item , item .name , ent -> name , ent -> len );
711
+
712
+ ALLOC_GROW (list -> file , list -> nr + 1 , list -> alloc );
713
+ list -> file [list -> nr ++ ] = item ;
714
+ }
715
+ }
716
+
717
+ return 0 ;
718
+ }
719
+
720
+ static int run_add_untracked (struct add_i_state * s , const struct pathspec * ps ,
721
+ struct file_list * files ,
722
+ struct list_and_choose_options * opts )
723
+ {
724
+ struct print_file_item_data * d = opts -> list_opts .print_item_data ;
725
+ int res = 0 , fd , * selected = NULL ;
726
+ size_t count , i ;
727
+
728
+ struct lock_file index_lock ;
729
+
730
+ reset_file_list (files );
731
+ if (get_untracked_files (s -> r , files , ps ) < 0 )
732
+ return -1 ;
733
+
734
+ if (!files -> nr ) {
735
+ printf (_ ("No untracked files.\n" ));
736
+ goto finish_add_untracked ;
737
+ }
738
+
739
+ opts -> prompt = N_ ("Add untracked" );
740
+ CALLOC_ARRAY (selected , files -> nr );
741
+
742
+ d -> only_names = 1 ;
743
+ count = list_and_choose ((struct prefix_item * * )files -> file ,
744
+ selected , files -> nr , s , opts );
745
+ d -> only_names = 0 ;
746
+ if (count <= 0 )
747
+ goto finish_add_untracked ;
748
+
749
+ fd = repo_hold_locked_index (s -> r , & index_lock , LOCK_REPORT_ON_ERROR );
750
+ if (fd < 0 ) {
751
+ res = -1 ;
752
+ goto finish_add_untracked ;
753
+ }
754
+
755
+ for (i = 0 ; i < files -> nr ; i ++ ) {
756
+ const char * name = files -> file [i ]-> item .name ;
757
+ if (selected [i ] &&
758
+ add_file_to_index (s -> r -> index , name , 0 ) < 0 ) {
759
+ res = error (_ ("could not stage '%s'" ), name );
760
+ break ;
761
+ }
762
+ }
763
+
764
+ if (!res && write_locked_index (s -> r -> index , & index_lock , COMMIT_LOCK ) < 0 )
765
+ res = error (_ ("could not write index" ));
766
+
767
+ if (!res )
768
+ printf (Q_ ("added %d path\n" ,
769
+ "added %d paths\n" , count ), (int )count );
770
+
771
+ finish_add_untracked :
772
+ putchar ('\n' );
773
+ free (selected );
774
+ return res ;
775
+ }
776
+
682
777
static int run_help (struct add_i_state * s , const struct pathspec * ps ,
683
778
struct file_list * files ,
684
779
struct list_and_choose_options * opts )
@@ -771,9 +866,10 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
771
866
status = { { "status" }, run_status },
772
867
update = { { "update" }, run_update },
773
868
revert = { { "revert" }, run_revert },
869
+ add_untracked = { { "add untracked" }, run_add_untracked },
774
870
help = { { "help" }, run_help };
775
871
struct command_item * commands [] = {
776
- & status , & update , & revert ,
872
+ & status , & update , & revert , & add_untracked ,
777
873
& help
778
874
};
779
875
0 commit comments