rugged 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +1 -0
- data/README.md +1 -1
- data/ext/rugged/rugged.c +7 -4
- data/ext/rugged/rugged_object.c +1 -1
- data/ext/rugged/rugged_repo.c +3 -3
- data/lib/rugged/repository.rb +2 -2
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +11 -6
- data/vendor/libgit2/COPYING +109 -1
- data/vendor/libgit2/cmake/Findfutimens.cmake +14 -0
- data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +4 -0
- data/vendor/libgit2/cmake/SelectHashes.cmake +1 -0
- data/vendor/libgit2/deps/chromium-zlib/CMakeLists.txt +101 -0
- data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +17 -5
- data/vendor/libgit2/deps/ntlmclient/crypt.h +14 -9
- data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +20 -20
- data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +3 -3
- data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +37 -36
- data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +4 -3
- data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +178 -51
- data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +74 -5
- data/vendor/libgit2/deps/ntlmclient/ntlm.c +150 -118
- data/vendor/libgit2/deps/ntlmclient/ntlm.h +13 -9
- data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +16 -3
- data/vendor/libgit2/deps/ntlmclient/unicode.h +10 -4
- data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +16 -27
- data/vendor/libgit2/deps/ntlmclient/unicode_builtin.h +20 -0
- data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +28 -52
- data/vendor/libgit2/deps/ntlmclient/unicode_iconv.h +22 -0
- data/vendor/libgit2/include/git2/attr.h +89 -0
- data/vendor/libgit2/include/git2/blame.h +93 -42
- data/vendor/libgit2/include/git2/blob.h +14 -2
- data/vendor/libgit2/include/git2/branch.h +25 -0
- data/vendor/libgit2/include/git2/cert.h +42 -5
- data/vendor/libgit2/include/git2/checkout.h +28 -12
- data/vendor/libgit2/include/git2/commit.h +35 -19
- data/vendor/libgit2/include/git2/common.h +14 -4
- data/vendor/libgit2/include/git2/deprecated.h +206 -6
- data/vendor/libgit2/include/git2/diff.h +34 -19
- data/vendor/libgit2/include/git2/errors.h +6 -6
- data/vendor/libgit2/include/git2/filter.h +57 -17
- data/vendor/libgit2/include/git2/graph.h +20 -2
- data/vendor/libgit2/include/git2/index.h +2 -2
- data/vendor/libgit2/include/git2/odb.h +29 -0
- data/vendor/libgit2/include/git2/patch.h +8 -0
- data/vendor/libgit2/include/git2/rebase.h +25 -1
- data/vendor/libgit2/include/git2/refs.h +6 -2
- data/vendor/libgit2/include/git2/remote.h +59 -6
- data/vendor/libgit2/include/git2/revparse.h +5 -5
- data/vendor/libgit2/include/git2/status.h +115 -59
- data/vendor/libgit2/include/git2/submodule.h +9 -0
- data/vendor/libgit2/include/git2/sys/commit_graph.h +174 -0
- data/vendor/libgit2/include/git2/sys/filter.h +49 -28
- data/vendor/libgit2/include/git2/sys/midx.h +74 -0
- data/vendor/libgit2/include/git2/sys/odb_backend.h +7 -0
- data/vendor/libgit2/include/git2/sys/transport.h +1 -0
- data/vendor/libgit2/include/git2/tag.h +12 -0
- data/vendor/libgit2/include/git2/tree.h +0 -14
- data/vendor/libgit2/include/git2/types.h +9 -0
- data/vendor/libgit2/include/git2/version.h +4 -4
- data/vendor/libgit2/include/git2/worktree.h +1 -0
- data/vendor/libgit2/src/CMakeLists.txt +25 -4
- data/vendor/libgit2/src/alloc.c +21 -8
- data/vendor/libgit2/src/allocators/failalloc.c +92 -0
- data/vendor/libgit2/src/allocators/failalloc.h +23 -0
- data/vendor/libgit2/src/allocators/stdalloc.c +41 -10
- data/vendor/libgit2/src/allocators/win32_leakcheck.c +118 -0
- data/vendor/libgit2/src/allocators/{win32_crtdbg.h → win32_leakcheck.h} +3 -3
- data/vendor/libgit2/src/annotated_commit.c +21 -9
- data/vendor/libgit2/src/apply.c +16 -7
- data/vendor/libgit2/src/array.h +11 -11
- data/vendor/libgit2/src/attr.c +181 -74
- data/vendor/libgit2/src/attr_file.c +84 -39
- data/vendor/libgit2/src/attr_file.h +32 -11
- data/vendor/libgit2/src/attrcache.c +42 -37
- data/vendor/libgit2/src/attrcache.h +4 -5
- data/vendor/libgit2/src/blame.c +11 -5
- data/vendor/libgit2/src/blob.c +35 -24
- data/vendor/libgit2/src/branch.c +69 -17
- data/vendor/libgit2/src/buffer.c +334 -25
- data/vendor/libgit2/src/buffer.h +153 -2
- data/vendor/libgit2/src/cache.c +2 -2
- data/vendor/libgit2/src/cache.h +7 -7
- data/vendor/libgit2/src/cc-compat.h +10 -2
- data/vendor/libgit2/src/checkout.c +48 -26
- data/vendor/libgit2/src/cherrypick.c +6 -2
- data/vendor/libgit2/src/clone.c +41 -47
- data/vendor/libgit2/src/commit.c +41 -28
- data/vendor/libgit2/src/commit_graph.c +1209 -0
- data/vendor/libgit2/src/commit_graph.h +162 -0
- data/vendor/libgit2/src/commit_list.c +46 -0
- data/vendor/libgit2/src/commit_list.h +2 -0
- data/vendor/libgit2/src/common.h +25 -2
- data/vendor/libgit2/src/config.c +37 -15
- data/vendor/libgit2/src/config_cache.c +5 -3
- data/vendor/libgit2/src/config_file.c +16 -8
- data/vendor/libgit2/src/config_parse.c +4 -6
- data/vendor/libgit2/src/crlf.c +16 -6
- data/vendor/libgit2/src/date.c +4 -3
- data/vendor/libgit2/src/delta.c +1 -1
- data/vendor/libgit2/src/describe.c +6 -3
- data/vendor/libgit2/src/diff.c +11 -8
- data/vendor/libgit2/src/diff_driver.c +21 -17
- data/vendor/libgit2/src/diff_file.c +2 -6
- data/vendor/libgit2/src/diff_generate.c +46 -17
- data/vendor/libgit2/src/diff_print.c +19 -6
- data/vendor/libgit2/src/diff_stats.c +7 -5
- data/vendor/libgit2/src/diff_tform.c +9 -8
- data/vendor/libgit2/src/diff_xdiff.c +4 -2
- data/vendor/libgit2/src/diff_xdiff.h +1 -1
- data/vendor/libgit2/src/errors.c +24 -19
- data/vendor/libgit2/src/features.h.in +5 -1
- data/vendor/libgit2/src/fetch.c +5 -2
- data/vendor/libgit2/src/fetchhead.c +8 -4
- data/vendor/libgit2/src/filebuf.c +9 -7
- data/vendor/libgit2/src/filter.c +206 -110
- data/vendor/libgit2/src/filter.h +24 -5
- data/vendor/libgit2/src/futils.c +5 -5
- data/vendor/libgit2/src/futils.h +1 -1
- data/vendor/libgit2/src/graph.c +64 -9
- data/vendor/libgit2/src/hash/sha1/collisiondetect.c +3 -3
- data/vendor/libgit2/src/hash/sha1/common_crypto.c +3 -3
- data/vendor/libgit2/src/hash/sha1/generic.h +1 -1
- data/vendor/libgit2/src/hash/sha1/mbedtls.c +12 -12
- data/vendor/libgit2/src/hash/sha1/openssl.c +3 -3
- data/vendor/libgit2/src/hash/sha1/sha1dc/sha1.c +0 -2
- data/vendor/libgit2/src/hash/sha1/win32.c +15 -11
- data/vendor/libgit2/src/hash.c +16 -13
- data/vendor/libgit2/src/hash.h +1 -1
- data/vendor/libgit2/src/hashsig.c +23 -10
- data/vendor/libgit2/src/ident.c +13 -3
- data/vendor/libgit2/src/ignore.c +35 -19
- data/vendor/libgit2/src/index.c +106 -70
- data/vendor/libgit2/src/index.h +1 -1
- data/vendor/libgit2/src/indexer.c +31 -29
- data/vendor/libgit2/src/integer.h +64 -2
- data/vendor/libgit2/src/iterator.c +36 -24
- data/vendor/libgit2/src/iterator.h +1 -1
- data/vendor/libgit2/src/khash.h +2 -11
- data/vendor/libgit2/src/{settings.c → libgit2.c} +117 -50
- data/vendor/libgit2/src/libgit2.h +15 -0
- data/vendor/libgit2/src/mailmap.c +23 -10
- data/vendor/libgit2/src/map.h +3 -3
- data/vendor/libgit2/src/merge.c +70 -30
- data/vendor/libgit2/src/merge.h +2 -1
- data/vendor/libgit2/src/merge_driver.c +19 -13
- data/vendor/libgit2/src/merge_file.c +11 -3
- data/vendor/libgit2/src/message.c +3 -1
- data/vendor/libgit2/src/midx.c +471 -10
- data/vendor/libgit2/src/midx.h +28 -1
- data/vendor/libgit2/src/mwindow.c +103 -59
- data/vendor/libgit2/src/mwindow.h +3 -3
- data/vendor/libgit2/src/net.c +127 -3
- data/vendor/libgit2/src/net.h +16 -2
- data/vendor/libgit2/src/netops.c +6 -4
- data/vendor/libgit2/src/netops.h +2 -2
- data/vendor/libgit2/src/notes.c +10 -10
- data/vendor/libgit2/src/object.c +22 -14
- data/vendor/libgit2/src/odb.c +285 -48
- data/vendor/libgit2/src/odb.h +16 -2
- data/vendor/libgit2/src/odb_loose.c +28 -18
- data/vendor/libgit2/src/odb_mempack.c +1 -1
- data/vendor/libgit2/src/odb_pack.c +391 -114
- data/vendor/libgit2/src/oid.c +5 -4
- data/vendor/libgit2/src/pack-objects.c +54 -48
- data/vendor/libgit2/src/pack.c +329 -119
- data/vendor/libgit2/src/pack.h +25 -7
- data/vendor/libgit2/src/patch.c +14 -7
- data/vendor/libgit2/src/patch_generate.c +2 -2
- data/vendor/libgit2/src/patch_parse.c +2 -1
- data/vendor/libgit2/src/path.c +98 -53
- data/vendor/libgit2/src/path.h +79 -6
- data/vendor/libgit2/src/pathspec.c +8 -8
- data/vendor/libgit2/src/pool.c +13 -7
- data/vendor/libgit2/src/posix.c +11 -3
- data/vendor/libgit2/src/reader.c +10 -6
- data/vendor/libgit2/src/rebase.c +93 -49
- data/vendor/libgit2/src/refdb.c +30 -13
- data/vendor/libgit2/src/refdb_fs.c +121 -69
- data/vendor/libgit2/src/reflog.c +19 -14
- data/vendor/libgit2/src/refs.c +76 -41
- data/vendor/libgit2/src/refspec.c +32 -12
- data/vendor/libgit2/src/remote.c +272 -102
- data/vendor/libgit2/src/remote.h +2 -1
- data/vendor/libgit2/src/repository.c +176 -103
- data/vendor/libgit2/src/repository.h +12 -1
- data/vendor/libgit2/src/reset.c +7 -6
- data/vendor/libgit2/src/revert.c +6 -2
- data/vendor/libgit2/src/revparse.c +14 -9
- data/vendor/libgit2/src/revwalk.c +32 -15
- data/vendor/libgit2/src/runtime.c +162 -0
- data/vendor/libgit2/src/runtime.h +62 -0
- data/vendor/libgit2/src/settings.h +11 -0
- data/vendor/libgit2/src/signature.c +6 -5
- data/vendor/libgit2/src/sortedcache.h +10 -8
- data/vendor/libgit2/src/stash.c +3 -1
- data/vendor/libgit2/src/status.c +7 -4
- data/vendor/libgit2/src/strarray.c +2 -1
- data/vendor/libgit2/src/streams/mbedtls.c +14 -17
- data/vendor/libgit2/src/streams/mbedtls.h +1 -1
- data/vendor/libgit2/src/streams/openssl.c +101 -201
- data/vendor/libgit2/src/streams/openssl.h +9 -1
- data/vendor/libgit2/src/streams/openssl_dynamic.c +309 -0
- data/vendor/libgit2/src/streams/openssl_dynamic.h +348 -0
- data/vendor/libgit2/src/streams/openssl_legacy.c +203 -0
- data/vendor/libgit2/src/streams/openssl_legacy.h +63 -0
- data/vendor/libgit2/src/streams/registry.c +5 -6
- data/vendor/libgit2/src/streams/socket.c +6 -2
- data/vendor/libgit2/src/streams/stransport.c +6 -3
- data/vendor/libgit2/src/streams/tls.c +5 -3
- data/vendor/libgit2/src/submodule.c +128 -62
- data/vendor/libgit2/src/submodule.h +9 -9
- data/vendor/libgit2/src/sysdir.c +4 -6
- data/vendor/libgit2/src/tag.c +47 -11
- data/vendor/libgit2/src/thread.c +140 -0
- data/vendor/libgit2/src/thread.h +479 -0
- data/vendor/libgit2/src/threadstate.c +83 -0
- data/vendor/libgit2/src/threadstate.h +24 -0
- data/vendor/libgit2/src/trace.c +2 -2
- data/vendor/libgit2/src/trace.h +17 -13
- data/vendor/libgit2/src/transaction.c +19 -8
- data/vendor/libgit2/src/transport.c +3 -3
- data/vendor/libgit2/src/transports/auth.c +1 -1
- data/vendor/libgit2/src/transports/auth_negotiate.c +11 -4
- data/vendor/libgit2/src/transports/auth_ntlm.c +10 -6
- data/vendor/libgit2/src/transports/credential.c +15 -7
- data/vendor/libgit2/src/transports/git.c +1 -3
- data/vendor/libgit2/src/transports/http.c +19 -17
- data/vendor/libgit2/src/transports/http.h +1 -0
- data/vendor/libgit2/src/transports/httpclient.c +53 -26
- data/vendor/libgit2/src/transports/httpclient.h +1 -1
- data/vendor/libgit2/src/transports/local.c +3 -3
- data/vendor/libgit2/src/transports/smart.c +12 -7
- data/vendor/libgit2/src/transports/smart.h +1 -1
- data/vendor/libgit2/src/transports/smart_protocol.c +11 -5
- data/vendor/libgit2/src/transports/ssh.c +51 -17
- data/vendor/libgit2/src/transports/winhttp.c +41 -31
- data/vendor/libgit2/src/tree.c +100 -77
- data/vendor/libgit2/src/tree.h +1 -0
- data/vendor/libgit2/src/tsort.c +0 -2
- data/vendor/libgit2/src/unix/map.c +3 -1
- data/vendor/libgit2/src/unix/pthread.h +2 -1
- data/vendor/libgit2/src/utf8.c +150 -0
- data/vendor/libgit2/src/utf8.h +52 -0
- data/vendor/libgit2/src/util.c +53 -129
- data/vendor/libgit2/src/util.h +33 -39
- data/vendor/libgit2/src/vector.c +23 -19
- data/vendor/libgit2/src/vector.h +4 -2
- data/vendor/libgit2/src/win32/findfile.c +4 -2
- data/vendor/libgit2/src/win32/map.c +1 -1
- data/vendor/libgit2/src/win32/msvc-compat.h +9 -1
- data/vendor/libgit2/src/win32/path_w32.c +22 -24
- data/vendor/libgit2/src/win32/path_w32.h +0 -1
- data/vendor/libgit2/src/win32/posix_w32.c +7 -1
- data/vendor/libgit2/src/win32/precompiled.h +0 -1
- data/vendor/libgit2/src/win32/reparse.h +4 -4
- data/vendor/libgit2/src/win32/thread.c +24 -15
- data/vendor/libgit2/src/win32/thread.h +1 -1
- data/vendor/libgit2/src/win32/w32_buffer.c +3 -3
- data/vendor/libgit2/src/win32/w32_common.h +18 -9
- data/vendor/libgit2/src/win32/{w32_crtdbg_stacktrace.c → w32_leakcheck.c} +269 -33
- data/vendor/libgit2/src/win32/w32_leakcheck.h +222 -0
- data/vendor/libgit2/src/win32/w32_util.h +6 -6
- data/vendor/libgit2/src/worktree.c +27 -16
- data/vendor/libgit2/src/zstream.c +1 -1
- metadata +32 -16
- data/vendor/libgit2/src/allocators/win32_crtdbg.c +0 -118
- data/vendor/libgit2/src/buf_text.c +0 -316
- data/vendor/libgit2/src/buf_text.h +0 -122
- data/vendor/libgit2/src/global.c +0 -363
- data/vendor/libgit2/src/global.h +0 -41
- data/vendor/libgit2/src/thread-utils.c +0 -58
- data/vendor/libgit2/src/thread-utils.h +0 -369
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +0 -127
- data/vendor/libgit2/src/win32/w32_stack.c +0 -188
- data/vendor/libgit2/src/win32/w32_stack.h +0 -140
data/vendor/libgit2/src/oid.c
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
#include "git2/oid.h"
|
|
11
11
|
#include "repository.h"
|
|
12
|
-
#include "
|
|
12
|
+
#include "threadstate.h"
|
|
13
13
|
#include <string.h>
|
|
14
14
|
#include <limits.h>
|
|
15
15
|
|
|
@@ -26,7 +26,8 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length)
|
|
|
26
26
|
size_t p;
|
|
27
27
|
int v;
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
GIT_ASSERT_ARG(out);
|
|
30
|
+
GIT_ASSERT_ARG(str);
|
|
30
31
|
|
|
31
32
|
if (!length)
|
|
32
33
|
return oid_error_invalid("too short");
|
|
@@ -107,7 +108,7 @@ int git_oid_pathfmt(char *str, const git_oid *oid)
|
|
|
107
108
|
|
|
108
109
|
char *git_oid_tostr_s(const git_oid *oid)
|
|
109
110
|
{
|
|
110
|
-
char *str =
|
|
111
|
+
char *str = GIT_THREADSTATE->oid_fmt;
|
|
111
112
|
git_oid_nfmt(str, GIT_OID_HEXSZ + 1, oid);
|
|
112
113
|
return str;
|
|
113
114
|
}
|
|
@@ -316,7 +317,7 @@ git_oid_shorten *git_oid_shorten_new(size_t min_length)
|
|
|
316
317
|
{
|
|
317
318
|
git_oid_shorten *os;
|
|
318
319
|
|
|
319
|
-
|
|
320
|
+
GIT_ASSERT_ARG_WITH_RETVAL((size_t)((int)min_length) == min_length, NULL);
|
|
320
321
|
|
|
321
322
|
os = git__calloc(1, sizeof(git_oid_shorten));
|
|
322
323
|
if (os == NULL)
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
#include "iterator.h"
|
|
13
13
|
#include "netops.h"
|
|
14
14
|
#include "pack.h"
|
|
15
|
-
#include "thread
|
|
15
|
+
#include "thread.h"
|
|
16
16
|
#include "tree.h"
|
|
17
17
|
#include "util.h"
|
|
18
18
|
#include "revwalk.h"
|
|
@@ -48,18 +48,10 @@ struct walk_object {
|
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
#ifdef GIT_THREADS
|
|
51
|
-
|
|
52
|
-
#define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) do { \
|
|
53
|
-
int result = git_mutex_##op(&(pb)->mtx); \
|
|
54
|
-
assert(!result); \
|
|
55
|
-
GIT_UNUSED(result); \
|
|
56
|
-
} while (0)
|
|
57
|
-
|
|
51
|
+
# define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) git_mutex_##op(&(pb)->mtx)
|
|
58
52
|
#else
|
|
59
|
-
|
|
60
|
-
#
|
|
61
|
-
|
|
62
|
-
#endif /* GIT_THREADS */
|
|
53
|
+
# define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) git__noop()
|
|
54
|
+
#endif
|
|
63
55
|
|
|
64
56
|
#define git_packbuilder__cache_lock(pb) GIT_PACKBUILDER__MUTEX_OP(pb, cache_mutex, lock)
|
|
65
57
|
#define git_packbuilder__cache_unlock(pb) GIT_PACKBUILDER__MUTEX_OP(pb, cache_mutex, unlock)
|
|
@@ -177,13 +169,13 @@ on_error:
|
|
|
177
169
|
|
|
178
170
|
unsigned int git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n)
|
|
179
171
|
{
|
|
180
|
-
|
|
172
|
+
GIT_ASSERT_ARG(pb);
|
|
181
173
|
|
|
182
174
|
#ifdef GIT_THREADS
|
|
183
175
|
pb->nr_threads = n;
|
|
184
176
|
#else
|
|
185
177
|
GIT_UNUSED(n);
|
|
186
|
-
|
|
178
|
+
GIT_ASSERT(pb->nr_threads == 1);
|
|
187
179
|
#endif
|
|
188
180
|
|
|
189
181
|
return pb->nr_threads;
|
|
@@ -211,7 +203,8 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
|
|
|
211
203
|
size_t newsize;
|
|
212
204
|
int ret;
|
|
213
205
|
|
|
214
|
-
|
|
206
|
+
GIT_ASSERT_ARG(pb);
|
|
207
|
+
GIT_ASSERT_ARG(oid);
|
|
215
208
|
|
|
216
209
|
/* If the object already exists in the hash table, then we don't
|
|
217
210
|
* have any work to do */
|
|
@@ -258,7 +251,7 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
|
|
|
258
251
|
double current_time = git__timer();
|
|
259
252
|
double elapsed = current_time - pb->last_progress_report_time;
|
|
260
253
|
|
|
261
|
-
if (elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
|
|
254
|
+
if (elapsed < 0 || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
|
|
262
255
|
pb->last_progress_report_time = current_time;
|
|
263
256
|
|
|
264
257
|
ret = pb->progress_cb(
|
|
@@ -347,10 +340,9 @@ static int write_object(
|
|
|
347
340
|
}
|
|
348
341
|
|
|
349
342
|
/* Write header */
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
(error = git_hash_update(&pb->ctx, hdr, hdr_len)) < 0)
|
|
343
|
+
if ((error = git_packfile__object_header(&hdr_len, hdr, data_len, type)) < 0 ||
|
|
344
|
+
(error = write_cb(hdr, hdr_len, cb_data)) < 0 ||
|
|
345
|
+
(error = git_hash_update(&pb->ctx, hdr, hdr_len)) < 0)
|
|
354
346
|
goto done;
|
|
355
347
|
|
|
356
348
|
if (type == GIT_OBJECT_REF_DELTA) {
|
|
@@ -525,13 +517,18 @@ static int cb_tag_foreach(const char *name, git_oid *oid, void *data)
|
|
|
525
517
|
return 0;
|
|
526
518
|
}
|
|
527
519
|
|
|
528
|
-
static
|
|
520
|
+
static int compute_write_order(git_pobject ***out, git_packbuilder *pb)
|
|
529
521
|
{
|
|
530
522
|
size_t i, wo_end, last_untagged;
|
|
531
523
|
git_pobject **wo;
|
|
532
524
|
|
|
525
|
+
*out = NULL;
|
|
526
|
+
|
|
527
|
+
if (!pb->nr_objects)
|
|
528
|
+
return 0;
|
|
529
|
+
|
|
533
530
|
if ((wo = git__mallocarray(pb->nr_objects, sizeof(*wo))) == NULL)
|
|
534
|
-
return
|
|
531
|
+
return -1;
|
|
535
532
|
|
|
536
533
|
for (i = 0; i < pb->nr_objects; i++) {
|
|
537
534
|
git_pobject *po = pb->object_list + i;
|
|
@@ -560,7 +557,7 @@ static git_pobject **compute_write_order(git_packbuilder *pb)
|
|
|
560
557
|
*/
|
|
561
558
|
if (git_tag_foreach(pb->repo, &cb_tag_foreach, pb) < 0) {
|
|
562
559
|
git__free(wo);
|
|
563
|
-
return
|
|
560
|
+
return -1;
|
|
564
561
|
}
|
|
565
562
|
|
|
566
563
|
/*
|
|
@@ -617,10 +614,11 @@ static git_pobject **compute_write_order(git_packbuilder *pb)
|
|
|
617
614
|
if (wo_end != pb->nr_objects) {
|
|
618
615
|
git__free(wo);
|
|
619
616
|
git_error_set(GIT_ERROR_INVALID, "invalid write order");
|
|
620
|
-
return
|
|
617
|
+
return -1;
|
|
621
618
|
}
|
|
622
619
|
|
|
623
|
-
|
|
620
|
+
*out = wo;
|
|
621
|
+
return 0;
|
|
624
622
|
}
|
|
625
623
|
|
|
626
624
|
static int write_pack(git_packbuilder *pb,
|
|
@@ -633,15 +631,15 @@ static int write_pack(git_packbuilder *pb,
|
|
|
633
631
|
struct git_pack_header ph;
|
|
634
632
|
git_oid entry_oid;
|
|
635
633
|
size_t i = 0;
|
|
636
|
-
int error
|
|
634
|
+
int error;
|
|
637
635
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
return -1;
|
|
636
|
+
if ((error = compute_write_order(&write_order, pb)) < 0)
|
|
637
|
+
return error;
|
|
641
638
|
|
|
642
639
|
if (!git__is_uint32(pb->nr_objects)) {
|
|
643
640
|
git_error_set(GIT_ERROR_INVALID, "too many objects");
|
|
644
|
-
|
|
641
|
+
error = -1;
|
|
642
|
+
goto done;
|
|
645
643
|
}
|
|
646
644
|
|
|
647
645
|
/* Write pack header */
|
|
@@ -852,10 +850,11 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
|
852
850
|
}
|
|
853
851
|
}
|
|
854
852
|
|
|
855
|
-
git_packbuilder__cache_lock(pb);
|
|
853
|
+
GIT_ASSERT(git_packbuilder__cache_lock(pb) == 0);
|
|
854
|
+
|
|
856
855
|
if (trg_object->delta_data) {
|
|
857
856
|
git__free(trg_object->delta_data);
|
|
858
|
-
|
|
857
|
+
GIT_ASSERT(pb->delta_cache_size >= trg_object->delta_size);
|
|
859
858
|
pb->delta_cache_size -= trg_object->delta_size;
|
|
860
859
|
trg_object->delta_data = NULL;
|
|
861
860
|
}
|
|
@@ -863,7 +862,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
|
863
862
|
bool overflow = git__add_sizet_overflow(
|
|
864
863
|
&pb->delta_cache_size, pb->delta_cache_size, delta_size);
|
|
865
864
|
|
|
866
|
-
git_packbuilder__cache_unlock(pb);
|
|
865
|
+
GIT_ASSERT(git_packbuilder__cache_unlock(pb) == 0);
|
|
867
866
|
|
|
868
867
|
if (overflow) {
|
|
869
868
|
git__free(delta_buf);
|
|
@@ -874,7 +873,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
|
874
873
|
GIT_ERROR_CHECK_ALLOC(trg_object->delta_data);
|
|
875
874
|
} else {
|
|
876
875
|
/* create delta when writing the pack */
|
|
877
|
-
git_packbuilder__cache_unlock(pb);
|
|
876
|
+
GIT_ASSERT(git_packbuilder__cache_unlock(pb) == 0);
|
|
878
877
|
git__free(delta_buf);
|
|
879
878
|
}
|
|
880
879
|
|
|
@@ -929,7 +928,7 @@ static int report_delta_progress(
|
|
|
929
928
|
double current_time = git__timer();
|
|
930
929
|
double elapsed = current_time - pb->last_progress_report_time;
|
|
931
930
|
|
|
932
|
-
if (force || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
|
|
931
|
+
if (force || elapsed < 0 || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
|
|
933
932
|
pb->last_progress_report_time = current_time;
|
|
934
933
|
|
|
935
934
|
ret = pb->progress_cb(
|
|
@@ -962,9 +961,9 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
|
962
961
|
struct unpacked *n = array + idx;
|
|
963
962
|
size_t max_depth, j, best_base = SIZE_MAX;
|
|
964
963
|
|
|
965
|
-
git_packbuilder__progress_lock(pb);
|
|
964
|
+
GIT_ASSERT(git_packbuilder__progress_lock(pb) == 0);
|
|
966
965
|
if (!*list_size) {
|
|
967
|
-
git_packbuilder__progress_unlock(pb);
|
|
966
|
+
GIT_ASSERT(git_packbuilder__progress_unlock(pb) == 0);
|
|
968
967
|
break;
|
|
969
968
|
}
|
|
970
969
|
|
|
@@ -973,7 +972,7 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
|
973
972
|
|
|
974
973
|
po = *list++;
|
|
975
974
|
(*list_size)--;
|
|
976
|
-
git_packbuilder__progress_unlock(pb);
|
|
975
|
+
GIT_ASSERT(git_packbuilder__progress_unlock(pb) == 0);
|
|
977
976
|
|
|
978
977
|
mem_usage -= free_unpacked(n);
|
|
979
978
|
n->object = po;
|
|
@@ -1048,10 +1047,10 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
|
1048
1047
|
po->z_delta_size = zbuf.size;
|
|
1049
1048
|
git_buf_clear(&zbuf);
|
|
1050
1049
|
|
|
1051
|
-
git_packbuilder__cache_lock(pb);
|
|
1050
|
+
GIT_ASSERT(git_packbuilder__cache_lock(pb) == 0);
|
|
1052
1051
|
pb->delta_cache_size -= po->delta_size;
|
|
1053
1052
|
pb->delta_cache_size += po->z_delta_size;
|
|
1054
|
-
git_packbuilder__cache_unlock(pb);
|
|
1053
|
+
GIT_ASSERT(git_packbuilder__cache_unlock(pb) == 0);
|
|
1055
1054
|
}
|
|
1056
1055
|
|
|
1057
1056
|
/*
|
|
@@ -1129,10 +1128,10 @@ static void *threaded_find_deltas(void *arg)
|
|
|
1129
1128
|
; /* TODO */
|
|
1130
1129
|
}
|
|
1131
1130
|
|
|
1132
|
-
git_packbuilder__progress_lock(me->pb);
|
|
1131
|
+
GIT_ASSERT_WITH_RETVAL(git_packbuilder__progress_lock(me->pb) == 0, NULL);
|
|
1133
1132
|
me->working = 0;
|
|
1134
1133
|
git_cond_signal(&me->pb->progress_cond);
|
|
1135
|
-
git_packbuilder__progress_unlock(me->pb);
|
|
1134
|
+
GIT_ASSERT_WITH_RETVAL(git_packbuilder__progress_unlock(me->pb) == 0, NULL);
|
|
1136
1135
|
|
|
1137
1136
|
if (git_mutex_lock(&me->mutex)) {
|
|
1138
1137
|
git_error_set(GIT_ERROR_THREAD, "unable to lock packfile condition mutex");
|
|
@@ -1165,7 +1164,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
|
1165
1164
|
int ret, active_threads = 0;
|
|
1166
1165
|
|
|
1167
1166
|
if (!pb->nr_threads)
|
|
1168
|
-
pb->nr_threads =
|
|
1167
|
+
pb->nr_threads = git__online_cpus();
|
|
1169
1168
|
|
|
1170
1169
|
if (pb->nr_threads <= 1) {
|
|
1171
1170
|
find_deltas(pb, list, &list_size, window, depth);
|
|
@@ -1237,7 +1236,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
|
1237
1236
|
* 'working' flag from 1 -> 0. This indicates that it is
|
|
1238
1237
|
* ready to receive more work using our work-stealing
|
|
1239
1238
|
* algorithm. */
|
|
1240
|
-
git_packbuilder__progress_lock(pb);
|
|
1239
|
+
GIT_ASSERT(git_packbuilder__progress_lock(pb) == 0);
|
|
1241
1240
|
for (;;) {
|
|
1242
1241
|
for (i = 0; !target && i < pb->nr_threads; i++)
|
|
1243
1242
|
if (!p[i].working)
|
|
@@ -1280,7 +1279,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
|
1280
1279
|
target->list_size = sub_size;
|
|
1281
1280
|
target->remaining = sub_size;
|
|
1282
1281
|
target->working = 1;
|
|
1283
|
-
git_packbuilder__progress_unlock(pb);
|
|
1282
|
+
GIT_ASSERT(git_packbuilder__progress_unlock(pb) == 0);
|
|
1284
1283
|
|
|
1285
1284
|
if (git_mutex_lock(&target->mutex)) {
|
|
1286
1285
|
git_error_set(GIT_ERROR_THREAD, "unable to lock packfile condition mutex");
|
|
@@ -1363,8 +1362,13 @@ int git_packbuilder_foreach(git_packbuilder *pb, int (*cb)(void *buf, size_t siz
|
|
|
1363
1362
|
|
|
1364
1363
|
int git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb)
|
|
1365
1364
|
{
|
|
1365
|
+
int error;
|
|
1366
|
+
|
|
1367
|
+
if ((error = git_buf_sanitize(buf)) < 0)
|
|
1368
|
+
return error;
|
|
1369
|
+
|
|
1366
1370
|
PREPARE_PACK;
|
|
1367
|
-
|
|
1371
|
+
|
|
1368
1372
|
return write_pack(pb, &write_pack_buf, buf);
|
|
1369
1373
|
}
|
|
1370
1374
|
|
|
@@ -1486,7 +1490,8 @@ int git_packbuilder_insert_recur(git_packbuilder *pb, const git_oid *id, const c
|
|
|
1486
1490
|
git_object *obj;
|
|
1487
1491
|
int error;
|
|
1488
1492
|
|
|
1489
|
-
|
|
1493
|
+
GIT_ASSERT_ARG(pb);
|
|
1494
|
+
GIT_ASSERT_ARG(id);
|
|
1490
1495
|
|
|
1491
1496
|
if ((error = git_object_lookup(&obj, pb->repo, id, GIT_OBJECT_ANY)) < 0)
|
|
1492
1497
|
return error;
|
|
@@ -1727,7 +1732,8 @@ int git_packbuilder_insert_walk(git_packbuilder *pb, git_revwalk *walk)
|
|
|
1727
1732
|
git_oid id;
|
|
1728
1733
|
struct walk_object *obj;
|
|
1729
1734
|
|
|
1730
|
-
|
|
1735
|
+
GIT_ASSERT_ARG(pb);
|
|
1736
|
+
GIT_ASSERT_ARG(walk);
|
|
1731
1737
|
|
|
1732
1738
|
if ((error = mark_edges_uninteresting(pb, walk->user_input)) < 0)
|
|
1733
1739
|
return error;
|
data/vendor/libgit2/src/pack.c
CHANGED
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
#include "mwindow.h"
|
|
13
13
|
#include "odb.h"
|
|
14
14
|
#include "oid.h"
|
|
15
|
+
#include "oidarray.h"
|
|
15
16
|
|
|
16
17
|
/* Option to bypass checking existence of '.keep' files */
|
|
17
18
|
bool git_disable_pack_keep_file_checks = false;
|
|
18
19
|
|
|
19
|
-
static int
|
|
20
|
-
static off64_t
|
|
20
|
+
static int packfile_open_locked(struct git_pack_file *p);
|
|
21
|
+
static off64_t nth_packed_object_offset_locked(struct git_pack_file *p, uint32_t n);
|
|
21
22
|
static int packfile_unpack_compressed(
|
|
22
23
|
git_rawobj *obj,
|
|
23
24
|
struct git_pack_file *p,
|
|
@@ -56,7 +57,7 @@ static git_pack_cache_entry *new_cache_object(git_rawobj *source)
|
|
|
56
57
|
if (!e)
|
|
57
58
|
return NULL;
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
git_atomic32_inc(&e->refcount);
|
|
60
61
|
memcpy(&e->raw, source, sizeof(git_rawobj));
|
|
61
62
|
|
|
62
63
|
return e;
|
|
@@ -67,7 +68,6 @@ static void free_cache_object(void *o)
|
|
|
67
68
|
git_pack_cache_entry *e = (git_pack_cache_entry *)o;
|
|
68
69
|
|
|
69
70
|
if (e != NULL) {
|
|
70
|
-
assert(e->refcount.val == 0);
|
|
71
71
|
git__free(e->raw.data);
|
|
72
72
|
git__free(e);
|
|
73
73
|
}
|
|
@@ -114,7 +114,7 @@ static git_pack_cache_entry *cache_get(git_pack_cache *cache, off64_t offset)
|
|
|
114
114
|
return NULL;
|
|
115
115
|
|
|
116
116
|
if ((entry = git_offmap_get(cache->entries, offset)) != NULL) {
|
|
117
|
-
|
|
117
|
+
git_atomic32_inc(&entry->refcount);
|
|
118
118
|
entry->last_usage = cache->use_ctr++;
|
|
119
119
|
}
|
|
120
120
|
git_mutex_unlock(&cache->lock);
|
|
@@ -129,7 +129,7 @@ static void free_lowest_entry(git_pack_cache *cache)
|
|
|
129
129
|
git_pack_cache_entry *entry;
|
|
130
130
|
|
|
131
131
|
git_offmap_foreach(cache->entries, offset, entry, {
|
|
132
|
-
if (entry && entry->refcount
|
|
132
|
+
if (entry && git_atomic32_get(&entry->refcount) == 0) {
|
|
133
133
|
cache->memory_used -= entry->raw.len;
|
|
134
134
|
git_offmap_delete(cache->entries, offset);
|
|
135
135
|
free_cache_object(entry);
|
|
@@ -196,7 +196,8 @@ static void pack_index_free(struct git_pack_file *p)
|
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
|
|
199
|
+
/* Run with the packfile lock held */
|
|
200
|
+
static int pack_index_check_locked(const char *path, struct git_pack_file *p)
|
|
200
201
|
{
|
|
201
202
|
struct git_pack_idx_header *hdr;
|
|
202
203
|
uint32_t version, nr, i, *index;
|
|
@@ -302,40 +303,36 @@ static int pack_index_check(const char *path, struct git_pack_file *p)
|
|
|
302
303
|
return 0;
|
|
303
304
|
}
|
|
304
305
|
|
|
305
|
-
|
|
306
|
+
/* Run with the packfile lock held */
|
|
307
|
+
static int pack_index_open_locked(struct git_pack_file *p)
|
|
306
308
|
{
|
|
307
309
|
int error = 0;
|
|
308
310
|
size_t name_len;
|
|
309
|
-
git_buf idx_name;
|
|
311
|
+
git_buf idx_name = GIT_BUF_INIT;
|
|
310
312
|
|
|
311
313
|
if (p->index_version > -1)
|
|
312
|
-
|
|
314
|
+
goto cleanup;
|
|
313
315
|
|
|
316
|
+
/* checked by git_pack_file alloc */
|
|
314
317
|
name_len = strlen(p->pack_name);
|
|
315
|
-
|
|
318
|
+
GIT_ASSERT(name_len > strlen(".pack"));
|
|
316
319
|
|
|
317
|
-
if (git_buf_init(&idx_name, name_len) < 0)
|
|
318
|
-
|
|
320
|
+
if ((error = git_buf_init(&idx_name, name_len)) < 0)
|
|
321
|
+
goto cleanup;
|
|
319
322
|
|
|
320
323
|
git_buf_put(&idx_name, p->pack_name, name_len - strlen(".pack"));
|
|
321
324
|
git_buf_puts(&idx_name, ".idx");
|
|
322
325
|
if (git_buf_oom(&idx_name)) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if ((error = git_mutex_lock(&p->lock)) < 0) {
|
|
328
|
-
git_buf_dispose(&idx_name);
|
|
329
|
-
return error;
|
|
326
|
+
error = -1;
|
|
327
|
+
goto cleanup;
|
|
330
328
|
}
|
|
331
329
|
|
|
332
330
|
if (p->index_version == -1)
|
|
333
|
-
error =
|
|
331
|
+
error = pack_index_check_locked(idx_name.ptr, p);
|
|
334
332
|
|
|
333
|
+
cleanup:
|
|
335
334
|
git_buf_dispose(&idx_name);
|
|
336
335
|
|
|
337
|
-
git_mutex_unlock(&p->lock);
|
|
338
|
-
|
|
339
336
|
return error;
|
|
340
337
|
}
|
|
341
338
|
|
|
@@ -345,8 +342,20 @@ static unsigned char *pack_window_open(
|
|
|
345
342
|
off64_t offset,
|
|
346
343
|
unsigned int *left)
|
|
347
344
|
{
|
|
348
|
-
|
|
345
|
+
unsigned char *pack_data = NULL;
|
|
346
|
+
|
|
347
|
+
if (git_mutex_lock(&p->lock) < 0) {
|
|
348
|
+
git_error_set(GIT_ERROR_THREAD, "unable to lock packfile");
|
|
349
|
+
return NULL;
|
|
350
|
+
}
|
|
351
|
+
if (git_mutex_lock(&p->mwf.lock) < 0) {
|
|
352
|
+
git_mutex_unlock(&p->lock);
|
|
353
|
+
git_error_set(GIT_ERROR_THREAD, "unable to lock packfile");
|
|
349
354
|
return NULL;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (p->mwf.fd == -1 && packfile_open_locked(p) < 0)
|
|
358
|
+
goto cleanup;
|
|
350
359
|
|
|
351
360
|
/* Since packfiles end in a hash of their content and it's
|
|
352
361
|
* pointless to ask for an offset into the middle of that
|
|
@@ -357,11 +366,16 @@ static unsigned char *pack_window_open(
|
|
|
357
366
|
* around.
|
|
358
367
|
*/
|
|
359
368
|
if (offset > (p->mwf.size - 20))
|
|
360
|
-
|
|
369
|
+
goto cleanup;
|
|
361
370
|
if (offset < 0)
|
|
362
|
-
|
|
371
|
+
goto cleanup;
|
|
372
|
+
|
|
373
|
+
pack_data = git_mwindow_open(&p->mwf, w_cursor, offset, 20, left);
|
|
363
374
|
|
|
364
|
-
|
|
375
|
+
cleanup:
|
|
376
|
+
git_mutex_unlock(&p->mwf.lock);
|
|
377
|
+
git_mutex_unlock(&p->lock);
|
|
378
|
+
return pack_data;
|
|
365
379
|
}
|
|
366
380
|
|
|
367
381
|
/*
|
|
@@ -372,12 +386,12 @@ static unsigned char *pack_window_open(
|
|
|
372
386
|
* - each byte afterwards: low seven bits are size continuation,
|
|
373
387
|
* with the high bit being "size continues"
|
|
374
388
|
*/
|
|
375
|
-
|
|
389
|
+
int git_packfile__object_header(size_t *out, unsigned char *hdr, size_t size, git_object_t type)
|
|
376
390
|
{
|
|
377
391
|
unsigned char *hdr_base;
|
|
378
392
|
unsigned char c;
|
|
379
393
|
|
|
380
|
-
|
|
394
|
+
GIT_ASSERT_ARG(type >= GIT_OBJECT_COMMIT && type <= GIT_OBJECT_REF_DELTA);
|
|
381
395
|
|
|
382
396
|
/* TODO: add support for chunked objects; see git.git 6c0d19b1 */
|
|
383
397
|
|
|
@@ -392,7 +406,8 @@ size_t git_packfile__object_header(unsigned char *hdr, size_t size, git_object_t
|
|
|
392
406
|
}
|
|
393
407
|
*hdr++ = c;
|
|
394
408
|
|
|
395
|
-
|
|
409
|
+
*out = (hdr - hdr_base);
|
|
410
|
+
return 0;
|
|
396
411
|
}
|
|
397
412
|
|
|
398
413
|
|
|
@@ -436,14 +451,27 @@ static int packfile_unpack_header1(
|
|
|
436
451
|
int git_packfile_unpack_header(
|
|
437
452
|
size_t *size_p,
|
|
438
453
|
git_object_t *type_p,
|
|
439
|
-
|
|
454
|
+
struct git_pack_file *p,
|
|
440
455
|
git_mwindow **w_curs,
|
|
441
456
|
off64_t *curpos)
|
|
442
457
|
{
|
|
443
458
|
unsigned char *base;
|
|
444
459
|
unsigned int left;
|
|
445
460
|
unsigned long used;
|
|
446
|
-
int
|
|
461
|
+
int error;
|
|
462
|
+
|
|
463
|
+
if ((error = git_mutex_lock(&p->lock)) < 0)
|
|
464
|
+
return error;
|
|
465
|
+
if ((error = git_mutex_lock(&p->mwf.lock)) < 0) {
|
|
466
|
+
git_mutex_unlock(&p->lock);
|
|
467
|
+
return error;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
if (p->mwf.fd == -1 && (error = packfile_open_locked(p)) < 0) {
|
|
471
|
+
git_mutex_unlock(&p->lock);
|
|
472
|
+
git_mutex_unlock(&p->mwf.lock);
|
|
473
|
+
return error;
|
|
474
|
+
}
|
|
447
475
|
|
|
448
476
|
/* pack_window_open() assures us we have [base, base + 20) available
|
|
449
477
|
* as a range that we can look at at. (Its actually the hash
|
|
@@ -451,16 +479,17 @@ int git_packfile_unpack_header(
|
|
|
451
479
|
* the maximum deflated object size is 2^137, which is just
|
|
452
480
|
* insane, so we know won't exceed what we have been given.
|
|
453
481
|
*/
|
|
454
|
-
|
|
455
|
-
|
|
482
|
+
base = git_mwindow_open(&p->mwf, w_curs, *curpos, 20, &left);
|
|
483
|
+
git_mutex_unlock(&p->lock);
|
|
484
|
+
git_mutex_unlock(&p->mwf.lock);
|
|
456
485
|
if (base == NULL)
|
|
457
486
|
return GIT_EBUFS;
|
|
458
487
|
|
|
459
|
-
|
|
488
|
+
error = packfile_unpack_header1(&used, size_p, type_p, base, left);
|
|
460
489
|
git_mwindow_close(w_curs);
|
|
461
|
-
if (
|
|
462
|
-
return
|
|
463
|
-
else if (
|
|
490
|
+
if (error == GIT_EBUFS)
|
|
491
|
+
return error;
|
|
492
|
+
else if (error < 0)
|
|
464
493
|
return packfile_error("header length is zero");
|
|
465
494
|
|
|
466
495
|
*curpos += used;
|
|
@@ -480,7 +509,27 @@ int git_packfile_resolve_header(
|
|
|
480
509
|
off64_t base_offset;
|
|
481
510
|
int error;
|
|
482
511
|
|
|
483
|
-
error =
|
|
512
|
+
error = git_mutex_lock(&p->lock);
|
|
513
|
+
if (error < 0) {
|
|
514
|
+
git_error_set(GIT_ERROR_OS, "failed to lock packfile reader");
|
|
515
|
+
return error;
|
|
516
|
+
}
|
|
517
|
+
error = git_mutex_lock(&p->mwf.lock);
|
|
518
|
+
if (error < 0) {
|
|
519
|
+
git_error_set(GIT_ERROR_OS, "failed to lock packfile reader");
|
|
520
|
+
git_mutex_unlock(&p->lock);
|
|
521
|
+
return error;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
if (p->mwf.fd == -1 && (error = packfile_open_locked(p)) < 0) {
|
|
525
|
+
git_mutex_unlock(&p->mwf.lock);
|
|
526
|
+
git_mutex_unlock(&p->lock);
|
|
527
|
+
return error;
|
|
528
|
+
}
|
|
529
|
+
git_mutex_unlock(&p->mwf.lock);
|
|
530
|
+
git_mutex_unlock(&p->lock);
|
|
531
|
+
|
|
532
|
+
error = git_packfile_unpack_header(&size, &type, p, &w_curs, &curpos);
|
|
484
533
|
if (error < 0)
|
|
485
534
|
return error;
|
|
486
535
|
|
|
@@ -507,7 +556,7 @@ int git_packfile_resolve_header(
|
|
|
507
556
|
|
|
508
557
|
while (type == GIT_OBJECT_OFS_DELTA || type == GIT_OBJECT_REF_DELTA) {
|
|
509
558
|
curpos = base_offset;
|
|
510
|
-
error = git_packfile_unpack_header(&size, &type,
|
|
559
|
+
error = git_packfile_unpack_header(&size, &type, p, &w_curs, &curpos);
|
|
511
560
|
if (error < 0)
|
|
512
561
|
return error;
|
|
513
562
|
if (type != GIT_OBJECT_OFS_DELTA && type != GIT_OBJECT_REF_DELTA)
|
|
@@ -578,8 +627,7 @@ static int pack_dependency_chain(git_dependency_chain *chain_out,
|
|
|
578
627
|
|
|
579
628
|
elem->base_key = obj_offset;
|
|
580
629
|
|
|
581
|
-
error = git_packfile_unpack_header(&size, &type,
|
|
582
|
-
|
|
630
|
+
error = git_packfile_unpack_header(&size, &type, p, &w_curs, &curpos);
|
|
583
631
|
if (error < 0)
|
|
584
632
|
goto on_error;
|
|
585
633
|
|
|
@@ -630,6 +678,25 @@ int git_packfile_unpack(
|
|
|
630
678
|
size_t stack_size = 0, elem_pos, alloclen;
|
|
631
679
|
git_object_t base_type;
|
|
632
680
|
|
|
681
|
+
error = git_mutex_lock(&p->lock);
|
|
682
|
+
if (error < 0) {
|
|
683
|
+
git_error_set(GIT_ERROR_OS, "failed to lock packfile reader");
|
|
684
|
+
return error;
|
|
685
|
+
}
|
|
686
|
+
error = git_mutex_lock(&p->mwf.lock);
|
|
687
|
+
if (error < 0) {
|
|
688
|
+
git_error_set(GIT_ERROR_OS, "failed to lock packfile reader");
|
|
689
|
+
git_mutex_unlock(&p->lock);
|
|
690
|
+
return error;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
if (p->mwf.fd == -1)
|
|
694
|
+
error = packfile_open_locked(p);
|
|
695
|
+
git_mutex_unlock(&p->mwf.lock);
|
|
696
|
+
git_mutex_unlock(&p->lock);
|
|
697
|
+
if (error < 0)
|
|
698
|
+
return error;
|
|
699
|
+
|
|
633
700
|
/*
|
|
634
701
|
* TODO: optionally check the CRC on the packfile
|
|
635
702
|
*/
|
|
@@ -692,7 +759,7 @@ int git_packfile_unpack(
|
|
|
692
759
|
GIT_ERROR_CHECK_ALLOC(obj->data);
|
|
693
760
|
|
|
694
761
|
memcpy(obj->data, data, obj->len + 1);
|
|
695
|
-
|
|
762
|
+
git_atomic32_dec(&cached->refcount);
|
|
696
763
|
goto cleanup;
|
|
697
764
|
}
|
|
698
765
|
|
|
@@ -740,7 +807,7 @@ int git_packfile_unpack(
|
|
|
740
807
|
}
|
|
741
808
|
|
|
742
809
|
if (cached) {
|
|
743
|
-
|
|
810
|
+
git_atomic32_dec(&cached->refcount);
|
|
744
811
|
cached = NULL;
|
|
745
812
|
}
|
|
746
813
|
|
|
@@ -754,7 +821,7 @@ cleanup:
|
|
|
754
821
|
if (error < 0) {
|
|
755
822
|
git__free(obj->data);
|
|
756
823
|
if (cached)
|
|
757
|
-
|
|
824
|
+
git_atomic32_dec(&cached->refcount);
|
|
758
825
|
}
|
|
759
826
|
|
|
760
827
|
if (elem)
|
|
@@ -904,7 +971,7 @@ int get_delta_base(
|
|
|
904
971
|
off64_t base_offset;
|
|
905
972
|
git_oid unused;
|
|
906
973
|
|
|
907
|
-
|
|
974
|
+
GIT_ASSERT_ARG(delta_base_out);
|
|
908
975
|
|
|
909
976
|
base_info = pack_window_open(p, w_curs, *curpos, &left);
|
|
910
977
|
/* Assumption: the only reason this would fail is because the file is too small */
|
|
@@ -976,63 +1043,63 @@ int get_delta_base(
|
|
|
976
1043
|
*
|
|
977
1044
|
***********************************************************/
|
|
978
1045
|
|
|
979
|
-
void
|
|
1046
|
+
void git_packfile_free(struct git_pack_file *p, bool unlink_packfile)
|
|
980
1047
|
{
|
|
1048
|
+
bool locked = true;
|
|
1049
|
+
|
|
1050
|
+
if (!p)
|
|
1051
|
+
return;
|
|
1052
|
+
|
|
1053
|
+
cache_free(&p->bases);
|
|
1054
|
+
|
|
1055
|
+
if (git_mutex_lock(&p->lock) < 0) {
|
|
1056
|
+
git_error_set(GIT_ERROR_OS, "failed to lock packfile");
|
|
1057
|
+
locked = false;
|
|
1058
|
+
}
|
|
981
1059
|
if (p->mwf.fd >= 0) {
|
|
982
|
-
|
|
1060
|
+
git_mwindow_free_all(&p->mwf);
|
|
983
1061
|
p_close(p->mwf.fd);
|
|
984
1062
|
p->mwf.fd = -1;
|
|
985
1063
|
}
|
|
1064
|
+
if (locked)
|
|
1065
|
+
git_mutex_unlock(&p->lock);
|
|
986
1066
|
|
|
987
1067
|
if (unlink_packfile)
|
|
988
1068
|
p_unlink(p->pack_name);
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
void git_packfile_free(struct git_pack_file *p)
|
|
992
|
-
{
|
|
993
|
-
if (!p)
|
|
994
|
-
return;
|
|
995
|
-
|
|
996
|
-
cache_free(&p->bases);
|
|
997
|
-
|
|
998
|
-
git_packfile_close(p, false);
|
|
999
1069
|
|
|
1000
1070
|
pack_index_free(p);
|
|
1001
1071
|
|
|
1002
1072
|
git__free(p->bad_object_sha1);
|
|
1003
1073
|
|
|
1004
|
-
git_mutex_free(&p->lock);
|
|
1005
1074
|
git_mutex_free(&p->bases.lock);
|
|
1075
|
+
git_mutex_free(&p->mwf.lock);
|
|
1076
|
+
git_mutex_free(&p->lock);
|
|
1006
1077
|
git__free(p);
|
|
1007
1078
|
}
|
|
1008
1079
|
|
|
1009
|
-
|
|
1080
|
+
/* Run with the packfile and mwf locks held */
|
|
1081
|
+
static int packfile_open_locked(struct git_pack_file *p)
|
|
1010
1082
|
{
|
|
1011
1083
|
struct stat st;
|
|
1012
1084
|
struct git_pack_header hdr;
|
|
1013
1085
|
git_oid sha1;
|
|
1014
1086
|
unsigned char *idx_sha1;
|
|
1015
1087
|
|
|
1016
|
-
if (
|
|
1088
|
+
if (pack_index_open_locked(p) < 0)
|
|
1017
1089
|
return git_odb__error_notfound("failed to open packfile", NULL, 0);
|
|
1018
1090
|
|
|
1019
|
-
|
|
1020
|
-
if (git_mutex_lock(&p->lock) < 0)
|
|
1021
|
-
return packfile_error("failed to get lock for open");
|
|
1022
|
-
|
|
1023
|
-
if (p->mwf.fd >= 0) {
|
|
1024
|
-
git_mutex_unlock(&p->lock);
|
|
1091
|
+
if (p->mwf.fd >= 0)
|
|
1025
1092
|
return 0;
|
|
1026
|
-
}
|
|
1027
1093
|
|
|
1028
1094
|
/* TODO: open with noatime */
|
|
1029
1095
|
p->mwf.fd = git_futils_open_ro(p->pack_name);
|
|
1030
1096
|
if (p->mwf.fd < 0)
|
|
1031
1097
|
goto cleanup;
|
|
1032
1098
|
|
|
1033
|
-
if (p_fstat(p->mwf.fd, &st) < 0
|
|
1034
|
-
|
|
1099
|
+
if (p_fstat(p->mwf.fd, &st) < 0) {
|
|
1100
|
+
git_error_set(GIT_ERROR_OS, "could not stat packfile");
|
|
1035
1101
|
goto cleanup;
|
|
1102
|
+
}
|
|
1036
1103
|
|
|
1037
1104
|
/* If we created the struct before we had the pack we lack size. */
|
|
1038
1105
|
if (!p->mwf.size) {
|
|
@@ -1071,7 +1138,9 @@ static int packfile_open(struct git_pack_file *p)
|
|
|
1071
1138
|
if (git_oid__cmp(&sha1, (git_oid *)idx_sha1) != 0)
|
|
1072
1139
|
goto cleanup;
|
|
1073
1140
|
|
|
1074
|
-
|
|
1141
|
+
if (git_mwindow_file_register(&p->mwf) < 0)
|
|
1142
|
+
goto cleanup;
|
|
1143
|
+
|
|
1075
1144
|
return 0;
|
|
1076
1145
|
|
|
1077
1146
|
cleanup:
|
|
@@ -1081,8 +1150,6 @@ cleanup:
|
|
|
1081
1150
|
p_close(p->mwf.fd);
|
|
1082
1151
|
p->mwf.fd = -1;
|
|
1083
1152
|
|
|
1084
|
-
git_mutex_unlock(&p->lock);
|
|
1085
|
-
|
|
1086
1153
|
return -1;
|
|
1087
1154
|
}
|
|
1088
1155
|
|
|
@@ -1152,13 +1219,22 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path)
|
|
|
1152
1219
|
p->mtime = (git_time_t)st.st_mtime;
|
|
1153
1220
|
p->index_version = -1;
|
|
1154
1221
|
|
|
1155
|
-
if (git_mutex_init(&p->lock)) {
|
|
1222
|
+
if (git_mutex_init(&p->lock) < 0) {
|
|
1156
1223
|
git_error_set(GIT_ERROR_OS, "failed to initialize packfile mutex");
|
|
1157
1224
|
git__free(p);
|
|
1158
1225
|
return -1;
|
|
1159
1226
|
}
|
|
1160
1227
|
|
|
1228
|
+
if (git_mutex_init(&p->mwf.lock) < 0) {
|
|
1229
|
+
git_error_set(GIT_ERROR_OS, "failed to initialize packfile window mutex");
|
|
1230
|
+
git_mutex_free(&p->lock);
|
|
1231
|
+
git__free(p);
|
|
1232
|
+
return -1;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1161
1235
|
if (cache_init(&p->bases) < 0) {
|
|
1236
|
+
git_mutex_free(&p->mwf.lock);
|
|
1237
|
+
git_mutex_free(&p->lock);
|
|
1162
1238
|
git__free(p);
|
|
1163
1239
|
return -1;
|
|
1164
1240
|
}
|
|
@@ -1174,28 +1250,29 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path)
|
|
|
1174
1250
|
*
|
|
1175
1251
|
***********************************************************/
|
|
1176
1252
|
|
|
1177
|
-
static off64_t
|
|
1253
|
+
static off64_t nth_packed_object_offset_locked(struct git_pack_file *p, uint32_t n)
|
|
1178
1254
|
{
|
|
1179
|
-
const unsigned char *index
|
|
1180
|
-
|
|
1255
|
+
const unsigned char *index, *end;
|
|
1256
|
+
uint32_t off32;
|
|
1257
|
+
|
|
1258
|
+
index = p->index_map.data;
|
|
1259
|
+
end = index + p->index_map.len;
|
|
1181
1260
|
index += 4 * 256;
|
|
1182
|
-
if (p->index_version == 1)
|
|
1261
|
+
if (p->index_version == 1)
|
|
1183
1262
|
return ntohl(*((uint32_t *)(index + 24 * n)));
|
|
1184
|
-
} else {
|
|
1185
|
-
uint32_t off;
|
|
1186
|
-
index += 8 + p->num_objects * (20 + 4);
|
|
1187
|
-
off = ntohl(*((uint32_t *)(index + 4 * n)));
|
|
1188
|
-
if (!(off & 0x80000000))
|
|
1189
|
-
return off;
|
|
1190
|
-
index += p->num_objects * 4 + (off & 0x7fffffff) * 8;
|
|
1191
|
-
|
|
1192
|
-
/* Make sure we're not being sent out of bounds */
|
|
1193
|
-
if (index >= end - 8)
|
|
1194
|
-
return -1;
|
|
1195
1263
|
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1264
|
+
index += 8 + p->num_objects * (20 + 4);
|
|
1265
|
+
off32 = ntohl(*((uint32_t *)(index + 4 * n)));
|
|
1266
|
+
if (!(off32 & 0x80000000))
|
|
1267
|
+
return off32;
|
|
1268
|
+
index += p->num_objects * 4 + (off32 & 0x7fffffff) * 8;
|
|
1269
|
+
|
|
1270
|
+
/* Make sure we're not being sent out of bounds */
|
|
1271
|
+
if (index >= end - 8)
|
|
1272
|
+
return -1;
|
|
1273
|
+
|
|
1274
|
+
return (((uint64_t)ntohl(*((uint32_t *)(index + 0)))) << 32) |
|
|
1275
|
+
ntohl(*((uint32_t *)(index + 4)));
|
|
1199
1276
|
}
|
|
1200
1277
|
|
|
1201
1278
|
static int git__memcmp4(const void *a, const void *b) {
|
|
@@ -1207,33 +1284,45 @@ int git_pack_foreach_entry(
|
|
|
1207
1284
|
git_odb_foreach_cb cb,
|
|
1208
1285
|
void *data)
|
|
1209
1286
|
{
|
|
1210
|
-
const unsigned char *index
|
|
1287
|
+
const unsigned char *index, *current;
|
|
1211
1288
|
uint32_t i;
|
|
1212
1289
|
int error = 0;
|
|
1290
|
+
git_array_oid_t oids = GIT_ARRAY_INIT;
|
|
1291
|
+
git_oid *oid;
|
|
1213
1292
|
|
|
1214
|
-
if (
|
|
1215
|
-
|
|
1216
|
-
return error;
|
|
1293
|
+
if (git_mutex_lock(&p->lock) < 0)
|
|
1294
|
+
return packfile_error("failed to get lock for git_pack_foreach_entry");
|
|
1217
1295
|
|
|
1218
|
-
|
|
1296
|
+
if ((error = pack_index_open_locked(p)) < 0) {
|
|
1297
|
+
git_mutex_unlock(&p->lock);
|
|
1298
|
+
return error;
|
|
1299
|
+
}
|
|
1219
1300
|
|
|
1220
|
-
|
|
1301
|
+
if (!p->index_map.data) {
|
|
1302
|
+
git_error_set(GIT_ERROR_INTERNAL, "internal error: p->index_map.data == NULL");
|
|
1303
|
+
git_mutex_unlock(&p->lock);
|
|
1304
|
+
return -1;
|
|
1221
1305
|
}
|
|
1222
1306
|
|
|
1223
|
-
|
|
1307
|
+
index = p->index_map.data;
|
|
1308
|
+
|
|
1309
|
+
if (p->index_version > 1)
|
|
1224
1310
|
index += 8;
|
|
1225
|
-
}
|
|
1226
1311
|
|
|
1227
1312
|
index += 4 * 256;
|
|
1228
1313
|
|
|
1229
1314
|
if (p->oids == NULL) {
|
|
1230
1315
|
git_vector offsets, oids;
|
|
1231
1316
|
|
|
1232
|
-
if ((error = git_vector_init(&oids, p->num_objects, NULL)))
|
|
1317
|
+
if ((error = git_vector_init(&oids, p->num_objects, NULL))) {
|
|
1318
|
+
git_mutex_unlock(&p->lock);
|
|
1233
1319
|
return error;
|
|
1320
|
+
}
|
|
1234
1321
|
|
|
1235
|
-
if ((error = git_vector_init(&offsets, p->num_objects, git__memcmp4)))
|
|
1322
|
+
if ((error = git_vector_init(&offsets, p->num_objects, git__memcmp4))) {
|
|
1323
|
+
git_mutex_unlock(&p->lock);
|
|
1236
1324
|
return error;
|
|
1325
|
+
}
|
|
1237
1326
|
|
|
1238
1327
|
if (p->index_version > 1) {
|
|
1239
1328
|
const unsigned char *off = index + 24 * p->num_objects;
|
|
@@ -1254,10 +1343,104 @@ int git_pack_foreach_entry(
|
|
|
1254
1343
|
p->oids = (git_oid **)git_vector_detach(NULL, NULL, &oids);
|
|
1255
1344
|
}
|
|
1256
1345
|
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1346
|
+
/* We need to copy the OIDs to another array before we relinquish the lock to avoid races. */
|
|
1347
|
+
git_array_init_to_size(oids, p->num_objects);
|
|
1348
|
+
if (!oids.ptr) {
|
|
1349
|
+
git_mutex_unlock(&p->lock);
|
|
1350
|
+
git_array_clear(oids);
|
|
1351
|
+
GIT_ERROR_CHECK_ARRAY(oids);
|
|
1352
|
+
}
|
|
1353
|
+
for (i = 0; i < p->num_objects; i++) {
|
|
1354
|
+
oid = git_array_alloc(oids);
|
|
1355
|
+
if (!oid) {
|
|
1356
|
+
git_mutex_unlock(&p->lock);
|
|
1357
|
+
git_array_clear(oids);
|
|
1358
|
+
GIT_ERROR_CHECK_ALLOC(oid);
|
|
1359
|
+
}
|
|
1360
|
+
git_oid_cpy(oid, p->oids[i]);
|
|
1361
|
+
}
|
|
1260
1362
|
|
|
1363
|
+
git_mutex_unlock(&p->lock);
|
|
1364
|
+
|
|
1365
|
+
git_array_foreach(oids, i, oid) {
|
|
1366
|
+
if ((error = cb(oid, data)) != 0) {
|
|
1367
|
+
git_error_set_after_callback(error);
|
|
1368
|
+
break;
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
git_array_clear(oids);
|
|
1373
|
+
return error;
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
int git_pack_foreach_entry_offset(
|
|
1377
|
+
struct git_pack_file *p,
|
|
1378
|
+
git_pack_foreach_entry_offset_cb cb,
|
|
1379
|
+
void *data)
|
|
1380
|
+
{
|
|
1381
|
+
const unsigned char *index;
|
|
1382
|
+
off64_t current_offset;
|
|
1383
|
+
const git_oid *current_oid;
|
|
1384
|
+
uint32_t i;
|
|
1385
|
+
int error = 0;
|
|
1386
|
+
|
|
1387
|
+
if (git_mutex_lock(&p->lock) < 0)
|
|
1388
|
+
return packfile_error("failed to get lock for git_pack_foreach_entry_offset");
|
|
1389
|
+
|
|
1390
|
+
index = p->index_map.data;
|
|
1391
|
+
if (index == NULL) {
|
|
1392
|
+
if ((error = pack_index_open_locked(p)) < 0)
|
|
1393
|
+
goto cleanup;
|
|
1394
|
+
|
|
1395
|
+
if (!p->index_map.data) {
|
|
1396
|
+
git_error_set(GIT_ERROR_INTERNAL, "internal error: p->index_map.data == NULL");
|
|
1397
|
+
goto cleanup;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
index = p->index_map.data;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
if (p->index_version > 1)
|
|
1404
|
+
index += 8;
|
|
1405
|
+
|
|
1406
|
+
index += 4 * 256;
|
|
1407
|
+
|
|
1408
|
+
/* all offsets should have been validated by pack_index_check_locked */
|
|
1409
|
+
if (p->index_version > 1) {
|
|
1410
|
+
const unsigned char *offsets = index + 24 * p->num_objects;
|
|
1411
|
+
const unsigned char *large_offset_ptr;
|
|
1412
|
+
const unsigned char *large_offsets = index + 28 * p->num_objects;
|
|
1413
|
+
const unsigned char *large_offsets_end = ((const unsigned char *)p->index_map.data) + p->index_map.len - 20;
|
|
1414
|
+
for (i = 0; i < p->num_objects; i++) {
|
|
1415
|
+
current_offset = ntohl(*(const uint32_t *)(offsets + 4 * i));
|
|
1416
|
+
if (current_offset & 0x80000000) {
|
|
1417
|
+
large_offset_ptr = large_offsets + (current_offset & 0x7fffffff) * 8;
|
|
1418
|
+
if (large_offset_ptr >= large_offsets_end) {
|
|
1419
|
+
error = packfile_error("invalid large offset");
|
|
1420
|
+
goto cleanup;
|
|
1421
|
+
}
|
|
1422
|
+
current_offset = (((off64_t)ntohl(*((uint32_t *)(large_offset_ptr + 0)))) << 32) |
|
|
1423
|
+
ntohl(*((uint32_t *)(large_offset_ptr + 4)));
|
|
1424
|
+
}
|
|
1425
|
+
current_oid = (const git_oid *)(index + 20 * i);
|
|
1426
|
+
if ((error = cb(current_oid, current_offset, data)) != 0) {
|
|
1427
|
+
error = git_error_set_after_callback(error);
|
|
1428
|
+
goto cleanup;
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
} else {
|
|
1432
|
+
for (i = 0; i < p->num_objects; i++) {
|
|
1433
|
+
current_offset = ntohl(*(const uint32_t *)(index + 24 * i));
|
|
1434
|
+
current_oid = (const git_oid *)(index + 24 * i + 4);
|
|
1435
|
+
if ((error = cb(current_oid, current_offset, data)) != 0) {
|
|
1436
|
+
error = git_error_set_after_callback(error);
|
|
1437
|
+
goto cleanup;
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
cleanup:
|
|
1443
|
+
git_mutex_unlock(&p->lock);
|
|
1261
1444
|
return error;
|
|
1262
1445
|
}
|
|
1263
1446
|
|
|
@@ -1295,15 +1478,19 @@ static int pack_entry_find_offset(
|
|
|
1295
1478
|
int pos, found = 0;
|
|
1296
1479
|
off64_t offset;
|
|
1297
1480
|
const unsigned char *current = 0;
|
|
1481
|
+
int error = 0;
|
|
1298
1482
|
|
|
1299
1483
|
*offset_out = 0;
|
|
1300
1484
|
|
|
1301
|
-
if (p->
|
|
1302
|
-
|
|
1485
|
+
if (git_mutex_lock(&p->lock) < 0)
|
|
1486
|
+
return packfile_error("failed to get lock for pack_entry_find_offset");
|
|
1303
1487
|
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1488
|
+
if ((error = pack_index_open_locked(p)) < 0)
|
|
1489
|
+
goto cleanup;
|
|
1490
|
+
|
|
1491
|
+
if (!p->index_map.data) {
|
|
1492
|
+
git_error_set(GIT_ERROR_INTERNAL, "internal error: p->index_map.data == NULL");
|
|
1493
|
+
goto cleanup;
|
|
1307
1494
|
}
|
|
1308
1495
|
|
|
1309
1496
|
index = p->index_map.data;
|
|
@@ -1357,14 +1544,19 @@ static int pack_entry_find_offset(
|
|
|
1357
1544
|
}
|
|
1358
1545
|
}
|
|
1359
1546
|
|
|
1360
|
-
if (!found)
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1547
|
+
if (!found) {
|
|
1548
|
+
error = git_odb__error_notfound("failed to find offset for pack entry", short_oid, len);
|
|
1549
|
+
goto cleanup;
|
|
1550
|
+
}
|
|
1551
|
+
if (found > 1) {
|
|
1552
|
+
error = git_odb__error_ambiguous("found multiple offsets for pack entry");
|
|
1553
|
+
goto cleanup;
|
|
1554
|
+
}
|
|
1364
1555
|
|
|
1365
|
-
if ((offset =
|
|
1556
|
+
if ((offset = nth_packed_object_offset_locked(p, pos)) < 0) {
|
|
1366
1557
|
git_error_set(GIT_ERROR_ODB, "packfile index is corrupt");
|
|
1367
|
-
|
|
1558
|
+
error = -1;
|
|
1559
|
+
goto cleanup;
|
|
1368
1560
|
}
|
|
1369
1561
|
|
|
1370
1562
|
*offset_out = offset;
|
|
@@ -1379,7 +1571,9 @@ static int pack_entry_find_offset(
|
|
|
1379
1571
|
}
|
|
1380
1572
|
#endif
|
|
1381
1573
|
|
|
1382
|
-
|
|
1574
|
+
cleanup:
|
|
1575
|
+
git_mutex_unlock(&p->lock);
|
|
1576
|
+
return error;
|
|
1383
1577
|
}
|
|
1384
1578
|
|
|
1385
1579
|
int git_pack_entry_find(
|
|
@@ -1392,7 +1586,7 @@ int git_pack_entry_find(
|
|
|
1392
1586
|
git_oid found_oid;
|
|
1393
1587
|
int error;
|
|
1394
1588
|
|
|
1395
|
-
|
|
1589
|
+
GIT_ASSERT_ARG(p);
|
|
1396
1590
|
|
|
1397
1591
|
if (len == GIT_OID_HEXSZ && p->num_bad_objects) {
|
|
1398
1592
|
unsigned i;
|
|
@@ -1405,10 +1599,26 @@ int git_pack_entry_find(
|
|
|
1405
1599
|
if (error < 0)
|
|
1406
1600
|
return error;
|
|
1407
1601
|
|
|
1602
|
+
error = git_mutex_lock(&p->lock);
|
|
1603
|
+
if (error < 0) {
|
|
1604
|
+
git_error_set(GIT_ERROR_OS, "failed to lock packfile reader");
|
|
1605
|
+
return error;
|
|
1606
|
+
}
|
|
1607
|
+
error = git_mutex_lock(&p->mwf.lock);
|
|
1608
|
+
if (error < 0) {
|
|
1609
|
+
git_mutex_unlock(&p->lock);
|
|
1610
|
+
git_error_set(GIT_ERROR_OS, "failed to lock packfile reader");
|
|
1611
|
+
return error;
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1408
1614
|
/* we found a unique entry in the index;
|
|
1409
1615
|
* make sure the packfile backing the index
|
|
1410
1616
|
* still exists on disk */
|
|
1411
|
-
if (p->mwf.fd == -1
|
|
1617
|
+
if (p->mwf.fd == -1)
|
|
1618
|
+
error = packfile_open_locked(p);
|
|
1619
|
+
git_mutex_unlock(&p->mwf.lock);
|
|
1620
|
+
git_mutex_unlock(&p->lock);
|
|
1621
|
+
if (error < 0)
|
|
1412
1622
|
return error;
|
|
1413
1623
|
|
|
1414
1624
|
e->offset = offset;
|