summaryrefslogtreecommitdiff
path: root/src/odb_loose.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/odb_loose.c')
-rw-r--r--src/odb_loose.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/src/odb_loose.c b/src/odb_loose.c
index dbfe18b43..57a0b0a8e 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -277,7 +277,7 @@ static void *inflate_tail(z_stream *s, void *hb, size_t used, obj_hdr *hdr)
else {
set_stream_output(s, buf + used, hdr->size - used);
if (finish_inflate(s)) {
- free(buf);
+ git__free(buf);
return NULL;
}
}
@@ -317,7 +317,7 @@ static int inflate_packlike_loose_disk_obj(git_rawobj *out, git_fbuffer *obj)
in = ((unsigned char *)obj->data) + used;
len = obj->len - used;
if (inflate_buffer(in, len, buf, hdr.size)) {
- free(buf);
+ git__free(buf);
return git__throw(GIT_ERROR, "Failed to inflate loose object. Could not inflate buffer");
}
buf[hdr.size] = '\0';
@@ -666,11 +666,22 @@ static int loose_backend__stream_fwrite(git_oid *oid, git_odb_stream *_stream)
if (object_file_name(final_path, sizeof(final_path), backend->objects_dir, oid))
return GIT_ENOMEM;
- if ((error = git_futils_mkpath2file(final_path)) < GIT_SUCCESS)
+ if ((error = git_futils_mkpath2file(final_path, GIT_OBJECT_DIR_MODE)) < GIT_SUCCESS)
return git__rethrow(error, "Failed to write loose backend");
stream->finished = 1;
- return git_filebuf_commit_at(&stream->fbuf, final_path);
+
+ /*
+ * Don't try to add an existing object to the repository. This
+ * is what git does and allows us to sidestep the fact that
+ * we're not allowed to overwrite a read-only file on Windows.
+ */
+ if (git_futils_exists(final_path) == GIT_SUCCESS) {
+ git_filebuf_cleanup(&stream->fbuf);
+ return GIT_SUCCESS;
+ }
+
+ return git_filebuf_commit_at(&stream->fbuf, final_path, GIT_OBJECT_FILE_MODE);
}
static int loose_backend__stream_write(git_odb_stream *_stream, const char *data, size_t len)
@@ -686,7 +697,7 @@ static void loose_backend__stream_free(git_odb_stream *_stream)
if (!stream->finished)
git_filebuf_cleanup(&stream->fbuf);
- free(stream);
+ git__free(stream);
}
static int format_object_header(char *hdr, size_t n, size_t obj_len, git_otype obj_type)
@@ -739,14 +750,14 @@ static int loose_backend__stream(git_odb_stream **stream_out, git_odb_backend *_
(backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT));
if (error < GIT_SUCCESS) {
- free(stream);
+ git__free(stream);
return git__rethrow(error, "Failed to create loose backend stream");
}
error = stream->stream.write((git_odb_stream *)stream, hdr, hdrlen);
if (error < GIT_SUCCESS) {
git_filebuf_cleanup(&stream->fbuf);
- free(stream);
+ git__free(stream);
return git__rethrow(error, "Failed to create loose backend stream");
}
@@ -787,10 +798,10 @@ static int loose_backend__write(git_oid *oid, git_odb_backend *_backend, const v
if ((error = object_file_name(final_path, sizeof(final_path), backend->objects_dir, oid)) < GIT_SUCCESS)
goto cleanup;
- if ((error = git_futils_mkpath2file(final_path)) < GIT_SUCCESS)
+ if ((error = git_futils_mkpath2file(final_path, GIT_OBJECT_DIR_MODE)) < GIT_SUCCESS)
goto cleanup;
- return git_filebuf_commit_at(&fbuf, final_path);
+ return git_filebuf_commit_at(&fbuf, final_path, GIT_OBJECT_FILE_MODE);
cleanup:
git_filebuf_cleanup(&fbuf);
@@ -803,8 +814,8 @@ static void loose_backend__free(git_odb_backend *_backend)
assert(_backend);
backend = (loose_backend *)_backend;
- free(backend->objects_dir);
- free(backend);
+ git__free(backend->objects_dir);
+ git__free(backend);
}
int git_odb_backend_loose(
@@ -821,7 +832,7 @@ int git_odb_backend_loose(
backend->objects_dir = git__strdup(objects_dir);
if (backend->objects_dir == NULL) {
- free(backend);
+ git__free(backend);
return GIT_ENOMEM;
}