1212#include "reachable.h"
1313#include "worktree.h"
1414
15- /* NEEDSWORK: switch to using parse_options */
16- static const char reflog_expire_usage [] =
17- N_ ("git reflog expire [--expire=<time>] "
18- "[--expire-unreachable=<time>] "
19- "[--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] "
20- "[--verbose] [--all] <refs>..." );
21- static const char reflog_delete_usage [] =
22- N_ ("git reflog delete [--rewrite] [--updateref] "
23- "[--dry-run | -n] [--verbose] <refs>..." );
2415static const char reflog_exists_usage [] =
2516N_ ("git reflog exists <ref>" );
2617
@@ -29,6 +20,7 @@ static timestamp_t default_reflog_expire_unreachable;
2920
3021struct cmd_reflog_expire_cb {
3122 int stalefix ;
23+ int explicit_expiry ;
3224 timestamp_t expire_total ;
3325 timestamp_t expire_unreachable ;
3426 int recno ;
@@ -520,18 +512,18 @@ static int reflog_expire_config(const char *var, const char *value, void *cb)
520512 return 0 ;
521513}
522514
523- static void set_reflog_expiry_param (struct cmd_reflog_expire_cb * cb , int slot , const char * ref )
515+ static void set_reflog_expiry_param (struct cmd_reflog_expire_cb * cb , const char * ref )
524516{
525517 struct reflog_expire_cfg * ent ;
526518
527- if (slot == (EXPIRE_TOTAL |EXPIRE_UNREACH ))
519+ if (cb -> explicit_expiry == (EXPIRE_TOTAL |EXPIRE_UNREACH ))
528520 return ; /* both given explicitly -- nothing to tweak */
529521
530522 for (ent = reflog_expire_cfg ; ent ; ent = ent -> next ) {
531523 if (!wildmatch (ent -> pattern , ref , 0 )) {
532- if (!(slot & EXPIRE_TOTAL ))
524+ if (!(cb -> explicit_expiry & EXPIRE_TOTAL ))
533525 cb -> expire_total = ent -> expire_total ;
534- if (!(slot & EXPIRE_UNREACH ))
526+ if (!(cb -> explicit_expiry & EXPIRE_UNREACH ))
535527 cb -> expire_unreachable = ent -> expire_unreachable ;
536528 return ;
537529 }
@@ -541,29 +533,89 @@ static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, int slot, c
541533 * If unconfigured, make stash never expire
542534 */
543535 if (!strcmp (ref , "refs/stash" )) {
544- if (!(slot & EXPIRE_TOTAL ))
536+ if (!(cb -> explicit_expiry & EXPIRE_TOTAL ))
545537 cb -> expire_total = 0 ;
546- if (!(slot & EXPIRE_UNREACH ))
538+ if (!(cb -> explicit_expiry & EXPIRE_UNREACH ))
547539 cb -> expire_unreachable = 0 ;
548540 return ;
549541 }
550542
551543 /* Nothing matched -- use the default value */
552- if (!(slot & EXPIRE_TOTAL ))
544+ if (!(cb -> explicit_expiry & EXPIRE_TOTAL ))
553545 cb -> expire_total = default_reflog_expire ;
554- if (!(slot & EXPIRE_UNREACH ))
546+ if (!(cb -> explicit_expiry & EXPIRE_UNREACH ))
555547 cb -> expire_unreachable = default_reflog_expire_unreachable ;
556548}
557549
550+ static const char * reflog_expire_usage [] = {
551+ N_ ("git reflog expire [--expire=<time>] "
552+ "[--expire-unreachable=<time>] "
553+ "[--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] "
554+ "[--verbose] [--all] <refs>..." ),
555+ NULL
556+ };
557+
558+ static int expire_unreachable_callback (const struct option * opt ,
559+ const char * arg ,
560+ int unset )
561+ {
562+ struct cmd_reflog_expire_cb * cmd = opt -> value ;
563+
564+ if (parse_expiry_date (arg , & cmd -> expire_unreachable ))
565+ die (_ ("invalid timestamp '%s' given to '--%s'" ),
566+ arg , opt -> long_name );
567+
568+ cmd -> explicit_expiry |= EXPIRE_UNREACH ;
569+ return 0 ;
570+ }
571+
572+ static int expire_total_callback (const struct option * opt ,
573+ const char * arg ,
574+ int unset )
575+ {
576+ struct cmd_reflog_expire_cb * cmd = opt -> value ;
577+
578+ if (parse_expiry_date (arg , & cmd -> expire_total ))
579+ die (_ ("invalid timestamp '%s' given to '--%s'" ),
580+ arg , opt -> long_name );
581+
582+ cmd -> explicit_expiry |= EXPIRE_TOTAL ;
583+ return 0 ;
584+ }
585+
558586static int cmd_reflog_expire (int argc , const char * * argv , const char * prefix )
559587{
560588 struct cmd_reflog_expire_cb cmd = { 0 };
561589 timestamp_t now = time (NULL );
562590 int i , status , do_all , all_worktrees = 1 ;
563- int explicit_expiry = 0 ;
564591 unsigned int flags = 0 ;
565592 int verbose = 0 ;
566593 reflog_expiry_should_prune_fn * should_prune_fn = should_expire_reflog_ent ;
594+ const struct option options [] = {
595+ OPT_BIT (0 , "dry-run" , & flags , N_ ("do not actually prune any entries" ),
596+ EXPIRE_REFLOGS_DRY_RUN ),
597+ OPT_BIT (0 , "rewrite" , & flags ,
598+ N_ ("rewrite the old SHA1 with the new SHA1 of the entry that now precedes it" ),
599+ EXPIRE_REFLOGS_REWRITE ),
600+ OPT_BIT (0 , "updateref" , & flags ,
601+ N_ ("update the reference to the value of the top reflog entry" ),
602+ EXPIRE_REFLOGS_UPDATE_REF ),
603+ OPT_BOOL (0 , "verbose" , & verbose , N_ ("print extra information on screen." )),
604+ OPT_CALLBACK_F (0 , "expire" , & cmd , N_ ("timestamp" ),
605+ N_ ("prune entries older than the specified time" ),
606+ PARSE_OPT_NONEG ,
607+ expire_total_callback ),
608+ OPT_CALLBACK_F (0 , "expire-unreachable" , & cmd , N_ ("timestamp" ),
609+ N_ ("prune entries older than <time> that are not reachable from the current tip of the branch" ),
610+ PARSE_OPT_NONEG ,
611+ expire_unreachable_callback ),
612+ OPT_BOOL (0 , "stale-fix" , & cmd .stalefix ,
613+ N_ ("prune any reflog entries that point to broken commits" )),
614+ OPT_BOOL (0 , "all" , & do_all , N_ ("process the reflogs of all references" )),
615+ OPT_BOOL (1 , "single-worktree" , & all_worktrees ,
616+ N_ ("limits processing to reflogs from the current worktree only." )),
617+ OPT_END ()
618+ };
567619
568620 default_reflog_expire_unreachable = now - 30 * 24 * 3600 ;
569621 default_reflog_expire = now - 90 * 24 * 3600 ;
@@ -572,45 +624,11 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
572624 save_commit_buffer = 0 ;
573625 do_all = status = 0 ;
574626
627+ cmd .explicit_expiry = 0 ;
575628 cmd .expire_total = default_reflog_expire ;
576629 cmd .expire_unreachable = default_reflog_expire_unreachable ;
577630
578- for (i = 1 ; i < argc ; i ++ ) {
579- const char * arg = argv [i ];
580-
581- if (!strcmp (arg , "--dry-run" ) || !strcmp (arg , "-n" ))
582- flags |= EXPIRE_REFLOGS_DRY_RUN ;
583- else if (skip_prefix (arg , "--expire=" , & arg )) {
584- if (parse_expiry_date (arg , & cmd .expire_total ))
585- die (_ ("'%s' is not a valid timestamp" ), arg );
586- explicit_expiry |= EXPIRE_TOTAL ;
587- }
588- else if (skip_prefix (arg , "--expire-unreachable=" , & arg )) {
589- if (parse_expiry_date (arg , & cmd .expire_unreachable ))
590- die (_ ("'%s' is not a valid timestamp" ), arg );
591- explicit_expiry |= EXPIRE_UNREACH ;
592- }
593- else if (!strcmp (arg , "--stale-fix" ))
594- cmd .stalefix = 1 ;
595- else if (!strcmp (arg , "--rewrite" ))
596- flags |= EXPIRE_REFLOGS_REWRITE ;
597- else if (!strcmp (arg , "--updateref" ))
598- flags |= EXPIRE_REFLOGS_UPDATE_REF ;
599- else if (!strcmp (arg , "--all" ))
600- do_all = 1 ;
601- else if (!strcmp (arg , "--single-worktree" ))
602- all_worktrees = 0 ;
603- else if (!strcmp (arg , "--verbose" ))
604- verbose = 1 ;
605- else if (!strcmp (arg , "--" )) {
606- i ++ ;
607- break ;
608- }
609- else if (arg [0 ] == '-' )
610- usage (_ (reflog_expire_usage ));
611- else
612- break ;
613- }
631+ argc = parse_options (argc , argv , prefix , options , reflog_expire_usage , 0 );
614632
615633 if (verbose )
616634 should_prune_fn = should_expire_reflog_ent_verbose ;
@@ -657,7 +675,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
657675 .dry_run = !!(flags & EXPIRE_REFLOGS_DRY_RUN ),
658676 };
659677
660- set_reflog_expiry_param (& cb .cmd , explicit_expiry , item -> string );
678+ set_reflog_expiry_param (& cb .cmd , item -> string );
661679 status |= reflog_expire (item -> string , flags ,
662680 reflog_expiry_prepare ,
663681 should_prune_fn ,
@@ -667,15 +685,15 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
667685 string_list_clear (& collected .reflogs , 0 );
668686 }
669687
670- for (; i < argc ; i ++ ) {
688+ for (i = 0 ; i < argc ; i ++ ) {
671689 char * ref ;
672690 struct expire_reflog_policy_cb cb = { .cmd = cmd };
673691
674692 if (!dwim_log (argv [i ], strlen (argv [i ]), NULL , & ref )) {
675693 status |= error (_ ("%s points nowhere!" ), argv [i ]);
676694 continue ;
677695 }
678- set_reflog_expiry_param (& cb .cmd , explicit_expiry , ref );
696+ set_reflog_expiry_param (& cb .cmd , ref );
679697 status |= reflog_expire (ref , flags ,
680698 reflog_expiry_prepare ,
681699 should_prune_fn ,
@@ -696,41 +714,41 @@ static int count_reflog_ent(struct object_id *ooid, struct object_id *noid,
696714 return 0 ;
697715}
698716
717+ static const char * reflog_delete_usage [] = {
718+ N_ ("git reflog delete [--rewrite] [--updateref] "
719+ "[--dry-run | -n] [--verbose] <refs>..." ),
720+ NULL
721+ };
722+
699723static int cmd_reflog_delete (int argc , const char * * argv , const char * prefix )
700724{
701725 struct cmd_reflog_expire_cb cmd = { 0 };
702726 int i , status = 0 ;
703727 unsigned int flags = 0 ;
704728 int verbose = 0 ;
705729 reflog_expiry_should_prune_fn * should_prune_fn = should_expire_reflog_ent ;
706-
707- for (i = 1 ; i < argc ; i ++ ) {
708- const char * arg = argv [i ];
709- if (!strcmp (arg , "--dry-run" ) || !strcmp (arg , "-n" ))
710- flags |= EXPIRE_REFLOGS_DRY_RUN ;
711- else if (!strcmp (arg , "--rewrite" ))
712- flags |= EXPIRE_REFLOGS_REWRITE ;
713- else if (!strcmp (arg , "--updateref" ))
714- flags |= EXPIRE_REFLOGS_UPDATE_REF ;
715- else if (!strcmp (arg , "--verbose" ))
716- verbose = 1 ;
717- else if (!strcmp (arg , "--" )) {
718- i ++ ;
719- break ;
720- }
721- else if (arg [0 ] == '-' )
722- usage (_ (reflog_delete_usage ));
723- else
724- break ;
725- }
730+ const struct option options [] = {
731+ OPT_BIT (0 , "dry-run" , & flags , N_ ("do not actually prune any entries" ),
732+ EXPIRE_REFLOGS_DRY_RUN ),
733+ OPT_BIT (0 , "rewrite" , & flags ,
734+ N_ ("rewrite the old SHA1 with the new SHA1 of the entry that now precedes it" ),
735+ EXPIRE_REFLOGS_REWRITE ),
736+ OPT_BIT (0 , "updateref" , & flags ,
737+ N_ ("update the reference to the value of the top reflog entry" ),
738+ EXPIRE_REFLOGS_UPDATE_REF ),
739+ OPT_BOOL (0 , "verbose" , & verbose , N_ ("print extra information on screen." )),
740+ OPT_END ()
741+ };
742+
743+ argc = parse_options (argc , argv , prefix , options , reflog_delete_usage , 0 );
726744
727745 if (verbose )
728746 should_prune_fn = should_expire_reflog_ent_verbose ;
729747
730- if (argc - i < 1 )
748+ if (argc < 1 )
731749 return error (_ ("no reflog specified to delete" ));
732750
733- for ( ; i < argc ; i ++ ) {
751+ for (i = 0 ; i < argc ; i ++ ) {
734752 const char * spec = strstr (argv [i ], "@{" );
735753 char * ep , * ref ;
736754 int recno ;
0 commit comments