@@ -32,7 +32,6 @@ static int write_bitmaps = -1;
32
32
static int use_delta_islands ;
33
33
static int run_update_server_info = 1 ;
34
34
static char * packdir , * packtmp_name , * packtmp ;
35
- static char * cruft_expiration ;
36
35
37
36
static const char * const git_repack_usage [] = {
38
37
N_ ("git repack [<options>]" ),
@@ -150,7 +149,8 @@ static void remove_redundant_pack(const char *dir_name, const char *base_name)
150
149
}
151
150
152
151
static void prepare_pack_objects (struct child_process * cmd ,
153
- const struct pack_objects_args * args )
152
+ const struct pack_objects_args * args ,
153
+ const char * out )
154
154
{
155
155
strvec_push (& cmd -> args , "pack-objects" );
156
156
if (args -> window )
@@ -173,7 +173,7 @@ static void prepare_pack_objects(struct child_process *cmd,
173
173
strvec_push (& cmd -> args , "--quiet" );
174
174
if (delta_base_offset )
175
175
strvec_push (& cmd -> args , "--delta-base-offset" );
176
- strvec_push (& cmd -> args , packtmp );
176
+ strvec_push (& cmd -> args , out );
177
177
cmd -> git_cmd = 1 ;
178
178
cmd -> out = -1 ;
179
179
}
@@ -241,7 +241,7 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
241
241
FILE * out ;
242
242
struct strbuf line = STRBUF_INIT ;
243
243
244
- prepare_pack_objects (& cmd , args );
244
+ prepare_pack_objects (& cmd , args , packtmp );
245
245
cmd .in = -1 ;
246
246
247
247
/*
@@ -657,7 +657,9 @@ static void remove_redundant_bitmaps(struct string_list *include,
657
657
}
658
658
659
659
static int write_cruft_pack (const struct pack_objects_args * args ,
660
+ const char * destination ,
660
661
const char * pack_prefix ,
662
+ const char * cruft_expiration ,
661
663
struct string_list * names ,
662
664
struct string_list * existing_packs ,
663
665
struct string_list * existing_kept_packs )
@@ -667,8 +669,10 @@ static int write_cruft_pack(const struct pack_objects_args *args,
667
669
struct string_list_item * item ;
668
670
FILE * in , * out ;
669
671
int ret ;
672
+ const char * scratch ;
673
+ int local = skip_prefix (destination , packdir , & scratch );
670
674
671
- prepare_pack_objects (& cmd , args );
675
+ prepare_pack_objects (& cmd , args , destination );
672
676
673
677
strvec_push (& cmd .args , "--cruft" );
674
678
if (cruft_expiration )
@@ -693,6 +697,10 @@ static int write_cruft_pack(const struct pack_objects_args *args,
693
697
* By the time it is read here, it contains only the pack(s)
694
698
* that were just written, which is exactly the set of packs we
695
699
* want to consider kept.
700
+ *
701
+ * If `--expire-to` is given, the double-use served by `names`
702
+ * ensures that the pack written to `--expire-to` excludes any
703
+ * objects contained in the cruft pack.
696
704
*/
697
705
in = xfdopen (cmd .in , "w" );
698
706
for_each_string_list_item (item , names )
@@ -710,9 +718,14 @@ static int write_cruft_pack(const struct pack_objects_args *args,
710
718
if (line .len != the_hash_algo -> hexsz )
711
719
die (_ ("repack: Expecting full hex object ID lines only "
712
720
"from pack-objects." ));
713
-
714
- item = string_list_append (names , line .buf );
715
- item -> util = populate_pack_exts (line .buf );
721
+ /*
722
+ * avoid putting packs written outside of the repository in the
723
+ * list of names
724
+ */
725
+ if (local ) {
726
+ item = string_list_append (names , line .buf );
727
+ item -> util = populate_pack_exts (line .buf );
728
+ }
716
729
}
717
730
fclose (out );
718
731
@@ -744,6 +757,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
744
757
struct pack_objects_args cruft_po_args = {NULL };
745
758
int geometric_factor = 0 ;
746
759
int write_midx = 0 ;
760
+ const char * cruft_expiration = NULL ;
761
+ const char * expire_to = NULL ;
747
762
748
763
struct option builtin_repack_options [] = {
749
764
OPT_BIT ('a' , NULL , & pack_everything ,
@@ -793,6 +808,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
793
808
N_ ("find a geometric progression with factor <N>" )),
794
809
OPT_BOOL ('m' , "write-midx" , & write_midx ,
795
810
N_ ("write a multi-pack index of the resulting packs" )),
811
+ OPT_STRING (0 , "expire-to" , & expire_to , N_ ("dir" ),
812
+ N_ ("pack prefix to store a pack containing pruned objects" )),
796
813
OPT_END ()
797
814
};
798
815
@@ -858,7 +875,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
858
875
split_pack_geometry (geometry , geometric_factor );
859
876
}
860
877
861
- prepare_pack_objects (& cmd , & po_args );
878
+ prepare_pack_objects (& cmd , & po_args , packtmp );
862
879
863
880
show_progress = !po_args .quiet && isatty (2 );
864
881
@@ -984,11 +1001,45 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
984
1001
cruft_po_args .local = po_args .local ;
985
1002
cruft_po_args .quiet = po_args .quiet ;
986
1003
987
- ret = write_cruft_pack (& cruft_po_args , pack_prefix , & names ,
1004
+ ret = write_cruft_pack (& cruft_po_args , packtmp , pack_prefix ,
1005
+ cruft_expiration , & names ,
988
1006
& existing_nonkept_packs ,
989
1007
& existing_kept_packs );
990
1008
if (ret )
991
1009
return ret ;
1010
+
1011
+ if (delete_redundant && expire_to ) {
1012
+ /*
1013
+ * If `--expire-to` is given with `-d`, it's possible
1014
+ * that we're about to prune some objects. With cruft
1015
+ * packs, pruning is implicit: any objects from existing
1016
+ * packs that weren't picked up by new packs are removed
1017
+ * when their packs are deleted.
1018
+ *
1019
+ * Generate an additional cruft pack, with one twist:
1020
+ * `names` now includes the name of the cruft pack
1021
+ * written in the previous step. So the contents of
1022
+ * _this_ cruft pack exclude everything contained in the
1023
+ * existing cruft pack (that is, all of the unreachable
1024
+ * objects which are no older than
1025
+ * `--cruft-expiration`).
1026
+ *
1027
+ * To make this work, cruft_expiration must become NULL
1028
+ * so that this cruft pack doesn't actually prune any
1029
+ * objects. If it were non-NULL, this call would always
1030
+ * generate an empty pack (since every object not in the
1031
+ * cruft pack generated above will have an mtime older
1032
+ * than the expiration).
1033
+ */
1034
+ ret = write_cruft_pack (& cruft_po_args , expire_to ,
1035
+ pack_prefix ,
1036
+ NULL ,
1037
+ & names ,
1038
+ & existing_nonkept_packs ,
1039
+ & existing_kept_packs );
1040
+ if (ret )
1041
+ return ret ;
1042
+ }
992
1043
}
993
1044
994
1045
string_list_sort (& names );
0 commit comments