43
#include "setup.h"
44
#include "submodule.h"
45
#include "fsck.h"
46
+#include "loose.h"
47
+#include "object-file-convert.h"
48
49
/* The maximum size for an object header. */
50
#define MAX_HEADER_LEN 32
1954
const char *filename, unsigned flags,
1955
git_zstream *stream,
1956
unsigned char *buf, size_t buflen,
1955
- git_hash_ctx *c,
1957
+ git_hash_ctx *c, git_hash_ctx *compat_c,
1958
char *hdr, int hdrlen)
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;
1963
int fd;
1964
1965
fd = create_tmpfile(tmp_file, filename);
1979
git_deflate_init(stream, zlib_compression_level);
1980
stream->next_out = buf;
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);
1985
1986
/* Start to feed header to zlib stream */
1987
stream->next_in = (unsigned char *)hdr;
1988
stream->avail_in = hdrlen;
1989
while (git_deflate(stream, 0) == Z_OK)
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);
1994
1995
return fd;
1996
}
1999
* Common steps for the inner git_deflate() loop for writing loose
2000
* objects. Returns what git_deflate() returns.
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,
2003
git_zstream *stream, const int flush,
2004
unsigned char *in0, const int fd,
2005
unsigned char *compressed,
2006
const size_t compressed_len)
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;
2011
int ret;
2012
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);
2017
if (write_in_full(fd, compressed, stream->next_out - compressed) < 0)
2018
die_errno(_("unable to write loose object file"));
2019
stream->next_out = compressed;
2028
* - End the compression of zlib stream.
2029
* - Get the calculated oid to "oid".
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)
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;
2038
int ret;
2039
2040
ret = git_deflate_end_gently(stream);
2041
if (ret != Z_OK)
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);
2046
2047
return Z_OK;
2048
}
2066
2067
fd = start_loose_object_common(&tmp_file, filename.buf, flags,
2068
&stream, compressed, sizeof(compressed),
2049
- &c, hdr, hdrlen);
2069
+ &c, NULL, hdr, hdrlen);
2070
if (fd < 0)
2071
return -1;
2072
2076
do {
2077
unsigned char *in0 = stream.next_in;
2078
2059
- ret = write_loose_object_common(&c, &stream, 1, in0, fd,
2079
+ ret = write_loose_object_common(&c, NULL, &stream, 1, in0, fd,
2080
compressed, sizeof(compressed));
2081
} while (ret == Z_OK);
2082
2083
if (ret != Z_STREAM_END)
2084
die(_("unable to deflate new object %s (%d)"), oid_to_hex(oid),
2085
ret);
2066
- ret = end_loose_object_common(&c, &stream, ¶no_oid);
2086
+ ret = end_loose_object_common(&c, NULL, &stream, ¶no_oid, NULL);
2087
if (ret != Z_OK)
2088
die(_("deflateEnd on object %s failed (%d)"), oid_to_hex(oid),
2089
ret);
2128
int stream_loose_object(struct input_stream *in_stream, size_t len,
2129
struct object_id *oid)
2130
{
2131
+ const struct git_hash_algo *compat = the_repository->compat_hash_algo;
2132
+ struct object_id compat_oid;
2133
int fd, ret, err = 0, flush = 0;
2134
unsigned char compressed[4096];
2135
git_zstream stream;
2114
- git_hash_ctx c;
2136
+ git_hash_ctx c, compat_c;
2137
struct strbuf tmp_file = STRBUF_INIT;
2138
struct strbuf filename = STRBUF_INIT;
2139
int dirlen;
2157
*/
2158
fd = start_loose_object_common(&tmp_file, filename.buf, 0,
2159
&stream, compressed, sizeof(compressed),
2138
- &c, hdr, hdrlen);
2160
+ &c, &compat_c, hdr, hdrlen);
2161
if (fd < 0) {
2162
err = -1;
2163
goto cleanup;
2175
if (in_stream->is_finished)
2176
flush = 1;
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,
2179
compressed, sizeof(compressed));
2180
/*
2181
* Unlike write_loose_object(), we do not have the entire
2198
*/
2199
if (ret != Z_STREAM_END)
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);
2202
if (ret != Z_OK)
2203
die(_("deflateEnd on stream object failed (%d)"), ret);
2204
close_loose_object(fd, tmp_file.buf);
2225
}
2226
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);
2230
cleanup:
2231
strbuf_release(&tmp_file);
2232
strbuf_release(&filename);
2237
enum object_type type, struct object_id *oid,
2238
unsigned flags)
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;
2244
char hdr[MAX_HEADER_LEN];
2245
int hdrlen = sizeof(hdr);
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
+
2261
/* Normally if we have it in the pack then we do not bother writing
2262
* it out into .git/objects/??/?{38} file.
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);
2265
if (freshen_packed_object(oid) || freshen_loose_object(oid))
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;
2272
}
2273
2274
int write_object_file_literally(const void *buf, unsigned long len,
2276
unsigned flags)
2277
{
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;
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
+ }
2300
2301
/* type string, SP, %lu of the length plus NUL must fit this */
2302
hdrlen = strlen(type) + MAX_HEADER_LEN;
2309
if (freshen_packed_object(oid) || freshen_loose_object(oid))
2310
goto cleanup;
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);
2314
2315
cleanup:
2316
free(header);
2319
2320
int force_object_loose(const struct object_id *oid, time_t mtime)
2321
{
2322
+ struct repository *repo = the_repository;
2323
+ const struct git_hash_algo *compat = repo->compat_hash_algo;
2324
void *buf;
2325
unsigned long len;
2326
struct object_info oi = OBJECT_INFO_INIT;
2327
+ struct object_id compat_oid;
2328
enum object_type type;
2329
char hdr[MAX_HEADER_LEN];
2330
int hdrlen;
2337
oi.contentp = &buf;
2338
if (oid_object_info_extended(the_repository, oid, &oi, 0))
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
+ }
2345
hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
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);
2349
free(buf);
2350
2351
return ret;