|
12 | 12 |
|
13 | 13 | #include "git-compat-util.h" |
14 | 14 | #include "bulk-checkin.h" |
15 | | -#include "convert.h" |
16 | 15 | #include "environment.h" |
17 | | -#include "fsck.h" |
18 | 16 | #include "gettext.h" |
19 | 17 | #include "hex.h" |
20 | 18 | #include "loose.h" |
|
25 | 23 | #include "pack.h" |
26 | 24 | #include "packfile.h" |
27 | 25 | #include "path.h" |
28 | | -#include "setup.h" |
29 | 26 | #include "streaming.h" |
30 | 27 |
|
31 | 28 | /* The maximum size for an object header. */ |
32 | 29 | #define MAX_HEADER_LEN 32 |
33 | 30 |
|
34 | | -static int get_conv_flags(unsigned flags) |
35 | | -{ |
36 | | - if (flags & INDEX_RENORMALIZE) |
37 | | - return CONV_EOL_RENORMALIZE; |
38 | | - else if (flags & INDEX_WRITE_OBJECT) |
39 | | - return global_conv_flags_eol | CONV_WRITE_OBJECT; |
40 | | - else |
41 | | - return 0; |
42 | | -} |
43 | | - |
44 | 31 | static void fill_loose_path(struct strbuf *buf, const struct object_id *oid) |
45 | 32 | { |
46 | 33 | int i; |
@@ -1225,218 +1212,6 @@ int force_object_loose(const struct object_id *oid, time_t mtime) |
1225 | 1212 | return ret; |
1226 | 1213 | } |
1227 | 1214 |
|
1228 | | -/* |
1229 | | - * We can't use the normal fsck_error_function() for index_mem(), |
1230 | | - * because we don't yet have a valid oid for it to report. Instead, |
1231 | | - * report the minimal fsck error here, and rely on the caller to |
1232 | | - * give more context. |
1233 | | - */ |
1234 | | -static int hash_format_check_report(struct fsck_options *opts UNUSED, |
1235 | | - void *fsck_report UNUSED, |
1236 | | - enum fsck_msg_type msg_type UNUSED, |
1237 | | - enum fsck_msg_id msg_id UNUSED, |
1238 | | - const char *message) |
1239 | | -{ |
1240 | | - error(_("object fails fsck: %s"), message); |
1241 | | - return 1; |
1242 | | -} |
1243 | | - |
1244 | | -static int index_mem(struct index_state *istate, |
1245 | | - struct object_id *oid, |
1246 | | - const void *buf, size_t size, |
1247 | | - enum object_type type, |
1248 | | - const char *path, unsigned flags) |
1249 | | -{ |
1250 | | - struct strbuf nbuf = STRBUF_INIT; |
1251 | | - int ret = 0; |
1252 | | - int write_object = flags & INDEX_WRITE_OBJECT; |
1253 | | - |
1254 | | - if (!type) |
1255 | | - type = OBJ_BLOB; |
1256 | | - |
1257 | | - /* |
1258 | | - * Convert blobs to git internal format |
1259 | | - */ |
1260 | | - if ((type == OBJ_BLOB) && path) { |
1261 | | - if (convert_to_git(istate, path, buf, size, &nbuf, |
1262 | | - get_conv_flags(flags))) { |
1263 | | - buf = nbuf.buf; |
1264 | | - size = nbuf.len; |
1265 | | - } |
1266 | | - } |
1267 | | - if (flags & INDEX_FORMAT_CHECK) { |
1268 | | - struct fsck_options opts = FSCK_OPTIONS_DEFAULT; |
1269 | | - |
1270 | | - opts.strict = 1; |
1271 | | - opts.error_func = hash_format_check_report; |
1272 | | - if (fsck_buffer(null_oid(the_hash_algo), type, buf, size, &opts)) |
1273 | | - die(_("refusing to create malformed object")); |
1274 | | - fsck_finish(&opts); |
1275 | | - } |
1276 | | - |
1277 | | - if (write_object) |
1278 | | - ret = write_object_file(buf, size, type, oid); |
1279 | | - else |
1280 | | - hash_object_file(the_hash_algo, buf, size, type, oid); |
1281 | | - |
1282 | | - strbuf_release(&nbuf); |
1283 | | - return ret; |
1284 | | -} |
1285 | | - |
1286 | | -static int index_stream_convert_blob(struct index_state *istate, |
1287 | | - struct object_id *oid, |
1288 | | - int fd, |
1289 | | - const char *path, |
1290 | | - unsigned flags) |
1291 | | -{ |
1292 | | - int ret = 0; |
1293 | | - const int write_object = flags & INDEX_WRITE_OBJECT; |
1294 | | - struct strbuf sbuf = STRBUF_INIT; |
1295 | | - |
1296 | | - assert(path); |
1297 | | - assert(would_convert_to_git_filter_fd(istate, path)); |
1298 | | - |
1299 | | - convert_to_git_filter_fd(istate, path, fd, &sbuf, |
1300 | | - get_conv_flags(flags)); |
1301 | | - |
1302 | | - if (write_object) |
1303 | | - ret = write_object_file(sbuf.buf, sbuf.len, OBJ_BLOB, |
1304 | | - oid); |
1305 | | - else |
1306 | | - hash_object_file(the_hash_algo, sbuf.buf, sbuf.len, OBJ_BLOB, |
1307 | | - oid); |
1308 | | - strbuf_release(&sbuf); |
1309 | | - return ret; |
1310 | | -} |
1311 | | - |
1312 | | -static int index_pipe(struct index_state *istate, struct object_id *oid, |
1313 | | - int fd, enum object_type type, |
1314 | | - const char *path, unsigned flags) |
1315 | | -{ |
1316 | | - struct strbuf sbuf = STRBUF_INIT; |
1317 | | - int ret; |
1318 | | - |
1319 | | - if (strbuf_read(&sbuf, fd, 4096) >= 0) |
1320 | | - ret = index_mem(istate, oid, sbuf.buf, sbuf.len, type, path, flags); |
1321 | | - else |
1322 | | - ret = -1; |
1323 | | - strbuf_release(&sbuf); |
1324 | | - return ret; |
1325 | | -} |
1326 | | - |
1327 | | -#define SMALL_FILE_SIZE (32*1024) |
1328 | | - |
1329 | | -static int index_core(struct index_state *istate, |
1330 | | - struct object_id *oid, int fd, size_t size, |
1331 | | - enum object_type type, const char *path, |
1332 | | - unsigned flags) |
1333 | | -{ |
1334 | | - int ret; |
1335 | | - |
1336 | | - if (!size) { |
1337 | | - ret = index_mem(istate, oid, "", size, type, path, flags); |
1338 | | - } else if (size <= SMALL_FILE_SIZE) { |
1339 | | - char *buf = xmalloc(size); |
1340 | | - ssize_t read_result = read_in_full(fd, buf, size); |
1341 | | - if (read_result < 0) |
1342 | | - ret = error_errno(_("read error while indexing %s"), |
1343 | | - path ? path : "<unknown>"); |
1344 | | - else if (read_result != size) |
1345 | | - ret = error(_("short read while indexing %s"), |
1346 | | - path ? path : "<unknown>"); |
1347 | | - else |
1348 | | - ret = index_mem(istate, oid, buf, size, type, path, flags); |
1349 | | - free(buf); |
1350 | | - } else { |
1351 | | - void *buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); |
1352 | | - ret = index_mem(istate, oid, buf, size, type, path, flags); |
1353 | | - munmap(buf, size); |
1354 | | - } |
1355 | | - return ret; |
1356 | | -} |
1357 | | - |
1358 | | -/* |
1359 | | - * This creates one packfile per large blob unless bulk-checkin |
1360 | | - * machinery is "plugged". |
1361 | | - * |
1362 | | - * This also bypasses the usual "convert-to-git" dance, and that is on |
1363 | | - * purpose. We could write a streaming version of the converting |
1364 | | - * functions and insert that before feeding the data to fast-import |
1365 | | - * (or equivalent in-core API described above). However, that is |
1366 | | - * somewhat complicated, as we do not know the size of the filter |
1367 | | - * result, which we need to know beforehand when writing a git object. |
1368 | | - * Since the primary motivation for trying to stream from the working |
1369 | | - * tree file and to avoid mmaping it in core is to deal with large |
1370 | | - * binary blobs, they generally do not want to get any conversion, and |
1371 | | - * callers should avoid this code path when filters are requested. |
1372 | | - */ |
1373 | | -static int index_blob_stream(struct object_id *oid, int fd, size_t size, |
1374 | | - const char *path, |
1375 | | - unsigned flags) |
1376 | | -{ |
1377 | | - return index_blob_bulk_checkin(oid, fd, size, path, flags); |
1378 | | -} |
1379 | | - |
1380 | | -int index_fd(struct index_state *istate, struct object_id *oid, |
1381 | | - int fd, struct stat *st, |
1382 | | - enum object_type type, const char *path, unsigned flags) |
1383 | | -{ |
1384 | | - int ret; |
1385 | | - |
1386 | | - /* |
1387 | | - * Call xsize_t() only when needed to avoid potentially unnecessary |
1388 | | - * die() for large files. |
1389 | | - */ |
1390 | | - if (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(istate, path)) |
1391 | | - ret = index_stream_convert_blob(istate, oid, fd, path, flags); |
1392 | | - else if (!S_ISREG(st->st_mode)) |
1393 | | - ret = index_pipe(istate, oid, fd, type, path, flags); |
1394 | | - else if (st->st_size <= repo_settings_get_big_file_threshold(the_repository) || |
1395 | | - type != OBJ_BLOB || |
1396 | | - (path && would_convert_to_git(istate, path))) |
1397 | | - ret = index_core(istate, oid, fd, xsize_t(st->st_size), |
1398 | | - type, path, flags); |
1399 | | - else |
1400 | | - ret = index_blob_stream(oid, fd, xsize_t(st->st_size), path, |
1401 | | - flags); |
1402 | | - close(fd); |
1403 | | - return ret; |
1404 | | -} |
1405 | | - |
1406 | | -int index_path(struct index_state *istate, struct object_id *oid, |
1407 | | - const char *path, struct stat *st, unsigned flags) |
1408 | | -{ |
1409 | | - int fd; |
1410 | | - struct strbuf sb = STRBUF_INIT; |
1411 | | - int rc = 0; |
1412 | | - |
1413 | | - switch (st->st_mode & S_IFMT) { |
1414 | | - case S_IFREG: |
1415 | | - fd = open(path, O_RDONLY); |
1416 | | - if (fd < 0) |
1417 | | - return error_errno("open(\"%s\")", path); |
1418 | | - if (index_fd(istate, oid, fd, st, OBJ_BLOB, path, flags) < 0) |
1419 | | - return error(_("%s: failed to insert into database"), |
1420 | | - path); |
1421 | | - break; |
1422 | | - case S_IFLNK: |
1423 | | - if (strbuf_readlink(&sb, path, st->st_size)) |
1424 | | - return error_errno("readlink(\"%s\")", path); |
1425 | | - if (!(flags & INDEX_WRITE_OBJECT)) |
1426 | | - hash_object_file(the_hash_algo, sb.buf, sb.len, |
1427 | | - OBJ_BLOB, oid); |
1428 | | - else if (write_object_file(sb.buf, sb.len, OBJ_BLOB, oid)) |
1429 | | - rc = error(_("%s: failed to insert into database"), path); |
1430 | | - strbuf_release(&sb); |
1431 | | - break; |
1432 | | - case S_IFDIR: |
1433 | | - return repo_resolve_gitlink_ref(the_repository, path, "HEAD", oid); |
1434 | | - default: |
1435 | | - return error(_("%s: unsupported file type"), path); |
1436 | | - } |
1437 | | - return rc; |
1438 | | -} |
1439 | | - |
1440 | 1215 | int read_pack_header(int fd, struct pack_header *header) |
1441 | 1216 | { |
1442 | 1217 | if (read_in_full(fd, header, sizeof(*header)) != sizeof(*header)) |
|
0 commit comments