summaryrefslogtreecommitdiff
path: root/object-file.c
diff options
context:
space:
mode:
Diffstat (limited to 'object-file.c')
-rw-r--r--object-file.c67
1 files changed, 55 insertions, 12 deletions
diff --git a/object-file.c b/object-file.c
index c3d866a287..8be57f48de 100644
--- a/object-file.c
+++ b/object-file.c
@@ -165,7 +165,6 @@ static void git_hash_unknown_final_oid(struct object_id *oid, git_hash_ctx *ctx)
BUG("trying to finalize unknown hash");
}
-
const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
{
NULL,
@@ -184,8 +183,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
},
{
"sha1",
- /* "sha1", big-endian */
- 0x73686131,
+ GIT_SHA1_FORMAT_ID,
GIT_SHA1_RAWSZ,
GIT_SHA1_HEXSZ,
GIT_SHA1_BLKSZ,
@@ -200,8 +198,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
},
{
"sha256",
- /* "s256", big-endian */
- 0x73323536,
+ GIT_SHA256_FORMAT_ID,
GIT_SHA256_RAWSZ,
GIT_SHA256_HEXSZ,
GIT_SHA256_BLKSZ,
@@ -683,6 +680,49 @@ void add_to_alternates_memory(const char *reference)
'\n', NULL, 0);
}
+struct object_directory *set_temporary_primary_odb(const char *dir, int will_destroy)
+{
+ struct object_directory *new_odb;
+
+ /*
+ * Make sure alternates are initialized, or else our entry may be
+ * overwritten when they are.
+ */
+ prepare_alt_odb(the_repository);
+
+ /*
+ * Make a new primary odb and link the old primary ODB in as an
+ * alternate
+ */
+ new_odb = xcalloc(1, sizeof(*new_odb));
+ new_odb->path = xstrdup(dir);
+
+ /*
+ * Disable ref updates while a temporary odb is active, since
+ * the objects in the database may roll back.
+ */
+ new_odb->disable_ref_updates = 1;
+ new_odb->will_destroy = will_destroy;
+ new_odb->next = the_repository->objects->odb;
+ the_repository->objects->odb = new_odb;
+ return new_odb->next;
+}
+
+void restore_primary_odb(struct object_directory *restore_odb, const char *old_path)
+{
+ struct object_directory *cur_odb = the_repository->objects->odb;
+
+ if (strcmp(old_path, cur_odb->path))
+ BUG("expected %s as primary object store; found %s",
+ old_path, cur_odb->path);
+
+ if (cur_odb->next != restore_odb)
+ BUG("we expect the old primary object store to be the first alternate");
+
+ the_repository->objects->odb = restore_odb;
+ free_object_directory(cur_odb);
+}
+
/*
* Compute the exact path an alternate is at and returns it. In case of
* error NULL is returned and the human readable error is added to `err`
@@ -797,7 +837,7 @@ static void fill_alternate_refs_command(struct child_process *cmd,
}
}
- cmd->env = local_repo_env;
+ strvec_pushv(&cmd->env_array, (const char **)local_repo_env);
cmd->out = -1;
}
@@ -1306,7 +1346,7 @@ static void *unpack_loose_rest(git_zstream *stream,
int parse_loose_header(const char *hdr, struct object_info *oi)
{
const char *type_buf = hdr;
- unsigned long size;
+ size_t size;
int type, type_len = 0;
/*
@@ -1341,12 +1381,12 @@ int parse_loose_header(const char *hdr, struct object_info *oi)
if (c > 9)
break;
hdr++;
- size = size * 10 + c;
+ size = st_add(st_mult(size, 10), c);
}
}
if (oi->sizep)
- *oi->sizep = size;
+ *oi->sizep = cast_size_t_to_ulong(size);
/*
* The length must be followed by a zero byte
@@ -1809,8 +1849,11 @@ int hash_object_file(const struct git_hash_algo *algo, const void *buf,
/* Finalize a file on disk, and close it. */
static void close_loose_object(int fd)
{
- if (fsync_object_files)
- fsync_or_die(fd, "loose object file");
+ if (!the_repository->objects->odb->will_destroy) {
+ if (fsync_object_files)
+ fsync_or_die(fd, "loose object file");
+ }
+
if (close(fd) != 0)
die_errno(_("error when closing loose object file"));
}
@@ -2425,7 +2468,7 @@ struct oidtree *odb_loose_cache(struct object_directory *odb,
struct strbuf buf = STRBUF_INIT;
size_t word_bits = bitsizeof(odb->loose_objects_subdir_seen[0]);
size_t word_index = subdir_nr / word_bits;
- size_t mask = 1u << (subdir_nr % word_bits);
+ size_t mask = (size_t)1u << (subdir_nr % word_bits);
uint32_t *bitmap;
if (subdir_nr < 0 ||