43
43
#include "setup.h"
44
44
#include "submodule.h"
45
45
#include "fsck.h"
46
+ #include "loose.h"
47
+ #include "object-file-convert.h"
46
48
47
49
/* The maximum size for an object header. */
48
50
#define MAX_HEADER_LEN 32
@@ -1952,9 +1954,12 @@ static int start_loose_object_common(struct strbuf *tmp_file,
1952
1954
const char * filename , unsigned flags ,
1953
1955
git_zstream * stream ,
1954
1956
unsigned char * buf , size_t buflen ,
1955
- git_hash_ctx * c ,
1957
+ git_hash_ctx * c , git_hash_ctx * compat_c ,
1956
1958
char * hdr , int hdrlen )
1957
1959
{
1960
+ struct repository * repo = the_repository ;
1961
+ const struct git_hash_algo * algo = repo -> hash_algo ;
1962
+ const struct git_hash_algo * compat = repo -> compat_hash_algo ;
1958
1963
int fd ;
1959
1964
1960
1965
fd = create_tmpfile (tmp_file , filename );
@@ -1974,14 +1979,18 @@ static int start_loose_object_common(struct strbuf *tmp_file,
1974
1979
git_deflate_init (stream , zlib_compression_level );
1975
1980
stream -> next_out = buf ;
1976
1981
stream -> avail_out = buflen ;
1977
- the_hash_algo -> init_fn (c );
1982
+ algo -> init_fn (c );
1983
+ if (compat && compat_c )
1984
+ compat -> init_fn (compat_c );
1978
1985
1979
1986
/* Start to feed header to zlib stream */
1980
1987
stream -> next_in = (unsigned char * )hdr ;
1981
1988
stream -> avail_in = hdrlen ;
1982
1989
while (git_deflate (stream , 0 ) == Z_OK )
1983
1990
; /* nothing */
1984
- the_hash_algo -> update_fn (c , hdr , hdrlen );
1991
+ algo -> update_fn (c , hdr , hdrlen );
1992
+ if (compat && compat_c )
1993
+ compat -> update_fn (compat_c , hdr , hdrlen );
1985
1994
1986
1995
return fd ;
1987
1996
}
@@ -1990,16 +1999,21 @@ static int start_loose_object_common(struct strbuf *tmp_file,
1990
1999
* Common steps for the inner git_deflate() loop for writing loose
1991
2000
* objects. Returns what git_deflate() returns.
1992
2001
*/
1993
- static int write_loose_object_common (git_hash_ctx * c ,
2002
+ static int write_loose_object_common (git_hash_ctx * c , git_hash_ctx * compat_c ,
1994
2003
git_zstream * stream , const int flush ,
1995
2004
unsigned char * in0 , const int fd ,
1996
2005
unsigned char * compressed ,
1997
2006
const size_t compressed_len )
1998
2007
{
2008
+ struct repository * repo = the_repository ;
2009
+ const struct git_hash_algo * algo = repo -> hash_algo ;
2010
+ const struct git_hash_algo * compat = repo -> compat_hash_algo ;
1999
2011
int ret ;
2000
2012
2001
2013
ret = git_deflate (stream , flush ? Z_FINISH : 0 );
2002
- the_hash_algo -> update_fn (c , in0 , stream -> next_in - in0 );
2014
+ algo -> update_fn (c , in0 , stream -> next_in - in0 );
2015
+ if (compat && compat_c )
2016
+ compat -> update_fn (compat_c , in0 , stream -> next_in - in0 );
2003
2017
if (write_in_full (fd , compressed , stream -> next_out - compressed ) < 0 )
2004
2018
die_errno (_ ("unable to write loose object file" ));
2005
2019
stream -> next_out = compressed ;
@@ -2014,15 +2028,21 @@ static int write_loose_object_common(git_hash_ctx *c,
2014
2028
* - End the compression of zlib stream.
2015
2029
* - Get the calculated oid to "oid".
2016
2030
*/
2017
- static int end_loose_object_common (git_hash_ctx * c , git_zstream * stream ,
2018
- struct object_id * oid )
2031
+ static int end_loose_object_common (git_hash_ctx * c , git_hash_ctx * compat_c ,
2032
+ git_zstream * stream , struct object_id * oid ,
2033
+ struct object_id * compat_oid )
2019
2034
{
2035
+ struct repository * repo = the_repository ;
2036
+ const struct git_hash_algo * algo = repo -> hash_algo ;
2037
+ const struct git_hash_algo * compat = repo -> compat_hash_algo ;
2020
2038
int ret ;
2021
2039
2022
2040
ret = git_deflate_end_gently (stream );
2023
2041
if (ret != Z_OK )
2024
2042
return ret ;
2025
- the_hash_algo -> final_oid_fn (oid , c );
2043
+ algo -> final_oid_fn (oid , c );
2044
+ if (compat && compat_c )
2045
+ compat -> final_oid_fn (compat_oid , compat_c );
2026
2046
2027
2047
return Z_OK ;
2028
2048
}
@@ -2046,7 +2066,7 @@ static int write_loose_object(const struct object_id *oid, char *hdr,
2046
2066
2047
2067
fd = start_loose_object_common (& tmp_file , filename .buf , flags ,
2048
2068
& stream , compressed , sizeof (compressed ),
2049
- & c , hdr , hdrlen );
2069
+ & c , NULL , hdr , hdrlen );
2050
2070
if (fd < 0 )
2051
2071
return -1 ;
2052
2072
@@ -2056,14 +2076,14 @@ static int write_loose_object(const struct object_id *oid, char *hdr,
2056
2076
do {
2057
2077
unsigned char * in0 = stream .next_in ;
2058
2078
2059
- ret = write_loose_object_common (& c , & stream , 1 , in0 , fd ,
2079
+ ret = write_loose_object_common (& c , NULL , & stream , 1 , in0 , fd ,
2060
2080
compressed , sizeof (compressed ));
2061
2081
} while (ret == Z_OK );
2062
2082
2063
2083
if (ret != Z_STREAM_END )
2064
2084
die (_ ("unable to deflate new object %s (%d)" ), oid_to_hex (oid ),
2065
2085
ret );
2066
- ret = end_loose_object_common (& c , & stream , & parano_oid );
2086
+ ret = end_loose_object_common (& c , NULL , & stream , & parano_oid , NULL );
2067
2087
if (ret != Z_OK )
2068
2088
die (_ ("deflateEnd on object %s failed (%d)" ), oid_to_hex (oid ),
2069
2089
ret );
@@ -2108,10 +2128,12 @@ static int freshen_packed_object(const struct object_id *oid)
2108
2128
int stream_loose_object (struct input_stream * in_stream , size_t len ,
2109
2129
struct object_id * oid )
2110
2130
{
2131
+ const struct git_hash_algo * compat = the_repository -> compat_hash_algo ;
2132
+ struct object_id compat_oid ;
2111
2133
int fd , ret , err = 0 , flush = 0 ;
2112
2134
unsigned char compressed [4096 ];
2113
2135
git_zstream stream ;
2114
- git_hash_ctx c ;
2136
+ git_hash_ctx c , compat_c ;
2115
2137
struct strbuf tmp_file = STRBUF_INIT ;
2116
2138
struct strbuf filename = STRBUF_INIT ;
2117
2139
int dirlen ;
@@ -2135,7 +2157,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,
2135
2157
*/
2136
2158
fd = start_loose_object_common (& tmp_file , filename .buf , 0 ,
2137
2159
& stream , compressed , sizeof (compressed ),
2138
- & c , hdr , hdrlen );
2160
+ & c , & compat_c , hdr , hdrlen );
2139
2161
if (fd < 0 ) {
2140
2162
err = -1 ;
2141
2163
goto cleanup ;
@@ -2153,7 +2175,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,
2153
2175
if (in_stream -> is_finished )
2154
2176
flush = 1 ;
2155
2177
}
2156
- ret = write_loose_object_common (& c , & stream , flush , in0 , fd ,
2178
+ ret = write_loose_object_common (& c , & compat_c , & stream , flush , in0 , fd ,
2157
2179
compressed , sizeof (compressed ));
2158
2180
/*
2159
2181
* Unlike write_loose_object(), we do not have the entire
@@ -2176,7 +2198,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,
2176
2198
*/
2177
2199
if (ret != Z_STREAM_END )
2178
2200
die (_ ("unable to stream deflate new object (%d)" ), ret );
2179
- ret = end_loose_object_common (& c , & stream , oid );
2201
+ ret = end_loose_object_common (& c , & compat_c , & stream , oid , & compat_oid );
2180
2202
if (ret != Z_OK )
2181
2203
die (_ ("deflateEnd on stream object failed (%d)" ), ret );
2182
2204
close_loose_object (fd , tmp_file .buf );
@@ -2203,6 +2225,8 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,
2203
2225
}
2204
2226
2205
2227
err = finalize_object_file (tmp_file .buf , filename .buf );
2228
+ if (!err && compat )
2229
+ err = repo_add_loose_object_map (the_repository , oid , & compat_oid );
2206
2230
cleanup :
2207
2231
strbuf_release (& tmp_file );
2208
2232
strbuf_release (& filename );
@@ -2213,25 +2237,66 @@ int write_object_file_flags(const void *buf, unsigned long len,
2213
2237
enum object_type type , struct object_id * oid ,
2214
2238
unsigned flags )
2215
2239
{
2240
+ struct repository * repo = the_repository ;
2241
+ const struct git_hash_algo * algo = repo -> hash_algo ;
2242
+ const struct git_hash_algo * compat = repo -> compat_hash_algo ;
2243
+ struct object_id compat_oid ;
2216
2244
char hdr [MAX_HEADER_LEN ];
2217
2245
int hdrlen = sizeof (hdr );
2218
2246
2247
+ /* Generate compat_oid */
2248
+ if (compat ) {
2249
+ if (type == OBJ_BLOB )
2250
+ hash_object_file (compat , buf , len , type , & compat_oid );
2251
+ else {
2252
+ struct strbuf converted = STRBUF_INIT ;
2253
+ convert_object_file (& converted , algo , compat ,
2254
+ buf , len , type , 0 );
2255
+ hash_object_file (compat , converted .buf , converted .len ,
2256
+ type , & compat_oid );
2257
+ strbuf_release (& converted );
2258
+ }
2259
+ }
2260
+
2219
2261
/* Normally if we have it in the pack then we do not bother writing
2220
2262
* it out into .git/objects/??/?{38} file.
2221
2263
*/
2222
- write_object_file_prepare (the_hash_algo , buf , len , type , oid , hdr ,
2223
- & hdrlen );
2264
+ write_object_file_prepare (algo , buf , len , type , oid , hdr , & hdrlen );
2224
2265
if (freshen_packed_object (oid ) || freshen_loose_object (oid ))
2225
2266
return 0 ;
2226
- return write_loose_object (oid , hdr , hdrlen , buf , len , 0 , flags );
2267
+ if (write_loose_object (oid , hdr , hdrlen , buf , len , 0 , flags ))
2268
+ return -1 ;
2269
+ if (compat )
2270
+ return repo_add_loose_object_map (repo , oid , & compat_oid );
2271
+ return 0 ;
2227
2272
}
2228
2273
2229
2274
int write_object_file_literally (const void * buf , unsigned long len ,
2230
2275
const char * type , struct object_id * oid ,
2231
2276
unsigned flags )
2232
2277
{
2233
2278
char * header ;
2279
+ struct repository * repo = the_repository ;
2280
+ const struct git_hash_algo * algo = repo -> hash_algo ;
2281
+ const struct git_hash_algo * compat = repo -> compat_hash_algo ;
2282
+ struct object_id compat_oid ;
2234
2283
int hdrlen , status = 0 ;
2284
+ int compat_type = -1 ;
2285
+
2286
+ if (compat ) {
2287
+ compat_type = type_from_string_gently (type , -1 , 1 );
2288
+ if (compat_type == OBJ_BLOB )
2289
+ hash_object_file (compat , buf , len , compat_type ,
2290
+ & compat_oid );
2291
+ else if (compat_type != -1 ) {
2292
+ struct strbuf converted = STRBUF_INIT ;
2293
+ convert_object_file (& converted , algo , compat ,
2294
+ buf , len , compat_type , 0 );
2295
+ hash_object_file (compat , converted .buf , converted .len ,
2296
+ compat_type , & compat_oid );
2297
+ strbuf_release (& converted );
2298
+ }
2299
+ }
2235
2300
2236
2301
/* type string, SP, %lu of the length plus NUL must fit this */
2237
2302
hdrlen = strlen (type ) + MAX_HEADER_LEN ;
@@ -2244,6 +2309,8 @@ int write_object_file_literally(const void *buf, unsigned long len,
2244
2309
if (freshen_packed_object (oid ) || freshen_loose_object (oid ))
2245
2310
goto cleanup ;
2246
2311
status = write_loose_object (oid , header , hdrlen , buf , len , 0 , 0 );
2312
+ if (compat_type != -1 )
2313
+ return repo_add_loose_object_map (repo , oid , & compat_oid );
2247
2314
2248
2315
cleanup :
2249
2316
free (header );
@@ -2252,9 +2319,12 @@ int write_object_file_literally(const void *buf, unsigned long len,
2252
2319
2253
2320
int force_object_loose (const struct object_id * oid , time_t mtime )
2254
2321
{
2322
+ struct repository * repo = the_repository ;
2323
+ const struct git_hash_algo * compat = repo -> compat_hash_algo ;
2255
2324
void * buf ;
2256
2325
unsigned long len ;
2257
2326
struct object_info oi = OBJECT_INFO_INIT ;
2327
+ struct object_id compat_oid ;
2258
2328
enum object_type type ;
2259
2329
char hdr [MAX_HEADER_LEN ];
2260
2330
int hdrlen ;
@@ -2267,8 +2337,15 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
2267
2337
oi .contentp = & buf ;
2268
2338
if (oid_object_info_extended (the_repository , oid , & oi , 0 ))
2269
2339
return error (_ ("cannot read object for %s" ), oid_to_hex (oid ));
2340
+ if (compat ) {
2341
+ if (repo_oid_to_algop (repo , oid , compat , & compat_oid ))
2342
+ return error (_ ("cannot map object %s to %s" ),
2343
+ oid_to_hex (oid ), compat -> name );
2344
+ }
2270
2345
hdrlen = format_object_header (hdr , sizeof (hdr ), type , len );
2271
2346
ret = write_loose_object (oid , hdr , hdrlen , buf , len , mtime , 0 );
2347
+ if (!ret && compat )
2348
+ ret = repo_add_loose_object_map (the_repository , oid , & compat_oid );
2272
2349
free (buf );
2273
2350
2274
2351
return ret ;
0 commit comments