Commit 4d185dd9b0dde93bf30b250e6c7dd751bc893268

David Michael Barr 2012-12-19T14:30:06

odb: check if object exists before writing Update the procondition of git_odb_backend::write. It may now be assumed that the object has already been hashed.

diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h
index 19a1540..7b5a51e 100644
--- a/include/git2/odb_backend.h
+++ b/include/git2/odb_backend.h
@@ -63,6 +63,10 @@ struct git_odb_backend {
 			struct git_odb_backend *,
 			const git_oid *);
 
+	/* The writer may assume that the object
+	 * has already been hashed and is passed
+	 * in the first parameter.
+	 */
 	int (* write)(
 			git_oid *,
 			struct git_odb_backend *,
diff --git a/src/odb.c b/src/odb.c
index 2385a58..1995669 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -713,6 +713,10 @@ int git_odb_write(
 
 	assert(oid && db);
 
+	git_odb_hash(oid, data, len, type);
+	if (git_odb_exists(db, oid))
+		return 0;
+
 	for (i = 0; i < db->backends.length && error < 0; ++i) {
 		backend_internal *internal = git_vector_get(&db->backends, i);
 		git_odb_backend *b = internal->backend;
diff --git a/src/odb_loose.c b/src/odb_loose.c
index df86d90..1ce6125 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -870,7 +870,6 @@ static int loose_backend__write(git_oid *oid, git_odb_backend *_backend, const v
 
 	if (git_buf_joinpath(&final_path, backend->objects_dir, "tmp_object") < 0 ||
 		git_filebuf_open(&fbuf, final_path.ptr,
-			GIT_FILEBUF_HASH_CONTENTS |
 			GIT_FILEBUF_TEMPORARY |
 			(backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT)) < 0)
 	{
@@ -880,7 +879,6 @@ static int loose_backend__write(git_oid *oid, git_odb_backend *_backend, const v
 
 	git_filebuf_write(&fbuf, header, header_len);
 	git_filebuf_write(&fbuf, data, len);
-	git_filebuf_hash(oid, &fbuf);
 
 	if (object_file_name(&final_path, backend->objects_dir, oid) < 0 ||
 		git_futils_mkpath2file(final_path.ptr, GIT_OBJECT_DIR_MODE) < 0 ||