21
21
#include "pack.h"
22
22
#include "pack-bitmap.h"
23
23
#include "refs.h"
24
+ #include "list-objects-filter-options.h"
24
25
25
26
#define ALL_INTO_ONE 1
26
27
#define LOOSEN_UNREACHABLE 2
@@ -56,6 +57,7 @@ struct pack_objects_args {
56
57
int no_reuse_object ;
57
58
int quiet ;
58
59
int local ;
60
+ struct list_objects_filter_options filter_options ;
59
61
};
60
62
61
63
static int repack_config (const char * var , const char * value ,
@@ -806,6 +808,86 @@ static void remove_redundant_bitmaps(struct string_list *include,
806
808
strbuf_release (& path );
807
809
}
808
810
811
+ static int finish_pack_objects_cmd (struct child_process * cmd ,
812
+ struct string_list * names ,
813
+ int local )
814
+ {
815
+ FILE * out ;
816
+ struct strbuf line = STRBUF_INIT ;
817
+
818
+ out = xfdopen (cmd -> out , "r" );
819
+ while (strbuf_getline_lf (& line , out ) != EOF ) {
820
+ struct string_list_item * item ;
821
+
822
+ if (line .len != the_hash_algo -> hexsz )
823
+ die (_ ("repack: Expecting full hex object ID lines only "
824
+ "from pack-objects." ));
825
+ /*
826
+ * Avoid putting packs written outside of the repository in the
827
+ * list of names.
828
+ */
829
+ if (local ) {
830
+ item = string_list_append (names , line .buf );
831
+ item -> util = populate_pack_exts (line .buf );
832
+ }
833
+ }
834
+ fclose (out );
835
+
836
+ strbuf_release (& line );
837
+
838
+ return finish_command (cmd );
839
+ }
840
+
841
+ static int write_filtered_pack (const struct pack_objects_args * args ,
842
+ const char * destination ,
843
+ const char * pack_prefix ,
844
+ struct existing_packs * existing ,
845
+ struct string_list * names )
846
+ {
847
+ struct child_process cmd = CHILD_PROCESS_INIT ;
848
+ struct string_list_item * item ;
849
+ FILE * in ;
850
+ int ret ;
851
+ const char * caret ;
852
+ const char * scratch ;
853
+ int local = skip_prefix (destination , packdir , & scratch );
854
+
855
+ prepare_pack_objects (& cmd , args , destination );
856
+
857
+ strvec_push (& cmd .args , "--stdin-packs" );
858
+
859
+ if (!pack_kept_objects )
860
+ strvec_push (& cmd .args , "--honor-pack-keep" );
861
+ for_each_string_list_item (item , & existing -> kept_packs )
862
+ strvec_pushf (& cmd .args , "--keep-pack=%s" , item -> string );
863
+
864
+ cmd .in = -1 ;
865
+
866
+ ret = start_command (& cmd );
867
+ if (ret )
868
+ return ret ;
869
+
870
+ /*
871
+ * Here 'names' contains only the pack(s) that were just
872
+ * written, which is exactly the packs we want to keep. Also
873
+ * 'existing_kept_packs' already contains the packs in
874
+ * 'keep_pack_list'.
875
+ */
876
+ in = xfdopen (cmd .in , "w" );
877
+ for_each_string_list_item (item , names )
878
+ fprintf (in , "^%s-%s.pack\n" , pack_prefix , item -> string );
879
+ for_each_string_list_item (item , & existing -> non_kept_packs )
880
+ fprintf (in , "%s.pack\n" , item -> string );
881
+ for_each_string_list_item (item , & existing -> cruft_packs )
882
+ fprintf (in , "%s.pack\n" , item -> string );
883
+ caret = pack_kept_objects ? "" : "^" ;
884
+ for_each_string_list_item (item , & existing -> kept_packs )
885
+ fprintf (in , "%s%s.pack\n" , caret , item -> string );
886
+ fclose (in );
887
+
888
+ return finish_pack_objects_cmd (& cmd , names , local );
889
+ }
890
+
809
891
static int write_cruft_pack (const struct pack_objects_args * args ,
810
892
const char * destination ,
811
893
const char * pack_prefix ,
@@ -814,9 +896,8 @@ static int write_cruft_pack(const struct pack_objects_args *args,
814
896
struct existing_packs * existing )
815
897
{
816
898
struct child_process cmd = CHILD_PROCESS_INIT ;
817
- struct strbuf line = STRBUF_INIT ;
818
899
struct string_list_item * item ;
819
- FILE * in , * out ;
900
+ FILE * in ;
820
901
int ret ;
821
902
const char * scratch ;
822
903
int local = skip_prefix (destination , packdir , & scratch );
@@ -861,27 +942,18 @@ static int write_cruft_pack(const struct pack_objects_args *args,
861
942
fprintf (in , "%s.pack\n" , item -> string );
862
943
fclose (in );
863
944
864
- out = xfdopen (cmd .out , "r" );
865
- while (strbuf_getline_lf (& line , out ) != EOF ) {
866
- struct string_list_item * item ;
867
-
868
- if (line .len != the_hash_algo -> hexsz )
869
- die (_ ("repack: Expecting full hex object ID lines only "
870
- "from pack-objects." ));
871
- /*
872
- * avoid putting packs written outside of the repository in the
873
- * list of names
874
- */
875
- if (local ) {
876
- item = string_list_append (names , line .buf );
877
- item -> util = populate_pack_exts (line .buf );
878
- }
879
- }
880
- fclose (out );
881
-
882
- strbuf_release (& line );
945
+ return finish_pack_objects_cmd (& cmd , names , local );
946
+ }
883
947
884
- return finish_command (& cmd );
948
+ static const char * find_pack_prefix (const char * packdir , const char * packtmp )
949
+ {
950
+ const char * pack_prefix ;
951
+ if (!skip_prefix (packtmp , packdir , & pack_prefix ))
952
+ die (_ ("pack prefix %s does not begin with objdir %s" ),
953
+ packtmp , packdir );
954
+ if (* pack_prefix == '/' )
955
+ pack_prefix ++ ;
956
+ return pack_prefix ;
885
957
}
886
958
887
959
int cmd_repack (int argc , const char * * argv , const char * prefix )
@@ -891,10 +963,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
891
963
struct string_list names = STRING_LIST_INIT_DUP ;
892
964
struct existing_packs existing = EXISTING_PACKS_INIT ;
893
965
struct pack_geometry geometry = { 0 };
894
- struct strbuf line = STRBUF_INIT ;
895
966
struct tempfile * refs_snapshot = NULL ;
896
967
int i , ext , ret ;
897
- FILE * out ;
898
968
int show_progress ;
899
969
900
970
/* variables to be filled by option parsing */
@@ -907,6 +977,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
907
977
int write_midx = 0 ;
908
978
const char * cruft_expiration = NULL ;
909
979
const char * expire_to = NULL ;
980
+ const char * filter_to = NULL ;
910
981
911
982
struct option builtin_repack_options [] = {
912
983
OPT_BIT ('a' , NULL , & pack_everything ,
@@ -948,6 +1019,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
948
1019
N_ ("limits the maximum number of threads" )),
949
1020
OPT_STRING (0 , "max-pack-size" , & po_args .max_pack_size , N_ ("bytes" ),
950
1021
N_ ("maximum size of each packfile" )),
1022
+ OPT_PARSE_LIST_OBJECTS_FILTER (& po_args .filter_options ),
951
1023
OPT_BOOL (0 , "pack-kept-objects" , & pack_kept_objects ,
952
1024
N_ ("repack objects in packs marked with .keep" )),
953
1025
OPT_STRING_LIST (0 , "keep-pack" , & keep_pack_list , N_ ("name" ),
@@ -958,9 +1030,13 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
958
1030
N_ ("write a multi-pack index of the resulting packs" )),
959
1031
OPT_STRING (0 , "expire-to" , & expire_to , N_ ("dir" ),
960
1032
N_ ("pack prefix to store a pack containing pruned objects" )),
1033
+ OPT_STRING (0 , "filter-to" , & filter_to , N_ ("dir" ),
1034
+ N_ ("pack prefix to store a pack containing filtered out objects" )),
961
1035
OPT_END ()
962
1036
};
963
1037
1038
+ list_objects_filter_init (& po_args .filter_options );
1039
+
964
1040
git_config (repack_config , & cruft_po_args );
965
1041
966
1042
argc = parse_options (argc , argv , prefix , builtin_repack_options ,
@@ -1101,6 +1177,12 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
1101
1177
strvec_push (& cmd .args , "--incremental" );
1102
1178
}
1103
1179
1180
+ if (po_args .filter_options .choice )
1181
+ strvec_pushf (& cmd .args , "--filter=%s" ,
1182
+ expand_list_objects_filter_spec (& po_args .filter_options ));
1183
+ else if (filter_to )
1184
+ die (_ ("option '%s' can only be used along with '%s'" ), "--filter-to" , "--filter" );
1185
+
1104
1186
if (geometry .split_factor )
1105
1187
cmd .in = -1 ;
1106
1188
else
@@ -1124,31 +1206,15 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
1124
1206
fclose (in );
1125
1207
}
1126
1208
1127
- out = xfdopen (cmd .out , "r" );
1128
- while (strbuf_getline_lf (& line , out ) != EOF ) {
1129
- struct string_list_item * item ;
1130
-
1131
- if (line .len != the_hash_algo -> hexsz )
1132
- die (_ ("repack: Expecting full hex object ID lines only from pack-objects." ));
1133
- item = string_list_append (& names , line .buf );
1134
- item -> util = populate_pack_exts (item -> string );
1135
- }
1136
- strbuf_release (& line );
1137
- fclose (out );
1138
- ret = finish_command (& cmd );
1209
+ ret = finish_pack_objects_cmd (& cmd , & names , 1 );
1139
1210
if (ret )
1140
1211
goto cleanup ;
1141
1212
1142
1213
if (!names .nr && !po_args .quiet )
1143
1214
printf_ln (_ ("Nothing new to pack." ));
1144
1215
1145
1216
if (pack_everything & PACK_CRUFT ) {
1146
- const char * pack_prefix ;
1147
- if (!skip_prefix (packtmp , packdir , & pack_prefix ))
1148
- die (_ ("pack prefix %s does not begin with objdir %s" ),
1149
- packtmp , packdir );
1150
- if (* pack_prefix == '/' )
1151
- pack_prefix ++ ;
1217
+ const char * pack_prefix = find_pack_prefix (packdir , packtmp );
1152
1218
1153
1219
if (!cruft_po_args .window )
1154
1220
cruft_po_args .window = po_args .window ;
@@ -1203,6 +1269,19 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
1203
1269
}
1204
1270
}
1205
1271
1272
+ if (po_args .filter_options .choice ) {
1273
+ if (!filter_to )
1274
+ filter_to = packtmp ;
1275
+
1276
+ ret = write_filtered_pack (& po_args ,
1277
+ filter_to ,
1278
+ find_pack_prefix (packdir , packtmp ),
1279
+ & existing ,
1280
+ & names );
1281
+ if (ret )
1282
+ goto cleanup ;
1283
+ }
1284
+
1206
1285
string_list_sort (& names );
1207
1286
1208
1287
close_object_store (the_repository -> objects );
@@ -1295,6 +1374,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
1295
1374
string_list_clear (& names , 1 );
1296
1375
existing_packs_release (& existing );
1297
1376
free_pack_geometry (& geometry );
1377
+ list_objects_filter_release (& po_args .filter_options );
1298
1378
1299
1379
return ret ;
1300
1380
}
0 commit comments