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 ;
@@ -459,30 +460,43 @@ static int is_valid_prefix(const char *prefix, size_t prefix_len)
459
460
}
460
461
461
462
struct print_file_item_data {
462
- const char * modified_fmt ;
463
- struct strbuf buf , index , worktree ;
463
+ const char * modified_fmt , * color , * reset ;
464
+ struct strbuf buf , name , index , worktree ;
464
465
};
465
466
466
467
static void print_file_item (int i , int selected , struct prefix_item * item ,
467
468
void * print_file_item_data )
468
469
{
469
470
struct file_item * c = (struct file_item * )item ;
470
471
struct print_file_item_data * d = print_file_item_data ;
472
+ const char * highlighted = NULL ;
471
473
472
474
strbuf_reset (& d -> index );
473
475
strbuf_reset (& d -> worktree );
474
476
strbuf_reset (& d -> buf );
475
477
478
+ /* Format the item with the prefix highlighted. */
479
+ if (item -> prefix_length > 0 &&
480
+ is_valid_prefix (item -> name , item -> prefix_length )) {
481
+ strbuf_reset (& d -> name );
482
+ strbuf_addf (& d -> name , "%s%.*s%s%s" , d -> color ,
483
+ (int )item -> prefix_length , item -> name , d -> reset ,
484
+ item -> name + item -> prefix_length );
485
+ highlighted = d -> name .buf ;
486
+ }
487
+
476
488
populate_wi_changes (& d -> worktree , & c -> worktree , _ ("nothing" ));
477
489
populate_wi_changes (& d -> index , & c -> index , _ ("unchanged" ));
478
490
strbuf_addf (& d -> buf , d -> modified_fmt ,
479
- d -> index .buf , d -> worktree .buf , item -> name );
491
+ d -> index .buf , d -> worktree .buf ,
492
+ highlighted ? highlighted : item -> name );
480
493
481
494
printf ("%c%2d: %s" , selected ? '*' : ' ' , i + 1 , d -> buf .buf );
482
495
}
483
496
484
497
static int run_status (struct add_i_state * s , const struct pathspec * ps ,
485
- struct file_list * files , struct list_options * opts )
498
+ struct file_list * files ,
499
+ struct list_and_choose_options * opts )
486
500
{
487
501
reset_file_list (files );
488
502
@@ -491,14 +505,72 @@ static int run_status(struct add_i_state *s, const struct pathspec *ps,
491
505
492
506
if (files -> nr )
493
507
list ((struct prefix_item * * )files -> file , NULL , files -> nr ,
494
- s , opts );
508
+ s , & opts -> list_opts );
495
509
putchar ('\n' );
496
510
497
511
return 0 ;
498
512
}
499
513
514
+ static int run_update (struct add_i_state * s , const struct pathspec * ps ,
515
+ struct file_list * files ,
516
+ struct list_and_choose_options * opts )
517
+ {
518
+ int res = 0 , fd , * selected = NULL ;
519
+ size_t count , i ;
520
+ struct lock_file index_lock ;
521
+
522
+ reset_file_list (files );
523
+
524
+ if (get_modified_files (s -> r , WORKTREE_ONLY , files , ps ) < 0 )
525
+ return -1 ;
526
+
527
+ if (!files -> nr ) {
528
+ putchar ('\n' );
529
+ return 0 ;
530
+ }
531
+
532
+ opts -> prompt = N_ ("Update" );
533
+ CALLOC_ARRAY (selected , files -> nr );
534
+
535
+ count = list_and_choose ((struct prefix_item * * )files -> file ,
536
+ selected , files -> nr , s , opts );
537
+ if (count <= 0 ) {
538
+ putchar ('\n' );
539
+ free (selected );
540
+ return 0 ;
541
+ }
542
+
543
+ fd = repo_hold_locked_index (s -> r , & index_lock , LOCK_REPORT_ON_ERROR );
544
+ if (fd < 0 ) {
545
+ putchar ('\n' );
546
+ free (selected );
547
+ return -1 ;
548
+ }
549
+
550
+ for (i = 0 ; i < files -> nr ; i ++ ) {
551
+ const char * name = files -> file [i ]-> item .name ;
552
+ if (selected [i ] &&
553
+ add_file_to_index (s -> r -> index , name , 0 ) < 0 ) {
554
+ res = error (_ ("could not stage '%s'" ), name );
555
+ break ;
556
+ }
557
+ }
558
+
559
+ if (!res && write_locked_index (s -> r -> index , & index_lock , COMMIT_LOCK ) < 0 )
560
+ res = error (_ ("could not write index" ));
561
+
562
+ if (!res )
563
+ printf (Q_ ("updated %d path\n" ,
564
+ "updated %d paths\n" , count ), (int )count );
565
+
566
+ putchar ('\n' );
567
+ free (selected );
568
+ return res ;
569
+ }
570
+
500
571
static int run_help (struct add_i_state * s , const struct pathspec * ps ,
501
- struct file_list * files , struct list_options * opts )
572
+ struct file_list * files ,
573
+ struct list_and_choose_options * opts )
502
574
{
503
575
const char * help_color = s -> help_color ;
504
576
@@ -518,6 +590,27 @@ static int run_help(struct add_i_state *s, const struct pathspec *ps,
518
590
return 0 ;
519
591
}
520
592
593
+ static void choose_prompt_help (struct add_i_state * s )
594
+ {
595
+ const char * help_color = s -> help_color ;
596
+ color_fprintf_ln (stdout , help_color , "%s" ,
597
+ _ ("Prompt help:" ));
598
+ color_fprintf_ln (stdout , help_color , "1 - %s" ,
599
+ _ ("select a single item" ));
600
+ color_fprintf_ln (stdout , help_color , "3-5 - %s" ,
601
+ _ ("select a range of items" ));
602
+ color_fprintf_ln (stdout , help_color , "2-3,6-9 - %s" ,
603
+ _ ("select multiple ranges" ));
604
+ color_fprintf_ln (stdout , help_color , "foo - %s" ,
605
+ _ ("select item based on unique prefix" ));
606
+ color_fprintf_ln (stdout , help_color , "-... - %s" ,
607
+ _ ("unselect specified items" ));
608
+ color_fprintf_ln (stdout , help_color , "* - %s" ,
609
+ _ ("choose all items" ));
610
+ color_fprintf_ln (stdout , help_color , " - %s" ,
611
+ _ ("(empty) finish selecting" ));
612
+ }
613
+
521
614
struct print_command_item_data {
522
615
const char * color , * reset ;
523
616
};
@@ -539,7 +632,8 @@ static void print_command_item(int i, int selected, struct prefix_item *item,
539
632
struct command_item {
540
633
struct prefix_item item ;
541
634
int (* command )(struct add_i_state * s , const struct pathspec * ps ,
542
- struct file_list * files , struct list_options * opts );
635
+ struct file_list * files ,
636
+ struct list_and_choose_options * opts );
543
637
};
544
638
545
639
static void command_prompt_help (struct add_i_state * s )
@@ -564,17 +658,20 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
564
658
};
565
659
struct command_item
566
660
status = { { "status" }, run_status },
661
+ update = { { "update" }, run_update },
567
662
help = { { "help" }, run_help };
568
663
struct command_item * commands [] = {
569
- & status ,
664
+ & status , & update ,
570
665
& help
571
666
};
572
667
573
668
struct print_file_item_data print_file_item_data = {
574
- "%12s %12s %s" , STRBUF_INIT , STRBUF_INIT , STRBUF_INIT
669
+ "%12s %12s %s" , NULL , NULL ,
670
+ STRBUF_INIT , STRBUF_INIT , STRBUF_INIT , STRBUF_INIT
575
671
};
576
- struct list_options opts = {
577
- 0 , NULL , print_file_item , & print_file_item_data
672
+ struct list_and_choose_options opts = {
673
+ { 0 , NULL , print_file_item , & print_file_item_data },
674
+ NULL , 0 , choose_prompt_help
578
675
};
579
676
struct strbuf header = STRBUF_INIT ;
580
677
struct file_list files = { NULL };
@@ -595,11 +692,13 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
595
692
data .color = "[" ;
596
693
data .reset = "]" ;
597
694
}
695
+ print_file_item_data .color = data .color ;
696
+ print_file_item_data .reset = data .reset ;
598
697
599
698
strbuf_addstr (& header , " " );
600
699
strbuf_addf (& header , print_file_item_data .modified_fmt ,
601
700
_ ("staged" ), _ ("unstaged" ), _ ("path" ));
602
- opts .header = header .buf ;
701
+ opts .list_opts . header = header .buf ;
603
702
604
703
repo_refresh_and_write_index (r , REFRESH_QUIET , 1 );
605
704
if (run_status (& s , ps , & files , & opts ) < 0 )
@@ -619,6 +718,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
619
718
620
719
release_file_list (& files );
621
720
strbuf_release (& print_file_item_data .buf );
721
+ strbuf_release (& print_file_item_data .name );
622
722
strbuf_release (& print_file_item_data .index );
623
723
strbuf_release (& print_file_item_data .worktree );
624
724
strbuf_release (& header );
0 commit comments