6
6
#include "revision.h"
7
7
#include "refs.h"
8
8
#include "prefix-map.h"
9
+ #include "lockfile.h"
9
10
10
11
struct add_i_state {
11
12
struct repository * r ;
@@ -452,30 +453,43 @@ static int is_valid_prefix(const char *prefix, size_t prefix_len)
452
453
}
453
454
454
455
struct print_file_item_data {
455
- const char * modified_fmt ;
456
- struct strbuf buf , index , worktree ;
456
+ const char * modified_fmt , * color , * reset ;
457
+ struct strbuf buf , name , index , worktree ;
457
458
};
458
459
459
460
static void print_file_item (int i , int selected , struct prefix_item * item ,
460
461
void * print_file_item_data )
461
462
{
462
463
struct file_item * c = (struct file_item * )item ;
463
464
struct print_file_item_data * d = print_file_item_data ;
465
+ const char * highlighted = NULL ;
464
466
465
467
strbuf_reset (& d -> index );
466
468
strbuf_reset (& d -> worktree );
467
469
strbuf_reset (& d -> buf );
468
470
471
+ /* Format the item with the prefix highlighted. */
472
+ if (item -> prefix_length > 0 &&
473
+ is_valid_prefix (item -> name , item -> prefix_length )) {
474
+ strbuf_reset (& d -> name );
475
+ strbuf_addf (& d -> name , "%s%.*s%s%s" , d -> color ,
476
+ (int )item -> prefix_length , item -> name , d -> reset ,
477
+ item -> name + item -> prefix_length );
478
+ highlighted = d -> name .buf ;
479
+ }
480
+
469
481
populate_wi_changes (& d -> worktree , & c -> worktree , _ ("nothing" ));
470
482
populate_wi_changes (& d -> index , & c -> index , _ ("unchanged" ));
471
483
strbuf_addf (& d -> buf , d -> modified_fmt ,
472
- d -> index .buf , d -> worktree .buf , item -> name );
484
+ d -> index .buf , d -> worktree .buf ,
485
+ highlighted ? highlighted : item -> name );
473
486
474
487
printf ("%c%2d: %s" , selected ? '*' : ' ' , i + 1 , d -> buf .buf );
475
488
}
476
489
477
490
static int run_status (struct add_i_state * s , const struct pathspec * ps ,
478
- struct file_list * files , struct list_options * opts )
491
+ struct file_list * files ,
492
+ struct list_and_choose_options * opts )
479
493
{
480
494
reset_file_list (files );
481
495
@@ -484,14 +498,72 @@ static int run_status(struct add_i_state *s, const struct pathspec *ps,
484
498
485
499
if (files -> nr )
486
500
list ((struct prefix_item * * )files -> file , NULL , files -> nr ,
487
- s , opts );
501
+ s , & opts -> list_opts );
488
502
putchar ('\n' );
489
503
490
504
return 0 ;
491
505
}
492
506
507
+ static int run_update (struct add_i_state * s , const struct pathspec * ps ,
508
+ struct file_list * files ,
509
+ struct list_and_choose_options * opts )
510
+ {
511
+ int res = 0 , fd , * selected = NULL ;
512
+ size_t count , i ;
513
+ struct lock_file index_lock ;
514
+
515
+ reset_file_list (files );
516
+
517
+ if (get_modified_files (s -> r , WORKTREE_ONLY , files , ps ) < 0 )
518
+ return -1 ;
519
+
520
+ if (!files -> nr ) {
521
+ putchar ('\n' );
522
+ return 0 ;
523
+ }
524
+
525
+ opts -> prompt = N_ ("Update" );
526
+ CALLOC_ARRAY (selected , files -> nr );
527
+
528
+ count = list_and_choose ((struct prefix_item * * )files -> file ,
529
+ selected , files -> nr , s , opts );
530
+ if (count <= 0 ) {
531
+ putchar ('\n' );
532
+ free (selected );
533
+ return 0 ;
534
+ }
535
+
536
+ fd = repo_hold_locked_index (s -> r , & index_lock , LOCK_REPORT_ON_ERROR );
537
+ if (fd < 0 ) {
538
+ putchar ('\n' );
539
+ free (selected );
540
+ return -1 ;
541
+ }
542
+
543
+ for (i = 0 ; i < files -> nr ; i ++ ) {
544
+ const char * name = files -> file [i ]-> item .name ;
545
+ if (selected [i ] &&
546
+ add_file_to_index (s -> r -> index , name , 0 ) < 0 ) {
547
+ res = error (_ ("could not stage '%s'" ), name );
548
+ break ;
549
+ }
550
+ }
551
+
552
+ if (!res && write_locked_index (s -> r -> index , & index_lock , COMMIT_LOCK ) < 0 )
553
+ res = error (_ ("could not write index" ));
554
+
555
+ if (!res )
556
+ printf (Q_ ("updated %d path\n" ,
557
+ "updated %d paths\n" , count ), (int )count );
558
+
559
+ putchar ('\n' );
560
+ free (selected );
561
+ return res ;
562
+ }
563
+
493
564
static int run_help (struct add_i_state * s , const struct pathspec * ps ,
494
- struct file_list * files , struct list_options * opts )
565
+ struct file_list * files ,
566
+ struct list_and_choose_options * opts )
495
567
{
496
568
const char * help_color = s -> help_color ;
497
569
@@ -511,6 +583,27 @@ static int run_help(struct add_i_state *s, const struct pathspec *ps,
511
583
return 0 ;
512
584
}
513
585
586
+ static void choose_prompt_help (struct add_i_state * s )
587
+ {
588
+ const char * help_color = s -> help_color ;
589
+ color_fprintf_ln (stdout , help_color , "%s" ,
590
+ _ ("Prompt help:" ));
591
+ color_fprintf_ln (stdout , help_color , "1 - %s" ,
592
+ _ ("select a single item" ));
593
+ color_fprintf_ln (stdout , help_color , "3-5 - %s" ,
594
+ _ ("select a range of items" ));
595
+ color_fprintf_ln (stdout , help_color , "2-3,6-9 - %s" ,
596
+ _ ("select multiple ranges" ));
597
+ color_fprintf_ln (stdout , help_color , "foo - %s" ,
598
+ _ ("select item based on unique prefix" ));
599
+ color_fprintf_ln (stdout , help_color , "-... - %s" ,
600
+ _ ("unselect specified items" ));
601
+ color_fprintf_ln (stdout , help_color , "* - %s" ,
602
+ _ ("choose all items" ));
603
+ color_fprintf_ln (stdout , help_color , " - %s" ,
604
+ _ ("(empty) finish selecting" ));
605
+ }
606
+
514
607
struct print_command_item_data {
515
608
const char * color , * reset ;
516
609
};
@@ -532,7 +625,8 @@ static void print_command_item(int i, int selected, struct prefix_item *item,
532
625
struct command_item {
533
626
struct prefix_item item ;
534
627
int (* command )(struct add_i_state * s , const struct pathspec * ps ,
535
- struct file_list * files , struct list_options * opts );
628
+ struct file_list * files ,
629
+ struct list_and_choose_options * opts );
536
630
};
537
631
538
632
static void command_prompt_help (struct add_i_state * s )
@@ -557,17 +651,20 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
557
651
};
558
652
struct command_item
559
653
status = { { "status" }, run_status },
654
+ update = { { "update" }, run_update },
560
655
help = { { "help" }, run_help };
561
656
struct command_item * commands [] = {
562
- & status ,
657
+ & status , & update ,
563
658
& help
564
659
};
565
660
566
661
struct print_file_item_data print_file_item_data = {
567
- "%12s %12s %s" , STRBUF_INIT , STRBUF_INIT , STRBUF_INIT
662
+ "%12s %12s %s" , NULL , NULL ,
663
+ STRBUF_INIT , STRBUF_INIT , STRBUF_INIT , STRBUF_INIT
568
664
};
569
- struct list_options opts = {
570
- 0 , NULL , print_file_item , & print_file_item_data
665
+ struct list_and_choose_options opts = {
666
+ { 0 , NULL , print_file_item , & print_file_item_data },
667
+ NULL , 0 , choose_prompt_help
571
668
};
572
669
struct strbuf header = STRBUF_INIT ;
573
670
struct file_list files = { NULL };
@@ -588,11 +685,13 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
588
685
data .color = "[" ;
589
686
data .reset = "]" ;
590
687
}
688
+ print_file_item_data .color = data .color ;
689
+ print_file_item_data .reset = data .reset ;
591
690
592
691
strbuf_addstr (& header , " " );
593
692
strbuf_addf (& header , print_file_item_data .modified_fmt ,
594
693
_ ("staged" ), _ ("unstaged" ), _ ("path" ));
595
- opts .header = header .buf ;
694
+ opts .list_opts . header = header .buf ;
596
695
597
696
repo_refresh_and_write_index (r , REFRESH_QUIET , 1 );
598
697
if (run_status (& s , ps , & files , & opts ) < 0 )
@@ -612,6 +711,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
612
711
613
712
release_file_list (& files );
614
713
strbuf_release (& print_file_item_data .buf );
714
+ strbuf_release (& print_file_item_data .name );
615
715
strbuf_release (& print_file_item_data .index );
616
716
strbuf_release (& print_file_item_data .worktree );
617
717
strbuf_release (& header );
0 commit comments