rugged 1.0.0 → 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 +3 -3
- data/ext/rugged/rugged.c +7 -4
- data/ext/rugged/rugged_commit.c +1 -1
- data/ext/rugged/rugged_config.c +1 -1
- data/ext/rugged/rugged_object.c +1 -1
- data/ext/rugged/rugged_remote.c +32 -2
- data/ext/rugged/rugged_repo.c +13 -3
- data/lib/rugged/commit.rb +17 -4
- data/lib/rugged/repository.rb +7 -8
- data/lib/rugged/submodule_collection.rb +4 -4
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +41 -74
- data/vendor/libgit2/COPYING +109 -1
- data/vendor/libgit2/cmake/{Modules/AddCFlagIfSupported.cmake → AddCFlagIfSupported.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/EnableWarnings.cmake → EnableWarnings.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindCoreFoundation.cmake → FindCoreFoundation.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindGSSAPI.cmake → FindGSSAPI.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindGSSFramework.cmake → FindGSSFramework.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindHTTP_Parser.cmake → FindHTTP_Parser.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindIconv.cmake → FindIconv.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindPCRE.cmake → FindPCRE.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindPCRE2.cmake → FindPCRE2.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindPkgLibraries.cmake → FindPkgLibraries.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindSecurity.cmake → FindSecurity.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/FindStatNsec.cmake → FindStatNsec.cmake} +0 -0
- data/vendor/libgit2/cmake/Findfutimens.cmake +14 -0
- data/vendor/libgit2/cmake/{Modules/FindmbedTLS.cmake → FindmbedTLS.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/IdeSplitSources.cmake → IdeSplitSources.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/PkgBuildConfig.cmake → PkgBuildConfig.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/SanitizeBool.cmake → SanitizeBool.cmake} +0 -0
- data/vendor/libgit2/cmake/{Modules/SelectGSSAPI.cmake → SelectGSSAPI.cmake} +18 -26
- data/vendor/libgit2/cmake/{Modules/SelectHTTPSBackend.cmake → SelectHTTPSBackend.cmake} +29 -32
- data/vendor/libgit2/cmake/{Modules/SelectHashes.cmake → SelectHashes.cmake} +21 -28
- data/vendor/libgit2/deps/chromium-zlib/CMakeLists.txt +101 -0
- data/vendor/libgit2/deps/http-parser/CMakeLists.txt +4 -3
- data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +24 -10
- data/vendor/libgit2/deps/ntlmclient/compat.h +0 -27
- 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 +164 -135
- 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/deps/ntlmclient/util.c +15 -1
- data/vendor/libgit2/deps/ntlmclient/util.h +2 -1
- data/vendor/libgit2/deps/pcre/LICENCE +93 -0
- data/vendor/libgit2/deps/pcre/pcre.h +2 -2
- data/vendor/libgit2/deps/pcre/pcre_compile.c +29 -17
- data/vendor/libgit2/deps/pcre/pcre_jit_compile.c +4 -4
- data/vendor/libgit2/deps/pcre/pcreposix.c +2 -3
- data/vendor/libgit2/deps/zlib/CMakeLists.txt +6 -5
- data/vendor/libgit2/deps/zlib/deflate.c +1 -0
- data/vendor/libgit2/include/git2/annotated_commit.h +1 -1
- data/vendor/libgit2/include/git2/apply.h +2 -0
- data/vendor/libgit2/include/git2/attr.h +89 -0
- data/vendor/libgit2/include/git2/blame.h +95 -42
- data/vendor/libgit2/include/git2/blob.h +31 -3
- 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 +33 -6
- data/vendor/libgit2/include/git2/config.h +1 -1
- data/vendor/libgit2/include/git2/deprecated.h +248 -8
- data/vendor/libgit2/include/git2/diff.h +35 -20
- data/vendor/libgit2/include/git2/errors.h +8 -7
- 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 +4 -5
- data/vendor/libgit2/include/git2/indexer.h +2 -1
- data/vendor/libgit2/include/git2/odb.h +44 -20
- data/vendor/libgit2/include/git2/pack.h +1 -1
- 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 +9 -5
- data/vendor/libgit2/include/git2/remote.h +59 -6
- data/vendor/libgit2/include/git2/repository.h +95 -52
- data/vendor/libgit2/include/git2/revparse.h +5 -5
- data/vendor/libgit2/include/git2/status.h +115 -59
- data/vendor/libgit2/include/git2/strarray.h +6 -10
- 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/transport.h +1 -1
- data/vendor/libgit2/include/git2/tree.h +2 -14
- data/vendor/libgit2/include/git2/types.h +9 -0
- data/vendor/libgit2/include/git2/version.h +3 -3
- data/vendor/libgit2/include/git2/worktree.h +1 -0
- data/vendor/libgit2/src/CMakeLists.txt +77 -44
- 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 +21 -8
- data/vendor/libgit2/src/array.h +11 -11
- data/vendor/libgit2/src/assert_safe.h +58 -0
- data/vendor/libgit2/src/attr.c +181 -74
- data/vendor/libgit2/src/attr_file.c +92 -42
- data/vendor/libgit2/src/attr_file.h +32 -11
- data/vendor/libgit2/src/attrcache.c +44 -40
- data/vendor/libgit2/src/attrcache.h +4 -5
- data/vendor/libgit2/src/blame.c +28 -15
- data/vendor/libgit2/src/blame_git.c +6 -3
- data/vendor/libgit2/src/blob.c +46 -24
- data/vendor/libgit2/src/branch.c +87 -37
- data/vendor/libgit2/src/buffer.c +339 -27
- data/vendor/libgit2/src/buffer.h +153 -2
- data/vendor/libgit2/src/cache.c +3 -24
- data/vendor/libgit2/src/cache.h +7 -7
- data/vendor/libgit2/src/cc-compat.h +10 -2
- data/vendor/libgit2/src/checkout.c +97 -98
- data/vendor/libgit2/src/cherrypick.c +8 -2
- data/vendor/libgit2/src/clone.c +104 -29
- 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 +26 -2
- data/vendor/libgit2/src/config.c +40 -22
- data/vendor/libgit2/src/config_cache.c +9 -4
- data/vendor/libgit2/src/config_entries.c +35 -27
- data/vendor/libgit2/src/config_file.c +25 -8
- data/vendor/libgit2/src/config_parse.c +5 -7
- data/vendor/libgit2/src/config_snapshot.c +2 -1
- 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 +11 -4
- data/vendor/libgit2/src/diff.c +23 -19
- data/vendor/libgit2/src/diff_driver.c +21 -17
- data/vendor/libgit2/src/diff_file.c +5 -7
- data/vendor/libgit2/src/diff_generate.c +56 -28
- data/vendor/libgit2/src/diff_parse.c +2 -3
- data/vendor/libgit2/src/diff_print.c +81 -65
- data/vendor/libgit2/src/diff_stats.c +19 -16
- data/vendor/libgit2/src/diff_tform.c +13 -13
- data/vendor/libgit2/src/diff_xdiff.c +4 -2
- data/vendor/libgit2/src/diff_xdiff.h +1 -1
- data/vendor/libgit2/src/errors.c +26 -19
- data/vendor/libgit2/src/features.h.in +5 -1
- data/vendor/libgit2/src/fetch.c +7 -2
- data/vendor/libgit2/src/fetchhead.c +8 -4
- data/vendor/libgit2/src/filebuf.c +9 -7
- data/vendor/libgit2/src/filter.c +209 -113
- data/vendor/libgit2/src/filter.h +24 -5
- data/vendor/libgit2/src/futils.c +8 -8
- data/vendor/libgit2/src/futils.h +4 -4
- 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/idxmap.c +0 -22
- data/vendor/libgit2/src/ignore.c +35 -19
- data/vendor/libgit2/src/index.c +126 -84
- data/vendor/libgit2/src/index.h +1 -1
- data/vendor/libgit2/src/indexer.c +60 -36
- data/vendor/libgit2/src/integer.h +79 -2
- data/vendor/libgit2/src/iterator.c +40 -28
- data/vendor/libgit2/src/iterator.h +1 -1
- data/vendor/libgit2/src/khash.h +2 -11
- data/vendor/libgit2/src/{settings.c → libgit2.c} +125 -49
- 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 +108 -46
- data/vendor/libgit2/src/merge.h +2 -1
- data/vendor/libgit2/src/merge_driver.c +19 -13
- data/vendor/libgit2/src/merge_file.c +15 -9
- data/vendor/libgit2/src/message.c +3 -1
- data/vendor/libgit2/src/midx.c +879 -0
- data/vendor/libgit2/src/midx.h +110 -0
- data/vendor/libgit2/src/mwindow.c +214 -95
- data/vendor/libgit2/src/mwindow.h +3 -3
- data/vendor/libgit2/src/net.c +133 -4
- 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 +24 -15
- data/vendor/libgit2/src/odb.c +298 -57
- data/vendor/libgit2/src/odb.h +16 -2
- data/vendor/libgit2/src/odb_loose.c +31 -21
- data/vendor/libgit2/src/odb_mempack.c +3 -1
- data/vendor/libgit2/src/odb_pack.c +391 -114
- data/vendor/libgit2/src/oid.c +7 -4
- data/vendor/libgit2/src/pack-objects.c +83 -69
- data/vendor/libgit2/src/pack.c +383 -150
- data/vendor/libgit2/src/pack.h +44 -9
- data/vendor/libgit2/src/patch.c +14 -7
- data/vendor/libgit2/src/patch_generate.c +3 -5
- data/vendor/libgit2/src/patch_parse.c +6 -3
- data/vendor/libgit2/src/path.c +102 -57
- data/vendor/libgit2/src/path.h +79 -6
- data/vendor/libgit2/src/pathspec.c +12 -11
- data/vendor/libgit2/src/pool.c +34 -22
- data/vendor/libgit2/src/pool.h +9 -1
- data/vendor/libgit2/src/posix.c +43 -12
- data/vendor/libgit2/src/posix.h +9 -0
- data/vendor/libgit2/src/proxy.c +2 -0
- data/vendor/libgit2/src/push.c +2 -0
- data/vendor/libgit2/src/reader.c +10 -6
- data/vendor/libgit2/src/rebase.c +95 -49
- data/vendor/libgit2/src/refdb.c +165 -13
- data/vendor/libgit2/src/refdb.h +69 -0
- data/vendor/libgit2/src/refdb_fs.c +144 -152
- data/vendor/libgit2/src/reflog.c +21 -20
- data/vendor/libgit2/src/refs.c +151 -231
- data/vendor/libgit2/src/refs.h +2 -20
- data/vendor/libgit2/src/refspec.c +80 -44
- data/vendor/libgit2/src/regexp.c +2 -2
- data/vendor/libgit2/src/remote.c +312 -121
- data/vendor/libgit2/src/remote.h +2 -1
- data/vendor/libgit2/src/repository.c +351 -189
- data/vendor/libgit2/src/repository.h +23 -29
- data/vendor/libgit2/src/reset.c +7 -6
- data/vendor/libgit2/src/revert.c +8 -2
- data/vendor/libgit2/src/revparse.c +19 -13
- data/vendor/libgit2/src/revwalk.c +35 -20
- data/vendor/libgit2/src/runtime.c +162 -0
- data/vendor/libgit2/src/runtime.h +62 -0
- data/vendor/libgit2/src/{refdb_fs.h → settings.h} +3 -11
- data/vendor/libgit2/src/signature.c +6 -5
- data/vendor/libgit2/src/sortedcache.c +2 -3
- data/vendor/libgit2/src/sortedcache.h +10 -8
- data/vendor/libgit2/src/stash.c +7 -3
- data/vendor/libgit2/src/status.c +9 -4
- data/vendor/libgit2/src/strarray.c +64 -0
- 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 +113 -207
- 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 +10 -9
- 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 +134 -66
- data/vendor/libgit2/src/submodule.h +9 -9
- data/vendor/libgit2/src/sysdir.c +8 -26
- data/vendor/libgit2/src/sysdir.h +0 -11
- data/vendor/libgit2/src/tag.c +49 -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 +21 -9
- 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 +17 -7
- data/vendor/libgit2/src/transports/credential_helpers.c +2 -0
- 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 +84 -42
- data/vendor/libgit2/src/transports/httpclient.h +1 -1
- data/vendor/libgit2/src/transports/local.c +5 -5
- data/vendor/libgit2/src/transports/smart.c +14 -9
- 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 +156 -88
- 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/posix.h +16 -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 +74 -183
- 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/git2.rc +18 -3
- 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 +23 -25
- data/vendor/libgit2/src/win32/path_w32.h +0 -1
- data/vendor/libgit2/src/win32/posix_w32.c +77 -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 +37 -15
- data/vendor/libgit2/src/zstream.c +1 -1
- metadata +56 -38
- data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.c.in +0 -29
- data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.cmake +0 -96
- 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 -361
- 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 -246
- 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
|
}
|
|
@@ -253,10 +254,12 @@ int git_oid_is_zero(const git_oid *oid_a)
|
|
|
253
254
|
return 1;
|
|
254
255
|
}
|
|
255
256
|
|
|
257
|
+
#ifndef GIT_DEPRECATE_HARD
|
|
256
258
|
int git_oid_iszero(const git_oid *oid_a)
|
|
257
259
|
{
|
|
258
260
|
return git_oid_is_zero(oid_a);
|
|
259
261
|
}
|
|
262
|
+
#endif
|
|
260
263
|
|
|
261
264
|
typedef short node_index;
|
|
262
265
|
|
|
@@ -314,7 +317,7 @@ git_oid_shorten *git_oid_shorten_new(size_t min_length)
|
|
|
314
317
|
{
|
|
315
318
|
git_oid_shorten *os;
|
|
316
319
|
|
|
317
|
-
|
|
320
|
+
GIT_ASSERT_ARG_WITH_RETVAL((size_t)((int)min_length) == min_length, NULL);
|
|
318
321
|
|
|
319
322
|
os = git__calloc(1, sizeof(git_oid_shorten));
|
|
320
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)
|
|
@@ -141,14 +133,11 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo)
|
|
|
141
133
|
pb = git__calloc(1, sizeof(*pb));
|
|
142
134
|
GIT_ERROR_CHECK_ALLOC(pb);
|
|
143
135
|
|
|
144
|
-
if (git_oidmap_new(&pb->object_ix) < 0
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (git_oidmap_new(&pb->walk_objects) < 0)
|
|
136
|
+
if (git_oidmap_new(&pb->object_ix) < 0 ||
|
|
137
|
+
git_oidmap_new(&pb->walk_objects) < 0 ||
|
|
138
|
+
git_pool_init(&pb->object_pool, sizeof(struct walk_object)) < 0)
|
|
148
139
|
goto on_error;
|
|
149
140
|
|
|
150
|
-
git_pool_init(&pb->object_pool, sizeof(struct walk_object));
|
|
151
|
-
|
|
152
141
|
pb->repo = repo;
|
|
153
142
|
pb->nr_threads = 1; /* do not spawn any thread by default */
|
|
154
143
|
|
|
@@ -180,13 +169,13 @@ on_error:
|
|
|
180
169
|
|
|
181
170
|
unsigned int git_packbuilder_set_threads(git_packbuilder *pb, unsigned int n)
|
|
182
171
|
{
|
|
183
|
-
|
|
172
|
+
GIT_ASSERT_ARG(pb);
|
|
184
173
|
|
|
185
174
|
#ifdef GIT_THREADS
|
|
186
175
|
pb->nr_threads = n;
|
|
187
176
|
#else
|
|
188
177
|
GIT_UNUSED(n);
|
|
189
|
-
|
|
178
|
+
GIT_ASSERT(pb->nr_threads == 1);
|
|
190
179
|
#endif
|
|
191
180
|
|
|
192
181
|
return pb->nr_threads;
|
|
@@ -214,7 +203,8 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
|
|
|
214
203
|
size_t newsize;
|
|
215
204
|
int ret;
|
|
216
205
|
|
|
217
|
-
|
|
206
|
+
GIT_ASSERT_ARG(pb);
|
|
207
|
+
GIT_ASSERT_ARG(oid);
|
|
218
208
|
|
|
219
209
|
/* If the object already exists in the hash table, then we don't
|
|
220
210
|
* have any work to do */
|
|
@@ -261,7 +251,7 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
|
|
|
261
251
|
double current_time = git__timer();
|
|
262
252
|
double elapsed = current_time - pb->last_progress_report_time;
|
|
263
253
|
|
|
264
|
-
if (elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
|
|
254
|
+
if (elapsed < 0 || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
|
|
265
255
|
pb->last_progress_report_time = current_time;
|
|
266
256
|
|
|
267
257
|
ret = pb->progress_cb(
|
|
@@ -350,10 +340,9 @@ static int write_object(
|
|
|
350
340
|
}
|
|
351
341
|
|
|
352
342
|
/* Write header */
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
(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)
|
|
357
346
|
goto done;
|
|
358
347
|
|
|
359
348
|
if (type == GIT_OBJECT_REF_DELTA) {
|
|
@@ -528,13 +517,18 @@ static int cb_tag_foreach(const char *name, git_oid *oid, void *data)
|
|
|
528
517
|
return 0;
|
|
529
518
|
}
|
|
530
519
|
|
|
531
|
-
static
|
|
520
|
+
static int compute_write_order(git_pobject ***out, git_packbuilder *pb)
|
|
532
521
|
{
|
|
533
522
|
size_t i, wo_end, last_untagged;
|
|
534
523
|
git_pobject **wo;
|
|
535
524
|
|
|
525
|
+
*out = NULL;
|
|
526
|
+
|
|
527
|
+
if (!pb->nr_objects)
|
|
528
|
+
return 0;
|
|
529
|
+
|
|
536
530
|
if ((wo = git__mallocarray(pb->nr_objects, sizeof(*wo))) == NULL)
|
|
537
|
-
return
|
|
531
|
+
return -1;
|
|
538
532
|
|
|
539
533
|
for (i = 0; i < pb->nr_objects; i++) {
|
|
540
534
|
git_pobject *po = pb->object_list + i;
|
|
@@ -563,7 +557,7 @@ static git_pobject **compute_write_order(git_packbuilder *pb)
|
|
|
563
557
|
*/
|
|
564
558
|
if (git_tag_foreach(pb->repo, &cb_tag_foreach, pb) < 0) {
|
|
565
559
|
git__free(wo);
|
|
566
|
-
return
|
|
560
|
+
return -1;
|
|
567
561
|
}
|
|
568
562
|
|
|
569
563
|
/*
|
|
@@ -620,10 +614,11 @@ static git_pobject **compute_write_order(git_packbuilder *pb)
|
|
|
620
614
|
if (wo_end != pb->nr_objects) {
|
|
621
615
|
git__free(wo);
|
|
622
616
|
git_error_set(GIT_ERROR_INVALID, "invalid write order");
|
|
623
|
-
return
|
|
617
|
+
return -1;
|
|
624
618
|
}
|
|
625
619
|
|
|
626
|
-
|
|
620
|
+
*out = wo;
|
|
621
|
+
return 0;
|
|
627
622
|
}
|
|
628
623
|
|
|
629
624
|
static int write_pack(git_packbuilder *pb,
|
|
@@ -636,15 +631,15 @@ static int write_pack(git_packbuilder *pb,
|
|
|
636
631
|
struct git_pack_header ph;
|
|
637
632
|
git_oid entry_oid;
|
|
638
633
|
size_t i = 0;
|
|
639
|
-
int error
|
|
634
|
+
int error;
|
|
640
635
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
return -1;
|
|
636
|
+
if ((error = compute_write_order(&write_order, pb)) < 0)
|
|
637
|
+
return error;
|
|
644
638
|
|
|
645
639
|
if (!git__is_uint32(pb->nr_objects)) {
|
|
646
640
|
git_error_set(GIT_ERROR_INVALID, "too many objects");
|
|
647
|
-
|
|
641
|
+
error = -1;
|
|
642
|
+
goto done;
|
|
648
643
|
}
|
|
649
644
|
|
|
650
645
|
/* Write pack header */
|
|
@@ -855,10 +850,11 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
|
855
850
|
}
|
|
856
851
|
}
|
|
857
852
|
|
|
858
|
-
git_packbuilder__cache_lock(pb);
|
|
853
|
+
GIT_ASSERT(git_packbuilder__cache_lock(pb) == 0);
|
|
854
|
+
|
|
859
855
|
if (trg_object->delta_data) {
|
|
860
856
|
git__free(trg_object->delta_data);
|
|
861
|
-
|
|
857
|
+
GIT_ASSERT(pb->delta_cache_size >= trg_object->delta_size);
|
|
862
858
|
pb->delta_cache_size -= trg_object->delta_size;
|
|
863
859
|
trg_object->delta_data = NULL;
|
|
864
860
|
}
|
|
@@ -866,7 +862,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
|
866
862
|
bool overflow = git__add_sizet_overflow(
|
|
867
863
|
&pb->delta_cache_size, pb->delta_cache_size, delta_size);
|
|
868
864
|
|
|
869
|
-
git_packbuilder__cache_unlock(pb);
|
|
865
|
+
GIT_ASSERT(git_packbuilder__cache_unlock(pb) == 0);
|
|
870
866
|
|
|
871
867
|
if (overflow) {
|
|
872
868
|
git__free(delta_buf);
|
|
@@ -877,7 +873,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
|
877
873
|
GIT_ERROR_CHECK_ALLOC(trg_object->delta_data);
|
|
878
874
|
} else {
|
|
879
875
|
/* create delta when writing the pack */
|
|
880
|
-
git_packbuilder__cache_unlock(pb);
|
|
876
|
+
GIT_ASSERT(git_packbuilder__cache_unlock(pb) == 0);
|
|
881
877
|
git__free(delta_buf);
|
|
882
878
|
}
|
|
883
879
|
|
|
@@ -932,7 +928,7 @@ static int report_delta_progress(
|
|
|
932
928
|
double current_time = git__timer();
|
|
933
929
|
double elapsed = current_time - pb->last_progress_report_time;
|
|
934
930
|
|
|
935
|
-
if (force || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
|
|
931
|
+
if (force || elapsed < 0 || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
|
|
936
932
|
pb->last_progress_report_time = current_time;
|
|
937
933
|
|
|
938
934
|
ret = pb->progress_cb(
|
|
@@ -965,9 +961,9 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
|
965
961
|
struct unpacked *n = array + idx;
|
|
966
962
|
size_t max_depth, j, best_base = SIZE_MAX;
|
|
967
963
|
|
|
968
|
-
git_packbuilder__progress_lock(pb);
|
|
964
|
+
GIT_ASSERT(git_packbuilder__progress_lock(pb) == 0);
|
|
969
965
|
if (!*list_size) {
|
|
970
|
-
git_packbuilder__progress_unlock(pb);
|
|
966
|
+
GIT_ASSERT(git_packbuilder__progress_unlock(pb) == 0);
|
|
971
967
|
break;
|
|
972
968
|
}
|
|
973
969
|
|
|
@@ -976,7 +972,7 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
|
976
972
|
|
|
977
973
|
po = *list++;
|
|
978
974
|
(*list_size)--;
|
|
979
|
-
git_packbuilder__progress_unlock(pb);
|
|
975
|
+
GIT_ASSERT(git_packbuilder__progress_unlock(pb) == 0);
|
|
980
976
|
|
|
981
977
|
mem_usage -= free_unpacked(n);
|
|
982
978
|
n->object = po;
|
|
@@ -1051,10 +1047,10 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
|
1051
1047
|
po->z_delta_size = zbuf.size;
|
|
1052
1048
|
git_buf_clear(&zbuf);
|
|
1053
1049
|
|
|
1054
|
-
git_packbuilder__cache_lock(pb);
|
|
1050
|
+
GIT_ASSERT(git_packbuilder__cache_lock(pb) == 0);
|
|
1055
1051
|
pb->delta_cache_size -= po->delta_size;
|
|
1056
1052
|
pb->delta_cache_size += po->z_delta_size;
|
|
1057
|
-
git_packbuilder__cache_unlock(pb);
|
|
1053
|
+
GIT_ASSERT(git_packbuilder__cache_unlock(pb) == 0);
|
|
1058
1054
|
}
|
|
1059
1055
|
|
|
1060
1056
|
/*
|
|
@@ -1132,10 +1128,10 @@ static void *threaded_find_deltas(void *arg)
|
|
|
1132
1128
|
; /* TODO */
|
|
1133
1129
|
}
|
|
1134
1130
|
|
|
1135
|
-
git_packbuilder__progress_lock(me->pb);
|
|
1131
|
+
GIT_ASSERT_WITH_RETVAL(git_packbuilder__progress_lock(me->pb) == 0, NULL);
|
|
1136
1132
|
me->working = 0;
|
|
1137
1133
|
git_cond_signal(&me->pb->progress_cond);
|
|
1138
|
-
git_packbuilder__progress_unlock(me->pb);
|
|
1134
|
+
GIT_ASSERT_WITH_RETVAL(git_packbuilder__progress_unlock(me->pb) == 0, NULL);
|
|
1139
1135
|
|
|
1140
1136
|
if (git_mutex_lock(&me->mutex)) {
|
|
1141
1137
|
git_error_set(GIT_ERROR_THREAD, "unable to lock packfile condition mutex");
|
|
@@ -1168,7 +1164,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
|
1168
1164
|
int ret, active_threads = 0;
|
|
1169
1165
|
|
|
1170
1166
|
if (!pb->nr_threads)
|
|
1171
|
-
pb->nr_threads =
|
|
1167
|
+
pb->nr_threads = git__online_cpus();
|
|
1172
1168
|
|
|
1173
1169
|
if (pb->nr_threads <= 1) {
|
|
1174
1170
|
find_deltas(pb, list, &list_size, window, depth);
|
|
@@ -1240,7 +1236,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
|
1240
1236
|
* 'working' flag from 1 -> 0. This indicates that it is
|
|
1241
1237
|
* ready to receive more work using our work-stealing
|
|
1242
1238
|
* algorithm. */
|
|
1243
|
-
git_packbuilder__progress_lock(pb);
|
|
1239
|
+
GIT_ASSERT(git_packbuilder__progress_lock(pb) == 0);
|
|
1244
1240
|
for (;;) {
|
|
1245
1241
|
for (i = 0; !target && i < pb->nr_threads; i++)
|
|
1246
1242
|
if (!p[i].working)
|
|
@@ -1283,7 +1279,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
|
1283
1279
|
target->list_size = sub_size;
|
|
1284
1280
|
target->remaining = sub_size;
|
|
1285
1281
|
target->working = 1;
|
|
1286
|
-
git_packbuilder__progress_unlock(pb);
|
|
1282
|
+
GIT_ASSERT(git_packbuilder__progress_unlock(pb) == 0);
|
|
1287
1283
|
|
|
1288
1284
|
if (git_mutex_lock(&target->mutex)) {
|
|
1289
1285
|
git_error_set(GIT_ERROR_THREAD, "unable to lock packfile condition mutex");
|
|
@@ -1366,8 +1362,13 @@ int git_packbuilder_foreach(git_packbuilder *pb, int (*cb)(void *buf, size_t siz
|
|
|
1366
1362
|
|
|
1367
1363
|
int git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb)
|
|
1368
1364
|
{
|
|
1365
|
+
int error;
|
|
1366
|
+
|
|
1367
|
+
if ((error = git_buf_sanitize(buf)) < 0)
|
|
1368
|
+
return error;
|
|
1369
|
+
|
|
1369
1370
|
PREPARE_PACK;
|
|
1370
|
-
|
|
1371
|
+
|
|
1371
1372
|
return write_pack(pb, &write_pack_buf, buf);
|
|
1372
1373
|
}
|
|
1373
1374
|
|
|
@@ -1384,20 +1385,29 @@ int git_packbuilder_write(
|
|
|
1384
1385
|
git_indexer_progress_cb progress_cb,
|
|
1385
1386
|
void *progress_cb_payload)
|
|
1386
1387
|
{
|
|
1388
|
+
int error = -1;
|
|
1389
|
+
git_buf object_path = GIT_BUF_INIT;
|
|
1387
1390
|
git_indexer_options opts = GIT_INDEXER_OPTIONS_INIT;
|
|
1388
|
-
git_indexer *indexer;
|
|
1391
|
+
git_indexer *indexer = NULL;
|
|
1389
1392
|
git_indexer_progress stats;
|
|
1390
1393
|
struct pack_write_context ctx;
|
|
1391
1394
|
int t;
|
|
1392
1395
|
|
|
1393
1396
|
PREPARE_PACK;
|
|
1394
1397
|
|
|
1398
|
+
if (path == NULL) {
|
|
1399
|
+
if ((error = git_repository_item_path(&object_path, pb->repo, GIT_REPOSITORY_ITEM_OBJECTS)) < 0)
|
|
1400
|
+
goto cleanup;
|
|
1401
|
+
if ((error = git_buf_joinpath(&object_path, git_buf_cstr(&object_path), "pack")) < 0)
|
|
1402
|
+
goto cleanup;
|
|
1403
|
+
path = git_buf_cstr(&object_path);
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1395
1406
|
opts.progress_cb = progress_cb;
|
|
1396
1407
|
opts.progress_cb_payload = progress_cb_payload;
|
|
1397
1408
|
|
|
1398
|
-
if (git_indexer_new(
|
|
1399
|
-
|
|
1400
|
-
return -1;
|
|
1409
|
+
if ((error = git_indexer_new(&indexer, path, mode, pb->odb, &opts)) < 0)
|
|
1410
|
+
goto cleanup;
|
|
1401
1411
|
|
|
1402
1412
|
if (!git_repository__configmap_lookup(&t, pb->repo, GIT_CONFIGMAP_FSYNCOBJECTFILES) && t)
|
|
1403
1413
|
git_indexer__set_fsync(indexer, 1);
|
|
@@ -1405,16 +1415,18 @@ int git_packbuilder_write(
|
|
|
1405
1415
|
ctx.indexer = indexer;
|
|
1406
1416
|
ctx.stats = &stats;
|
|
1407
1417
|
|
|
1408
|
-
if (git_packbuilder_foreach(pb, write_cb, &ctx) < 0
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1418
|
+
if ((error = git_packbuilder_foreach(pb, write_cb, &ctx)) < 0)
|
|
1419
|
+
goto cleanup;
|
|
1420
|
+
|
|
1421
|
+
if ((error = git_indexer_commit(indexer, &stats)) < 0)
|
|
1422
|
+
goto cleanup;
|
|
1413
1423
|
|
|
1414
1424
|
git_oid_cpy(&pb->pack_oid, git_indexer_hash(indexer));
|
|
1415
1425
|
|
|
1426
|
+
cleanup:
|
|
1416
1427
|
git_indexer_free(indexer);
|
|
1417
|
-
|
|
1428
|
+
git_buf_dispose(&object_path);
|
|
1429
|
+
return error;
|
|
1418
1430
|
}
|
|
1419
1431
|
|
|
1420
1432
|
#undef PREPARE_PACK
|
|
@@ -1478,7 +1490,8 @@ int git_packbuilder_insert_recur(git_packbuilder *pb, const git_oid *id, const c
|
|
|
1478
1490
|
git_object *obj;
|
|
1479
1491
|
int error;
|
|
1480
1492
|
|
|
1481
|
-
|
|
1493
|
+
GIT_ASSERT_ARG(pb);
|
|
1494
|
+
GIT_ASSERT_ARG(id);
|
|
1482
1495
|
|
|
1483
1496
|
if ((error = git_object_lookup(&obj, pb->repo, id, GIT_OBJECT_ANY)) < 0)
|
|
1484
1497
|
return error;
|
|
@@ -1634,7 +1647,7 @@ static int mark_edges_uninteresting(git_packbuilder *pb, git_commit_list *commit
|
|
|
1634
1647
|
return 0;
|
|
1635
1648
|
}
|
|
1636
1649
|
|
|
1637
|
-
int
|
|
1650
|
+
static int pack_objects_insert_tree(git_packbuilder *pb, git_tree *tree)
|
|
1638
1651
|
{
|
|
1639
1652
|
size_t i;
|
|
1640
1653
|
int error;
|
|
@@ -1661,7 +1674,7 @@ int insert_tree(git_packbuilder *pb, git_tree *tree)
|
|
|
1661
1674
|
if ((error = git_tree_lookup(&subtree, pb->repo, entry_id)) < 0)
|
|
1662
1675
|
return error;
|
|
1663
1676
|
|
|
1664
|
-
error =
|
|
1677
|
+
error = pack_objects_insert_tree(pb, subtree);
|
|
1665
1678
|
git_tree_free(subtree);
|
|
1666
1679
|
|
|
1667
1680
|
if (error < 0)
|
|
@@ -1687,7 +1700,7 @@ int insert_tree(git_packbuilder *pb, git_tree *tree)
|
|
|
1687
1700
|
return error;
|
|
1688
1701
|
}
|
|
1689
1702
|
|
|
1690
|
-
int
|
|
1703
|
+
static int pack_objects_insert_commit(git_packbuilder *pb, struct walk_object *obj)
|
|
1691
1704
|
{
|
|
1692
1705
|
int error;
|
|
1693
1706
|
git_commit *commit = NULL;
|
|
@@ -1704,7 +1717,7 @@ int insert_commit(git_packbuilder *pb, struct walk_object *obj)
|
|
|
1704
1717
|
if ((error = git_tree_lookup(&tree, pb->repo, git_commit_tree_id(commit))) < 0)
|
|
1705
1718
|
goto cleanup;
|
|
1706
1719
|
|
|
1707
|
-
if ((error =
|
|
1720
|
+
if ((error = pack_objects_insert_tree(pb, tree)) < 0)
|
|
1708
1721
|
goto cleanup;
|
|
1709
1722
|
|
|
1710
1723
|
cleanup:
|
|
@@ -1719,7 +1732,8 @@ int git_packbuilder_insert_walk(git_packbuilder *pb, git_revwalk *walk)
|
|
|
1719
1732
|
git_oid id;
|
|
1720
1733
|
struct walk_object *obj;
|
|
1721
1734
|
|
|
1722
|
-
|
|
1735
|
+
GIT_ASSERT_ARG(pb);
|
|
1736
|
+
GIT_ASSERT_ARG(walk);
|
|
1723
1737
|
|
|
1724
1738
|
if ((error = mark_edges_uninteresting(pb, walk->user_input)) < 0)
|
|
1725
1739
|
return error;
|
|
@@ -1739,7 +1753,7 @@ int git_packbuilder_insert_walk(git_packbuilder *pb, git_revwalk *walk)
|
|
|
1739
1753
|
if (obj->seen || obj->uninteresting)
|
|
1740
1754
|
continue;
|
|
1741
1755
|
|
|
1742
|
-
if ((error =
|
|
1756
|
+
if ((error = pack_objects_insert_commit(pb, obj)) < 0)
|
|
1743
1757
|
return error;
|
|
1744
1758
|
}
|
|
1745
1759
|
|
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
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");
|
|
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;
|
|
363
372
|
|
|
364
|
-
|
|
373
|
+
pack_data = git_mwindow_open(&p->mwf, w_cursor, offset, 20, left);
|
|
374
|
+
|
|
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
|
|
|
@@ -488,8 +537,12 @@ int git_packfile_resolve_header(
|
|
|
488
537
|
size_t base_size;
|
|
489
538
|
git_packfile_stream stream;
|
|
490
539
|
|
|
491
|
-
|
|
540
|
+
error = get_delta_base(&base_offset, p, &w_curs, &curpos, type, offset);
|
|
492
541
|
git_mwindow_close(&w_curs);
|
|
542
|
+
|
|
543
|
+
if (error < 0)
|
|
544
|
+
return error;
|
|
545
|
+
|
|
493
546
|
if ((error = git_packfile_stream_open(&stream, p, curpos)) < 0)
|
|
494
547
|
return error;
|
|
495
548
|
error = git_delta_read_header_fromstream(&base_size, size_p, &stream);
|
|
@@ -503,13 +556,17 @@ int git_packfile_resolve_header(
|
|
|
503
556
|
|
|
504
557
|
while (type == GIT_OBJECT_OFS_DELTA || type == GIT_OBJECT_REF_DELTA) {
|
|
505
558
|
curpos = base_offset;
|
|
506
|
-
error = git_packfile_unpack_header(&size, &type,
|
|
559
|
+
error = git_packfile_unpack_header(&size, &type, p, &w_curs, &curpos);
|
|
507
560
|
if (error < 0)
|
|
508
561
|
return error;
|
|
509
562
|
if (type != GIT_OBJECT_OFS_DELTA && type != GIT_OBJECT_REF_DELTA)
|
|
510
563
|
break;
|
|
511
|
-
|
|
564
|
+
|
|
565
|
+
error = get_delta_base(&base_offset, p, &w_curs, &curpos, type, base_offset);
|
|
512
566
|
git_mwindow_close(&w_curs);
|
|
567
|
+
|
|
568
|
+
if (error < 0)
|
|
569
|
+
return error;
|
|
513
570
|
}
|
|
514
571
|
*type_p = type;
|
|
515
572
|
|
|
@@ -570,8 +627,7 @@ static int pack_dependency_chain(git_dependency_chain *chain_out,
|
|
|
570
627
|
|
|
571
628
|
elem->base_key = obj_offset;
|
|
572
629
|
|
|
573
|
-
error = git_packfile_unpack_header(&size, &type,
|
|
574
|
-
|
|
630
|
+
error = git_packfile_unpack_header(&size, &type, p, &w_curs, &curpos);
|
|
575
631
|
if (error < 0)
|
|
576
632
|
goto on_error;
|
|
577
633
|
|
|
@@ -583,17 +639,11 @@ static int pack_dependency_chain(git_dependency_chain *chain_out,
|
|
|
583
639
|
if (type != GIT_OBJECT_OFS_DELTA && type != GIT_OBJECT_REF_DELTA)
|
|
584
640
|
break;
|
|
585
641
|
|
|
586
|
-
|
|
642
|
+
error = get_delta_base(&base_offset, p, &w_curs, &curpos, type, obj_offset);
|
|
587
643
|
git_mwindow_close(&w_curs);
|
|
588
644
|
|
|
589
|
-
if (
|
|
590
|
-
error = packfile_error("delta offset is zero");
|
|
591
|
-
goto on_error;
|
|
592
|
-
}
|
|
593
|
-
if (base_offset < 0) { /* must actually be an error code */
|
|
594
|
-
error = (int)base_offset;
|
|
645
|
+
if (error < 0)
|
|
595
646
|
goto on_error;
|
|
596
|
-
}
|
|
597
647
|
|
|
598
648
|
/* we need to pass the pos *after* the delta-base bit */
|
|
599
649
|
elem->offset = curpos;
|
|
@@ -628,6 +678,25 @@ int git_packfile_unpack(
|
|
|
628
678
|
size_t stack_size = 0, elem_pos, alloclen;
|
|
629
679
|
git_object_t base_type;
|
|
630
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
|
+
|
|
631
700
|
/*
|
|
632
701
|
* TODO: optionally check the CRC on the packfile
|
|
633
702
|
*/
|
|
@@ -690,7 +759,7 @@ int git_packfile_unpack(
|
|
|
690
759
|
GIT_ERROR_CHECK_ALLOC(obj->data);
|
|
691
760
|
|
|
692
761
|
memcpy(obj->data, data, obj->len + 1);
|
|
693
|
-
|
|
762
|
+
git_atomic32_dec(&cached->refcount);
|
|
694
763
|
goto cleanup;
|
|
695
764
|
}
|
|
696
765
|
|
|
@@ -738,7 +807,7 @@ int git_packfile_unpack(
|
|
|
738
807
|
}
|
|
739
808
|
|
|
740
809
|
if (cached) {
|
|
741
|
-
|
|
810
|
+
git_atomic32_dec(&cached->refcount);
|
|
742
811
|
cached = NULL;
|
|
743
812
|
}
|
|
744
813
|
|
|
@@ -752,7 +821,7 @@ cleanup:
|
|
|
752
821
|
if (error < 0) {
|
|
753
822
|
git__free(obj->data);
|
|
754
823
|
if (cached)
|
|
755
|
-
|
|
824
|
+
git_atomic32_dec(&cached->refcount);
|
|
756
825
|
}
|
|
757
826
|
|
|
758
827
|
if (elem)
|
|
@@ -839,10 +908,13 @@ static int packfile_unpack_compressed(
|
|
|
839
908
|
|
|
840
909
|
do {
|
|
841
910
|
size_t bytes = buffer_len - total;
|
|
842
|
-
unsigned int window_len;
|
|
911
|
+
unsigned int window_len, consumed;
|
|
843
912
|
unsigned char *in;
|
|
844
913
|
|
|
845
|
-
in = pack_window_open(p, mwindow, *position, &window_len)
|
|
914
|
+
if ((in = pack_window_open(p, mwindow, *position, &window_len)) == NULL) {
|
|
915
|
+
error = -1;
|
|
916
|
+
goto out;
|
|
917
|
+
}
|
|
846
918
|
|
|
847
919
|
if ((error = git_zstream_set_input(&zstream, in, window_len)) < 0 ||
|
|
848
920
|
(error = git_zstream_get_output_chunk(data + total, &bytes, &zstream)) < 0) {
|
|
@@ -852,9 +924,17 @@ static int packfile_unpack_compressed(
|
|
|
852
924
|
|
|
853
925
|
git_mwindow_close(mwindow);
|
|
854
926
|
|
|
855
|
-
|
|
927
|
+
consumed = window_len - (unsigned int)zstream.in_len;
|
|
928
|
+
|
|
929
|
+
if (!bytes && !consumed) {
|
|
930
|
+
git_error_set(GIT_ERROR_ZLIB, "error inflating zlib stream");
|
|
931
|
+
error = -1;
|
|
932
|
+
goto out;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
*position += consumed;
|
|
856
936
|
total += bytes;
|
|
857
|
-
} while (
|
|
937
|
+
} while (!git_zstream_eos(&zstream));
|
|
858
938
|
|
|
859
939
|
if (total != size || !git_zstream_eos(&zstream)) {
|
|
860
940
|
git_error_set(GIT_ERROR_ZLIB, "error inflating zlib stream");
|
|
@@ -878,18 +958,21 @@ out:
|
|
|
878
958
|
* curpos is where the data starts, delta_obj_offset is the where the
|
|
879
959
|
* header starts
|
|
880
960
|
*/
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
961
|
+
int get_delta_base(
|
|
962
|
+
off64_t *delta_base_out,
|
|
963
|
+
struct git_pack_file *p,
|
|
964
|
+
git_mwindow **w_curs,
|
|
965
|
+
off64_t *curpos,
|
|
966
|
+
git_object_t type,
|
|
967
|
+
off64_t delta_obj_offset)
|
|
887
968
|
{
|
|
888
969
|
unsigned int left = 0;
|
|
889
970
|
unsigned char *base_info;
|
|
890
971
|
off64_t base_offset;
|
|
891
972
|
git_oid unused;
|
|
892
973
|
|
|
974
|
+
GIT_ASSERT_ARG(delta_base_out);
|
|
975
|
+
|
|
893
976
|
base_info = pack_window_open(p, w_curs, *curpos, &left);
|
|
894
977
|
/* Assumption: the only reason this would fail is because the file is too small */
|
|
895
978
|
if (base_info == NULL)
|
|
@@ -909,12 +992,12 @@ off64_t get_delta_base(
|
|
|
909
992
|
return GIT_EBUFS;
|
|
910
993
|
unsigned_base_offset += 1;
|
|
911
994
|
if (!unsigned_base_offset || MSB(unsigned_base_offset, 7))
|
|
912
|
-
return
|
|
995
|
+
return packfile_error("overflow");
|
|
913
996
|
c = base_info[used++];
|
|
914
997
|
unsigned_base_offset = (unsigned_base_offset << 7) + (c & 127);
|
|
915
998
|
}
|
|
916
999
|
if (unsigned_base_offset == 0 || (size_t)delta_obj_offset <= unsigned_base_offset)
|
|
917
|
-
return
|
|
1000
|
+
return packfile_error("out of bounds");
|
|
918
1001
|
base_offset = delta_obj_offset - unsigned_base_offset;
|
|
919
1002
|
*curpos += used;
|
|
920
1003
|
} else if (type == GIT_OBJECT_REF_DELTA) {
|
|
@@ -925,8 +1008,12 @@ off64_t get_delta_base(
|
|
|
925
1008
|
|
|
926
1009
|
git_oid_fromraw(&oid, base_info);
|
|
927
1010
|
if ((entry = git_oidmap_get(p->idx_cache, &oid)) != NULL) {
|
|
1011
|
+
if (entry->offset == 0)
|
|
1012
|
+
return packfile_error("delta offset is zero");
|
|
1013
|
+
|
|
928
1014
|
*curpos += 20;
|
|
929
|
-
|
|
1015
|
+
*delta_base_out = entry->offset;
|
|
1016
|
+
return 0;
|
|
930
1017
|
} else {
|
|
931
1018
|
/* If we're building an index, don't try to find the pack
|
|
932
1019
|
* entry; we just haven't seen it yet. We'll make
|
|
@@ -941,9 +1028,13 @@ off64_t get_delta_base(
|
|
|
941
1028
|
return packfile_error("base entry delta is not in the same pack");
|
|
942
1029
|
*curpos += 20;
|
|
943
1030
|
} else
|
|
944
|
-
return
|
|
1031
|
+
return packfile_error("unknown object type");
|
|
945
1032
|
|
|
946
|
-
|
|
1033
|
+
if (base_offset == 0)
|
|
1034
|
+
return packfile_error("delta offset is zero");
|
|
1035
|
+
|
|
1036
|
+
*delta_base_out = base_offset;
|
|
1037
|
+
return 0;
|
|
947
1038
|
}
|
|
948
1039
|
|
|
949
1040
|
/***********************************************************
|
|
@@ -952,63 +1043,63 @@ off64_t get_delta_base(
|
|
|
952
1043
|
*
|
|
953
1044
|
***********************************************************/
|
|
954
1045
|
|
|
955
|
-
void
|
|
1046
|
+
void git_packfile_free(struct git_pack_file *p, bool unlink_packfile)
|
|
956
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
|
+
}
|
|
957
1059
|
if (p->mwf.fd >= 0) {
|
|
958
|
-
|
|
1060
|
+
git_mwindow_free_all(&p->mwf);
|
|
959
1061
|
p_close(p->mwf.fd);
|
|
960
1062
|
p->mwf.fd = -1;
|
|
961
1063
|
}
|
|
1064
|
+
if (locked)
|
|
1065
|
+
git_mutex_unlock(&p->lock);
|
|
962
1066
|
|
|
963
1067
|
if (unlink_packfile)
|
|
964
1068
|
p_unlink(p->pack_name);
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
void git_packfile_free(struct git_pack_file *p)
|
|
968
|
-
{
|
|
969
|
-
if (!p)
|
|
970
|
-
return;
|
|
971
|
-
|
|
972
|
-
cache_free(&p->bases);
|
|
973
|
-
|
|
974
|
-
git_packfile_close(p, false);
|
|
975
1069
|
|
|
976
1070
|
pack_index_free(p);
|
|
977
1071
|
|
|
978
1072
|
git__free(p->bad_object_sha1);
|
|
979
1073
|
|
|
980
|
-
git_mutex_free(&p->lock);
|
|
981
1074
|
git_mutex_free(&p->bases.lock);
|
|
1075
|
+
git_mutex_free(&p->mwf.lock);
|
|
1076
|
+
git_mutex_free(&p->lock);
|
|
982
1077
|
git__free(p);
|
|
983
1078
|
}
|
|
984
1079
|
|
|
985
|
-
|
|
1080
|
+
/* Run with the packfile and mwf locks held */
|
|
1081
|
+
static int packfile_open_locked(struct git_pack_file *p)
|
|
986
1082
|
{
|
|
987
1083
|
struct stat st;
|
|
988
1084
|
struct git_pack_header hdr;
|
|
989
1085
|
git_oid sha1;
|
|
990
1086
|
unsigned char *idx_sha1;
|
|
991
1087
|
|
|
992
|
-
if (
|
|
1088
|
+
if (pack_index_open_locked(p) < 0)
|
|
993
1089
|
return git_odb__error_notfound("failed to open packfile", NULL, 0);
|
|
994
1090
|
|
|
995
|
-
|
|
996
|
-
if (git_mutex_lock(&p->lock) < 0)
|
|
997
|
-
return packfile_error("failed to get lock for open");
|
|
998
|
-
|
|
999
|
-
if (p->mwf.fd >= 0) {
|
|
1000
|
-
git_mutex_unlock(&p->lock);
|
|
1091
|
+
if (p->mwf.fd >= 0)
|
|
1001
1092
|
return 0;
|
|
1002
|
-
}
|
|
1003
1093
|
|
|
1004
1094
|
/* TODO: open with noatime */
|
|
1005
1095
|
p->mwf.fd = git_futils_open_ro(p->pack_name);
|
|
1006
1096
|
if (p->mwf.fd < 0)
|
|
1007
1097
|
goto cleanup;
|
|
1008
1098
|
|
|
1009
|
-
if (p_fstat(p->mwf.fd, &st) < 0
|
|
1010
|
-
|
|
1099
|
+
if (p_fstat(p->mwf.fd, &st) < 0) {
|
|
1100
|
+
git_error_set(GIT_ERROR_OS, "could not stat packfile");
|
|
1011
1101
|
goto cleanup;
|
|
1102
|
+
}
|
|
1012
1103
|
|
|
1013
1104
|
/* If we created the struct before we had the pack we lack size. */
|
|
1014
1105
|
if (!p->mwf.size) {
|
|
@@ -1039,8 +1130,7 @@ static int packfile_open(struct git_pack_file *p)
|
|
|
1039
1130
|
|
|
1040
1131
|
/* Verify the pack matches its index. */
|
|
1041
1132
|
if (p->num_objects != ntohl(hdr.hdr_entries) ||
|
|
1042
|
-
|
|
1043
|
-
p_read(p->mwf.fd, sha1.id, GIT_OID_RAWSZ) < 0)
|
|
1133
|
+
p_pread(p->mwf.fd, sha1.id, GIT_OID_RAWSZ, p->mwf.size - GIT_OID_RAWSZ) < 0)
|
|
1044
1134
|
goto cleanup;
|
|
1045
1135
|
|
|
1046
1136
|
idx_sha1 = ((unsigned char *)p->index_map.data) + p->index_map.len - 40;
|
|
@@ -1048,7 +1138,9 @@ static int packfile_open(struct git_pack_file *p)
|
|
|
1048
1138
|
if (git_oid__cmp(&sha1, (git_oid *)idx_sha1) != 0)
|
|
1049
1139
|
goto cleanup;
|
|
1050
1140
|
|
|
1051
|
-
|
|
1141
|
+
if (git_mwindow_file_register(&p->mwf) < 0)
|
|
1142
|
+
goto cleanup;
|
|
1143
|
+
|
|
1052
1144
|
return 0;
|
|
1053
1145
|
|
|
1054
1146
|
cleanup:
|
|
@@ -1058,8 +1150,6 @@ cleanup:
|
|
|
1058
1150
|
p_close(p->mwf.fd);
|
|
1059
1151
|
p->mwf.fd = -1;
|
|
1060
1152
|
|
|
1061
|
-
git_mutex_unlock(&p->lock);
|
|
1062
|
-
|
|
1063
1153
|
return -1;
|
|
1064
1154
|
}
|
|
1065
1155
|
|
|
@@ -1129,13 +1219,22 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path)
|
|
|
1129
1219
|
p->mtime = (git_time_t)st.st_mtime;
|
|
1130
1220
|
p->index_version = -1;
|
|
1131
1221
|
|
|
1132
|
-
if (git_mutex_init(&p->lock)) {
|
|
1222
|
+
if (git_mutex_init(&p->lock) < 0) {
|
|
1133
1223
|
git_error_set(GIT_ERROR_OS, "failed to initialize packfile mutex");
|
|
1134
1224
|
git__free(p);
|
|
1135
1225
|
return -1;
|
|
1136
1226
|
}
|
|
1137
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
|
+
|
|
1138
1235
|
if (cache_init(&p->bases) < 0) {
|
|
1236
|
+
git_mutex_free(&p->mwf.lock);
|
|
1237
|
+
git_mutex_free(&p->lock);
|
|
1139
1238
|
git__free(p);
|
|
1140
1239
|
return -1;
|
|
1141
1240
|
}
|
|
@@ -1151,28 +1250,29 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path)
|
|
|
1151
1250
|
*
|
|
1152
1251
|
***********************************************************/
|
|
1153
1252
|
|
|
1154
|
-
static off64_t
|
|
1253
|
+
static off64_t nth_packed_object_offset_locked(struct git_pack_file *p, uint32_t n)
|
|
1155
1254
|
{
|
|
1156
|
-
const unsigned char *index
|
|
1157
|
-
|
|
1255
|
+
const unsigned char *index, *end;
|
|
1256
|
+
uint32_t off32;
|
|
1257
|
+
|
|
1258
|
+
index = p->index_map.data;
|
|
1259
|
+
end = index + p->index_map.len;
|
|
1158
1260
|
index += 4 * 256;
|
|
1159
|
-
if (p->index_version == 1)
|
|
1261
|
+
if (p->index_version == 1)
|
|
1160
1262
|
return ntohl(*((uint32_t *)(index + 24 * n)));
|
|
1161
|
-
} else {
|
|
1162
|
-
uint32_t off;
|
|
1163
|
-
index += 8 + p->num_objects * (20 + 4);
|
|
1164
|
-
off = ntohl(*((uint32_t *)(index + 4 * n)));
|
|
1165
|
-
if (!(off & 0x80000000))
|
|
1166
|
-
return off;
|
|
1167
|
-
index += p->num_objects * 4 + (off & 0x7fffffff) * 8;
|
|
1168
|
-
|
|
1169
|
-
/* Make sure we're not being sent out of bounds */
|
|
1170
|
-
if (index >= end - 8)
|
|
1171
|
-
return -1;
|
|
1172
1263
|
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
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)));
|
|
1176
1276
|
}
|
|
1177
1277
|
|
|
1178
1278
|
static int git__memcmp4(const void *a, const void *b) {
|
|
@@ -1184,33 +1284,45 @@ int git_pack_foreach_entry(
|
|
|
1184
1284
|
git_odb_foreach_cb cb,
|
|
1185
1285
|
void *data)
|
|
1186
1286
|
{
|
|
1187
|
-
const unsigned char *index
|
|
1287
|
+
const unsigned char *index, *current;
|
|
1188
1288
|
uint32_t i;
|
|
1189
1289
|
int error = 0;
|
|
1290
|
+
git_array_oid_t oids = GIT_ARRAY_INIT;
|
|
1291
|
+
git_oid *oid;
|
|
1190
1292
|
|
|
1191
|
-
if (
|
|
1192
|
-
|
|
1193
|
-
return error;
|
|
1293
|
+
if (git_mutex_lock(&p->lock) < 0)
|
|
1294
|
+
return packfile_error("failed to get lock for git_pack_foreach_entry");
|
|
1194
1295
|
|
|
1195
|
-
|
|
1296
|
+
if ((error = pack_index_open_locked(p)) < 0) {
|
|
1297
|
+
git_mutex_unlock(&p->lock);
|
|
1298
|
+
return error;
|
|
1299
|
+
}
|
|
1196
1300
|
|
|
1197
|
-
|
|
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;
|
|
1198
1305
|
}
|
|
1199
1306
|
|
|
1200
|
-
|
|
1307
|
+
index = p->index_map.data;
|
|
1308
|
+
|
|
1309
|
+
if (p->index_version > 1)
|
|
1201
1310
|
index += 8;
|
|
1202
|
-
}
|
|
1203
1311
|
|
|
1204
1312
|
index += 4 * 256;
|
|
1205
1313
|
|
|
1206
1314
|
if (p->oids == NULL) {
|
|
1207
1315
|
git_vector offsets, oids;
|
|
1208
1316
|
|
|
1209
|
-
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);
|
|
1210
1319
|
return error;
|
|
1320
|
+
}
|
|
1211
1321
|
|
|
1212
|
-
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);
|
|
1213
1324
|
return error;
|
|
1325
|
+
}
|
|
1214
1326
|
|
|
1215
1327
|
if (p->index_version > 1) {
|
|
1216
1328
|
const unsigned char *off = index + 24 * p->num_objects;
|
|
@@ -1231,21 +1343,115 @@ int git_pack_foreach_entry(
|
|
|
1231
1343
|
p->oids = (git_oid **)git_vector_detach(NULL, NULL, &oids);
|
|
1232
1344
|
}
|
|
1233
1345
|
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
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
|
+
}
|
|
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
|
+
}
|
|
1237
1441
|
|
|
1442
|
+
cleanup:
|
|
1443
|
+
git_mutex_unlock(&p->lock);
|
|
1238
1444
|
return error;
|
|
1239
1445
|
}
|
|
1240
1446
|
|
|
1241
|
-
|
|
1242
|
-
|
|
1447
|
+
int git_pack__lookup_sha1(const void *oid_lookup_table, size_t stride, unsigned lo,
|
|
1448
|
+
unsigned hi, const unsigned char *oid_prefix)
|
|
1243
1449
|
{
|
|
1244
|
-
const unsigned char *base =
|
|
1450
|
+
const unsigned char *base = oid_lookup_table;
|
|
1245
1451
|
|
|
1246
1452
|
while (lo < hi) {
|
|
1247
1453
|
unsigned mi = (lo + hi) / 2;
|
|
1248
|
-
int cmp = git_oid__hashcmp(base + mi * stride,
|
|
1454
|
+
int cmp = git_oid__hashcmp(base + mi * stride, oid_prefix);
|
|
1249
1455
|
|
|
1250
1456
|
if (!cmp)
|
|
1251
1457
|
return mi;
|
|
@@ -1272,15 +1478,19 @@ static int pack_entry_find_offset(
|
|
|
1272
1478
|
int pos, found = 0;
|
|
1273
1479
|
off64_t offset;
|
|
1274
1480
|
const unsigned char *current = 0;
|
|
1481
|
+
int error = 0;
|
|
1275
1482
|
|
|
1276
1483
|
*offset_out = 0;
|
|
1277
1484
|
|
|
1278
|
-
if (p->
|
|
1279
|
-
|
|
1485
|
+
if (git_mutex_lock(&p->lock) < 0)
|
|
1486
|
+
return packfile_error("failed to get lock for pack_entry_find_offset");
|
|
1280
1487
|
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
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;
|
|
1284
1494
|
}
|
|
1285
1495
|
|
|
1286
1496
|
index = p->index_map.data;
|
|
@@ -1307,7 +1517,7 @@ static int pack_entry_find_offset(
|
|
|
1307
1517
|
short_oid->id[0], short_oid->id[1], short_oid->id[2], lo, hi, p->num_objects);
|
|
1308
1518
|
#endif
|
|
1309
1519
|
|
|
1310
|
-
pos =
|
|
1520
|
+
pos = git_pack__lookup_sha1(index, stride, lo, hi, short_oid->id);
|
|
1311
1521
|
|
|
1312
1522
|
if (pos >= 0) {
|
|
1313
1523
|
/* An object matching exactly the oid was found */
|
|
@@ -1334,14 +1544,19 @@ static int pack_entry_find_offset(
|
|
|
1334
1544
|
}
|
|
1335
1545
|
}
|
|
1336
1546
|
|
|
1337
|
-
if (!found)
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
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
|
+
}
|
|
1341
1555
|
|
|
1342
|
-
if ((offset =
|
|
1556
|
+
if ((offset = nth_packed_object_offset_locked(p, pos)) < 0) {
|
|
1343
1557
|
git_error_set(GIT_ERROR_ODB, "packfile index is corrupt");
|
|
1344
|
-
|
|
1558
|
+
error = -1;
|
|
1559
|
+
goto cleanup;
|
|
1345
1560
|
}
|
|
1346
1561
|
|
|
1347
1562
|
*offset_out = offset;
|
|
@@ -1356,7 +1571,9 @@ static int pack_entry_find_offset(
|
|
|
1356
1571
|
}
|
|
1357
1572
|
#endif
|
|
1358
1573
|
|
|
1359
|
-
|
|
1574
|
+
cleanup:
|
|
1575
|
+
git_mutex_unlock(&p->lock);
|
|
1576
|
+
return error;
|
|
1360
1577
|
}
|
|
1361
1578
|
|
|
1362
1579
|
int git_pack_entry_find(
|
|
@@ -1369,7 +1586,7 @@ int git_pack_entry_find(
|
|
|
1369
1586
|
git_oid found_oid;
|
|
1370
1587
|
int error;
|
|
1371
1588
|
|
|
1372
|
-
|
|
1589
|
+
GIT_ASSERT_ARG(p);
|
|
1373
1590
|
|
|
1374
1591
|
if (len == GIT_OID_HEXSZ && p->num_bad_objects) {
|
|
1375
1592
|
unsigned i;
|
|
@@ -1382,10 +1599,26 @@ int git_pack_entry_find(
|
|
|
1382
1599
|
if (error < 0)
|
|
1383
1600
|
return error;
|
|
1384
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
|
+
|
|
1385
1614
|
/* we found a unique entry in the index;
|
|
1386
1615
|
* make sure the packfile backing the index
|
|
1387
1616
|
* still exists on disk */
|
|
1388
|
-
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)
|
|
1389
1622
|
return error;
|
|
1390
1623
|
|
|
1391
1624
|
e->offset = offset;
|