@@ -139,9 +139,9 @@ struct gc_config {
139
139
int gc_auto_threshold ;
140
140
int gc_auto_pack_limit ;
141
141
int detach_auto ;
142
- const char * gc_log_expire ;
143
- const char * prune_expire ;
144
- const char * prune_worktrees_expire ;
142
+ char * gc_log_expire ;
143
+ char * prune_expire ;
144
+ char * prune_worktrees_expire ;
145
145
char * repack_filter ;
146
146
char * repack_filter_to ;
147
147
unsigned long big_pack_threshold ;
@@ -157,15 +157,25 @@ struct gc_config {
157
157
.gc_auto_threshold = 6700, \
158
158
.gc_auto_pack_limit = 50, \
159
159
.detach_auto = 1, \
160
- .gc_log_expire = "1.day.ago", \
161
- .prune_expire = "2.weeks.ago", \
162
- .prune_worktrees_expire = "3.months.ago", \
160
+ .gc_log_expire = xstrdup( "1.day.ago") , \
161
+ .prune_expire = xstrdup( "2.weeks.ago") , \
162
+ .prune_worktrees_expire = xstrdup( "3.months.ago") , \
163
163
.max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE, \
164
164
}
165
165
166
+ static void gc_config_release (struct gc_config * cfg )
167
+ {
168
+ free (cfg -> gc_log_expire );
169
+ free (cfg -> prune_expire );
170
+ free (cfg -> prune_worktrees_expire );
171
+ free (cfg -> repack_filter );
172
+ free (cfg -> repack_filter_to );
173
+ }
174
+
166
175
static void gc_config (struct gc_config * cfg )
167
176
{
168
177
const char * value ;
178
+ char * owned = NULL ;
169
179
170
180
if (!git_config_get_value ("gc.packrefs" , & value )) {
171
181
if (value && !strcmp (value , "notbare" ))
@@ -185,15 +195,34 @@ static void gc_config(struct gc_config *cfg)
185
195
git_config_get_bool ("gc.autodetach" , & cfg -> detach_auto );
186
196
git_config_get_bool ("gc.cruftpacks" , & cfg -> cruft_packs );
187
197
git_config_get_ulong ("gc.maxcruftsize" , & cfg -> max_cruft_size );
188
- git_config_get_expiry ("gc.pruneexpire" , (char * * ) & cfg -> prune_expire );
189
- git_config_get_expiry ("gc.worktreepruneexpire" , (char * * ) & cfg -> prune_worktrees_expire );
190
- git_config_get_expiry ("gc.logexpiry" , (char * * ) & cfg -> gc_log_expire );
198
+
199
+ if (!git_config_get_expiry ("gc.pruneexpire" , & owned )) {
200
+ free (cfg -> prune_expire );
201
+ cfg -> prune_expire = owned ;
202
+ }
203
+
204
+ if (!git_config_get_expiry ("gc.worktreepruneexpire" , & owned )) {
205
+ free (cfg -> prune_worktrees_expire );
206
+ cfg -> prune_worktrees_expire = owned ;
207
+ }
208
+
209
+ if (!git_config_get_expiry ("gc.logexpiry" , & owned )) {
210
+ free (cfg -> gc_log_expire );
211
+ cfg -> gc_log_expire = owned ;
212
+ }
191
213
192
214
git_config_get_ulong ("gc.bigpackthreshold" , & cfg -> big_pack_threshold );
193
215
git_config_get_ulong ("pack.deltacachesize" , & cfg -> max_delta_cache_size );
194
216
195
- git_config_get_string ("gc.repackfilter" , & cfg -> repack_filter );
196
- git_config_get_string ("gc.repackfilterto" , & cfg -> repack_filter_to );
217
+ if (!git_config_get_string ("gc.repackfilter" , & owned )) {
218
+ free (cfg -> repack_filter );
219
+ cfg -> repack_filter = owned ;
220
+ }
221
+
222
+ if (!git_config_get_string ("gc.repackfilterto" , & owned )) {
223
+ free (cfg -> repack_filter_to );
224
+ cfg -> repack_filter_to = owned ;
225
+ }
197
226
198
227
git_config (git_default_config , NULL );
199
228
}
@@ -644,12 +673,15 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
644
673
struct child_process rerere_cmd = CHILD_PROCESS_INIT ;
645
674
struct maintenance_run_opts opts = {0 };
646
675
struct gc_config cfg = GC_CONFIG_INIT ;
676
+ const char * prune_expire_sentinel = "sentinel" ;
677
+ const char * prune_expire_arg = prune_expire_sentinel ;
678
+ int ret ;
647
679
648
680
struct option builtin_gc_options [] = {
649
681
OPT__QUIET (& quiet , N_ ("suppress progress reporting" )),
650
- { OPTION_STRING , 0 , "prune" , & cfg . prune_expire , N_ ("date" ),
682
+ { OPTION_STRING , 0 , "prune" , & prune_expire_arg , N_ ("date" ),
651
683
N_ ("prune unreferenced objects" ),
652
- PARSE_OPT_OPTARG , NULL , (intptr_t )cfg . prune_expire },
684
+ PARSE_OPT_OPTARG , NULL , (intptr_t )prune_expire_arg },
653
685
OPT_BOOL (0 , "cruft" , & cfg .cruft_packs , N_ ("pack unreferenced objects separately" )),
654
686
OPT_MAGNITUDE (0 , "max-cruft-size" , & cfg .max_cruft_size ,
655
687
N_ ("with --cruft, limit the size of new cruft packs" )),
@@ -673,8 +705,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
673
705
strvec_pushl (& prune_worktrees , "worktree" , "prune" , "--expire" , NULL );
674
706
strvec_pushl (& rerere , "rerere" , "gc" , NULL );
675
707
676
- /* default expiry time, overwritten in gc_config */
677
708
gc_config (& cfg );
709
+
678
710
if (parse_expiry_date (cfg .gc_log_expire , & gc_log_expire_time ))
679
711
die (_ ("failed to parse gc.logExpiry value %s" ), cfg .gc_log_expire );
680
712
@@ -686,6 +718,10 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
686
718
if (argc > 0 )
687
719
usage_with_options (builtin_gc_usage , builtin_gc_options );
688
720
721
+ if (prune_expire_arg != prune_expire_sentinel ) {
722
+ free (cfg .prune_expire );
723
+ cfg .prune_expire = xstrdup_or_null (prune_expire_arg );
724
+ }
689
725
if (cfg .prune_expire && parse_expiry_date (cfg .prune_expire , & dummy ))
690
726
die (_ ("failed to parse prune expiry value %s" ), cfg .prune_expire );
691
727
@@ -703,8 +739,11 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
703
739
/*
704
740
* Auto-gc should be least intrusive as possible.
705
741
*/
706
- if (!need_to_gc (& cfg ))
707
- return 0 ;
742
+ if (!need_to_gc (& cfg )) {
743
+ ret = 0 ;
744
+ goto out ;
745
+ }
746
+
708
747
if (!quiet ) {
709
748
if (cfg .detach_auto )
710
749
fprintf (stderr , _ ("Auto packing the repository in background for optimum performance.\n" ));
@@ -713,17 +752,22 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
713
752
fprintf (stderr , _ ("See \"git help gc\" for manual housekeeping.\n" ));
714
753
}
715
754
if (cfg .detach_auto ) {
716
- int ret = report_last_gc_error ();
717
-
718
- if (ret == 1 )
755
+ ret = report_last_gc_error ();
756
+ if (ret == 1 ) {
719
757
/* Last gc --auto failed. Skip this one. */
720
- return 0 ;
721
- else if (ret )
758
+ ret = 0 ;
759
+ goto out ;
760
+
761
+ } else if (ret ) {
722
762
/* an I/O error occurred, already reported */
723
- return ret ;
763
+ goto out ;
764
+ }
765
+
766
+ if (lock_repo_for_gc (force , & pid )) {
767
+ ret = 0 ;
768
+ goto out ;
769
+ }
724
770
725
- if (lock_repo_for_gc (force , & pid ))
726
- return 0 ;
727
771
gc_before_repack (& opts , & cfg ); /* dies on failure */
728
772
delete_tempfile (& pidfile );
729
773
@@ -749,8 +793,11 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
749
793
750
794
name = lock_repo_for_gc (force , & pid );
751
795
if (name ) {
752
- if (opts .auto_flag )
753
- return 0 ; /* be quiet on --auto */
796
+ if (opts .auto_flag ) {
797
+ ret = 0 ;
798
+ goto out ; /* be quiet on --auto */
799
+ }
800
+
754
801
die (_ ("gc is already running on machine '%s' pid %" PRIuMAX " (use --force if not)" ),
755
802
name , (uintmax_t )pid );
756
803
}
@@ -826,6 +873,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
826
873
if (!daemonized )
827
874
unlink (git_path ("gc.log" ));
828
875
876
+ out :
877
+ gc_config_release (& cfg );
829
878
return 0 ;
830
879
}
831
880
@@ -1511,6 +1560,8 @@ static int maintenance_run(int argc, const char **argv, const char *prefix)
1511
1560
PARSE_OPT_NONEG , task_option_parse ),
1512
1561
OPT_END ()
1513
1562
};
1563
+ int ret ;
1564
+
1514
1565
memset (& opts , 0 , sizeof (opts ));
1515
1566
1516
1567
opts .quiet = !isatty (2 );
@@ -1532,7 +1583,10 @@ static int maintenance_run(int argc, const char **argv, const char *prefix)
1532
1583
if (argc != 0 )
1533
1584
usage_with_options (builtin_maintenance_run_usage ,
1534
1585
builtin_maintenance_run_options );
1535
- return maintenance_run_tasks (& opts , & cfg );
1586
+
1587
+ ret = maintenance_run_tasks (& opts , & cfg );
1588
+ gc_config_release (& cfg );
1589
+ return ret ;
1536
1590
}
1537
1591
1538
1592
static char * get_maintpath (void )
0 commit comments