rugged 1.1.1 → 1.4.3
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 +1 -1
- data/ext/rugged/extconf.rb +2 -2
- data/ext/rugged/rugged.c +7 -4
- data/ext/rugged/rugged_config.c +7 -2
- data/ext/rugged/rugged_object.c +1 -1
- data/ext/rugged/rugged_remote.c +17 -0
- data/ext/rugged/rugged_repo.c +3 -3
- data/lib/rugged/repository.rb +2 -2
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +103 -271
- data/vendor/libgit2/COPYING +149 -24
- data/vendor/libgit2/cmake/AddCFlagIfSupported.cmake +21 -21
- data/vendor/libgit2/cmake/DefaultCFlags.cmake +154 -0
- data/vendor/libgit2/cmake/EnableWarnings.cmake +13 -13
- data/vendor/libgit2/cmake/FindCoreFoundation.cmake +13 -13
- data/vendor/libgit2/cmake/FindGSSAPI.cmake +171 -287
- data/vendor/libgit2/cmake/FindGSSFramework.cmake +13 -13
- data/vendor/libgit2/cmake/{FindHTTP_Parser.cmake → FindHTTPParser.cmake} +17 -17
- data/vendor/libgit2/cmake/FindIconv.cmake +27 -27
- data/vendor/libgit2/cmake/FindLibSSH2.cmake +13 -0
- data/vendor/libgit2/cmake/FindPCRE.cmake +13 -13
- data/vendor/libgit2/cmake/FindPCRE2.cmake +12 -12
- data/vendor/libgit2/cmake/FindPkgLibraries.cmake +19 -19
- data/vendor/libgit2/cmake/FindSecurity.cmake +14 -14
- data/vendor/libgit2/cmake/FindStatNsec.cmake +12 -18
- data/vendor/libgit2/cmake/Findfutimens.cmake +14 -0
- data/vendor/libgit2/cmake/FindmbedTLS.cmake +63 -70
- data/vendor/libgit2/cmake/IdeSplitSources.cmake +18 -18
- data/vendor/libgit2/cmake/PkgBuildConfig.cmake +60 -60
- data/vendor/libgit2/cmake/SanitizeBool.cmake +20 -20
- data/vendor/libgit2/cmake/SelectGSSAPI.cmake +37 -37
- data/vendor/libgit2/cmake/SelectHTTPParser.cmake +19 -0
- data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +100 -96
- data/vendor/libgit2/cmake/SelectHashes.cmake +39 -48
- data/vendor/libgit2/cmake/SelectRegex.cmake +51 -0
- data/vendor/libgit2/cmake/SelectSSH.cmake +41 -0
- data/vendor/libgit2/cmake/SelectWinHTTP.cmake +17 -0
- data/vendor/libgit2/cmake/SelectZlib.cmake +34 -0
- data/vendor/libgit2/deps/chromium-zlib/CMakeLists.txt +101 -0
- data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +32 -20
- 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 +154 -122
- data/vendor/libgit2/deps/ntlmclient/ntlm.h +17 -13
- data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +17 -4
- 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/pcre/CMakeLists.txt +88 -88
- data/vendor/libgit2/deps/winhttp/CMakeLists.txt +14 -16
- data/vendor/libgit2/include/git2/apply.h +16 -2
- data/vendor/libgit2/include/git2/attr.h +106 -2
- data/vendor/libgit2/include/git2/blame.h +97 -43
- data/vendor/libgit2/include/git2/blob.h +33 -2
- data/vendor/libgit2/include/git2/branch.h +27 -0
- data/vendor/libgit2/include/git2/buffer.h +18 -78
- data/vendor/libgit2/include/git2/cert.h +43 -6
- data/vendor/libgit2/include/git2/checkout.h +32 -13
- data/vendor/libgit2/include/git2/clone.h +4 -4
- data/vendor/libgit2/include/git2/commit.h +37 -19
- data/vendor/libgit2/include/git2/common.h +46 -5
- data/vendor/libgit2/include/git2/config.h +19 -3
- data/vendor/libgit2/include/git2/credential.h +2 -1
- data/vendor/libgit2/include/git2/credential_helpers.h +1 -0
- data/vendor/libgit2/include/git2/deprecated.h +326 -6
- data/vendor/libgit2/include/git2/describe.h +7 -2
- data/vendor/libgit2/include/git2/diff.h +50 -121
- data/vendor/libgit2/include/git2/email.h +127 -0
- data/vendor/libgit2/include/git2/errors.h +7 -6
- data/vendor/libgit2/include/git2/filter.h +69 -18
- data/vendor/libgit2/include/git2/graph.h +21 -2
- data/vendor/libgit2/include/git2/ignore.h +1 -1
- data/vendor/libgit2/include/git2/index.h +13 -7
- data/vendor/libgit2/include/git2/indexer.h +19 -0
- data/vendor/libgit2/include/git2/merge.h +23 -3
- data/vendor/libgit2/include/git2/message.h +2 -0
- data/vendor/libgit2/include/git2/notes.h +2 -2
- data/vendor/libgit2/include/git2/object.h +23 -0
- data/vendor/libgit2/include/git2/odb.h +65 -6
- data/vendor/libgit2/include/git2/odb_backend.h +1 -1
- data/vendor/libgit2/include/git2/oidarray.h +5 -8
- data/vendor/libgit2/include/git2/pack.h +24 -8
- data/vendor/libgit2/include/git2/patch.h +16 -0
- data/vendor/libgit2/include/git2/pathspec.h +1 -1
- data/vendor/libgit2/include/git2/proxy.h +1 -1
- data/vendor/libgit2/include/git2/rebase.h +34 -2
- data/vendor/libgit2/include/git2/refdb.h +3 -0
- data/vendor/libgit2/include/git2/reflog.h +1 -1
- data/vendor/libgit2/include/git2/refs.h +8 -4
- data/vendor/libgit2/include/git2/remote.h +246 -46
- data/vendor/libgit2/include/git2/repository.h +25 -18
- data/vendor/libgit2/include/git2/reset.h +2 -2
- data/vendor/libgit2/include/git2/revparse.h +5 -5
- data/vendor/libgit2/include/git2/revwalk.h +4 -1
- data/vendor/libgit2/include/git2/signature.h +1 -1
- data/vendor/libgit2/include/git2/stash.h +4 -4
- data/vendor/libgit2/include/git2/status.h +124 -62
- data/vendor/libgit2/include/git2/stdint.h +3 -3
- data/vendor/libgit2/include/git2/submodule.h +16 -2
- data/vendor/libgit2/include/git2/sys/commit_graph.h +174 -0
- data/vendor/libgit2/include/git2/sys/email.h +45 -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 +9 -5
- data/vendor/libgit2/include/git2/sys/remote.h +31 -0
- data/vendor/libgit2/include/git2/sys/stream.h +1 -1
- data/vendor/libgit2/include/git2/sys/transport.h +26 -34
- data/vendor/libgit2/include/git2/tag.h +13 -0
- data/vendor/libgit2/include/git2/tree.h +4 -17
- data/vendor/libgit2/include/git2/types.h +16 -7
- data/vendor/libgit2/include/git2/version.h +4 -4
- data/vendor/libgit2/include/git2/worktree.h +13 -2
- data/vendor/libgit2/include/git2.h +1 -0
- data/vendor/libgit2/src/CMakeLists.txt +192 -290
- 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/annotated_commit.h +1 -1
- data/vendor/libgit2/src/apply.c +34 -25
- data/vendor/libgit2/src/apply.h +2 -2
- data/vendor/libgit2/src/array.h +11 -11
- data/vendor/libgit2/src/attr.c +204 -82
- data/vendor/libgit2/src/attr_file.c +105 -52
- data/vendor/libgit2/src/attr_file.h +36 -15
- data/vendor/libgit2/src/attrcache.c +55 -45
- data/vendor/libgit2/src/attrcache.h +4 -5
- data/vendor/libgit2/src/blame.c +15 -9
- data/vendor/libgit2/src/blame_git.c +2 -2
- data/vendor/libgit2/src/blob.c +76 -52
- data/vendor/libgit2/src/blob.h +1 -1
- data/vendor/libgit2/src/branch.c +203 -110
- data/vendor/libgit2/src/branch.h +15 -3
- data/vendor/libgit2/src/buf.c +126 -0
- data/vendor/libgit2/src/buf.h +50 -0
- data/vendor/libgit2/src/cache.c +2 -2
- data/vendor/libgit2/src/cache.h +7 -7
- data/vendor/libgit2/src/cc-compat.h +11 -9
- data/vendor/libgit2/src/checkout.c +118 -91
- data/vendor/libgit2/src/cherrypick.c +16 -12
- data/vendor/libgit2/src/clone.c +97 -103
- data/vendor/libgit2/src/commit.c +167 -84
- data/vendor/libgit2/src/commit.h +24 -1
- data/vendor/libgit2/src/commit_graph.c +1224 -0
- data/vendor/libgit2/src/commit_graph.h +169 -0
- data/vendor/libgit2/src/commit_list.c +48 -3
- data/vendor/libgit2/src/commit_list.h +2 -0
- data/vendor/libgit2/src/common.h +35 -5
- data/vendor/libgit2/src/config.c +119 -64
- data/vendor/libgit2/src/config.h +15 -2
- data/vendor/libgit2/src/config_cache.c +5 -3
- data/vendor/libgit2/src/config_file.c +120 -100
- data/vendor/libgit2/src/config_mem.c +9 -9
- data/vendor/libgit2/src/config_parse.c +29 -27
- data/vendor/libgit2/src/crlf.c +36 -23
- data/vendor/libgit2/src/date.c +13 -19
- data/vendor/libgit2/src/date.h +33 -0
- data/vendor/libgit2/src/delta.c +1 -1
- data/vendor/libgit2/src/describe.c +32 -21
- data/vendor/libgit2/src/diff.c +71 -183
- data/vendor/libgit2/src/diff.h +2 -4
- data/vendor/libgit2/src/diff_driver.c +53 -51
- data/vendor/libgit2/src/diff_driver.h +3 -3
- data/vendor/libgit2/src/diff_file.c +31 -26
- data/vendor/libgit2/src/diff_generate.c +76 -23
- data/vendor/libgit2/src/diff_generate.h +5 -3
- data/vendor/libgit2/src/diff_print.c +120 -95
- data/vendor/libgit2/src/diff_stats.c +47 -34
- data/vendor/libgit2/src/{message.h → diff_stats.h} +7 -6
- data/vendor/libgit2/src/diff_tform.c +18 -16
- data/vendor/libgit2/src/diff_xdiff.c +7 -10
- data/vendor/libgit2/src/diff_xdiff.h +1 -1
- data/vendor/libgit2/src/email.c +315 -0
- data/vendor/libgit2/src/email.h +25 -0
- data/vendor/libgit2/src/errors.c +37 -32
- data/vendor/libgit2/src/features.h.in +11 -2
- data/vendor/libgit2/src/fetch.c +77 -26
- data/vendor/libgit2/src/fetch.h +1 -1
- data/vendor/libgit2/src/fetchhead.c +27 -23
- data/vendor/libgit2/src/filebuf.c +36 -34
- data/vendor/libgit2/src/filebuf.h +1 -1
- data/vendor/libgit2/src/filter.c +278 -132
- data/vendor/libgit2/src/filter.h +46 -6
- data/vendor/libgit2/src/fs_path.c +2071 -0
- data/vendor/libgit2/src/fs_path.h +772 -0
- data/vendor/libgit2/src/futils.c +96 -90
- data/vendor/libgit2/src/futils.h +27 -15
- data/vendor/libgit2/src/graph.c +64 -9
- data/vendor/libgit2/src/hash/sha1/collisiondetect.c +5 -5
- data/vendor/libgit2/src/hash/sha1/common_crypto.c +5 -5
- data/vendor/libgit2/src/hash/sha1/generic.c +2 -2
- data/vendor/libgit2/src/hash/sha1/generic.h +1 -1
- data/vendor/libgit2/src/hash/sha1/mbedtls.c +13 -13
- data/vendor/libgit2/src/hash/sha1/openssl.c +5 -5
- data/vendor/libgit2/src/hash/sha1/sha1dc/sha1.c +9 -11
- data/vendor/libgit2/src/hash/sha1/win32.c +21 -17
- data/vendor/libgit2/src/hash/sha1.h +3 -1
- data/vendor/libgit2/src/hash.c +71 -36
- data/vendor/libgit2/src/hash.h +13 -13
- data/vendor/libgit2/src/hashsig.c +23 -10
- data/vendor/libgit2/src/ident.c +30 -20
- data/vendor/libgit2/src/ignore.c +63 -46
- data/vendor/libgit2/src/ignore.h +2 -2
- data/vendor/libgit2/src/index.c +184 -149
- data/vendor/libgit2/src/index.h +7 -4
- data/vendor/libgit2/src/indexer.c +143 -89
- data/vendor/libgit2/src/integer.h +64 -2
- data/vendor/libgit2/src/iterator.c +93 -73
- data/vendor/libgit2/src/iterator.h +6 -6
- data/vendor/libgit2/src/khash.h +3 -12
- data/vendor/libgit2/src/{settings.c → libgit2.c} +165 -56
- data/vendor/libgit2/src/libgit2.h +15 -0
- data/vendor/libgit2/src/mailmap.c +60 -45
- data/vendor/libgit2/src/map.h +3 -3
- data/vendor/libgit2/src/merge.c +104 -61
- data/vendor/libgit2/src/merge.h +3 -15
- data/vendor/libgit2/src/merge_driver.c +21 -15
- data/vendor/libgit2/src/merge_file.c +24 -6
- data/vendor/libgit2/src/message.c +21 -8
- data/vendor/libgit2/src/midx.c +501 -18
- data/vendor/libgit2/src/midx.h +29 -2
- data/vendor/libgit2/src/mwindow.c +103 -59
- data/vendor/libgit2/src/mwindow.h +3 -3
- data/vendor/libgit2/src/net.c +405 -71
- data/vendor/libgit2/src/net.h +26 -5
- data/vendor/libgit2/src/netops.c +7 -5
- data/vendor/libgit2/src/netops.h +3 -3
- data/vendor/libgit2/src/notes.c +40 -49
- data/vendor/libgit2/src/object.c +68 -20
- data/vendor/libgit2/src/object.h +1 -1
- data/vendor/libgit2/src/odb.c +320 -80
- data/vendor/libgit2/src/odb.h +17 -3
- data/vendor/libgit2/src/odb_loose.c +96 -86
- data/vendor/libgit2/src/odb_mempack.c +19 -6
- data/vendor/libgit2/src/odb_pack.c +402 -125
- data/vendor/libgit2/src/oid.c +16 -8
- data/vendor/libgit2/src/oid.h +15 -0
- data/vendor/libgit2/src/oidarray.c +10 -1
- data/vendor/libgit2/src/pack-objects.c +90 -69
- data/vendor/libgit2/src/pack-objects.h +11 -6
- data/vendor/libgit2/src/pack.c +337 -127
- data/vendor/libgit2/src/pack.h +25 -7
- data/vendor/libgit2/src/patch.c +17 -10
- data/vendor/libgit2/src/patch.h +1 -0
- data/vendor/libgit2/src/patch_generate.c +29 -13
- data/vendor/libgit2/src/patch_generate.h +5 -5
- data/vendor/libgit2/src/patch_parse.c +26 -25
- data/vendor/libgit2/src/path.c +86 -1768
- data/vendor/libgit2/src/path.h +39 -635
- data/vendor/libgit2/src/pathspec.c +12 -12
- data/vendor/libgit2/src/pathspec.h +2 -2
- data/vendor/libgit2/src/pool.c +13 -7
- data/vendor/libgit2/src/posix.c +14 -6
- data/vendor/libgit2/src/posix.h +1 -0
- data/vendor/libgit2/src/pqueue.h +1 -1
- data/vendor/libgit2/src/proxy.c +4 -1
- data/vendor/libgit2/src/proxy.h +1 -1
- data/vendor/libgit2/src/push.c +30 -35
- data/vendor/libgit2/src/push.h +4 -16
- data/vendor/libgit2/src/rand.c +226 -0
- data/vendor/libgit2/src/rand.h +37 -0
- data/vendor/libgit2/src/reader.c +18 -14
- data/vendor/libgit2/src/reader.h +2 -2
- data/vendor/libgit2/src/rebase.c +177 -132
- data/vendor/libgit2/src/refdb.c +30 -13
- data/vendor/libgit2/src/refdb_fs.c +548 -222
- data/vendor/libgit2/src/reflog.c +19 -14
- data/vendor/libgit2/src/refs.c +107 -72
- data/vendor/libgit2/src/refs.h +2 -2
- data/vendor/libgit2/src/refspec.c +53 -38
- data/vendor/libgit2/src/refspec.h +5 -2
- data/vendor/libgit2/src/regexp.c +1 -1
- data/vendor/libgit2/src/remote.c +960 -486
- data/vendor/libgit2/src/remote.h +16 -10
- data/vendor/libgit2/src/repository.c +702 -422
- data/vendor/libgit2/src/repository.h +26 -8
- data/vendor/libgit2/src/reset.c +16 -12
- data/vendor/libgit2/src/revert.c +16 -12
- data/vendor/libgit2/src/revparse.c +66 -48
- data/vendor/libgit2/src/revwalk.c +39 -22
- data/vendor/libgit2/src/runtime.c +162 -0
- data/vendor/libgit2/src/runtime.h +62 -0
- data/vendor/libgit2/src/settings.h +11 -0
- data/vendor/libgit2/src/signature.c +18 -11
- data/vendor/libgit2/src/signature.h +1 -1
- data/vendor/libgit2/src/sortedcache.c +1 -1
- data/vendor/libgit2/src/sortedcache.h +10 -8
- data/vendor/libgit2/src/stash.c +39 -38
- data/vendor/libgit2/src/status.c +11 -5
- data/vendor/libgit2/src/{buffer.c → str.c} +459 -136
- data/vendor/libgit2/src/str.h +357 -0
- data/vendor/libgit2/src/strarray.c +2 -1
- data/vendor/libgit2/src/streams/mbedtls.c +22 -23
- data/vendor/libgit2/src/streams/mbedtls.h +1 -1
- data/vendor/libgit2/src/streams/openssl.c +101 -201
- data/vendor/libgit2/src/streams/openssl.h +9 -1
- data/vendor/libgit2/src/streams/openssl_dynamic.c +309 -0
- data/vendor/libgit2/src/streams/openssl_dynamic.h +348 -0
- data/vendor/libgit2/src/streams/openssl_legacy.c +203 -0
- data/vendor/libgit2/src/streams/openssl_legacy.h +63 -0
- data/vendor/libgit2/src/streams/registry.c +5 -6
- data/vendor/libgit2/src/streams/socket.c +6 -2
- data/vendor/libgit2/src/streams/stransport.c +6 -3
- data/vendor/libgit2/src/streams/tls.c +5 -3
- data/vendor/libgit2/src/submodule.c +290 -212
- data/vendor/libgit2/src/submodule.h +10 -10
- data/vendor/libgit2/src/sysdir.c +70 -56
- data/vendor/libgit2/src/sysdir.h +15 -10
- data/vendor/libgit2/src/tag.c +72 -34
- data/vendor/libgit2/src/thread.c +140 -0
- data/vendor/libgit2/src/thread.h +479 -0
- data/vendor/libgit2/src/threadstate.c +84 -0
- data/vendor/libgit2/src/threadstate.h +24 -0
- data/vendor/libgit2/src/trace.c +3 -16
- data/vendor/libgit2/src/trace.h +17 -30
- data/vendor/libgit2/src/trailer.c +2 -2
- data/vendor/libgit2/src/transaction.c +20 -9
- data/vendor/libgit2/src/transport.c +13 -13
- data/vendor/libgit2/src/transports/auth.c +8 -10
- data/vendor/libgit2/src/transports/auth.h +2 -3
- data/vendor/libgit2/src/transports/auth_negotiate.c +23 -17
- data/vendor/libgit2/src/transports/auth_ntlm.c +20 -16
- data/vendor/libgit2/src/transports/auth_ntlm.h +0 -1
- data/vendor/libgit2/src/transports/credential.c +15 -7
- data/vendor/libgit2/src/transports/git.c +10 -14
- data/vendor/libgit2/src/transports/http.c +56 -34
- data/vendor/libgit2/src/transports/http.h +3 -3
- data/vendor/libgit2/src/transports/httpclient.c +106 -79
- data/vendor/libgit2/src/transports/httpclient.h +1 -1
- data/vendor/libgit2/src/transports/local.c +127 -119
- data/vendor/libgit2/src/transports/smart.c +61 -144
- data/vendor/libgit2/src/transports/smart.h +26 -32
- data/vendor/libgit2/src/transports/smart_pkt.c +33 -33
- data/vendor/libgit2/src/transports/smart_protocol.c +68 -44
- data/vendor/libgit2/src/transports/ssh.c +100 -131
- data/vendor/libgit2/src/transports/winhttp.c +86 -82
- data/vendor/libgit2/src/tree-cache.c +5 -5
- data/vendor/libgit2/src/tree-cache.h +2 -2
- data/vendor/libgit2/src/tree.c +150 -116
- data/vendor/libgit2/src/tree.h +1 -0
- data/vendor/libgit2/src/tsort.c +0 -2
- data/vendor/libgit2/src/unix/map.c +3 -3
- data/vendor/libgit2/src/unix/posix.h +1 -4
- data/vendor/libgit2/src/unix/pthread.h +2 -1
- data/vendor/libgit2/src/unix/realpath.c +0 -2
- data/vendor/libgit2/src/utf8.c +150 -0
- data/vendor/libgit2/src/utf8.h +52 -0
- data/vendor/libgit2/src/util.c +68 -144
- data/vendor/libgit2/src/util.h +36 -68
- data/vendor/libgit2/src/vector.c +23 -19
- data/vendor/libgit2/src/vector.h +5 -3
- data/vendor/libgit2/src/win32/findfile.c +172 -114
- data/vendor/libgit2/src/win32/findfile.h +7 -4
- 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 +162 -33
- data/vendor/libgit2/src/win32/path_w32.h +2 -1
- data/vendor/libgit2/src/win32/posix.h +6 -7
- data/vendor/libgit2/src/win32/posix_w32.c +26 -33
- 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 +5 -6
- data/vendor/libgit2/src/win32/w32_buffer.h +2 -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 +138 -105
- data/vendor/libgit2/src/worktree.h +1 -1
- data/vendor/libgit2/src/xdiff/git-xdiff.h +53 -0
- data/vendor/libgit2/src/xdiff/xdiff.h +15 -15
- data/vendor/libgit2/src/xdiff/xdiffi.c +134 -108
- data/vendor/libgit2/src/xdiff/xemit.c +23 -7
- data/vendor/libgit2/src/xdiff/xhistogram.c +87 -78
- data/vendor/libgit2/src/xdiff/xinclude.h +1 -12
- data/vendor/libgit2/src/xdiff/xmerge.c +104 -117
- data/vendor/libgit2/src/xdiff/xpatience.c +6 -17
- data/vendor/libgit2/src/xdiff/xprepare.c +15 -20
- data/vendor/libgit2/src/xdiff/xutils.c +18 -7
- data/vendor/libgit2/src/zstream.c +6 -6
- data/vendor/libgit2/src/zstream.h +4 -4
- metadata +60 -24
- 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/buffer.h +0 -222
- data/vendor/libgit2/src/global.c +0 -363
- data/vendor/libgit2/src/global.h +0 -41
- data/vendor/libgit2/src/thread-utils.c +0 -58
- data/vendor/libgit2/src/thread-utils.h +0 -369
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +0 -127
- data/vendor/libgit2/src/win32/w32_stack.c +0 -188
- data/vendor/libgit2/src/win32/w32_stack.h +0 -140
@@ -12,6 +12,7 @@
|
|
12
12
|
#include "git2/object.h"
|
13
13
|
#include "git2/sys/repository.h"
|
14
14
|
|
15
|
+
#include "buf.h"
|
15
16
|
#include "common.h"
|
16
17
|
#include "commit.h"
|
17
18
|
#include "tag.h"
|
@@ -31,13 +32,14 @@
|
|
31
32
|
#include "annotated_commit.h"
|
32
33
|
#include "submodule.h"
|
33
34
|
#include "worktree.h"
|
34
|
-
|
35
|
+
#include "path.h"
|
35
36
|
#include "strmap.h"
|
36
37
|
|
37
38
|
#ifdef GIT_WIN32
|
38
39
|
# include "win32/w32_util.h"
|
39
40
|
#endif
|
40
41
|
|
42
|
+
bool git_repository__validate_ownership = true;
|
41
43
|
bool git_repository__fsync_gitdir = false;
|
42
44
|
|
43
45
|
static const struct {
|
@@ -64,6 +66,7 @@ static const struct {
|
|
64
66
|
|
65
67
|
static int check_repositoryformatversion(int *version, git_config *config);
|
66
68
|
static int check_extensions(git_config *config, int version);
|
69
|
+
static int load_global_config(git_config **config);
|
67
70
|
|
68
71
|
#define GIT_COMMONDIR_FILE "commondir"
|
69
72
|
#define GIT_GITDIR_FILE "gitdir"
|
@@ -75,13 +78,13 @@ static int check_extensions(git_config *config, int version);
|
|
75
78
|
#define GIT_REPO_VERSION 0
|
76
79
|
#define GIT_REPO_MAX_VERSION 1
|
77
80
|
|
78
|
-
|
81
|
+
git_str git_repository__reserved_names_win32[] = {
|
79
82
|
{ DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
|
80
83
|
{ GIT_DIR_SHORTNAME, 0, CONST_STRLEN(GIT_DIR_SHORTNAME) }
|
81
84
|
};
|
82
85
|
size_t git_repository__reserved_names_win32_len = 2;
|
83
86
|
|
84
|
-
|
87
|
+
git_str git_repository__reserved_names_posix[] = {
|
85
88
|
{ DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
|
86
89
|
};
|
87
90
|
size_t git_repository__reserved_names_posix_len = 1;
|
@@ -93,7 +96,7 @@ static void set_odb(git_repository *repo, git_odb *odb)
|
|
93
96
|
GIT_REFCOUNT_INC(odb);
|
94
97
|
}
|
95
98
|
|
96
|
-
if ((odb =
|
99
|
+
if ((odb = git_atomic_swap(repo->_odb, odb)) != NULL) {
|
97
100
|
GIT_REFCOUNT_OWN(odb, NULL);
|
98
101
|
git_odb_free(odb);
|
99
102
|
}
|
@@ -106,7 +109,7 @@ static void set_refdb(git_repository *repo, git_refdb *refdb)
|
|
106
109
|
GIT_REFCOUNT_INC(refdb);
|
107
110
|
}
|
108
111
|
|
109
|
-
if ((refdb =
|
112
|
+
if ((refdb = git_atomic_swap(repo->_refdb, refdb)) != NULL) {
|
110
113
|
GIT_REFCOUNT_OWN(refdb, NULL);
|
111
114
|
git_refdb_free(refdb);
|
112
115
|
}
|
@@ -119,7 +122,7 @@ static void set_config(git_repository *repo, git_config *config)
|
|
119
122
|
GIT_REFCOUNT_INC(config);
|
120
123
|
}
|
121
124
|
|
122
|
-
if ((config =
|
125
|
+
if ((config = git_atomic_swap(repo->_config, config)) != NULL) {
|
123
126
|
GIT_REFCOUNT_OWN(config, NULL);
|
124
127
|
git_config_free(config);
|
125
128
|
}
|
@@ -134,7 +137,7 @@ static void set_index(git_repository *repo, git_index *index)
|
|
134
137
|
GIT_REFCOUNT_INC(index);
|
135
138
|
}
|
136
139
|
|
137
|
-
if ((index =
|
140
|
+
if ((index = git_atomic_swap(repo->_index, index)) != NULL) {
|
138
141
|
GIT_REFCOUNT_OWN(index, NULL);
|
139
142
|
git_index_free(index);
|
140
143
|
}
|
@@ -142,7 +145,7 @@ static void set_index(git_repository *repo, git_index *index)
|
|
142
145
|
|
143
146
|
int git_repository__cleanup(git_repository *repo)
|
144
147
|
{
|
145
|
-
|
148
|
+
GIT_ASSERT_ARG(repo);
|
146
149
|
|
147
150
|
git_repository_submodule_cache_clear(repo);
|
148
151
|
git_cache_clear(&repo->objects);
|
@@ -171,7 +174,7 @@ void git_repository_free(git_repository *repo)
|
|
171
174
|
repo->diff_drivers = NULL;
|
172
175
|
|
173
176
|
for (i = 0; i < repo->reserved_names.size; i++)
|
174
|
-
|
177
|
+
git_str_dispose(git_array_get(repo->reserved_names, i));
|
175
178
|
git_array_clear(repo->reserved_names);
|
176
179
|
|
177
180
|
git__free(repo->gitlink);
|
@@ -186,55 +189,94 @@ void git_repository_free(git_repository *repo)
|
|
186
189
|
git__free(repo);
|
187
190
|
}
|
188
191
|
|
192
|
+
/* Check if we have a separate commondir (e.g. we have a worktree) */
|
193
|
+
static int lookup_commondir(bool *separate, git_str *commondir, git_str *repository_path)
|
194
|
+
{
|
195
|
+
git_str common_link = GIT_STR_INIT;
|
196
|
+
int error;
|
197
|
+
|
198
|
+
/*
|
199
|
+
* If there's no commondir file, the repository path is the
|
200
|
+
* common path, but it needs a trailing slash.
|
201
|
+
*/
|
202
|
+
if (!git_fs_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) {
|
203
|
+
if ((error = git_str_set(commondir, repository_path->ptr, repository_path->size)) == 0)
|
204
|
+
error = git_fs_path_to_dir(commondir);
|
205
|
+
|
206
|
+
*separate = false;
|
207
|
+
goto done;
|
208
|
+
}
|
209
|
+
|
210
|
+
*separate = true;
|
211
|
+
|
212
|
+
if ((error = git_str_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE)) < 0 ||
|
213
|
+
(error = git_futils_readbuffer(&common_link, common_link.ptr)) < 0)
|
214
|
+
goto done;
|
215
|
+
|
216
|
+
git_str_rtrim(&common_link);
|
217
|
+
if (git_fs_path_is_relative(common_link.ptr)) {
|
218
|
+
if ((error = git_str_joinpath(commondir, repository_path->ptr, common_link.ptr)) < 0)
|
219
|
+
goto done;
|
220
|
+
} else {
|
221
|
+
git_str_swap(commondir, &common_link);
|
222
|
+
}
|
223
|
+
|
224
|
+
git_str_dispose(&common_link);
|
225
|
+
|
226
|
+
/* Make sure the commondir path always has a trailing slash */
|
227
|
+
error = git_fs_path_prettify_dir(commondir, commondir->ptr, NULL);
|
228
|
+
|
229
|
+
done:
|
230
|
+
return error;
|
231
|
+
}
|
232
|
+
|
233
|
+
GIT_INLINE(int) validate_repo_path(git_str *path)
|
234
|
+
{
|
235
|
+
/*
|
236
|
+
* The longest static path in a repository (or commondir) is the
|
237
|
+
* packed refs file. (Loose refs may be longer since they
|
238
|
+
* include the reference name, but will be validated when the
|
239
|
+
* path is constructed.)
|
240
|
+
*/
|
241
|
+
static size_t suffix_len =
|
242
|
+
CONST_STRLEN("objects/pack/pack-.pack.lock") +
|
243
|
+
GIT_OID_HEXSZ;
|
244
|
+
|
245
|
+
return git_fs_path_validate_str_length_with_suffix(
|
246
|
+
path, suffix_len);
|
247
|
+
}
|
248
|
+
|
189
249
|
/*
|
190
250
|
* Git repository open methods
|
191
251
|
*
|
192
252
|
* Open a repository object from its path
|
193
253
|
*/
|
194
|
-
static int is_valid_repository_path(bool *out,
|
254
|
+
static int is_valid_repository_path(bool *out, git_str *repository_path, git_str *common_path)
|
195
255
|
{
|
256
|
+
bool separate_commondir = false;
|
196
257
|
int error;
|
197
258
|
|
198
259
|
*out = false;
|
199
260
|
|
200
|
-
|
201
|
-
|
202
|
-
if (git_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) {
|
203
|
-
git_buf common_link = GIT_BUF_INIT;
|
204
|
-
|
205
|
-
if ((error = git_buf_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE)) < 0 ||
|
206
|
-
(error = git_futils_readbuffer(&common_link, common_link.ptr)) < 0)
|
207
|
-
return error;
|
208
|
-
|
209
|
-
git_buf_rtrim(&common_link);
|
210
|
-
if (git_path_is_relative(common_link.ptr)) {
|
211
|
-
if ((error = git_buf_joinpath(common_path, repository_path->ptr, common_link.ptr)) < 0)
|
212
|
-
return error;
|
213
|
-
} else {
|
214
|
-
git_buf_swap(common_path, &common_link);
|
215
|
-
}
|
216
|
-
|
217
|
-
git_buf_dispose(&common_link);
|
218
|
-
}
|
219
|
-
else {
|
220
|
-
if ((error = git_buf_set(common_path, repository_path->ptr, repository_path->size)) < 0)
|
221
|
-
return error;
|
222
|
-
}
|
223
|
-
|
224
|
-
/* Make sure the commondir path always has a trailing * slash */
|
225
|
-
if (git_buf_rfind(common_path, '/') != (ssize_t)common_path->size - 1)
|
226
|
-
if ((error = git_buf_putc(common_path, '/')) < 0)
|
227
|
-
return error;
|
261
|
+
if ((error = lookup_commondir(&separate_commondir, common_path, repository_path)) < 0)
|
262
|
+
return error;
|
228
263
|
|
229
264
|
/* Ensure HEAD file exists */
|
230
|
-
if (
|
265
|
+
if (git_fs_path_contains_file(repository_path, GIT_HEAD_FILE) == false)
|
231
266
|
return 0;
|
267
|
+
|
232
268
|
/* Check files in common dir */
|
233
|
-
if (
|
269
|
+
if (git_fs_path_contains_dir(common_path, GIT_OBJECTS_DIR) == false)
|
234
270
|
return 0;
|
235
|
-
if (
|
271
|
+
if (git_fs_path_contains_dir(common_path, GIT_REFS_DIR) == false)
|
236
272
|
return 0;
|
237
273
|
|
274
|
+
/* Ensure the repo (and commondir) are valid paths */
|
275
|
+
if ((error = validate_repo_path(common_path)) < 0 ||
|
276
|
+
(separate_commondir &&
|
277
|
+
(error = validate_repo_path(repository_path)) < 0))
|
278
|
+
return error;
|
279
|
+
|
238
280
|
*out = true;
|
239
281
|
return 0;
|
240
282
|
}
|
@@ -294,12 +336,12 @@ static int load_config_data(git_repository *repo, const git_config *config)
|
|
294
336
|
return 0;
|
295
337
|
}
|
296
338
|
|
297
|
-
static int load_workdir(git_repository *repo, git_config *config,
|
339
|
+
static int load_workdir(git_repository *repo, git_config *config, git_str *parent_path)
|
298
340
|
{
|
299
341
|
int error;
|
300
342
|
git_config_entry *ce;
|
301
|
-
|
302
|
-
|
343
|
+
git_str worktree = GIT_STR_INIT;
|
344
|
+
git_str path = GIT_STR_INIT;
|
303
345
|
|
304
346
|
if (repo->is_bare)
|
305
347
|
return 0;
|
@@ -315,38 +357,38 @@ static int load_workdir(git_repository *repo, git_config *config, git_buf *paren
|
|
315
357
|
goto cleanup;
|
316
358
|
}
|
317
359
|
|
318
|
-
|
360
|
+
git_str_attach(&worktree, gitlink, 0);
|
319
361
|
|
320
|
-
if ((
|
321
|
-
|
362
|
+
if ((git_fs_path_dirname_r(&worktree, worktree.ptr)) < 0 ||
|
363
|
+
git_fs_path_to_dir(&worktree) < 0) {
|
322
364
|
error = -1;
|
323
365
|
goto cleanup;
|
324
366
|
}
|
325
367
|
|
326
|
-
repo->workdir =
|
368
|
+
repo->workdir = git_str_detach(&worktree);
|
327
369
|
}
|
328
370
|
else if (ce && ce->value) {
|
329
|
-
if ((error =
|
371
|
+
if ((error = git_fs_path_prettify_dir(
|
330
372
|
&worktree, ce->value, repo->gitdir)) < 0)
|
331
373
|
goto cleanup;
|
332
374
|
|
333
|
-
repo->workdir =
|
375
|
+
repo->workdir = git_str_detach(&worktree);
|
334
376
|
}
|
335
|
-
else if (parent_path &&
|
336
|
-
repo->workdir =
|
377
|
+
else if (parent_path && git_fs_path_isdir(parent_path->ptr))
|
378
|
+
repo->workdir = git_str_detach(parent_path);
|
337
379
|
else {
|
338
|
-
if (
|
339
|
-
|
380
|
+
if (git_fs_path_dirname_r(&worktree, repo->gitdir) < 0 ||
|
381
|
+
git_fs_path_to_dir(&worktree) < 0) {
|
340
382
|
error = -1;
|
341
383
|
goto cleanup;
|
342
384
|
}
|
343
385
|
|
344
|
-
repo->workdir =
|
386
|
+
repo->workdir = git_str_detach(&worktree);
|
345
387
|
}
|
346
388
|
|
347
389
|
GIT_ERROR_CHECK_ALLOC(repo->workdir);
|
348
390
|
cleanup:
|
349
|
-
|
391
|
+
git_str_dispose(&path);
|
350
392
|
git_config_entry_free(ce);
|
351
393
|
return error;
|
352
394
|
}
|
@@ -355,7 +397,7 @@ cleanup:
|
|
355
397
|
* This function returns furthest offset into path where a ceiling dir
|
356
398
|
* is found, so we can stop processing the path at that point.
|
357
399
|
*
|
358
|
-
* Note: converting this to use
|
400
|
+
* Note: converting this to use git_strs instead of GIT_PATH_MAX buffers on
|
359
401
|
* the stack could remove directories name limits, but at the cost of doing
|
360
402
|
* repeated malloc/frees inside the loop below, so let's not do it now.
|
361
403
|
*/
|
@@ -368,9 +410,9 @@ static size_t find_ceiling_dir_offset(
|
|
368
410
|
const char *ceil, *sep;
|
369
411
|
size_t len, max_len = 0, min_len;
|
370
412
|
|
371
|
-
|
413
|
+
GIT_ASSERT_ARG(path);
|
372
414
|
|
373
|
-
min_len = (size_t)(
|
415
|
+
min_len = (size_t)(git_fs_path_root(path) + 1);
|
374
416
|
|
375
417
|
if (ceiling_directories == NULL || min_len == 0)
|
376
418
|
return min_len;
|
@@ -379,7 +421,7 @@ static size_t find_ceiling_dir_offset(
|
|
379
421
|
for (sep = ceil; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++);
|
380
422
|
len = sep - ceil;
|
381
423
|
|
382
|
-
if (len == 0 || len >= sizeof(buf) ||
|
424
|
+
if (len == 0 || len >= sizeof(buf) || git_fs_path_root(ceil) == -1)
|
383
425
|
continue;
|
384
426
|
|
385
427
|
strncpy(buf, ceil, len);
|
@@ -408,52 +450,110 @@ static size_t find_ceiling_dir_offset(
|
|
408
450
|
* it points to. Before calling, set `path_out` to the base directory that
|
409
451
|
* should be used if the contents of `file_path` are a relative path.
|
410
452
|
*/
|
411
|
-
static int read_gitfile(
|
453
|
+
static int read_gitfile(git_str *path_out, const char *file_path)
|
412
454
|
{
|
413
455
|
int error = 0;
|
414
|
-
|
456
|
+
git_str file = GIT_STR_INIT;
|
415
457
|
size_t prefix_len = strlen(GIT_FILE_CONTENT_PREFIX);
|
416
458
|
|
417
|
-
|
459
|
+
GIT_ASSERT_ARG(path_out);
|
460
|
+
GIT_ASSERT_ARG(file_path);
|
418
461
|
|
419
462
|
if (git_futils_readbuffer(&file, file_path) < 0)
|
420
463
|
return -1;
|
421
464
|
|
422
|
-
|
465
|
+
git_str_rtrim(&file);
|
423
466
|
/* apparently on Windows, some people use backslashes in paths */
|
424
|
-
|
467
|
+
git_fs_path_mkposix(file.ptr);
|
425
468
|
|
426
|
-
if (
|
427
|
-
memcmp(
|
469
|
+
if (git_str_len(&file) <= prefix_len ||
|
470
|
+
memcmp(git_str_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0)
|
428
471
|
{
|
429
472
|
git_error_set(GIT_ERROR_REPOSITORY,
|
430
473
|
"the `.git` file at '%s' is malformed", file_path);
|
431
474
|
error = -1;
|
432
475
|
}
|
433
|
-
else if ((error =
|
434
|
-
const char *gitlink =
|
476
|
+
else if ((error = git_fs_path_dirname_r(path_out, file_path)) >= 0) {
|
477
|
+
const char *gitlink = git_str_cstr(&file) + prefix_len;
|
435
478
|
while (*gitlink && git__isspace(*gitlink)) gitlink++;
|
436
479
|
|
437
|
-
error =
|
438
|
-
path_out, gitlink,
|
480
|
+
error = git_fs_path_prettify_dir(
|
481
|
+
path_out, gitlink, git_str_cstr(path_out));
|
482
|
+
}
|
483
|
+
|
484
|
+
git_str_dispose(&file);
|
485
|
+
return error;
|
486
|
+
}
|
487
|
+
|
488
|
+
typedef struct {
|
489
|
+
const char *repo_path;
|
490
|
+
git_str tmp;
|
491
|
+
bool is_safe;
|
492
|
+
} validate_ownership_data;
|
493
|
+
|
494
|
+
static int validate_ownership_cb(const git_config_entry *entry, void *payload)
|
495
|
+
{
|
496
|
+
validate_ownership_data *data = payload;
|
497
|
+
|
498
|
+
if (strcmp(entry->value, "") == 0)
|
499
|
+
data->is_safe = false;
|
500
|
+
|
501
|
+
if (git_fs_path_prettify_dir(&data->tmp, entry->value, NULL) == 0 &&
|
502
|
+
strcmp(data->tmp.ptr, data->repo_path) == 0)
|
503
|
+
data->is_safe = true;
|
504
|
+
|
505
|
+
return 0;
|
506
|
+
}
|
507
|
+
|
508
|
+
static int validate_ownership(const char *repo_path)
|
509
|
+
{
|
510
|
+
git_config *config = NULL;
|
511
|
+
validate_ownership_data data = { repo_path, GIT_STR_INIT, false };
|
512
|
+
bool is_safe;
|
513
|
+
int error;
|
514
|
+
|
515
|
+
if ((error = git_fs_path_owner_is_current_user(&is_safe, repo_path)) < 0) {
|
516
|
+
if (error == GIT_ENOTFOUND)
|
517
|
+
error = 0;
|
518
|
+
|
519
|
+
goto done;
|
439
520
|
}
|
440
521
|
|
441
|
-
|
522
|
+
if (is_safe) {
|
523
|
+
error = 0;
|
524
|
+
goto done;
|
525
|
+
}
|
526
|
+
|
527
|
+
if (load_global_config(&config) == 0) {
|
528
|
+
error = git_config_get_multivar_foreach(config, "safe.directory", NULL, validate_ownership_cb, &data);
|
529
|
+
|
530
|
+
if (!error && data.is_safe)
|
531
|
+
goto done;
|
532
|
+
}
|
533
|
+
|
534
|
+
git_error_set(GIT_ERROR_CONFIG,
|
535
|
+
"repository path '%s' is not owned by current user",
|
536
|
+
repo_path);
|
537
|
+
error = GIT_EOWNER;
|
538
|
+
|
539
|
+
done:
|
540
|
+
git_config_free(config);
|
541
|
+
git_str_dispose(&data.tmp);
|
442
542
|
return error;
|
443
543
|
}
|
444
544
|
|
445
545
|
static int find_repo(
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
546
|
+
git_str *gitdir_path,
|
547
|
+
git_str *workdir_path,
|
548
|
+
git_str *gitlink_path,
|
549
|
+
git_str *commondir_path,
|
450
550
|
const char *start_path,
|
451
551
|
uint32_t flags,
|
452
552
|
const char *ceiling_dirs)
|
453
553
|
{
|
454
|
-
|
455
|
-
|
456
|
-
|
554
|
+
git_str path = GIT_STR_INIT;
|
555
|
+
git_str repo_link = GIT_STR_INIT;
|
556
|
+
git_str common_link = GIT_STR_INIT;
|
457
557
|
struct stat st;
|
458
558
|
dev_t initial_device = 0;
|
459
559
|
int min_iterations;
|
@@ -461,9 +561,9 @@ static int find_repo(
|
|
461
561
|
size_t ceiling_offset = 0;
|
462
562
|
int error;
|
463
563
|
|
464
|
-
|
564
|
+
git_str_clear(gitdir_path);
|
465
565
|
|
466
|
-
error =
|
566
|
+
error = git_fs_path_prettify(&path, start_path, NULL);
|
467
567
|
if (error < 0)
|
468
568
|
return error;
|
469
569
|
|
@@ -485,7 +585,7 @@ static int find_repo(
|
|
485
585
|
for (;;) {
|
486
586
|
if (!(flags & GIT_REPOSITORY_OPEN_NO_DOTGIT)) {
|
487
587
|
if (!in_dot_git) {
|
488
|
-
if ((error =
|
588
|
+
if ((error = git_str_joinpath(&path, path.ptr, DOT_GIT)) < 0)
|
489
589
|
goto out;
|
490
590
|
}
|
491
591
|
in_dot_git = !in_dot_git;
|
@@ -504,15 +604,15 @@ static int find_repo(
|
|
504
604
|
goto out;
|
505
605
|
|
506
606
|
if (is_valid) {
|
507
|
-
if ((error =
|
508
|
-
(error =
|
607
|
+
if ((error = git_fs_path_to_dir(&path)) < 0 ||
|
608
|
+
(error = git_str_set(gitdir_path, path.ptr, path.size)) < 0)
|
509
609
|
goto out;
|
510
610
|
|
511
611
|
if (gitlink_path)
|
512
|
-
if ((error =
|
612
|
+
if ((error = git_str_attach(gitlink_path, git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0)) < 0)
|
513
613
|
goto out;
|
514
614
|
if (commondir_path)
|
515
|
-
|
615
|
+
git_str_swap(&common_link, commondir_path);
|
516
616
|
|
517
617
|
break;
|
518
618
|
}
|
@@ -522,13 +622,13 @@ static int find_repo(
|
|
522
622
|
goto out;
|
523
623
|
|
524
624
|
if (is_valid) {
|
525
|
-
|
625
|
+
git_str_swap(gitdir_path, &repo_link);
|
526
626
|
|
527
627
|
if (gitlink_path)
|
528
|
-
if ((error =
|
628
|
+
if ((error = git_str_put(gitlink_path, path.ptr, path.size)) < 0)
|
529
629
|
goto out;
|
530
630
|
if (commondir_path)
|
531
|
-
|
631
|
+
git_str_swap(&common_link, commondir_path);
|
532
632
|
}
|
533
633
|
break;
|
534
634
|
}
|
@@ -537,7 +637,7 @@ static int find_repo(
|
|
537
637
|
/* Move up one directory. If we're in_dot_git, we'll search the
|
538
638
|
* parent itself next. If we're !in_dot_git, we'll search .git
|
539
639
|
* in the parent directory next (added at the top of the loop). */
|
540
|
-
if ((error =
|
640
|
+
if ((error = git_fs_path_dirname_r(&path, path.ptr)) < 0)
|
541
641
|
goto out;
|
542
642
|
|
543
643
|
/* Once we've checked the directory (and .git if applicable),
|
@@ -552,25 +652,25 @@ static int find_repo(
|
|
552
652
|
}
|
553
653
|
|
554
654
|
if (workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) {
|
555
|
-
if (!
|
556
|
-
|
557
|
-
else if ((error =
|
558
|
-
(error =
|
655
|
+
if (!git_str_len(gitdir_path))
|
656
|
+
git_str_clear(workdir_path);
|
657
|
+
else if ((error = git_fs_path_dirname_r(workdir_path, path.ptr)) < 0 ||
|
658
|
+
(error = git_fs_path_to_dir(workdir_path)) < 0)
|
559
659
|
goto out;
|
560
660
|
}
|
561
661
|
|
562
662
|
/* If we didn't find the repository, and we don't have any other error
|
563
663
|
* to report, report that. */
|
564
|
-
if (!
|
664
|
+
if (!git_str_len(gitdir_path)) {
|
565
665
|
git_error_set(GIT_ERROR_REPOSITORY, "could not find repository from '%s'", start_path);
|
566
666
|
error = GIT_ENOTFOUND;
|
567
667
|
goto out;
|
568
668
|
}
|
569
669
|
|
570
670
|
out:
|
571
|
-
|
572
|
-
|
573
|
-
|
671
|
+
git_str_dispose(&path);
|
672
|
+
git_str_dispose(&repo_link);
|
673
|
+
git_str_dispose(&common_link);
|
574
674
|
return error;
|
575
675
|
}
|
576
676
|
|
@@ -578,18 +678,18 @@ int git_repository_open_bare(
|
|
578
678
|
git_repository **repo_ptr,
|
579
679
|
const char *bare_path)
|
580
680
|
{
|
581
|
-
|
681
|
+
git_str path = GIT_STR_INIT, common_path = GIT_STR_INIT;
|
582
682
|
git_repository *repo = NULL;
|
583
683
|
bool is_valid;
|
584
684
|
int error;
|
585
685
|
|
586
|
-
if ((error =
|
686
|
+
if ((error = git_fs_path_prettify_dir(&path, bare_path, NULL)) < 0 ||
|
587
687
|
(error = is_valid_repository_path(&is_valid, &path, &common_path)) < 0)
|
588
688
|
return error;
|
589
689
|
|
590
690
|
if (!is_valid) {
|
591
|
-
|
592
|
-
|
691
|
+
git_str_dispose(&path);
|
692
|
+
git_str_dispose(&common_path);
|
593
693
|
git_error_set(GIT_ERROR_REPOSITORY, "path is not a repository: %s", bare_path);
|
594
694
|
return GIT_ENOTFOUND;
|
595
695
|
}
|
@@ -597,9 +697,9 @@ int git_repository_open_bare(
|
|
597
697
|
repo = repository_alloc();
|
598
698
|
GIT_ERROR_CHECK_ALLOC(repo);
|
599
699
|
|
600
|
-
repo->gitdir =
|
700
|
+
repo->gitdir = git_str_detach(&path);
|
601
701
|
GIT_ERROR_CHECK_ALLOC(repo->gitdir);
|
602
|
-
repo->commondir =
|
702
|
+
repo->commondir = git_str_detach(&common_path);
|
603
703
|
GIT_ERROR_CHECK_ALLOC(repo->commondir);
|
604
704
|
|
605
705
|
/* of course we're bare! */
|
@@ -618,15 +718,15 @@ static int _git_repository_open_ext_from_env(
|
|
618
718
|
git_repository *repo = NULL;
|
619
719
|
git_index *index = NULL;
|
620
720
|
git_odb *odb = NULL;
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
721
|
+
git_str dir_buf = GIT_STR_INIT;
|
722
|
+
git_str ceiling_dirs_buf = GIT_STR_INIT;
|
723
|
+
git_str across_fs_buf = GIT_STR_INIT;
|
724
|
+
git_str index_file_buf = GIT_STR_INIT;
|
725
|
+
git_str namespace_buf = GIT_STR_INIT;
|
726
|
+
git_str object_dir_buf = GIT_STR_INIT;
|
727
|
+
git_str alts_buf = GIT_STR_INIT;
|
728
|
+
git_str work_tree_buf = GIT_STR_INIT;
|
729
|
+
git_str common_dir_buf = GIT_STR_INIT;
|
630
730
|
const char *ceiling_dirs = NULL;
|
631
731
|
unsigned flags = 0;
|
632
732
|
int error;
|
@@ -639,7 +739,7 @@ static int _git_repository_open_ext_from_env(
|
|
639
739
|
} else if (error < 0)
|
640
740
|
goto error;
|
641
741
|
else {
|
642
|
-
start_path =
|
742
|
+
start_path = git_str_cstr(&dir_buf);
|
643
743
|
flags |= GIT_REPOSITORY_OPEN_NO_SEARCH;
|
644
744
|
flags |= GIT_REPOSITORY_OPEN_NO_DOTGIT;
|
645
745
|
}
|
@@ -651,7 +751,7 @@ static int _git_repository_open_ext_from_env(
|
|
651
751
|
else if (error < 0)
|
652
752
|
goto error;
|
653
753
|
else
|
654
|
-
ceiling_dirs =
|
754
|
+
ceiling_dirs = git_str_cstr(&ceiling_dirs_buf);
|
655
755
|
|
656
756
|
error = git__getenv(&across_fs_buf, "GIT_DISCOVERY_ACROSS_FILESYSTEM");
|
657
757
|
if (error == GIT_ENOTFOUND)
|
@@ -660,7 +760,7 @@ static int _git_repository_open_ext_from_env(
|
|
660
760
|
goto error;
|
661
761
|
else {
|
662
762
|
int across_fs = 0;
|
663
|
-
error = git_config_parse_bool(&across_fs,
|
763
|
+
error = git_config_parse_bool(&across_fs, git_str_cstr(&across_fs_buf));
|
664
764
|
if (error < 0)
|
665
765
|
goto error;
|
666
766
|
if (across_fs)
|
@@ -673,7 +773,7 @@ static int _git_repository_open_ext_from_env(
|
|
673
773
|
else if (error < 0)
|
674
774
|
goto error;
|
675
775
|
else {
|
676
|
-
error = git_index_open(&index,
|
776
|
+
error = git_index_open(&index, git_str_cstr(&index_file_buf));
|
677
777
|
if (error < 0)
|
678
778
|
goto error;
|
679
779
|
}
|
@@ -690,7 +790,7 @@ static int _git_repository_open_ext_from_env(
|
|
690
790
|
else if (error < 0)
|
691
791
|
goto error;
|
692
792
|
else {
|
693
|
-
error = git_odb_open(&odb,
|
793
|
+
error = git_odb_open(&odb, git_str_cstr(&object_dir_buf));
|
694
794
|
if (error < 0)
|
695
795
|
goto error;
|
696
796
|
}
|
@@ -739,7 +839,7 @@ static int _git_repository_open_ext_from_env(
|
|
739
839
|
goto error;
|
740
840
|
}
|
741
841
|
|
742
|
-
end =
|
842
|
+
end = git_str_cstr(&alts_buf) + git_str_len(&alts_buf);
|
743
843
|
for (sep = alt = alts_buf.ptr; sep != end; alt = sep+1) {
|
744
844
|
for (sep = alt; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++)
|
745
845
|
;
|
@@ -751,8 +851,8 @@ static int _git_repository_open_ext_from_env(
|
|
751
851
|
}
|
752
852
|
}
|
753
853
|
|
754
|
-
if (
|
755
|
-
error = git_repository_set_namespace(repo,
|
854
|
+
if (git_str_len(&namespace_buf)) {
|
855
|
+
error = git_repository_set_namespace(repo, git_str_cstr(&namespace_buf));
|
756
856
|
if (error < 0)
|
757
857
|
goto error;
|
758
858
|
}
|
@@ -768,21 +868,21 @@ error:
|
|
768
868
|
success:
|
769
869
|
git_odb_free(odb);
|
770
870
|
git_index_free(index);
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
871
|
+
git_str_dispose(&common_dir_buf);
|
872
|
+
git_str_dispose(&work_tree_buf);
|
873
|
+
git_str_dispose(&alts_buf);
|
874
|
+
git_str_dispose(&object_dir_buf);
|
875
|
+
git_str_dispose(&namespace_buf);
|
876
|
+
git_str_dispose(&index_file_buf);
|
877
|
+
git_str_dispose(&across_fs_buf);
|
878
|
+
git_str_dispose(&ceiling_dirs_buf);
|
879
|
+
git_str_dispose(&dir_buf);
|
780
880
|
return error;
|
781
881
|
}
|
782
882
|
|
783
883
|
static int repo_is_worktree(unsigned *out, const git_repository *repo)
|
784
884
|
{
|
785
|
-
|
885
|
+
git_str gitdir_link = GIT_STR_INIT;
|
786
886
|
int error;
|
787
887
|
|
788
888
|
/* Worktrees cannot have the same commondir and gitdir */
|
@@ -792,14 +892,14 @@ static int repo_is_worktree(unsigned *out, const git_repository *repo)
|
|
792
892
|
return 0;
|
793
893
|
}
|
794
894
|
|
795
|
-
if ((error =
|
895
|
+
if ((error = git_str_joinpath(&gitdir_link, repo->gitdir, "gitdir")) < 0)
|
796
896
|
return -1;
|
797
897
|
|
798
898
|
/* A 'gitdir' file inside a git directory is currently
|
799
899
|
* only used when the repository is a working tree. */
|
800
|
-
*out = !!
|
900
|
+
*out = !!git_fs_path_exists(gitdir_link.ptr);
|
801
901
|
|
802
|
-
|
902
|
+
git_str_dispose(&gitdir_link);
|
803
903
|
return error;
|
804
904
|
}
|
805
905
|
|
@@ -811,10 +911,11 @@ int git_repository_open_ext(
|
|
811
911
|
{
|
812
912
|
int error;
|
813
913
|
unsigned is_worktree;
|
814
|
-
|
815
|
-
gitlink =
|
914
|
+
git_str gitdir = GIT_STR_INIT, workdir = GIT_STR_INIT,
|
915
|
+
gitlink = GIT_STR_INIT, commondir = GIT_STR_INIT;
|
816
916
|
git_repository *repo = NULL;
|
817
917
|
git_config *config = NULL;
|
918
|
+
const char *validation_path;
|
818
919
|
int version = 0;
|
819
920
|
|
820
921
|
if (flags & GIT_REPOSITORY_OPEN_FROM_ENV)
|
@@ -832,15 +933,15 @@ int git_repository_open_ext(
|
|
832
933
|
repo = repository_alloc();
|
833
934
|
GIT_ERROR_CHECK_ALLOC(repo);
|
834
935
|
|
835
|
-
repo->gitdir =
|
936
|
+
repo->gitdir = git_str_detach(&gitdir);
|
836
937
|
GIT_ERROR_CHECK_ALLOC(repo->gitdir);
|
837
938
|
|
838
939
|
if (gitlink.size) {
|
839
|
-
repo->gitlink =
|
940
|
+
repo->gitlink = git_str_detach(&gitlink);
|
840
941
|
GIT_ERROR_CHECK_ALLOC(repo->gitlink);
|
841
942
|
}
|
842
943
|
if (commondir.size) {
|
843
|
-
repo->commondir =
|
944
|
+
repo->commondir = git_str_detach(&commondir);
|
844
945
|
GIT_ERROR_CHECK_ALLOC(repo->commondir);
|
845
946
|
}
|
846
947
|
|
@@ -863,21 +964,29 @@ int git_repository_open_ext(
|
|
863
964
|
if ((error = check_extensions(config, version)) < 0)
|
864
965
|
goto cleanup;
|
865
966
|
|
866
|
-
if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0)
|
967
|
+
if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0) {
|
867
968
|
repo->is_bare = 1;
|
868
|
-
else {
|
869
|
-
|
969
|
+
} else {
|
870
970
|
if (config &&
|
871
971
|
((error = load_config_data(repo, config)) < 0 ||
|
872
972
|
(error = load_workdir(repo, config, &workdir)) < 0))
|
873
973
|
goto cleanup;
|
874
974
|
}
|
875
975
|
|
976
|
+
/*
|
977
|
+
* Ensure that the git directory is owned by the current user.
|
978
|
+
*/
|
979
|
+
validation_path = repo->is_bare ? repo->gitdir : repo->workdir;
|
980
|
+
|
981
|
+
if (git_repository__validate_ownership &&
|
982
|
+
(error = validate_ownership(validation_path)) < 0)
|
983
|
+
goto cleanup;
|
984
|
+
|
876
985
|
cleanup:
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
986
|
+
git_str_dispose(&gitdir);
|
987
|
+
git_str_dispose(&workdir);
|
988
|
+
git_str_dispose(&gitlink);
|
989
|
+
git_str_dispose(&commondir);
|
881
990
|
git_config_free(config);
|
882
991
|
|
883
992
|
if (error < 0)
|
@@ -896,12 +1005,13 @@ int git_repository_open(git_repository **repo_out, const char *path)
|
|
896
1005
|
|
897
1006
|
int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *wt)
|
898
1007
|
{
|
899
|
-
|
1008
|
+
git_str path = GIT_STR_INIT;
|
900
1009
|
git_repository *repo = NULL;
|
901
1010
|
size_t len;
|
902
1011
|
int err;
|
903
1012
|
|
904
|
-
|
1013
|
+
GIT_ASSERT_ARG(repo_out);
|
1014
|
+
GIT_ASSERT_ARG(wt);
|
905
1015
|
|
906
1016
|
*repo_out = NULL;
|
907
1017
|
len = strlen(wt->gitlink_path);
|
@@ -911,7 +1021,7 @@ int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *w
|
|
911
1021
|
goto out;
|
912
1022
|
}
|
913
1023
|
|
914
|
-
if ((err =
|
1024
|
+
if ((err = git_str_set(&path, wt->gitlink_path, len - 4)) < 0)
|
915
1025
|
goto out;
|
916
1026
|
|
917
1027
|
if ((err = git_repository_open(&repo, path.ptr)) < 0)
|
@@ -920,7 +1030,7 @@ int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *w
|
|
920
1030
|
*repo_out = repo;
|
921
1031
|
|
922
1032
|
out:
|
923
|
-
|
1033
|
+
git_str_dispose(&path);
|
924
1034
|
|
925
1035
|
return err;
|
926
1036
|
}
|
@@ -946,11 +1056,9 @@ int git_repository_discover(
|
|
946
1056
|
{
|
947
1057
|
uint32_t flags = across_fs ? GIT_REPOSITORY_OPEN_CROSS_FS : 0;
|
948
1058
|
|
949
|
-
|
950
|
-
|
951
|
-
git_buf_sanitize(out);
|
1059
|
+
GIT_ASSERT_ARG(start_path);
|
952
1060
|
|
953
|
-
|
1061
|
+
GIT_BUF_WRAP_PRIVATE(out, find_repo, NULL, NULL, NULL, start_path, flags, ceiling_dirs);
|
954
1062
|
}
|
955
1063
|
|
956
1064
|
static int load_config(
|
@@ -962,22 +1070,22 @@ static int load_config(
|
|
962
1070
|
const char *programdata_path)
|
963
1071
|
{
|
964
1072
|
int error;
|
965
|
-
|
1073
|
+
git_str config_path = GIT_STR_INIT;
|
966
1074
|
git_config *cfg = NULL;
|
967
1075
|
|
968
|
-
|
1076
|
+
GIT_ASSERT_ARG(out);
|
969
1077
|
|
970
1078
|
if ((error = git_config_new(&cfg)) < 0)
|
971
1079
|
return error;
|
972
1080
|
|
973
1081
|
if (repo) {
|
974
|
-
if ((error =
|
1082
|
+
if ((error = git_repository__item_path(&config_path, repo, GIT_REPOSITORY_ITEM_CONFIG)) == 0)
|
975
1083
|
error = git_config_add_file_ondisk(cfg, config_path.ptr, GIT_CONFIG_LEVEL_LOCAL, repo, 0);
|
976
1084
|
|
977
1085
|
if (error && error != GIT_ENOTFOUND)
|
978
1086
|
goto on_error;
|
979
1087
|
|
980
|
-
|
1088
|
+
git_str_dispose(&config_path);
|
981
1089
|
}
|
982
1090
|
|
983
1091
|
if (global_config_path != NULL &&
|
@@ -1010,15 +1118,15 @@ static int load_config(
|
|
1010
1118
|
return 0;
|
1011
1119
|
|
1012
1120
|
on_error:
|
1013
|
-
|
1121
|
+
git_str_dispose(&config_path);
|
1014
1122
|
git_config_free(cfg);
|
1015
1123
|
*out = NULL;
|
1016
1124
|
return error;
|
1017
1125
|
}
|
1018
1126
|
|
1019
|
-
static const char *path_unless_empty(
|
1127
|
+
static const char *path_unless_empty(git_str *buf)
|
1020
1128
|
{
|
1021
|
-
return
|
1129
|
+
return git_str_len(buf) > 0 ? git_str_cstr(buf) : NULL;
|
1022
1130
|
}
|
1023
1131
|
|
1024
1132
|
int git_repository_config__weakptr(git_config **out, git_repository *repo)
|
@@ -1026,19 +1134,19 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo)
|
|
1026
1134
|
int error = 0;
|
1027
1135
|
|
1028
1136
|
if (repo->_config == NULL) {
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1137
|
+
git_str global_buf = GIT_STR_INIT;
|
1138
|
+
git_str xdg_buf = GIT_STR_INIT;
|
1139
|
+
git_str system_buf = GIT_STR_INIT;
|
1140
|
+
git_str programdata_buf = GIT_STR_INIT;
|
1033
1141
|
git_config *config;
|
1034
1142
|
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1143
|
+
git_config__find_global(&global_buf);
|
1144
|
+
git_config__find_xdg(&xdg_buf);
|
1145
|
+
git_config__find_system(&system_buf);
|
1146
|
+
git_config__find_programdata(&programdata_buf);
|
1039
1147
|
|
1040
1148
|
/* If there is no global file, open a backend for it anyway */
|
1041
|
-
if (
|
1149
|
+
if (git_str_len(&global_buf) == 0)
|
1042
1150
|
git_config__global_location(&global_buf);
|
1043
1151
|
|
1044
1152
|
error = load_config(
|
@@ -1050,17 +1158,16 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo)
|
|
1050
1158
|
if (!error) {
|
1051
1159
|
GIT_REFCOUNT_OWN(config, repo);
|
1052
1160
|
|
1053
|
-
|
1054
|
-
if (config != NULL) {
|
1161
|
+
if (git_atomic_compare_and_swap(&repo->_config, NULL, config) != NULL) {
|
1055
1162
|
GIT_REFCOUNT_OWN(config, NULL);
|
1056
1163
|
git_config_free(config);
|
1057
1164
|
}
|
1058
1165
|
}
|
1059
1166
|
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1167
|
+
git_str_dispose(&global_buf);
|
1168
|
+
git_str_dispose(&xdg_buf);
|
1169
|
+
git_str_dispose(&system_buf);
|
1170
|
+
git_str_dispose(&programdata_buf);
|
1064
1171
|
}
|
1065
1172
|
|
1066
1173
|
*out = repo->_config;
|
@@ -1089,7 +1196,9 @@ int git_repository_config_snapshot(git_config **out, git_repository *repo)
|
|
1089
1196
|
|
1090
1197
|
int git_repository_set_config(git_repository *repo, git_config *config)
|
1091
1198
|
{
|
1092
|
-
|
1199
|
+
GIT_ASSERT_ARG(repo);
|
1200
|
+
GIT_ASSERT_ARG(config);
|
1201
|
+
|
1093
1202
|
set_config(repo, config);
|
1094
1203
|
return 0;
|
1095
1204
|
}
|
@@ -1098,13 +1207,15 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
|
|
1098
1207
|
{
|
1099
1208
|
int error = 0;
|
1100
1209
|
|
1101
|
-
|
1210
|
+
GIT_ASSERT_ARG(repo);
|
1211
|
+
GIT_ASSERT_ARG(out);
|
1102
1212
|
|
1103
|
-
|
1104
|
-
|
1213
|
+
*out = git_atomic_load(repo->_odb);
|
1214
|
+
if (*out == NULL) {
|
1215
|
+
git_str odb_path = GIT_STR_INIT;
|
1105
1216
|
git_odb *odb;
|
1106
1217
|
|
1107
|
-
if ((error =
|
1218
|
+
if ((error = git_repository__item_path(&odb_path, repo,
|
1108
1219
|
GIT_REPOSITORY_ITEM_OBJECTS)) < 0 ||
|
1109
1220
|
(error = git_odb_new(&odb)) < 0)
|
1110
1221
|
return error;
|
@@ -1117,16 +1228,15 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
|
|
1117
1228
|
return error;
|
1118
1229
|
}
|
1119
1230
|
|
1120
|
-
|
1121
|
-
if (odb != NULL) {
|
1231
|
+
if (git_atomic_compare_and_swap(&repo->_odb, NULL, odb) != NULL) {
|
1122
1232
|
GIT_REFCOUNT_OWN(odb, NULL);
|
1123
1233
|
git_odb_free(odb);
|
1124
1234
|
}
|
1125
1235
|
|
1126
|
-
|
1236
|
+
git_str_dispose(&odb_path);
|
1237
|
+
*out = git_atomic_load(repo->_odb);
|
1127
1238
|
}
|
1128
1239
|
|
1129
|
-
*out = repo->_odb;
|
1130
1240
|
return error;
|
1131
1241
|
}
|
1132
1242
|
|
@@ -1141,7 +1251,9 @@ int git_repository_odb(git_odb **out, git_repository *repo)
|
|
1141
1251
|
|
1142
1252
|
int git_repository_set_odb(git_repository *repo, git_odb *odb)
|
1143
1253
|
{
|
1144
|
-
|
1254
|
+
GIT_ASSERT_ARG(repo);
|
1255
|
+
GIT_ASSERT_ARG(odb);
|
1256
|
+
|
1145
1257
|
set_odb(repo, odb);
|
1146
1258
|
return 0;
|
1147
1259
|
}
|
@@ -1150,7 +1262,8 @@ int git_repository_refdb__weakptr(git_refdb **out, git_repository *repo)
|
|
1150
1262
|
{
|
1151
1263
|
int error = 0;
|
1152
1264
|
|
1153
|
-
|
1265
|
+
GIT_ASSERT_ARG(out);
|
1266
|
+
GIT_ASSERT_ARG(repo);
|
1154
1267
|
|
1155
1268
|
if (repo->_refdb == NULL) {
|
1156
1269
|
git_refdb *refdb;
|
@@ -1159,8 +1272,7 @@ int git_repository_refdb__weakptr(git_refdb **out, git_repository *repo)
|
|
1159
1272
|
if (!error) {
|
1160
1273
|
GIT_REFCOUNT_OWN(refdb, repo);
|
1161
1274
|
|
1162
|
-
|
1163
|
-
if (refdb != NULL) {
|
1275
|
+
if (git_atomic_compare_and_swap(&repo->_refdb, NULL, refdb) != NULL) {
|
1164
1276
|
GIT_REFCOUNT_OWN(refdb, NULL);
|
1165
1277
|
git_refdb_free(refdb);
|
1166
1278
|
}
|
@@ -1182,7 +1294,9 @@ int git_repository_refdb(git_refdb **out, git_repository *repo)
|
|
1182
1294
|
|
1183
1295
|
int git_repository_set_refdb(git_repository *repo, git_refdb *refdb)
|
1184
1296
|
{
|
1185
|
-
|
1297
|
+
GIT_ASSERT_ARG(repo);
|
1298
|
+
GIT_ASSERT_ARG(refdb);
|
1299
|
+
|
1186
1300
|
set_refdb(repo, refdb);
|
1187
1301
|
return 0;
|
1188
1302
|
}
|
@@ -1191,21 +1305,21 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo)
|
|
1191
1305
|
{
|
1192
1306
|
int error = 0;
|
1193
1307
|
|
1194
|
-
|
1308
|
+
GIT_ASSERT_ARG(out);
|
1309
|
+
GIT_ASSERT_ARG(repo);
|
1195
1310
|
|
1196
1311
|
if (repo->_index == NULL) {
|
1197
|
-
|
1312
|
+
git_str index_path = GIT_STR_INIT;
|
1198
1313
|
git_index *index;
|
1199
1314
|
|
1200
|
-
if ((error =
|
1315
|
+
if ((error = git_str_joinpath(&index_path, repo->gitdir, GIT_INDEX_FILE)) < 0)
|
1201
1316
|
return error;
|
1202
1317
|
|
1203
1318
|
error = git_index_open(&index, index_path.ptr);
|
1204
1319
|
if (!error) {
|
1205
1320
|
GIT_REFCOUNT_OWN(index, repo);
|
1206
1321
|
|
1207
|
-
|
1208
|
-
if (index != NULL) {
|
1322
|
+
if (git_atomic_compare_and_swap(&repo->_index, NULL, index) != NULL) {
|
1209
1323
|
GIT_REFCOUNT_OWN(index, NULL);
|
1210
1324
|
git_index_free(index);
|
1211
1325
|
}
|
@@ -1214,7 +1328,7 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo)
|
|
1214
1328
|
GIT_INDEX_CAPABILITY_FROM_OWNER);
|
1215
1329
|
}
|
1216
1330
|
|
1217
|
-
|
1331
|
+
git_str_dispose(&index_path);
|
1218
1332
|
}
|
1219
1333
|
|
1220
1334
|
*out = repo->_index;
|
@@ -1232,7 +1346,7 @@ int git_repository_index(git_index **out, git_repository *repo)
|
|
1232
1346
|
|
1233
1347
|
int git_repository_set_index(git_repository *repo, git_index *index)
|
1234
1348
|
{
|
1235
|
-
|
1349
|
+
GIT_ASSERT_ARG(repo);
|
1236
1350
|
set_index(repo, index);
|
1237
1351
|
return 0;
|
1238
1352
|
}
|
@@ -1262,7 +1376,7 @@ static int reserved_names_add8dot3(git_repository *repo, const char *path)
|
|
1262
1376
|
const char *def_dot_git = DOT_GIT;
|
1263
1377
|
size_t name_len, def_len = CONST_STRLEN(GIT_DIR_SHORTNAME);
|
1264
1378
|
size_t def_dot_git_len = CONST_STRLEN(DOT_GIT);
|
1265
|
-
|
1379
|
+
git_str *buf;
|
1266
1380
|
|
1267
1381
|
if (!name)
|
1268
1382
|
return 0;
|
@@ -1278,17 +1392,17 @@ static int reserved_names_add8dot3(git_repository *repo, const char *path)
|
|
1278
1392
|
if ((buf = git_array_alloc(repo->reserved_names)) == NULL)
|
1279
1393
|
return -1;
|
1280
1394
|
|
1281
|
-
|
1395
|
+
git_str_attach(buf, name, name_len);
|
1282
1396
|
return true;
|
1283
1397
|
}
|
1284
1398
|
|
1285
1399
|
bool git_repository__reserved_names(
|
1286
|
-
|
1400
|
+
git_str **out, size_t *outlen, git_repository *repo, bool include_ntfs)
|
1287
1401
|
{
|
1288
1402
|
GIT_UNUSED(include_ntfs);
|
1289
1403
|
|
1290
1404
|
if (repo->reserved_names.size == 0) {
|
1291
|
-
|
1405
|
+
git_str *buf;
|
1292
1406
|
size_t i;
|
1293
1407
|
|
1294
1408
|
/* Add the static defaults */
|
@@ -1340,7 +1454,7 @@ on_error:
|
|
1340
1454
|
}
|
1341
1455
|
#else
|
1342
1456
|
bool git_repository__reserved_names(
|
1343
|
-
|
1457
|
+
git_str **out, size_t *outlen, git_repository *repo, bool include_ntfs)
|
1344
1458
|
{
|
1345
1459
|
GIT_UNUSED(repo);
|
1346
1460
|
|
@@ -1378,15 +1492,60 @@ static int check_repositoryformatversion(int *version, git_config *config)
|
|
1378
1492
|
return 0;
|
1379
1493
|
}
|
1380
1494
|
|
1495
|
+
static const char *builtin_extensions[] = {
|
1496
|
+
"noop"
|
1497
|
+
};
|
1498
|
+
|
1499
|
+
static git_vector user_extensions = GIT_VECTOR_INIT;
|
1500
|
+
|
1381
1501
|
static int check_valid_extension(const git_config_entry *entry, void *payload)
|
1382
1502
|
{
|
1503
|
+
git_str cfg = GIT_STR_INIT;
|
1504
|
+
bool reject;
|
1505
|
+
const char *extension;
|
1506
|
+
size_t i;
|
1507
|
+
int error = 0;
|
1508
|
+
|
1383
1509
|
GIT_UNUSED(payload);
|
1384
1510
|
|
1385
|
-
|
1386
|
-
|
1511
|
+
git_vector_foreach (&user_extensions, i, extension) {
|
1512
|
+
git_str_clear(&cfg);
|
1513
|
+
|
1514
|
+
/*
|
1515
|
+
* Users can specify that they don't want to support an
|
1516
|
+
* extension with a '!' prefix.
|
1517
|
+
*/
|
1518
|
+
if ((reject = (extension[0] == '!')) == true)
|
1519
|
+
extension = &extension[1];
|
1520
|
+
|
1521
|
+
if ((error = git_str_printf(&cfg, "extensions.%s", extension)) < 0)
|
1522
|
+
goto done;
|
1523
|
+
|
1524
|
+
if (strcmp(entry->name, cfg.ptr) == 0) {
|
1525
|
+
if (reject)
|
1526
|
+
goto fail;
|
1527
|
+
|
1528
|
+
goto done;
|
1529
|
+
}
|
1530
|
+
}
|
1387
1531
|
|
1532
|
+
for (i = 0; i < ARRAY_SIZE(builtin_extensions); i++) {
|
1533
|
+
extension = builtin_extensions[i];
|
1534
|
+
|
1535
|
+
if ((error = git_str_printf(&cfg, "extensions.%s", extension)) < 0)
|
1536
|
+
goto done;
|
1537
|
+
|
1538
|
+
if (strcmp(entry->name, cfg.ptr) == 0)
|
1539
|
+
goto done;
|
1540
|
+
}
|
1541
|
+
|
1542
|
+
fail:
|
1388
1543
|
git_error_set(GIT_ERROR_REPOSITORY, "unsupported extension name %s", entry->name);
|
1389
|
-
|
1544
|
+
error = -1;
|
1545
|
+
|
1546
|
+
done:
|
1547
|
+
git_str_dispose(&cfg);
|
1548
|
+
return error;
|
1390
1549
|
}
|
1391
1550
|
|
1392
1551
|
static int check_extensions(git_config *config, int version)
|
@@ -1397,14 +1556,78 @@ static int check_extensions(git_config *config, int version)
|
|
1397
1556
|
return git_config_foreach_match(config, "^extensions\\.", check_valid_extension, NULL);
|
1398
1557
|
}
|
1399
1558
|
|
1559
|
+
int git_repository__extensions(char ***out, size_t *out_len)
|
1560
|
+
{
|
1561
|
+
git_vector extensions;
|
1562
|
+
const char *builtin, *user;
|
1563
|
+
char *extension;
|
1564
|
+
size_t i, j;
|
1565
|
+
|
1566
|
+
if (git_vector_init(&extensions, 8, NULL) < 0)
|
1567
|
+
return -1;
|
1568
|
+
|
1569
|
+
for (i = 0; i < ARRAY_SIZE(builtin_extensions); i++) {
|
1570
|
+
bool match = false;
|
1571
|
+
|
1572
|
+
builtin = builtin_extensions[i];
|
1573
|
+
|
1574
|
+
git_vector_foreach (&user_extensions, j, user) {
|
1575
|
+
if (user[0] == '!' && strcmp(builtin, &user[1]) == 0) {
|
1576
|
+
match = true;
|
1577
|
+
break;
|
1578
|
+
}
|
1579
|
+
}
|
1580
|
+
|
1581
|
+
if (match)
|
1582
|
+
continue;
|
1583
|
+
|
1584
|
+
if ((extension = git__strdup(builtin)) == NULL ||
|
1585
|
+
git_vector_insert(&extensions, extension) < 0)
|
1586
|
+
return -1;
|
1587
|
+
}
|
1588
|
+
|
1589
|
+
git_vector_foreach (&user_extensions, i, user) {
|
1590
|
+
if (user[0] == '!')
|
1591
|
+
continue;
|
1592
|
+
|
1593
|
+
if ((extension = git__strdup(user)) == NULL ||
|
1594
|
+
git_vector_insert(&extensions, extension) < 0)
|
1595
|
+
return -1;
|
1596
|
+
}
|
1597
|
+
|
1598
|
+
*out = (char **)git_vector_detach(out_len, NULL, &extensions);
|
1599
|
+
return 0;
|
1600
|
+
}
|
1601
|
+
|
1602
|
+
int git_repository__set_extensions(const char **extensions, size_t len)
|
1603
|
+
{
|
1604
|
+
char *extension;
|
1605
|
+
size_t i;
|
1606
|
+
|
1607
|
+
git_repository__free_extensions();
|
1608
|
+
|
1609
|
+
for (i = 0; i < len; i++) {
|
1610
|
+
if ((extension = git__strdup(extensions[i])) == NULL ||
|
1611
|
+
git_vector_insert(&user_extensions, extension) < 0)
|
1612
|
+
return -1;
|
1613
|
+
}
|
1614
|
+
|
1615
|
+
return 0;
|
1616
|
+
}
|
1617
|
+
|
1618
|
+
void git_repository__free_extensions(void)
|
1619
|
+
{
|
1620
|
+
git_vector_free_deep(&user_extensions);
|
1621
|
+
}
|
1622
|
+
|
1400
1623
|
int git_repository_create_head(const char *git_dir, const char *ref_name)
|
1401
1624
|
{
|
1402
|
-
|
1625
|
+
git_str ref_path = GIT_STR_INIT;
|
1403
1626
|
git_filebuf ref = GIT_FILEBUF_INIT;
|
1404
1627
|
const char *fmt;
|
1405
1628
|
int error;
|
1406
1629
|
|
1407
|
-
if ((error =
|
1630
|
+
if ((error = git_str_joinpath(&ref_path, git_dir, GIT_HEAD_FILE)) < 0 ||
|
1408
1631
|
(error = git_filebuf_open(&ref, ref_path.ptr, 0, GIT_REFS_FILE_MODE)) < 0)
|
1409
1632
|
goto out;
|
1410
1633
|
|
@@ -1418,7 +1641,7 @@ int git_repository_create_head(const char *git_dir, const char *ref_name)
|
|
1418
1641
|
goto out;
|
1419
1642
|
|
1420
1643
|
out:
|
1421
|
-
|
1644
|
+
git_str_dispose(&ref_path);
|
1422
1645
|
git_filebuf_cleanup(&ref);
|
1423
1646
|
return error;
|
1424
1647
|
}
|
@@ -1441,23 +1664,50 @@ static bool is_chmod_supported(const char *file_path)
|
|
1441
1664
|
|
1442
1665
|
static bool is_filesystem_case_insensitive(const char *gitdir_path)
|
1443
1666
|
{
|
1444
|
-
|
1667
|
+
git_str path = GIT_STR_INIT;
|
1445
1668
|
int is_insensitive = -1;
|
1446
1669
|
|
1447
|
-
if (!
|
1448
|
-
is_insensitive =
|
1670
|
+
if (!git_str_joinpath(&path, gitdir_path, "CoNfIg"))
|
1671
|
+
is_insensitive = git_fs_path_exists(git_str_cstr(&path));
|
1449
1672
|
|
1450
|
-
|
1673
|
+
git_str_dispose(&path);
|
1451
1674
|
return is_insensitive;
|
1452
1675
|
}
|
1453
1676
|
|
1677
|
+
/*
|
1678
|
+
* Return a configuration object with only the global and system
|
1679
|
+
* configurations; no repository-level configuration.
|
1680
|
+
*/
|
1681
|
+
static int load_global_config(git_config **config)
|
1682
|
+
{
|
1683
|
+
git_str global_buf = GIT_STR_INIT;
|
1684
|
+
git_str xdg_buf = GIT_STR_INIT;
|
1685
|
+
git_str system_buf = GIT_STR_INIT;
|
1686
|
+
git_str programdata_buf = GIT_STR_INIT;
|
1687
|
+
int error;
|
1688
|
+
|
1689
|
+
git_config__find_global(&global_buf);
|
1690
|
+
git_config__find_xdg(&xdg_buf);
|
1691
|
+
git_config__find_system(&system_buf);
|
1692
|
+
git_config__find_programdata(&programdata_buf);
|
1693
|
+
|
1694
|
+
error = load_config(config, NULL,
|
1695
|
+
path_unless_empty(&global_buf),
|
1696
|
+
path_unless_empty(&xdg_buf),
|
1697
|
+
path_unless_empty(&system_buf),
|
1698
|
+
path_unless_empty(&programdata_buf));
|
1699
|
+
|
1700
|
+
git_str_dispose(&global_buf);
|
1701
|
+
git_str_dispose(&xdg_buf);
|
1702
|
+
git_str_dispose(&system_buf);
|
1703
|
+
git_str_dispose(&programdata_buf);
|
1704
|
+
|
1705
|
+
return error;
|
1706
|
+
}
|
1707
|
+
|
1454
1708
|
static bool are_symlinks_supported(const char *wd_path)
|
1455
1709
|
{
|
1456
1710
|
git_config *config = NULL;
|
1457
|
-
git_buf global_buf = GIT_BUF_INIT;
|
1458
|
-
git_buf xdg_buf = GIT_BUF_INIT;
|
1459
|
-
git_buf system_buf = GIT_BUF_INIT;
|
1460
|
-
git_buf programdata_buf = GIT_BUF_INIT;
|
1461
1711
|
int symlinks = 0;
|
1462
1712
|
|
1463
1713
|
/*
|
@@ -1468,30 +1718,16 @@ static bool are_symlinks_supported(const char *wd_path)
|
|
1468
1718
|
* _not_ set, then we do not test or enable symlink support.
|
1469
1719
|
*/
|
1470
1720
|
#ifdef GIT_WIN32
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
git_config_find_programdata(&programdata_buf);
|
1475
|
-
|
1476
|
-
if (load_config(&config, NULL,
|
1477
|
-
path_unless_empty(&global_buf),
|
1478
|
-
path_unless_empty(&xdg_buf),
|
1479
|
-
path_unless_empty(&system_buf),
|
1480
|
-
path_unless_empty(&programdata_buf)) < 0)
|
1481
|
-
goto done;
|
1482
|
-
|
1483
|
-
if (git_config_get_bool(&symlinks, config, "core.symlinks") < 0 || !symlinks)
|
1721
|
+
if (load_global_config(&config) < 0 ||
|
1722
|
+
git_config_get_bool(&symlinks, config, "core.symlinks") < 0 ||
|
1723
|
+
!symlinks)
|
1484
1724
|
goto done;
|
1485
1725
|
#endif
|
1486
1726
|
|
1487
|
-
if (!(symlinks =
|
1727
|
+
if (!(symlinks = git_fs_path_supports_symlinks(wd_path)))
|
1488
1728
|
goto done;
|
1489
1729
|
|
1490
1730
|
done:
|
1491
|
-
git_buf_dispose(&global_buf);
|
1492
|
-
git_buf_dispose(&xdg_buf);
|
1493
|
-
git_buf_dispose(&system_buf);
|
1494
|
-
git_buf_dispose(&programdata_buf);
|
1495
1731
|
git_config_free(config);
|
1496
1732
|
return symlinks != 0;
|
1497
1733
|
}
|
@@ -1515,7 +1751,7 @@ static int create_empty_file(const char *path, mode_t mode)
|
|
1515
1751
|
|
1516
1752
|
static int repo_local_config(
|
1517
1753
|
git_config **out,
|
1518
|
-
|
1754
|
+
git_str *config_dir,
|
1519
1755
|
git_repository *repo,
|
1520
1756
|
const char *repo_dir)
|
1521
1757
|
{
|
@@ -1523,12 +1759,12 @@ static int repo_local_config(
|
|
1523
1759
|
git_config *parent;
|
1524
1760
|
const char *cfg_path;
|
1525
1761
|
|
1526
|
-
if (
|
1762
|
+
if (git_str_joinpath(config_dir, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0)
|
1527
1763
|
return -1;
|
1528
|
-
cfg_path =
|
1764
|
+
cfg_path = git_str_cstr(config_dir);
|
1529
1765
|
|
1530
1766
|
/* make LOCAL config if missing */
|
1531
|
-
if (!
|
1767
|
+
if (!git_fs_path_isfile(cfg_path) &&
|
1532
1768
|
(error = create_empty_file(cfg_path, GIT_CONFIG_FILE_MODE)) < 0)
|
1533
1769
|
return error;
|
1534
1770
|
|
@@ -1586,7 +1822,7 @@ static int repo_init_fs_configs(
|
|
1586
1822
|
#ifdef GIT_USE_ICONV
|
1587
1823
|
if ((error = git_config_set_bool(
|
1588
1824
|
cfg, "core.precomposeunicode",
|
1589
|
-
|
1825
|
+
git_fs_path_does_decompose_unicode(work_dir))) < 0)
|
1590
1826
|
return error;
|
1591
1827
|
/* on non-iconv platforms, don't even set core.precomposeunicode */
|
1592
1828
|
#endif
|
@@ -1601,7 +1837,7 @@ static int repo_init_config(
|
|
1601
1837
|
uint32_t mode)
|
1602
1838
|
{
|
1603
1839
|
int error = 0;
|
1604
|
-
|
1840
|
+
git_str cfg_path = GIT_STR_INIT, worktree_path = GIT_STR_INIT;
|
1605
1841
|
git_config *config = NULL;
|
1606
1842
|
bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0);
|
1607
1843
|
bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0);
|
@@ -1631,11 +1867,11 @@ static int repo_init_config(
|
|
1631
1867
|
SET_REPO_CONFIG(bool, "core.logallrefupdates", true);
|
1632
1868
|
|
1633
1869
|
if (!(flags & GIT_REPOSITORY_INIT__NATURAL_WD)) {
|
1634
|
-
if ((error =
|
1870
|
+
if ((error = git_str_sets(&worktree_path, work_dir)) < 0)
|
1635
1871
|
goto cleanup;
|
1636
1872
|
|
1637
1873
|
if ((flags & GIT_REPOSITORY_INIT_RELATIVE_GITLINK))
|
1638
|
-
if ((error =
|
1874
|
+
if ((error = git_fs_path_make_relative(&worktree_path, repo_dir)) < 0)
|
1639
1875
|
goto cleanup;
|
1640
1876
|
|
1641
1877
|
SET_REPO_CONFIG(string, "core.worktree", worktree_path.ptr);
|
@@ -1655,8 +1891,8 @@ static int repo_init_config(
|
|
1655
1891
|
}
|
1656
1892
|
|
1657
1893
|
cleanup:
|
1658
|
-
|
1659
|
-
|
1894
|
+
git_str_dispose(&cfg_path);
|
1895
|
+
git_str_dispose(&worktree_path);
|
1660
1896
|
git_config_free(config);
|
1661
1897
|
|
1662
1898
|
return error;
|
@@ -1678,7 +1914,7 @@ static int repo_reinit_submodule_fs(git_submodule *sm, const char *n, void *p)
|
|
1678
1914
|
int git_repository_reinit_filesystem(git_repository *repo, int recurse)
|
1679
1915
|
{
|
1680
1916
|
int error = 0;
|
1681
|
-
|
1917
|
+
git_str path = GIT_STR_INIT;
|
1682
1918
|
git_config *config = NULL;
|
1683
1919
|
const char *repo_dir = git_repository_path(repo);
|
1684
1920
|
|
@@ -1687,7 +1923,7 @@ int git_repository_reinit_filesystem(git_repository *repo, int recurse)
|
|
1687
1923
|
config, path.ptr, repo_dir, git_repository_workdir(repo), true);
|
1688
1924
|
|
1689
1925
|
git_config_free(config);
|
1690
|
-
|
1926
|
+
git_str_dispose(&path);
|
1691
1927
|
|
1692
1928
|
git_repository__configmap_lookup_cache_clear(repo);
|
1693
1929
|
|
@@ -1705,10 +1941,10 @@ static int repo_write_template(
|
|
1705
1941
|
bool hidden,
|
1706
1942
|
const char *content)
|
1707
1943
|
{
|
1708
|
-
|
1944
|
+
git_str path = GIT_STR_INIT;
|
1709
1945
|
int fd, error = 0, flags;
|
1710
1946
|
|
1711
|
-
if (
|
1947
|
+
if (git_str_joinpath(&path, git_dir, file) < 0)
|
1712
1948
|
return -1;
|
1713
1949
|
|
1714
1950
|
if (allow_overwrite)
|
@@ -1716,7 +1952,7 @@ static int repo_write_template(
|
|
1716
1952
|
else
|
1717
1953
|
flags = O_WRONLY | O_CREAT | O_EXCL;
|
1718
1954
|
|
1719
|
-
fd = p_open(
|
1955
|
+
fd = p_open(git_str_cstr(&path), flags, mode);
|
1720
1956
|
|
1721
1957
|
if (fd >= 0) {
|
1722
1958
|
error = p_write(fd, content, strlen(content));
|
@@ -1735,7 +1971,7 @@ static int repo_write_template(
|
|
1735
1971
|
GIT_UNUSED(hidden);
|
1736
1972
|
#endif
|
1737
1973
|
|
1738
|
-
|
1974
|
+
git_str_dispose(&path);
|
1739
1975
|
|
1740
1976
|
if (error)
|
1741
1977
|
git_error_set(GIT_ERROR_OS,
|
@@ -1748,13 +1984,13 @@ static int repo_write_gitlink(
|
|
1748
1984
|
const char *in_dir, const char *to_repo, bool use_relative_path)
|
1749
1985
|
{
|
1750
1986
|
int error;
|
1751
|
-
|
1752
|
-
|
1987
|
+
git_str buf = GIT_STR_INIT;
|
1988
|
+
git_str path_to_repo = GIT_STR_INIT;
|
1753
1989
|
struct stat st;
|
1754
1990
|
|
1755
|
-
|
1756
|
-
|
1757
|
-
if (
|
1991
|
+
git_fs_path_dirname_r(&buf, to_repo);
|
1992
|
+
git_fs_path_to_dir(&buf);
|
1993
|
+
if (git_str_oom(&buf))
|
1758
1994
|
return -1;
|
1759
1995
|
|
1760
1996
|
/* don't write gitlink to natural workdir */
|
@@ -1765,7 +2001,7 @@ static int repo_write_gitlink(
|
|
1765
2001
|
goto cleanup;
|
1766
2002
|
}
|
1767
2003
|
|
1768
|
-
if ((error =
|
2004
|
+
if ((error = git_str_joinpath(&buf, in_dir, DOT_GIT)) < 0)
|
1769
2005
|
goto cleanup;
|
1770
2006
|
|
1771
2007
|
if (!p_stat(buf.ptr, &st) && !S_ISREG(st.st_mode)) {
|
@@ -1775,22 +2011,22 @@ static int repo_write_gitlink(
|
|
1775
2011
|
goto cleanup;
|
1776
2012
|
}
|
1777
2013
|
|
1778
|
-
|
2014
|
+
git_str_clear(&buf);
|
1779
2015
|
|
1780
|
-
error =
|
2016
|
+
error = git_str_sets(&path_to_repo, to_repo);
|
1781
2017
|
|
1782
2018
|
if (!error && use_relative_path)
|
1783
|
-
error =
|
2019
|
+
error = git_fs_path_make_relative(&path_to_repo, in_dir);
|
1784
2020
|
|
1785
2021
|
if (!error)
|
1786
|
-
error =
|
2022
|
+
error = git_str_join(&buf, ' ', GIT_FILE_CONTENT_PREFIX, path_to_repo.ptr);
|
1787
2023
|
|
1788
2024
|
if (!error)
|
1789
2025
|
error = repo_write_template(in_dir, true, DOT_GIT, 0666, true, buf.ptr);
|
1790
2026
|
|
1791
2027
|
cleanup:
|
1792
|
-
|
1793
|
-
|
2028
|
+
git_str_dispose(&buf);
|
2029
|
+
git_str_dispose(&path_to_repo);
|
1794
2030
|
return error;
|
1795
2031
|
}
|
1796
2032
|
|
@@ -1843,12 +2079,12 @@ static int repo_init_structure(
|
|
1843
2079
|
git_config *cfg = NULL;
|
1844
2080
|
const char *tdir = NULL;
|
1845
2081
|
bool default_template = false;
|
1846
|
-
|
2082
|
+
git_str template_buf = GIT_STR_INIT;
|
1847
2083
|
|
1848
2084
|
if (opts->template_path)
|
1849
2085
|
tdir = opts->template_path;
|
1850
2086
|
else if ((error = git_config_open_default(&cfg)) >= 0) {
|
1851
|
-
if (!
|
2087
|
+
if (!git_config__get_path(&template_buf, cfg, "init.templatedir"))
|
1852
2088
|
tdir = template_buf.ptr;
|
1853
2089
|
git_error_clear();
|
1854
2090
|
}
|
@@ -1874,11 +2110,16 @@ static int repo_init_structure(
|
|
1874
2110
|
error = git_futils_cp_r(tdir, repo_dir, cpflags, dmode);
|
1875
2111
|
}
|
1876
2112
|
|
1877
|
-
|
2113
|
+
git_str_dispose(&template_buf);
|
1878
2114
|
git_config_free(cfg);
|
1879
2115
|
|
2116
|
+
/* If tdir does not exist, then do not error out. This matches the
|
2117
|
+
* behaviour of git(1), which just prints a warning and continues.
|
2118
|
+
* TODO: issue warning when warning API is available.
|
2119
|
+
* `git` prints to stderr: 'warning: templates not found in /path/to/tdir'
|
2120
|
+
*/
|
1880
2121
|
if (error < 0) {
|
1881
|
-
if (!default_template)
|
2122
|
+
if (!default_template && error != GIT_ENOTFOUND)
|
1882
2123
|
return error;
|
1883
2124
|
|
1884
2125
|
/* if template was default, ignore error and use internal */
|
@@ -1915,7 +2156,7 @@ static int repo_init_structure(
|
|
1915
2156
|
return error;
|
1916
2157
|
}
|
1917
2158
|
|
1918
|
-
static int mkdir_parent(
|
2159
|
+
static int mkdir_parent(git_str *buf, uint32_t mode, bool skip2)
|
1919
2160
|
{
|
1920
2161
|
/* When making parent directories during repository initialization
|
1921
2162
|
* don't try to set gid or grant world write access
|
@@ -1927,8 +2168,8 @@ static int mkdir_parent(git_buf *buf, uint32_t mode, bool skip2)
|
|
1927
2168
|
}
|
1928
2169
|
|
1929
2170
|
static int repo_init_directories(
|
1930
|
-
|
1931
|
-
|
2171
|
+
git_str *repo_path,
|
2172
|
+
git_str *wd_path,
|
1932
2173
|
const char *given_repo,
|
1933
2174
|
git_repository_init_options *opts)
|
1934
2175
|
{
|
@@ -1966,7 +2207,7 @@ static int repo_init_directories(
|
|
1966
2207
|
git__suffixcmp(given_repo, "/" DOT_GIT) != 0 &&
|
1967
2208
|
git__suffixcmp(given_repo, "/" GIT_DIR) != 0;
|
1968
2209
|
|
1969
|
-
if (
|
2210
|
+
if (git_str_joinpath(repo_path, given_repo, add_dotgit ? GIT_DIR : "") < 0)
|
1970
2211
|
return -1;
|
1971
2212
|
|
1972
2213
|
has_dotgit = (git__suffixcmp(repo_path->ptr, "/" GIT_DIR) == 0);
|
@@ -1977,11 +2218,11 @@ static int repo_init_directories(
|
|
1977
2218
|
|
1978
2219
|
if (!is_bare) {
|
1979
2220
|
if (opts->workdir_path) {
|
1980
|
-
if (
|
2221
|
+
if (git_fs_path_join_unrooted(
|
1981
2222
|
wd_path, opts->workdir_path, repo_path->ptr, NULL) < 0)
|
1982
2223
|
return -1;
|
1983
2224
|
} else if (has_dotgit) {
|
1984
|
-
if (
|
2225
|
+
if (git_fs_path_dirname_r(wd_path, repo_path->ptr) < 0)
|
1985
2226
|
return -1;
|
1986
2227
|
} else {
|
1987
2228
|
git_error_set(GIT_ERROR_REPOSITORY, "cannot pick working directory"
|
@@ -1989,10 +2230,10 @@ static int repo_init_directories(
|
|
1989
2230
|
return -1;
|
1990
2231
|
}
|
1991
2232
|
|
1992
|
-
if (
|
2233
|
+
if (git_fs_path_to_dir(wd_path) < 0)
|
1993
2234
|
return -1;
|
1994
2235
|
} else {
|
1995
|
-
|
2236
|
+
git_str_clear(wd_path);
|
1996
2237
|
}
|
1997
2238
|
|
1998
2239
|
natural_wd =
|
@@ -2049,10 +2290,10 @@ static int repo_init_directories(
|
|
2049
2290
|
/* prettify both directories now that they are created */
|
2050
2291
|
|
2051
2292
|
if (!error) {
|
2052
|
-
error =
|
2293
|
+
error = git_fs_path_prettify_dir(repo_path, repo_path->ptr, NULL);
|
2053
2294
|
|
2054
2295
|
if (!error && wd_path->size > 0)
|
2055
|
-
error =
|
2296
|
+
error = git_fs_path_prettify_dir(wd_path, wd_path->ptr, NULL);
|
2056
2297
|
}
|
2057
2298
|
|
2058
2299
|
return error;
|
@@ -2061,24 +2302,24 @@ static int repo_init_directories(
|
|
2061
2302
|
static int repo_init_head(const char *repo_dir, const char *given)
|
2062
2303
|
{
|
2063
2304
|
git_config *cfg = NULL;
|
2064
|
-
|
2305
|
+
git_str head_path = GIT_STR_INIT, cfg_branch = GIT_STR_INIT;
|
2065
2306
|
const char *initial_head = NULL;
|
2066
2307
|
int error;
|
2067
2308
|
|
2068
|
-
if ((error =
|
2309
|
+
if ((error = git_str_joinpath(&head_path, repo_dir, GIT_HEAD_FILE)) < 0)
|
2069
2310
|
goto out;
|
2070
2311
|
|
2071
2312
|
/*
|
2072
2313
|
* A template may have set a HEAD; use that unless it's been
|
2073
2314
|
* overridden by the caller's given initial head setting.
|
2074
2315
|
*/
|
2075
|
-
if (
|
2316
|
+
if (git_fs_path_exists(head_path.ptr) && !given)
|
2076
2317
|
goto out;
|
2077
2318
|
|
2078
2319
|
if (given) {
|
2079
2320
|
initial_head = given;
|
2080
2321
|
} else if ((error = git_config_open_default(&cfg)) >= 0 &&
|
2081
|
-
(error =
|
2322
|
+
(error = git_config__get_string_buf(&cfg_branch, cfg, "init.defaultbranch")) >= 0 &&
|
2082
2323
|
*cfg_branch.ptr) {
|
2083
2324
|
initial_head = cfg_branch.ptr;
|
2084
2325
|
}
|
@@ -2090,8 +2331,8 @@ static int repo_init_head(const char *repo_dir, const char *given)
|
|
2090
2331
|
|
2091
2332
|
out:
|
2092
2333
|
git_config_free(cfg);
|
2093
|
-
|
2094
|
-
|
2334
|
+
git_str_dispose(&head_path);
|
2335
|
+
git_str_dispose(&cfg_branch);
|
2095
2336
|
|
2096
2337
|
return error;
|
2097
2338
|
}
|
@@ -2125,20 +2366,22 @@ int git_repository_init_ext(
|
|
2125
2366
|
const char *given_repo,
|
2126
2367
|
git_repository_init_options *opts)
|
2127
2368
|
{
|
2128
|
-
|
2129
|
-
common_path =
|
2369
|
+
git_str repo_path = GIT_STR_INIT, wd_path = GIT_STR_INIT,
|
2370
|
+
common_path = GIT_STR_INIT;
|
2130
2371
|
const char *wd;
|
2131
2372
|
bool is_valid;
|
2132
2373
|
int error;
|
2133
2374
|
|
2134
|
-
|
2375
|
+
GIT_ASSERT_ARG(out);
|
2376
|
+
GIT_ASSERT_ARG(given_repo);
|
2377
|
+
GIT_ASSERT_ARG(opts);
|
2135
2378
|
|
2136
2379
|
GIT_ERROR_CHECK_VERSION(opts, GIT_REPOSITORY_INIT_OPTIONS_VERSION, "git_repository_init_options");
|
2137
2380
|
|
2138
2381
|
if ((error = repo_init_directories(&repo_path, &wd_path, given_repo, opts)) < 0)
|
2139
2382
|
goto out;
|
2140
2383
|
|
2141
|
-
wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL :
|
2384
|
+
wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_str_cstr(&wd_path);
|
2142
2385
|
|
2143
2386
|
if ((error = is_valid_repository_path(&is_valid, &repo_path, &common_path)) < 0)
|
2144
2387
|
goto out;
|
@@ -2172,9 +2415,9 @@ int git_repository_init_ext(
|
|
2172
2415
|
goto out;
|
2173
2416
|
|
2174
2417
|
out:
|
2175
|
-
|
2176
|
-
|
2177
|
-
|
2418
|
+
git_str_dispose(&common_path);
|
2419
|
+
git_str_dispose(&repo_path);
|
2420
|
+
git_str_dispose(&wd_path);
|
2178
2421
|
|
2179
2422
|
return error;
|
2180
2423
|
}
|
@@ -2207,7 +2450,8 @@ int git_repository_head_detached_for_worktree(git_repository *repo, const char *
|
|
2207
2450
|
git_reference *ref = NULL;
|
2208
2451
|
int error;
|
2209
2452
|
|
2210
|
-
|
2453
|
+
GIT_ASSERT_ARG(repo);
|
2454
|
+
GIT_ASSERT_ARG(name);
|
2211
2455
|
|
2212
2456
|
if ((error = git_repository_head_for_worktree(&ref, repo, name)) < 0)
|
2213
2457
|
goto out;
|
@@ -2224,7 +2468,7 @@ int git_repository_head(git_reference **head_out, git_repository *repo)
|
|
2224
2468
|
git_reference *head;
|
2225
2469
|
int error;
|
2226
2470
|
|
2227
|
-
|
2471
|
+
GIT_ASSERT_ARG(head_out);
|
2228
2472
|
|
2229
2473
|
if ((error = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0)
|
2230
2474
|
return error;
|
@@ -2247,7 +2491,9 @@ int git_repository_head_for_worktree(git_reference **out, git_repository *repo,
|
|
2247
2491
|
git_reference *head = NULL;
|
2248
2492
|
int error;
|
2249
2493
|
|
2250
|
-
|
2494
|
+
GIT_ASSERT_ARG(out);
|
2495
|
+
GIT_ASSERT_ARG(repo);
|
2496
|
+
GIT_ASSERT_ARG(name);
|
2251
2497
|
|
2252
2498
|
*out = NULL;
|
2253
2499
|
|
@@ -2281,6 +2527,12 @@ int git_repository_foreach_worktree(git_repository *repo,
|
|
2281
2527
|
int error;
|
2282
2528
|
size_t i;
|
2283
2529
|
|
2530
|
+
/* apply operation to repository supplied when commondir is empty, implying there's
|
2531
|
+
* no linked worktrees to iterate, which can occur when using custom odb/refdb
|
2532
|
+
*/
|
2533
|
+
if (!repo->commondir)
|
2534
|
+
return cb(repo, payload);
|
2535
|
+
|
2284
2536
|
if ((error = git_repository_open(&worktree_repo, repo->commondir)) < 0 ||
|
2285
2537
|
(error = cb(worktree_repo, payload) != 0))
|
2286
2538
|
goto out;
|
@@ -2353,12 +2605,12 @@ static int repo_contains_no_reference(git_repository *repo)
|
|
2353
2605
|
return error;
|
2354
2606
|
}
|
2355
2607
|
|
2356
|
-
int git_repository_initialbranch(
|
2608
|
+
int git_repository_initialbranch(git_str *out, git_repository *repo)
|
2357
2609
|
{
|
2358
2610
|
git_config *config;
|
2359
2611
|
git_config_entry *entry = NULL;
|
2360
2612
|
const char *branch;
|
2361
|
-
int error;
|
2613
|
+
int valid, error;
|
2362
2614
|
|
2363
2615
|
if ((error = git_repository_config__weakptr(&config, repo)) < 0)
|
2364
2616
|
return error;
|
@@ -2374,11 +2626,12 @@ int git_repository_initialbranch(git_buf *out, git_repository *repo)
|
|
2374
2626
|
goto done;
|
2375
2627
|
}
|
2376
2628
|
|
2377
|
-
if ((error =
|
2378
|
-
(error =
|
2629
|
+
if ((error = git_str_puts(out, GIT_REFS_HEADS_DIR)) < 0 ||
|
2630
|
+
(error = git_str_puts(out, branch)) < 0 ||
|
2631
|
+
(error = git_reference_name_is_valid(&valid, out->ptr)) < 0)
|
2379
2632
|
goto done;
|
2380
2633
|
|
2381
|
-
if (!
|
2634
|
+
if (!valid) {
|
2382
2635
|
git_error_set(GIT_ERROR_INVALID, "the value of init.defaultBranch is not a valid branch name");
|
2383
2636
|
error = -1;
|
2384
2637
|
}
|
@@ -2391,7 +2644,7 @@ done:
|
|
2391
2644
|
int git_repository_is_empty(git_repository *repo)
|
2392
2645
|
{
|
2393
2646
|
git_reference *head = NULL;
|
2394
|
-
|
2647
|
+
git_str initialbranch = GIT_STR_INIT;
|
2395
2648
|
int result = 0;
|
2396
2649
|
|
2397
2650
|
if ((result = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0 ||
|
@@ -2404,7 +2657,7 @@ int git_repository_is_empty(git_repository *repo)
|
|
2404
2657
|
|
2405
2658
|
done:
|
2406
2659
|
git_reference_free(head);
|
2407
|
-
|
2660
|
+
git_str_dispose(&initialbranch);
|
2408
2661
|
|
2409
2662
|
return result;
|
2410
2663
|
}
|
@@ -2433,7 +2686,18 @@ static const char *resolved_parent_path(const git_repository *repo, git_reposito
|
|
2433
2686
|
return parent;
|
2434
2687
|
}
|
2435
2688
|
|
2436
|
-
int git_repository_item_path(
|
2689
|
+
int git_repository_item_path(
|
2690
|
+
git_buf *out,
|
2691
|
+
const git_repository *repo,
|
2692
|
+
git_repository_item_t item)
|
2693
|
+
{
|
2694
|
+
GIT_BUF_WRAP_PRIVATE(out, git_repository__item_path, repo, item);
|
2695
|
+
}
|
2696
|
+
|
2697
|
+
int git_repository__item_path(
|
2698
|
+
git_str *out,
|
2699
|
+
const git_repository *repo,
|
2700
|
+
git_repository_item_t item)
|
2437
2701
|
{
|
2438
2702
|
const char *parent = resolved_parent_path(repo, items[item].parent, items[item].fallback);
|
2439
2703
|
if (parent == NULL) {
|
@@ -2441,16 +2705,16 @@ int git_repository_item_path(git_buf *out, const git_repository *repo, git_repos
|
|
2441
2705
|
return GIT_ENOTFOUND;
|
2442
2706
|
}
|
2443
2707
|
|
2444
|
-
if (
|
2708
|
+
if (git_str_sets(out, parent) < 0)
|
2445
2709
|
return -1;
|
2446
2710
|
|
2447
2711
|
if (items[item].name) {
|
2448
|
-
if (
|
2712
|
+
if (git_str_joinpath(out, parent, items[item].name) < 0)
|
2449
2713
|
return -1;
|
2450
2714
|
}
|
2451
2715
|
|
2452
2716
|
if (items[item].directory) {
|
2453
|
-
if (
|
2717
|
+
if (git_fs_path_to_dir(out) < 0)
|
2454
2718
|
return -1;
|
2455
2719
|
}
|
2456
2720
|
|
@@ -2459,13 +2723,13 @@ int git_repository_item_path(git_buf *out, const git_repository *repo, git_repos
|
|
2459
2723
|
|
2460
2724
|
const char *git_repository_path(const git_repository *repo)
|
2461
2725
|
{
|
2462
|
-
|
2726
|
+
GIT_ASSERT_ARG_WITH_RETVAL(repo, NULL);
|
2463
2727
|
return repo->gitdir;
|
2464
2728
|
}
|
2465
2729
|
|
2466
2730
|
const char *git_repository_workdir(const git_repository *repo)
|
2467
2731
|
{
|
2468
|
-
|
2732
|
+
GIT_ASSERT_ARG_WITH_RETVAL(repo, NULL);
|
2469
2733
|
|
2470
2734
|
if (repo->is_bare)
|
2471
2735
|
return NULL;
|
@@ -2473,9 +2737,25 @@ const char *git_repository_workdir(const git_repository *repo)
|
|
2473
2737
|
return repo->workdir;
|
2474
2738
|
}
|
2475
2739
|
|
2740
|
+
int git_repository_workdir_path(
|
2741
|
+
git_str *out, git_repository *repo, const char *path)
|
2742
|
+
{
|
2743
|
+
int error;
|
2744
|
+
|
2745
|
+
if (!repo->workdir) {
|
2746
|
+
git_error_set(GIT_ERROR_REPOSITORY, "repository has no working directory");
|
2747
|
+
return GIT_EBAREREPO;
|
2748
|
+
}
|
2749
|
+
|
2750
|
+
if (!(error = git_str_joinpath(out, repo->workdir, path)))
|
2751
|
+
error = git_path_validate_str_length(repo, out);
|
2752
|
+
|
2753
|
+
return error;
|
2754
|
+
}
|
2755
|
+
|
2476
2756
|
const char *git_repository_commondir(const git_repository *repo)
|
2477
2757
|
{
|
2478
|
-
|
2758
|
+
GIT_ASSERT_ARG_WITH_RETVAL(repo, NULL);
|
2479
2759
|
return repo->commondir;
|
2480
2760
|
}
|
2481
2761
|
|
@@ -2483,11 +2763,12 @@ int git_repository_set_workdir(
|
|
2483
2763
|
git_repository *repo, const char *workdir, int update_gitlink)
|
2484
2764
|
{
|
2485
2765
|
int error = 0;
|
2486
|
-
|
2766
|
+
git_str path = GIT_STR_INIT;
|
2487
2767
|
|
2488
|
-
|
2768
|
+
GIT_ASSERT_ARG(repo);
|
2769
|
+
GIT_ASSERT_ARG(workdir);
|
2489
2770
|
|
2490
|
-
if (
|
2771
|
+
if (git_fs_path_prettify_dir(&path, workdir, NULL) < 0)
|
2491
2772
|
return -1;
|
2492
2773
|
|
2493
2774
|
if (repo->workdir && strcmp(repo->workdir, path.ptr) == 0)
|
@@ -2514,7 +2795,7 @@ int git_repository_set_workdir(
|
|
2514
2795
|
if (!error) {
|
2515
2796
|
char *old_workdir = repo->workdir;
|
2516
2797
|
|
2517
|
-
repo->workdir =
|
2798
|
+
repo->workdir = git_str_detach(&path);
|
2518
2799
|
repo->is_bare = 0;
|
2519
2800
|
|
2520
2801
|
git__free(old_workdir);
|
@@ -2525,13 +2806,13 @@ int git_repository_set_workdir(
|
|
2525
2806
|
|
2526
2807
|
int git_repository_is_bare(const git_repository *repo)
|
2527
2808
|
{
|
2528
|
-
|
2809
|
+
GIT_ASSERT_ARG(repo);
|
2529
2810
|
return repo->is_bare;
|
2530
2811
|
}
|
2531
2812
|
|
2532
2813
|
int git_repository_is_worktree(const git_repository *repo)
|
2533
2814
|
{
|
2534
|
-
|
2815
|
+
GIT_ASSERT_ARG(repo);
|
2535
2816
|
return repo->is_worktree;
|
2536
2817
|
}
|
2537
2818
|
|
@@ -2540,7 +2821,7 @@ int git_repository_set_bare(git_repository *repo)
|
|
2540
2821
|
int error;
|
2541
2822
|
git_config *config;
|
2542
2823
|
|
2543
|
-
|
2824
|
+
GIT_ASSERT_ARG(repo);
|
2544
2825
|
|
2545
2826
|
if (repo->is_bare)
|
2546
2827
|
return 0;
|
@@ -2583,13 +2864,13 @@ cleanup:
|
|
2583
2864
|
int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head)
|
2584
2865
|
{
|
2585
2866
|
git_filebuf file = GIT_FILEBUF_INIT;
|
2586
|
-
|
2867
|
+
git_str file_path = GIT_STR_INIT;
|
2587
2868
|
char orig_head_str[GIT_OID_HEXSZ];
|
2588
2869
|
int error = 0;
|
2589
2870
|
|
2590
2871
|
git_oid_fmt(orig_head_str, orig_head);
|
2591
2872
|
|
2592
|
-
if ((error =
|
2873
|
+
if ((error = git_str_joinpath(&file_path, repo->gitdir, GIT_ORIG_HEAD_FILE)) == 0 &&
|
2593
2874
|
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) == 0 &&
|
2594
2875
|
(error = git_filebuf_printf(&file, "%.*s\n", GIT_OID_HEXSZ, orig_head_str)) == 0)
|
2595
2876
|
error = git_filebuf_commit(&file);
|
@@ -2597,45 +2878,48 @@ int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head
|
|
2597
2878
|
if (error < 0)
|
2598
2879
|
git_filebuf_cleanup(&file);
|
2599
2880
|
|
2600
|
-
|
2881
|
+
git_str_dispose(&file_path);
|
2601
2882
|
|
2602
2883
|
return error;
|
2603
2884
|
}
|
2604
2885
|
|
2605
|
-
int
|
2886
|
+
static int git_repository__message(git_str *out, git_repository *repo)
|
2606
2887
|
{
|
2607
|
-
|
2888
|
+
git_str path = GIT_STR_INIT;
|
2608
2889
|
struct stat st;
|
2609
2890
|
int error;
|
2610
2891
|
|
2611
|
-
|
2612
|
-
|
2613
|
-
if (git_buf_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0)
|
2892
|
+
if (git_str_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0)
|
2614
2893
|
return -1;
|
2615
2894
|
|
2616
|
-
if ((error = p_stat(
|
2895
|
+
if ((error = p_stat(git_str_cstr(&path), &st)) < 0) {
|
2617
2896
|
if (errno == ENOENT)
|
2618
2897
|
error = GIT_ENOTFOUND;
|
2619
2898
|
git_error_set(GIT_ERROR_OS, "could not access message file");
|
2620
2899
|
} else {
|
2621
|
-
error = git_futils_readbuffer(out,
|
2900
|
+
error = git_futils_readbuffer(out, git_str_cstr(&path));
|
2622
2901
|
}
|
2623
2902
|
|
2624
|
-
|
2903
|
+
git_str_dispose(&path);
|
2625
2904
|
|
2626
2905
|
return error;
|
2627
2906
|
}
|
2628
2907
|
|
2908
|
+
int git_repository_message(git_buf *out, git_repository *repo)
|
2909
|
+
{
|
2910
|
+
GIT_BUF_WRAP_PRIVATE(out, git_repository__message, repo);
|
2911
|
+
}
|
2912
|
+
|
2629
2913
|
int git_repository_message_remove(git_repository *repo)
|
2630
2914
|
{
|
2631
|
-
|
2915
|
+
git_str path = GIT_STR_INIT;
|
2632
2916
|
int error;
|
2633
2917
|
|
2634
|
-
if (
|
2918
|
+
if (git_str_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0)
|
2635
2919
|
return -1;
|
2636
2920
|
|
2637
|
-
error = p_unlink(
|
2638
|
-
|
2921
|
+
error = p_unlink(git_str_cstr(&path));
|
2922
|
+
git_str_dispose(&path);
|
2639
2923
|
|
2640
2924
|
return error;
|
2641
2925
|
}
|
@@ -2651,32 +2935,37 @@ int git_repository_hashfile(
|
|
2651
2935
|
git_filter_list *fl = NULL;
|
2652
2936
|
git_file fd = -1;
|
2653
2937
|
uint64_t len;
|
2654
|
-
|
2938
|
+
git_str full_path = GIT_STR_INIT;
|
2939
|
+
const char *workdir = git_repository_workdir(repo);
|
2655
2940
|
|
2656
|
-
|
2657
|
-
|
2658
|
-
|
2659
|
-
|
2660
|
-
* now that is not possible because git_filters_load() needs it.
|
2661
|
-
*/
|
2941
|
+
/* as_path can be NULL */
|
2942
|
+
GIT_ASSERT_ARG(out);
|
2943
|
+
GIT_ASSERT_ARG(path);
|
2944
|
+
GIT_ASSERT_ARG(repo);
|
2662
2945
|
|
2663
|
-
error =
|
2664
|
-
|
2665
|
-
if (error < 0)
|
2946
|
+
if ((error = git_fs_path_join_unrooted(&full_path, path, workdir, NULL)) < 0 ||
|
2947
|
+
(error = git_path_validate_str_length(repo, &full_path)) < 0)
|
2666
2948
|
return error;
|
2667
2949
|
|
2668
|
-
|
2669
|
-
|
2950
|
+
/*
|
2951
|
+
* NULL as_path means that we should derive it from the
|
2952
|
+
* given path.
|
2953
|
+
*/
|
2954
|
+
if (!as_path) {
|
2955
|
+
if (workdir && !git__prefixcmp(full_path.ptr, workdir))
|
2956
|
+
as_path = full_path.ptr + strlen(workdir);
|
2957
|
+
else
|
2958
|
+
as_path = "";
|
2959
|
+
}
|
2670
2960
|
|
2671
2961
|
/* passing empty string for "as_path" indicated --no-filters */
|
2672
2962
|
if (strlen(as_path) > 0) {
|
2673
2963
|
error = git_filter_list_load(
|
2674
2964
|
&fl, repo, NULL, as_path,
|
2675
2965
|
GIT_FILTER_TO_ODB, GIT_FILTER_DEFAULT);
|
2966
|
+
|
2676
2967
|
if (error < 0)
|
2677
2968
|
return error;
|
2678
|
-
} else {
|
2679
|
-
error = 0;
|
2680
2969
|
}
|
2681
2970
|
|
2682
2971
|
/* at this point, error is a count of the number of loaded filters */
|
@@ -2702,30 +2991,30 @@ cleanup:
|
|
2702
2991
|
if (fd >= 0)
|
2703
2992
|
p_close(fd);
|
2704
2993
|
git_filter_list_free(fl);
|
2705
|
-
|
2994
|
+
git_str_dispose(&full_path);
|
2706
2995
|
|
2707
2996
|
return error;
|
2708
2997
|
}
|
2709
2998
|
|
2710
|
-
static int checkout_message(
|
2999
|
+
static int checkout_message(git_str *out, git_reference *old, const char *new)
|
2711
3000
|
{
|
2712
|
-
|
3001
|
+
git_str_puts(out, "checkout: moving from ");
|
2713
3002
|
|
2714
3003
|
if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC)
|
2715
|
-
|
3004
|
+
git_str_puts(out, git_reference__shorthand(git_reference_symbolic_target(old)));
|
2716
3005
|
else
|
2717
|
-
|
3006
|
+
git_str_puts(out, git_oid_tostr_s(git_reference_target(old)));
|
2718
3007
|
|
2719
|
-
|
3008
|
+
git_str_puts(out, " to ");
|
2720
3009
|
|
2721
3010
|
if (git_reference__is_branch(new) ||
|
2722
3011
|
git_reference__is_tag(new) ||
|
2723
3012
|
git_reference__is_remote(new))
|
2724
|
-
|
3013
|
+
git_str_puts(out, git_reference__shorthand(new));
|
2725
3014
|
else
|
2726
|
-
|
3015
|
+
git_str_puts(out, new);
|
2727
3016
|
|
2728
|
-
if (
|
3017
|
+
if (git_str_oom(out))
|
2729
3018
|
return -1;
|
2730
3019
|
|
2731
3020
|
return 0;
|
@@ -2734,11 +3023,12 @@ static int checkout_message(git_buf *out, git_reference *old, const char *new)
|
|
2734
3023
|
static int detach(git_repository *repo, const git_oid *id, const char *new)
|
2735
3024
|
{
|
2736
3025
|
int error;
|
2737
|
-
|
3026
|
+
git_str log_message = GIT_STR_INIT;
|
2738
3027
|
git_object *object = NULL, *peeled = NULL;
|
2739
3028
|
git_reference *new_head = NULL, *current = NULL;
|
2740
3029
|
|
2741
|
-
|
3030
|
+
GIT_ASSERT_ARG(repo);
|
3031
|
+
GIT_ASSERT_ARG(id);
|
2742
3032
|
|
2743
3033
|
if ((error = git_reference_lookup(¤t, repo, GIT_HEAD_FILE)) < 0)
|
2744
3034
|
return error;
|
@@ -2755,10 +3045,10 @@ static int detach(git_repository *repo, const git_oid *id, const char *new)
|
|
2755
3045
|
if ((error = checkout_message(&log_message, current, new)) < 0)
|
2756
3046
|
goto cleanup;
|
2757
3047
|
|
2758
|
-
error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true,
|
3048
|
+
error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, git_str_cstr(&log_message));
|
2759
3049
|
|
2760
3050
|
cleanup:
|
2761
|
-
|
3051
|
+
git_str_dispose(&log_message);
|
2762
3052
|
git_object_free(object);
|
2763
3053
|
git_object_free(peeled);
|
2764
3054
|
git_reference_free(current);
|
@@ -2767,14 +3057,15 @@ cleanup:
|
|
2767
3057
|
}
|
2768
3058
|
|
2769
3059
|
int git_repository_set_head(
|
2770
|
-
git_repository*
|
2771
|
-
const char*
|
3060
|
+
git_repository *repo,
|
3061
|
+
const char *refname)
|
2772
3062
|
{
|
2773
3063
|
git_reference *ref = NULL, *current = NULL, *new_head = NULL;
|
2774
|
-
|
3064
|
+
git_str log_message = GIT_STR_INIT;
|
2775
3065
|
int error;
|
2776
3066
|
|
2777
|
-
|
3067
|
+
GIT_ASSERT_ARG(repo);
|
3068
|
+
GIT_ASSERT_ARG(refname);
|
2778
3069
|
|
2779
3070
|
if ((error = git_reference_lookup(¤t, repo, GIT_HEAD_FILE)) < 0)
|
2780
3071
|
return error;
|
@@ -2797,18 +3088,18 @@ int git_repository_set_head(
|
|
2797
3088
|
if (!error) {
|
2798
3089
|
if (git_reference_is_branch(ref)) {
|
2799
3090
|
error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE,
|
2800
|
-
git_reference_name(ref), true,
|
3091
|
+
git_reference_name(ref), true, git_str_cstr(&log_message));
|
2801
3092
|
} else {
|
2802
3093
|
error = detach(repo, git_reference_target(ref),
|
2803
3094
|
git_reference_is_tag(ref) || git_reference_is_remote(ref) ? refname : NULL);
|
2804
3095
|
}
|
2805
3096
|
} else if (git_reference__is_branch(refname)) {
|
2806
3097
|
error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname,
|
2807
|
-
true,
|
3098
|
+
true, git_str_cstr(&log_message));
|
2808
3099
|
}
|
2809
3100
|
|
2810
3101
|
cleanup:
|
2811
|
-
|
3102
|
+
git_str_dispose(&log_message);
|
2812
3103
|
git_reference_free(current);
|
2813
3104
|
git_reference_free(ref);
|
2814
3105
|
git_reference_free(new_head);
|
@@ -2816,29 +3107,30 @@ cleanup:
|
|
2816
3107
|
}
|
2817
3108
|
|
2818
3109
|
int git_repository_set_head_detached(
|
2819
|
-
git_repository*
|
2820
|
-
const git_oid*
|
3110
|
+
git_repository *repo,
|
3111
|
+
const git_oid *committish)
|
2821
3112
|
{
|
2822
|
-
return detach(repo,
|
3113
|
+
return detach(repo, committish, NULL);
|
2823
3114
|
}
|
2824
3115
|
|
2825
3116
|
int git_repository_set_head_detached_from_annotated(
|
2826
3117
|
git_repository *repo,
|
2827
|
-
const git_annotated_commit *
|
3118
|
+
const git_annotated_commit *committish)
|
2828
3119
|
{
|
2829
|
-
|
3120
|
+
GIT_ASSERT_ARG(repo);
|
3121
|
+
GIT_ASSERT_ARG(committish);
|
2830
3122
|
|
2831
|
-
return detach(repo, git_annotated_commit_id(
|
3123
|
+
return detach(repo, git_annotated_commit_id(committish), committish->description);
|
2832
3124
|
}
|
2833
3125
|
|
2834
|
-
int git_repository_detach_head(git_repository*
|
3126
|
+
int git_repository_detach_head(git_repository *repo)
|
2835
3127
|
{
|
2836
3128
|
git_reference *old_head = NULL, *new_head = NULL, *current = NULL;
|
2837
3129
|
git_object *object = NULL;
|
2838
|
-
|
3130
|
+
git_str log_message = GIT_STR_INIT;
|
2839
3131
|
int error;
|
2840
3132
|
|
2841
|
-
|
3133
|
+
GIT_ASSERT_ARG(repo);
|
2842
3134
|
|
2843
3135
|
if ((error = git_reference_lookup(¤t, repo, GIT_HEAD_FILE)) < 0)
|
2844
3136
|
return error;
|
@@ -2853,10 +3145,10 @@ int git_repository_detach_head(git_repository* repo)
|
|
2853
3145
|
goto cleanup;
|
2854
3146
|
|
2855
3147
|
error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head),
|
2856
|
-
1,
|
3148
|
+
1, git_str_cstr(&log_message));
|
2857
3149
|
|
2858
3150
|
cleanup:
|
2859
|
-
|
3151
|
+
git_str_dispose(&log_message);
|
2860
3152
|
git_object_free(object);
|
2861
3153
|
git_reference_free(old_head);
|
2862
3154
|
git_reference_free(new_head);
|
@@ -2870,69 +3162,69 @@ cleanup:
|
|
2870
3162
|
*/
|
2871
3163
|
int git_repository_state(git_repository *repo)
|
2872
3164
|
{
|
2873
|
-
|
3165
|
+
git_str repo_path = GIT_STR_INIT;
|
2874
3166
|
int state = GIT_REPOSITORY_STATE_NONE;
|
2875
3167
|
|
2876
|
-
|
3168
|
+
GIT_ASSERT_ARG(repo);
|
2877
3169
|
|
2878
|
-
if (
|
3170
|
+
if (git_str_puts(&repo_path, repo->gitdir) < 0)
|
2879
3171
|
return -1;
|
2880
3172
|
|
2881
|
-
if (
|
3173
|
+
if (git_fs_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE))
|
2882
3174
|
state = GIT_REPOSITORY_STATE_REBASE_INTERACTIVE;
|
2883
|
-
else if (
|
3175
|
+
else if (git_fs_path_contains_dir(&repo_path, GIT_REBASE_MERGE_DIR))
|
2884
3176
|
state = GIT_REPOSITORY_STATE_REBASE_MERGE;
|
2885
|
-
else if (
|
3177
|
+
else if (git_fs_path_contains_file(&repo_path, GIT_REBASE_APPLY_REBASING_FILE))
|
2886
3178
|
state = GIT_REPOSITORY_STATE_REBASE;
|
2887
|
-
else if (
|
3179
|
+
else if (git_fs_path_contains_file(&repo_path, GIT_REBASE_APPLY_APPLYING_FILE))
|
2888
3180
|
state = GIT_REPOSITORY_STATE_APPLY_MAILBOX;
|
2889
|
-
else if (
|
3181
|
+
else if (git_fs_path_contains_dir(&repo_path, GIT_REBASE_APPLY_DIR))
|
2890
3182
|
state = GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE;
|
2891
|
-
else if (
|
3183
|
+
else if (git_fs_path_contains_file(&repo_path, GIT_MERGE_HEAD_FILE))
|
2892
3184
|
state = GIT_REPOSITORY_STATE_MERGE;
|
2893
|
-
else if (
|
3185
|
+
else if (git_fs_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE)) {
|
2894
3186
|
state = GIT_REPOSITORY_STATE_REVERT;
|
2895
|
-
if (
|
3187
|
+
if (git_fs_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) {
|
2896
3188
|
state = GIT_REPOSITORY_STATE_REVERT_SEQUENCE;
|
2897
3189
|
}
|
2898
|
-
} else if (
|
3190
|
+
} else if (git_fs_path_contains_file(&repo_path, GIT_CHERRYPICK_HEAD_FILE)) {
|
2899
3191
|
state = GIT_REPOSITORY_STATE_CHERRYPICK;
|
2900
|
-
if (
|
3192
|
+
if (git_fs_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) {
|
2901
3193
|
state = GIT_REPOSITORY_STATE_CHERRYPICK_SEQUENCE;
|
2902
3194
|
}
|
2903
|
-
} else if (
|
3195
|
+
} else if (git_fs_path_contains_file(&repo_path, GIT_BISECT_LOG_FILE))
|
2904
3196
|
state = GIT_REPOSITORY_STATE_BISECT;
|
2905
3197
|
|
2906
|
-
|
3198
|
+
git_str_dispose(&repo_path);
|
2907
3199
|
return state;
|
2908
3200
|
}
|
2909
3201
|
|
2910
3202
|
int git_repository__cleanup_files(
|
2911
3203
|
git_repository *repo, const char *files[], size_t files_len)
|
2912
3204
|
{
|
2913
|
-
|
3205
|
+
git_str buf = GIT_STR_INIT;
|
2914
3206
|
size_t i;
|
2915
3207
|
int error;
|
2916
3208
|
|
2917
3209
|
for (error = 0, i = 0; !error && i < files_len; ++i) {
|
2918
3210
|
const char *path;
|
2919
3211
|
|
2920
|
-
if (
|
3212
|
+
if (git_str_joinpath(&buf, repo->gitdir, files[i]) < 0)
|
2921
3213
|
return -1;
|
2922
3214
|
|
2923
|
-
path =
|
3215
|
+
path = git_str_cstr(&buf);
|
2924
3216
|
|
2925
|
-
if (
|
3217
|
+
if (git_fs_path_isfile(path)) {
|
2926
3218
|
error = p_unlink(path);
|
2927
|
-
} else if (
|
3219
|
+
} else if (git_fs_path_isdir(path)) {
|
2928
3220
|
error = git_futils_rmdir_r(path, NULL,
|
2929
3221
|
GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_REMOVE_BLOCKERS);
|
2930
3222
|
}
|
2931
3223
|
|
2932
|
-
|
3224
|
+
git_str_clear(&buf);
|
2933
3225
|
}
|
2934
3226
|
|
2935
|
-
|
3227
|
+
git_str_dispose(&buf);
|
2936
3228
|
return error;
|
2937
3229
|
}
|
2938
3230
|
|
@@ -2950,22 +3242,22 @@ static const char *state_files[] = {
|
|
2950
3242
|
|
2951
3243
|
int git_repository_state_cleanup(git_repository *repo)
|
2952
3244
|
{
|
2953
|
-
|
3245
|
+
GIT_ASSERT_ARG(repo);
|
2954
3246
|
|
2955
3247
|
return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files));
|
2956
3248
|
}
|
2957
3249
|
|
2958
3250
|
int git_repository_is_shallow(git_repository *repo)
|
2959
3251
|
{
|
2960
|
-
|
3252
|
+
git_str path = GIT_STR_INIT;
|
2961
3253
|
struct stat st;
|
2962
3254
|
int error;
|
2963
3255
|
|
2964
|
-
if ((error =
|
3256
|
+
if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0)
|
2965
3257
|
return error;
|
2966
3258
|
|
2967
|
-
error =
|
2968
|
-
|
3259
|
+
error = git_fs_path_lstat(path.ptr, &st);
|
3260
|
+
git_str_dispose(&path);
|
2969
3261
|
|
2970
3262
|
if (error == GIT_ENOTFOUND) {
|
2971
3263
|
git_error_clear();
|
@@ -3016,8 +3308,8 @@ int git_repository_set_ident(git_repository *repo, const char *name, const char
|
|
3016
3308
|
GIT_ERROR_CHECK_ALLOC(tmp_email);
|
3017
3309
|
}
|
3018
3310
|
|
3019
|
-
tmp_name =
|
3020
|
-
tmp_email =
|
3311
|
+
tmp_name = git_atomic_swap(repo->ident_name, tmp_name);
|
3312
|
+
tmp_email = git_atomic_swap(repo->ident_email, tmp_email);
|
3021
3313
|
|
3022
3314
|
git__free(tmp_name);
|
3023
3315
|
git__free(tmp_email);
|
@@ -3027,28 +3319,16 @@ int git_repository_set_ident(git_repository *repo, const char *name, const char
|
|
3027
3319
|
|
3028
3320
|
int git_repository_submodule_cache_all(git_repository *repo)
|
3029
3321
|
{
|
3030
|
-
|
3031
|
-
|
3032
|
-
assert(repo);
|
3033
|
-
|
3034
|
-
if ((error = git_strmap_new(&repo->submodule_cache)))
|
3035
|
-
return error;
|
3036
|
-
|
3037
|
-
error = git_submodule__map(repo, repo->submodule_cache);
|
3038
|
-
return error;
|
3322
|
+
GIT_ASSERT_ARG(repo);
|
3323
|
+
return git_submodule_cache_init(&repo->submodule_cache, repo);
|
3039
3324
|
}
|
3040
3325
|
|
3041
3326
|
int git_repository_submodule_cache_clear(git_repository *repo)
|
3042
3327
|
{
|
3043
|
-
|
3044
|
-
|
3045
|
-
|
3046
|
-
|
3047
|
-
|
3048
|
-
|
3049
|
-
git_submodule_free(sm);
|
3050
|
-
});
|
3051
|
-
git_strmap_free(repo->submodule_cache);
|
3052
|
-
repo->submodule_cache = 0;
|
3053
|
-
return 0;
|
3328
|
+
int error = 0;
|
3329
|
+
GIT_ASSERT_ARG(repo);
|
3330
|
+
|
3331
|
+
error = git_submodule_cache_free(repo->submodule_cache);
|
3332
|
+
repo->submodule_cache = NULL;
|
3333
|
+
return error;
|
3054
3334
|
}
|