rugged 1.0.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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;
|