@@ -111,6 +111,8 @@ static unsigned long window_memory_limit = 0;
111111
112112static struct list_objects_filter_options filter_options ;
113113
114+ static struct string_list uri_protocols = STRING_LIST_INIT_NODUP ;
115+
114116enum missing_action {
115117 MA_ERROR = 0 , /* fail if any missing objects are encountered */
116118 MA_ALLOW_ANY , /* silently allow ALL missing objects */
@@ -119,6 +121,15 @@ enum missing_action {
119121static enum missing_action arg_missing_action ;
120122static show_object_fn fn_show_object ;
121123
124+ struct configured_exclusion {
125+ struct oidmap_entry e ;
126+ char * pack_hash_hex ;
127+ char * uri ;
128+ };
129+ static struct oidmap configured_exclusions ;
130+
131+ static struct oidset excluded_by_config ;
132+
122133/*
123134 * stats
124135 */
@@ -833,6 +844,25 @@ static off_t write_reused_pack(struct hashfile *f)
833844 return reuse_packfile_offset - sizeof (struct pack_header );
834845}
835846
847+ static void write_excluded_by_configs (void )
848+ {
849+ struct oidset_iter iter ;
850+ const struct object_id * oid ;
851+
852+ oidset_iter_init (& excluded_by_config , & iter );
853+ while ((oid = oidset_iter_next (& iter ))) {
854+ struct configured_exclusion * ex =
855+ oidmap_get (& configured_exclusions , oid );
856+
857+ if (!ex )
858+ BUG ("configured exclusion wasn't configured" );
859+ write_in_full (1 , ex -> pack_hash_hex , strlen (ex -> pack_hash_hex ));
860+ write_in_full (1 , " " , 1 );
861+ write_in_full (1 , ex -> uri , strlen (ex -> uri ));
862+ write_in_full (1 , "\n" , 1 );
863+ }
864+ }
865+
836866static const char no_split_warning [] = N_ (
837867"disabling bitmap writing, packs are split due to pack.packSizeLimit"
838868);
@@ -1128,6 +1158,25 @@ static int want_object_in_pack(const struct object_id *oid,
11281158 }
11291159 }
11301160
1161+ if (uri_protocols .nr ) {
1162+ struct configured_exclusion * ex =
1163+ oidmap_get (& configured_exclusions , oid );
1164+ int i ;
1165+ const char * p ;
1166+
1167+ if (ex ) {
1168+ for (i = 0 ; i < uri_protocols .nr ; i ++ ) {
1169+ if (skip_prefix (ex -> uri ,
1170+ uri_protocols .items [i ].string ,
1171+ & p ) &&
1172+ * p == ':' ) {
1173+ oidset_insert (& excluded_by_config , oid );
1174+ return 0 ;
1175+ }
1176+ }
1177+ }
1178+ }
1179+
11311180 return 1 ;
11321181}
11331182
@@ -2730,6 +2779,29 @@ static int git_pack_config(const char *k, const char *v, void *cb)
27302779 pack_idx_opts .version );
27312780 return 0 ;
27322781 }
2782+ if (!strcmp (k , "uploadpack.blobpackfileuri" )) {
2783+ struct configured_exclusion * ex = xmalloc (sizeof (* ex ));
2784+ const char * oid_end , * pack_end ;
2785+ /*
2786+ * Stores the pack hash. This is not a true object ID, but is
2787+ * of the same form.
2788+ */
2789+ struct object_id pack_hash ;
2790+
2791+ if (parse_oid_hex (v , & ex -> e .oid , & oid_end ) ||
2792+ * oid_end != ' ' ||
2793+ parse_oid_hex (oid_end + 1 , & pack_hash , & pack_end ) ||
2794+ * pack_end != ' ' )
2795+ die (_ ("value of uploadpack.blobpackfileuri must be "
2796+ "of the form '<object-hash> <pack-hash> <uri>' (got '%s')" ), v );
2797+ if (oidmap_get (& configured_exclusions , & ex -> e .oid ))
2798+ die (_ ("object already configured in another "
2799+ "uploadpack.blobpackfileuri (got '%s')" ), v );
2800+ ex -> pack_hash_hex = xcalloc (1 , pack_end - oid_end );
2801+ memcpy (ex -> pack_hash_hex , oid_end + 1 , pack_end - oid_end - 1 );
2802+ ex -> uri = xstrdup (pack_end + 1 );
2803+ oidmap_put (& configured_exclusions , ex );
2804+ }
27332805 return git_default_config (k , v , cb );
27342806}
27352807
@@ -3322,6 +3394,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
33223394 N_ ("do not pack objects in promisor packfiles" )),
33233395 OPT_BOOL (0 , "delta-islands" , & use_delta_islands ,
33243396 N_ ("respect islands during delta compression" )),
3397+ OPT_STRING_LIST (0 , "uri-protocol" , & uri_protocols ,
3398+ N_ ("protocol" ),
3399+ N_ ("exclude any configured uploadpack.blobpackfileuri with this protocol" )),
33253400 OPT_END (),
33263401 };
33273402
@@ -3506,6 +3581,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
35063581 the_repository );
35073582 }
35083583
3584+ write_excluded_by_configs ();
35093585 trace2_region_enter ("pack-objects" , "write-pack-file" , the_repository );
35103586 write_pack_file ();
35113587 trace2_region_leave ("pack-objects" , "write-pack-file" , the_repository );
0 commit comments