diff options
Diffstat (limited to 'src/odb_loose.c')
-rw-r--r-- | src/odb_loose.c | 35 |
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; } |