diff options
author | Edward Thomson <ethomson@github.com> | 2016-07-14 16:23:24 -0400 |
---|---|---|
committer | Edward Thomson <ethomson@github.com> | 2016-08-04 15:12:04 -0400 |
commit | 8f09a98e1809dcdfd9d25b8268657bac4d942e6a (patch) | |
tree | 25f4b977d9a9055569d95a5ba5b038dfbfb01d6a /src/odb.c | |
parent | d2794b0e37e98206b991ba4c8639ddf53c03bdb9 (diff) | |
download | libgit2-8f09a98e1809dcdfd9d25b8268657bac4d942e6a.tar.gz |
odb: freshen existing objects when writing
When writing an object, we calculate its OID and see if it exists in the
object database. If it does, we need to freshen the file that contains
it.
Diffstat (limited to 'src/odb.c')
-rw-r--r-- | src/odb.c | 47 |
1 files changed, 44 insertions, 3 deletions
@@ -654,7 +654,10 @@ void git_odb_free(git_odb *db) GIT_REFCOUNT_DEC(db, odb_free); } -static int odb_exists_1(git_odb *db, const git_oid *id, bool only_refreshed) +static int odb_exists_1( + git_odb *db, + const git_oid *id, + bool only_refreshed) { size_t i; bool found = false; @@ -673,6 +676,44 @@ static int odb_exists_1(git_odb *db, const git_oid *id, bool only_refreshed) return (int)found; } +static int odb_freshen_1( + git_odb *db, + const git_oid *id, + bool only_refreshed) +{ + size_t i; + bool found = false; + + for (i = 0; i < db->backends.length && !found; ++i) { + backend_internal *internal = git_vector_get(&db->backends, i); + git_odb_backend *b = internal->backend; + + if (only_refreshed && !b->refresh) + continue; + + if (b->freshen != NULL) + found = !b->freshen(b, id); + else if (b->exists != NULL) + found = b->exists(b, id); + } + + return (int)found; +} + +static int odb_freshen(git_odb *db, const git_oid *id) +{ + assert(db && id); + + if (odb_freshen_1(db, id, false)) + return 1; + + if (!git_odb_refresh(db)) + return odb_freshen_1(db, id, true); + + /* Failed to refresh, hence not found */ + return 0; +} + int git_odb_exists(git_odb *db, const git_oid *id) { git_odb_object *object; @@ -1131,7 +1172,7 @@ int git_odb_write( assert(oid && db); git_odb_hash(oid, data, len, type); - if (git_odb_exists(db, oid)) + if (odb_freshen(db, oid)) return 0; for (i = 0; i < db->backends.length && error < 0; ++i) { @@ -1257,7 +1298,7 @@ int git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream) git_hash_final(out, stream->hash_ctx); - if (git_odb_exists(stream->backend->odb, out)) + if (odb_freshen(stream->backend->odb, out)) return 0; return stream->finalize_write(stream, out); |