3636#include "reflog.h"
3737#include "repack.h"
3838#include "rerere.h"
39+ #include "revision.h"
3940#include "blob.h"
4041#include "tree.h"
4142#include "promisor-remote.h"
@@ -286,12 +287,26 @@ static void maintenance_run_opts_release(struct maintenance_run_opts *opts)
286287
287288static int pack_refs_condition (UNUSED struct gc_config * cfg )
288289{
289- /*
290- * The auto-repacking logic for refs is handled by the ref backends and
291- * exposed via `git pack-refs --auto`. We thus always return truish
292- * here and let the backend decide for us.
293- */
294- return 1 ;
290+ struct string_list included_refs = STRING_LIST_INIT_NODUP ;
291+ struct ref_exclusions excludes = REF_EXCLUSIONS_INIT ;
292+ struct refs_optimize_opts optimize_opts = {
293+ .exclusions = & excludes ,
294+ .includes = & included_refs ,
295+ .flags = REFS_OPTIMIZE_PRUNE | REFS_OPTIMIZE_AUTO ,
296+ };
297+ bool required ;
298+
299+ /* Check for all refs, similar to 'git refs optimize --all'. */
300+ string_list_append (optimize_opts .includes , "*" );
301+
302+ if (refs_optimize_required (get_main_ref_store (the_repository ),
303+ & optimize_opts , & required ))
304+ return 0 ;
305+
306+ clear_ref_exclusions (& excludes );
307+ string_list_clear (& included_refs , 0 );
308+
309+ return required == true;
295310}
296311
297312static int maintenance_task_pack_refs (struct maintenance_run_opts * opts ,
@@ -1095,9 +1110,6 @@ static int maintenance_opt_schedule(const struct option *opt, const char *arg,
10951110 return 0 ;
10961111}
10971112
1098- /* Remember to update object flag allocation in object.h */
1099- #define SEEN (1u<<0)
1100-
11011113struct cg_auto_data {
11021114 int num_not_in_graph ;
11031115 int limit ;
@@ -3444,7 +3456,59 @@ static int maintenance_stop(int argc, const char **argv, const char *prefix,
34443456 return update_background_schedule (NULL , 0 );
34453457}
34463458
3447- static const char * const builtin_maintenance_usage [] = {
3459+ static const char * const builtin_maintenance_is_needed_usage [] = {
3460+ "git maintenance is-needed [--task=<task>] [--schedule]" ,
3461+ NULL
3462+ };
3463+
3464+ static int maintenance_is_needed (int argc , const char * * argv , const char * prefix ,
3465+ struct repository * repo UNUSED )
3466+ {
3467+ struct maintenance_run_opts opts = MAINTENANCE_RUN_OPTS_INIT ;
3468+ struct string_list selected_tasks = STRING_LIST_INIT_DUP ;
3469+ struct gc_config cfg = GC_CONFIG_INIT ;
3470+ struct option options [] = {
3471+ OPT_BOOL (0 , "auto" , & opts .auto_flag ,
3472+ N_ ("run tasks based on the state of the repository" )),
3473+ OPT_CALLBACK_F (0 , "task" , & selected_tasks , N_ ("task" ),
3474+ N_ ("check a specific task" ),
3475+ PARSE_OPT_NONEG , task_option_parse ),
3476+ OPT_END ()
3477+ };
3478+ bool is_needed = false;
3479+
3480+ argc = parse_options (argc , argv , prefix , options ,
3481+ builtin_maintenance_is_needed_usage ,
3482+ PARSE_OPT_STOP_AT_NON_OPTION );
3483+ if (argc )
3484+ usage_with_options (builtin_maintenance_is_needed_usage , options );
3485+
3486+ gc_config (& cfg );
3487+ initialize_task_config (& opts , & selected_tasks );
3488+
3489+ if (opts .auto_flag ) {
3490+ for (size_t i = 0 ; i < opts .tasks_nr ; i ++ ) {
3491+ if (tasks [opts .tasks [i ]].auto_condition &&
3492+ tasks [opts .tasks [i ]].auto_condition (& cfg )) {
3493+ is_needed = true;
3494+ break ;
3495+ }
3496+ }
3497+ } else {
3498+ /* When not using --auto, we should always require maintenance. */
3499+ is_needed = true;
3500+ }
3501+
3502+ string_list_clear (& selected_tasks , 0 );
3503+ maintenance_run_opts_release (& opts );
3504+ gc_config_release (& cfg );
3505+
3506+ if (is_needed )
3507+ return 0 ;
3508+ return 1 ;
3509+ }
3510+
3511+ static const char * const builtin_maintenance_usage [] = {
34483512 N_ ("git maintenance <subcommand> [<options>]" ),
34493513 NULL ,
34503514};
@@ -3461,6 +3525,7 @@ int cmd_maintenance(int argc,
34613525 OPT_SUBCOMMAND ("stop" , & fn , maintenance_stop ),
34623526 OPT_SUBCOMMAND ("register" , & fn , maintenance_register ),
34633527 OPT_SUBCOMMAND ("unregister" , & fn , maintenance_unregister ),
3528+ OPT_SUBCOMMAND ("is-needed" , & fn , maintenance_is_needed ),
34643529 OPT_END (),
34653530 };
34663531
0 commit comments