rugged 0.19.0 → 0.28.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +1 -1
- data/README.md +184 -33
- data/ext/rugged/extconf.rb +111 -28
- data/ext/rugged/rugged.c +327 -89
- data/ext/rugged/rugged.h +64 -28
- data/ext/rugged/rugged_allocator.c +89 -0
- data/ext/rugged/rugged_backend.c +17 -0
- data/ext/rugged/rugged_blame.c +278 -0
- data/ext/rugged/rugged_blob.c +301 -75
- data/ext/rugged/rugged_branch.c +92 -242
- data/ext/rugged/rugged_branch_collection.c +388 -0
- data/ext/rugged/rugged_commit.c +575 -79
- data/ext/rugged/rugged_config.c +129 -36
- data/ext/rugged/rugged_cred.c +131 -0
- data/ext/rugged/rugged_diff.c +291 -122
- data/ext/rugged/rugged_diff_delta.c +16 -22
- data/ext/rugged/rugged_diff_hunk.c +35 -51
- data/ext/rugged/rugged_diff_line.c +23 -36
- data/ext/rugged/rugged_index.c +289 -152
- data/ext/rugged/rugged_note.c +50 -60
- data/ext/rugged/rugged_object.c +13 -30
- data/ext/rugged/rugged_patch.c +400 -0
- data/ext/rugged/rugged_rebase.c +397 -0
- data/ext/rugged/rugged_reference.c +76 -346
- data/ext/rugged/rugged_reference_collection.c +423 -0
- data/ext/rugged/rugged_remote.c +438 -461
- data/ext/rugged/rugged_remote_collection.c +435 -0
- data/ext/rugged/rugged_repo.c +1548 -365
- data/ext/rugged/rugged_revwalk.c +378 -99
- data/ext/rugged/rugged_settings.c +86 -23
- data/ext/rugged/rugged_signature.c +47 -37
- data/ext/rugged/rugged_submodule.c +835 -0
- data/ext/rugged/rugged_submodule_collection.c +366 -0
- data/ext/rugged/rugged_tag.c +88 -210
- data/ext/rugged/rugged_tag_collection.c +326 -0
- data/ext/rugged/rugged_tree.c +460 -217
- data/lib/rugged/attributes.rb +46 -0
- data/lib/rugged/blob.rb +33 -0
- data/lib/rugged/branch.rb +12 -16
- data/lib/rugged/commit.rb +9 -0
- data/lib/rugged/console.rb +5 -0
- data/lib/rugged/credentials.rb +48 -0
- data/lib/rugged/diff/delta.rb +6 -2
- data/lib/rugged/diff/hunk.rb +9 -9
- data/lib/rugged/diff/line.rb +28 -5
- data/lib/rugged/diff.rb +7 -1
- data/lib/rugged/index.rb +120 -0
- data/lib/rugged/object.rb +5 -0
- data/lib/rugged/patch.rb +41 -0
- data/lib/rugged/reference.rb +6 -3
- data/lib/rugged/remote.rb +5 -9
- data/lib/rugged/repository.rb +126 -14
- data/lib/rugged/submodule_collection.rb +53 -0
- data/lib/rugged/tag.rb +45 -16
- data/lib/rugged/tree.rb +163 -1
- data/lib/rugged/version.rb +6 -1
- data/lib/rugged/walker.rb +5 -0
- data/lib/rugged.rb +16 -1
- data/vendor/libgit2/AUTHORS +77 -0
- data/vendor/libgit2/CMakeLists.txt +317 -0
- data/vendor/libgit2/COPYING +993 -0
- data/vendor/libgit2/cmake/Modules/AddCFlagIfSupported.cmake +30 -0
- data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.c.in +29 -0
- data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.cmake +96 -0
- data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +11 -0
- data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +26 -0
- data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +324 -0
- data/vendor/libgit2/cmake/Modules/FindHTTP_Parser.cmake +39 -0
- data/vendor/libgit2/cmake/Modules/FindIconv.cmake +45 -0
- data/vendor/libgit2/cmake/Modules/FindPkgLibraries.cmake +28 -0
- data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +28 -0
- data/vendor/libgit2/cmake/Modules/FindStatNsec.cmake +20 -0
- data/vendor/libgit2/cmake/Modules/FindmbedTLS.cmake +93 -0
- data/vendor/libgit2/cmake/Modules/IdeSplitSources.cmake +22 -0
- data/vendor/libgit2/deps/http-parser/CMakeLists.txt +5 -0
- data/vendor/libgit2/deps/http-parser/COPYING +23 -0
- data/vendor/libgit2/deps/http-parser/http_parser.c +5 -2
- data/vendor/libgit2/deps/http-parser/http_parser.h +2 -0
- data/vendor/libgit2/deps/regex/CMakeLists.txt +2 -0
- data/vendor/libgit2/deps/regex/COPYING +502 -0
- data/vendor/libgit2/deps/regex/regex.c +10 -3
- data/vendor/libgit2/deps/winhttp/CMakeLists.txt +26 -0
- data/vendor/libgit2/deps/winhttp/COPYING.GPL +993 -0
- data/vendor/libgit2/deps/winhttp/COPYING.LGPL +502 -0
- data/vendor/libgit2/deps/winhttp/urlmon.h +45 -0
- data/vendor/libgit2/deps/winhttp/winhttp.def +29 -0
- data/vendor/libgit2/deps/winhttp/winhttp.h +594 -0
- data/vendor/libgit2/deps/winhttp/winhttp64.def +29 -0
- data/vendor/libgit2/deps/zlib/CMakeLists.txt +5 -0
- data/vendor/libgit2/deps/zlib/COPYING +27 -0
- data/vendor/libgit2/deps/zlib/adler32.c +51 -34
- data/vendor/libgit2/deps/zlib/crc32.c +61 -61
- data/vendor/libgit2/deps/zlib/crc32.h +1 -1
- data/vendor/libgit2/deps/zlib/deflate.c +681 -352
- data/vendor/libgit2/deps/zlib/deflate.h +25 -18
- data/vendor/libgit2/deps/zlib/gzguts.h +218 -0
- data/vendor/libgit2/deps/zlib/infback.c +640 -0
- data/vendor/libgit2/deps/zlib/inffast.c +36 -53
- data/vendor/libgit2/deps/zlib/inffixed.h +3 -3
- data/vendor/libgit2/deps/zlib/inflate.c +167 -86
- data/vendor/libgit2/deps/zlib/inflate.h +7 -4
- data/vendor/libgit2/deps/zlib/inftrees.c +24 -50
- data/vendor/libgit2/deps/zlib/trees.c +55 -96
- data/vendor/libgit2/deps/zlib/zconf.h +499 -19
- data/vendor/libgit2/deps/zlib/zlib.h +526 -227
- data/vendor/libgit2/deps/zlib/zutil.c +39 -32
- data/vendor/libgit2/deps/zlib/zutil.h +75 -78
- data/vendor/libgit2/include/git2/annotated_commit.h +125 -0
- data/vendor/libgit2/include/git2/apply.h +129 -0
- data/vendor/libgit2/include/git2/attr.h +36 -21
- data/vendor/libgit2/include/git2/blame.h +229 -0
- data/vendor/libgit2/include/git2/blob.h +81 -44
- data/vendor/libgit2/include/git2/branch.h +81 -42
- data/vendor/libgit2/include/git2/buffer.h +128 -0
- data/vendor/libgit2/include/git2/checkout.h +141 -67
- data/vendor/libgit2/include/git2/cherrypick.h +92 -0
- data/vendor/libgit2/include/git2/clone.h +157 -58
- data/vendor/libgit2/include/git2/commit.h +231 -12
- data/vendor/libgit2/include/git2/common.h +216 -30
- data/vendor/libgit2/include/git2/config.h +274 -48
- data/vendor/libgit2/include/git2/cred_helpers.h +4 -4
- data/vendor/libgit2/include/git2/deprecated.h +253 -0
- data/vendor/libgit2/include/git2/describe.h +189 -0
- data/vendor/libgit2/include/git2/diff.h +985 -575
- data/vendor/libgit2/include/git2/errors.h +93 -52
- data/vendor/libgit2/include/git2/filter.h +217 -0
- data/vendor/libgit2/include/git2/global.h +44 -0
- data/vendor/libgit2/include/git2/graph.h +17 -0
- data/vendor/libgit2/include/git2/ignore.h +2 -2
- data/vendor/libgit2/include/git2/index.h +269 -94
- data/vendor/libgit2/include/git2/indexer.h +44 -12
- data/vendor/libgit2/include/git2/mailmap.h +115 -0
- data/vendor/libgit2/include/git2/merge.h +501 -64
- data/vendor/libgit2/include/git2/message.h +52 -17
- data/vendor/libgit2/include/git2/net.h +11 -5
- data/vendor/libgit2/include/git2/notes.h +120 -16
- data/vendor/libgit2/include/git2/object.h +62 -23
- data/vendor/libgit2/include/git2/odb.h +140 -24
- data/vendor/libgit2/include/git2/odb_backend.h +56 -12
- data/vendor/libgit2/include/git2/oid.h +17 -18
- data/vendor/libgit2/include/git2/oidarray.h +40 -0
- data/vendor/libgit2/include/git2/pack.h +86 -7
- data/vendor/libgit2/include/git2/patch.h +274 -0
- data/vendor/libgit2/include/git2/pathspec.h +280 -0
- data/vendor/libgit2/include/git2/proxy.h +96 -0
- data/vendor/libgit2/include/git2/rebase.h +323 -0
- data/vendor/libgit2/include/git2/reflog.h +12 -9
- data/vendor/libgit2/include/git2/refs.h +241 -46
- data/vendor/libgit2/include/git2/refspec.h +20 -4
- data/vendor/libgit2/include/git2/remote.h +636 -209
- data/vendor/libgit2/include/git2/repository.h +267 -57
- data/vendor/libgit2/include/git2/reset.h +36 -6
- data/vendor/libgit2/include/git2/revert.h +91 -0
- data/vendor/libgit2/include/git2/revparse.h +27 -16
- data/vendor/libgit2/include/git2/revwalk.h +78 -35
- data/vendor/libgit2/include/git2/signature.h +32 -5
- data/vendor/libgit2/include/git2/stash.h +160 -21
- data/vendor/libgit2/include/git2/status.h +92 -30
- data/vendor/libgit2/include/git2/submodule.h +226 -133
- data/vendor/libgit2/include/git2/sys/alloc.h +101 -0
- data/vendor/libgit2/include/git2/sys/commit.h +38 -4
- data/vendor/libgit2/include/git2/sys/config.h +68 -9
- data/vendor/libgit2/include/git2/sys/diff.h +94 -0
- data/vendor/libgit2/include/git2/sys/filter.h +332 -0
- data/vendor/libgit2/include/git2/sys/hashsig.h +106 -0
- data/vendor/libgit2/include/git2/sys/index.h +6 -5
- data/vendor/libgit2/include/git2/sys/mempack.h +86 -0
- data/vendor/libgit2/include/git2/sys/merge.h +182 -0
- data/vendor/libgit2/include/git2/sys/odb_backend.h +66 -28
- data/vendor/libgit2/include/git2/sys/openssl.h +38 -0
- data/vendor/libgit2/include/git2/sys/path.h +64 -0
- data/vendor/libgit2/include/git2/sys/refdb_backend.h +79 -19
- data/vendor/libgit2/include/git2/sys/reflog.h +21 -0
- data/vendor/libgit2/include/git2/sys/refs.h +13 -2
- data/vendor/libgit2/include/git2/sys/repository.h +64 -1
- data/vendor/libgit2/include/git2/sys/stream.h +138 -0
- data/vendor/libgit2/include/git2/sys/time.h +31 -0
- data/vendor/libgit2/include/git2/sys/transport.h +439 -0
- data/vendor/libgit2/include/git2/tag.h +11 -2
- data/vendor/libgit2/include/git2/trace.h +1 -1
- data/vendor/libgit2/include/git2/transaction.h +121 -0
- data/vendor/libgit2/include/git2/transport.h +261 -292
- data/vendor/libgit2/include/git2/tree.h +111 -21
- data/vendor/libgit2/include/git2/types.h +244 -32
- data/vendor/libgit2/include/git2/version.h +5 -2
- data/vendor/libgit2/include/git2/worktree.h +255 -0
- data/vendor/libgit2/include/git2.h +50 -40
- data/vendor/libgit2/libgit2.pc.in +13 -0
- data/vendor/libgit2/src/CMakeLists.txt +525 -0
- data/vendor/libgit2/src/alloc.c +55 -0
- data/vendor/libgit2/src/alloc.h +40 -0
- data/vendor/libgit2/src/annotated_commit.c +228 -0
- data/vendor/libgit2/src/annotated_commit.h +52 -0
- data/vendor/libgit2/src/apply.c +855 -0
- data/vendor/libgit2/src/apply.h +25 -0
- data/vendor/libgit2/src/array.h +74 -16
- data/vendor/libgit2/src/attr.c +239 -408
- data/vendor/libgit2/src/attr.h +3 -33
- data/vendor/libgit2/src/attr_file.c +424 -156
- data/vendor/libgit2/src/attr_file.h +95 -23
- data/vendor/libgit2/src/attrcache.c +469 -0
- data/vendor/libgit2/src/attrcache.h +37 -5
- data/vendor/libgit2/src/bitvec.h +75 -0
- data/vendor/libgit2/src/blame.c +532 -0
- data/vendor/libgit2/src/blame.h +95 -0
- data/vendor/libgit2/src/blame_git.c +668 -0
- data/vendor/libgit2/src/blame_git.h +22 -0
- data/vendor/libgit2/src/blob.c +233 -129
- data/vendor/libgit2/src/blob.h +29 -1
- data/vendor/libgit2/src/branch.c +295 -197
- data/vendor/libgit2/src/branch.h +2 -0
- data/vendor/libgit2/src/buf_text.c +52 -27
- data/vendor/libgit2/src/buf_text.h +7 -7
- data/vendor/libgit2/src/buffer.c +609 -52
- data/vendor/libgit2/src/buffer.h +68 -23
- data/vendor/libgit2/src/cache.c +48 -51
- data/vendor/libgit2/src/cache.h +6 -4
- data/vendor/libgit2/src/cc-compat.h +35 -7
- data/vendor/libgit2/src/checkout.c +1827 -483
- data/vendor/libgit2/src/checkout.h +4 -1
- data/vendor/libgit2/src/cherrypick.c +230 -0
- data/vendor/libgit2/src/clone.c +338 -258
- data/vendor/libgit2/src/{compress.h → clone.h} +5 -5
- data/vendor/libgit2/src/commit.c +711 -124
- data/vendor/libgit2/src/commit.h +10 -3
- data/vendor/libgit2/src/commit_list.c +21 -14
- data/vendor/libgit2/src/commit_list.h +9 -3
- data/vendor/libgit2/src/common.h +153 -13
- data/vendor/libgit2/src/config.c +871 -242
- data/vendor/libgit2/src/config.h +58 -14
- data/vendor/libgit2/src/config_backend.h +84 -0
- data/vendor/libgit2/src/config_cache.c +44 -18
- data/vendor/libgit2/src/config_entries.c +259 -0
- data/vendor/libgit2/src/config_entries.h +23 -0
- data/vendor/libgit2/src/config_file.c +837 -1113
- data/vendor/libgit2/src/config_mem.c +224 -0
- data/vendor/libgit2/src/config_parse.c +558 -0
- data/vendor/libgit2/src/config_parse.h +64 -0
- data/vendor/libgit2/src/crlf.c +290 -195
- data/vendor/libgit2/src/date.c +35 -7
- data/vendor/libgit2/src/delta.c +275 -71
- data/vendor/libgit2/src/delta.h +80 -58
- data/vendor/libgit2/src/describe.c +893 -0
- data/vendor/libgit2/src/diff.c +330 -1128
- data/vendor/libgit2/src/diff.h +25 -67
- data/vendor/libgit2/src/diff_driver.c +225 -109
- data/vendor/libgit2/src/diff_driver.h +5 -2
- data/vendor/libgit2/src/diff_file.c +128 -103
- data/vendor/libgit2/src/diff_file.h +17 -12
- data/vendor/libgit2/src/diff_generate.c +1622 -0
- data/vendor/libgit2/src/diff_generate.h +128 -0
- data/vendor/libgit2/src/diff_parse.c +108 -0
- data/vendor/libgit2/src/diff_parse.h +20 -0
- data/vendor/libgit2/src/diff_print.c +578 -218
- data/vendor/libgit2/src/diff_stats.c +362 -0
- data/vendor/libgit2/src/diff_tform.c +429 -257
- data/vendor/libgit2/src/diff_tform.h +25 -0
- data/vendor/libgit2/src/diff_xdiff.c +143 -46
- data/vendor/libgit2/src/diff_xdiff.h +12 -5
- data/vendor/libgit2/src/errors.c +150 -34
- data/vendor/libgit2/src/features.h.in +37 -0
- data/vendor/libgit2/src/fetch.c +69 -46
- data/vendor/libgit2/src/fetch.h +6 -12
- data/vendor/libgit2/src/fetchhead.c +40 -33
- data/vendor/libgit2/src/fetchhead.h +5 -4
- data/vendor/libgit2/src/filebuf.c +163 -61
- data/vendor/libgit2/src/filebuf.h +13 -7
- data/vendor/libgit2/src/fileops.c +549 -407
- data/vendor/libgit2/src/fileops.h +97 -106
- data/vendor/libgit2/src/filter.c +989 -46
- data/vendor/libgit2/src/filter.h +21 -70
- data/vendor/libgit2/src/fnmatch.c +67 -11
- data/vendor/libgit2/src/fnmatch.h +27 -7
- data/vendor/libgit2/src/global.c +257 -63
- data/vendor/libgit2/src/global.h +19 -0
- data/vendor/libgit2/src/graph.c +39 -23
- data/vendor/libgit2/src/hash/hash_collisiondetect.h +51 -0
- data/vendor/libgit2/src/hash/hash_common_crypto.h +61 -0
- data/vendor/libgit2/src/hash/hash_generic.c +3 -3
- data/vendor/libgit2/src/hash/hash_generic.h +10 -5
- data/vendor/libgit2/src/hash/hash_mbedtls.c +38 -0
- data/vendor/libgit2/src/hash/hash_mbedtls.h +24 -0
- data/vendor/libgit2/src/hash/hash_openssl.h +26 -8
- data/vendor/libgit2/src/hash/hash_win32.c +71 -43
- data/vendor/libgit2/src/hash/hash_win32.h +4 -3
- data/vendor/libgit2/src/hash/sha1dc/sha1.c +1900 -0
- data/vendor/libgit2/src/hash/sha1dc/sha1.h +110 -0
- data/vendor/libgit2/src/hash/sha1dc/ubc_check.c +372 -0
- data/vendor/libgit2/src/hash/sha1dc/ubc_check.h +52 -0
- data/vendor/libgit2/src/hash.c +0 -1
- data/vendor/libgit2/src/hash.h +13 -6
- data/vendor/libgit2/src/hashsig.c +121 -126
- data/vendor/libgit2/src/ident.c +129 -0
- data/vendor/libgit2/src/idxmap.c +153 -0
- data/vendor/libgit2/src/idxmap.h +41 -0
- data/vendor/libgit2/src/ignore.c +362 -123
- data/vendor/libgit2/src/ignore.h +16 -4
- data/vendor/libgit2/src/index.c +2131 -692
- data/vendor/libgit2/src/index.h +138 -6
- data/vendor/libgit2/src/indexer.c +866 -266
- data/vendor/libgit2/src/indexer.h +16 -0
- data/vendor/libgit2/src/integer.h +106 -0
- data/vendor/libgit2/src/iterator.c +1888 -967
- data/vendor/libgit2/src/iterator.h +130 -67
- data/vendor/libgit2/src/khash.h +43 -29
- data/vendor/libgit2/src/mailmap.c +485 -0
- data/vendor/libgit2/src/mailmap.h +35 -0
- data/vendor/libgit2/src/map.h +1 -1
- data/vendor/libgit2/src/merge.c +1679 -479
- data/vendor/libgit2/src/merge.h +89 -22
- data/vendor/libgit2/src/merge_driver.c +426 -0
- data/vendor/libgit2/src/merge_driver.h +62 -0
- data/vendor/libgit2/src/merge_file.c +238 -101
- data/vendor/libgit2/src/message.c +4 -28
- data/vendor/libgit2/src/message.h +3 -1
- data/vendor/libgit2/src/mwindow.c +123 -15
- data/vendor/libgit2/src/mwindow.h +10 -1
- data/vendor/libgit2/src/netops.c +178 -499
- data/vendor/libgit2/src/netops.h +51 -27
- data/vendor/libgit2/src/notes.c +251 -94
- data/vendor/libgit2/src/notes.h +5 -2
- data/vendor/libgit2/src/object.c +253 -67
- data/vendor/libgit2/src/object.h +40 -2
- data/vendor/libgit2/src/object_api.c +30 -11
- data/vendor/libgit2/src/odb.c +765 -201
- data/vendor/libgit2/src/odb.h +40 -8
- data/vendor/libgit2/src/odb_loose.c +560 -346
- data/vendor/libgit2/src/odb_mempack.c +185 -0
- data/vendor/libgit2/src/odb_pack.c +117 -73
- data/vendor/libgit2/src/offmap.c +113 -0
- data/vendor/libgit2/src/offmap.h +32 -42
- data/vendor/libgit2/src/oid.c +45 -25
- data/vendor/libgit2/src/oid.h +26 -8
- data/vendor/libgit2/src/oidarray.c +34 -0
- data/vendor/libgit2/src/oidarray.h +20 -0
- data/vendor/libgit2/src/oidmap.c +125 -0
- data/vendor/libgit2/src/oidmap.h +30 -17
- data/vendor/libgit2/src/pack-objects.c +688 -265
- data/vendor/libgit2/src/pack-objects.h +27 -13
- data/vendor/libgit2/src/pack.c +418 -202
- data/vendor/libgit2/src/pack.h +25 -16
- data/vendor/libgit2/src/parse.c +124 -0
- data/vendor/libgit2/src/parse.h +61 -0
- data/vendor/libgit2/src/patch.c +223 -0
- data/vendor/libgit2/src/patch.h +68 -0
- data/vendor/libgit2/src/patch_generate.c +901 -0
- data/vendor/libgit2/src/patch_generate.h +69 -0
- data/vendor/libgit2/src/patch_parse.c +1136 -0
- data/vendor/libgit2/src/patch_parse.h +51 -0
- data/vendor/libgit2/src/path.c +1247 -241
- data/vendor/libgit2/src/path.h +353 -57
- data/vendor/libgit2/src/pathspec.c +586 -58
- data/vendor/libgit2/src/pathspec.h +37 -15
- data/vendor/libgit2/src/pool.c +134 -221
- data/vendor/libgit2/src/pool.h +38 -50
- data/vendor/libgit2/src/posix.c +76 -10
- data/vendor/libgit2/src/posix.h +74 -32
- data/vendor/libgit2/src/pqueue.c +79 -117
- data/vendor/libgit2/src/pqueue.h +38 -82
- data/vendor/libgit2/src/proxy.c +39 -0
- data/vendor/libgit2/src/proxy.h +17 -0
- data/vendor/libgit2/src/push.c +178 -279
- data/vendor/libgit2/src/push.h +93 -4
- data/vendor/libgit2/src/reader.c +265 -0
- data/vendor/libgit2/src/reader.h +107 -0
- data/vendor/libgit2/src/rebase.c +1364 -0
- data/vendor/libgit2/src/refdb.c +74 -19
- data/vendor/libgit2/src/refdb.h +16 -3
- data/vendor/libgit2/src/refdb_fs.c +1472 -603
- data/vendor/libgit2/src/refdb_fs.h +4 -0
- data/vendor/libgit2/src/reflog.c +40 -330
- data/vendor/libgit2/src/reflog.h +8 -2
- data/vendor/libgit2/src/refs.c +641 -225
- data/vendor/libgit2/src/refs.h +53 -6
- data/vendor/libgit2/src/refspec.c +175 -62
- data/vendor/libgit2/src/refspec.h +10 -25
- data/vendor/libgit2/src/remote.c +1741 -723
- data/vendor/libgit2/src/remote.h +17 -5
- data/vendor/libgit2/src/repository.c +1505 -421
- data/vendor/libgit2/src/repository.h +95 -15
- data/vendor/libgit2/src/reset.c +63 -26
- data/vendor/libgit2/src/revert.c +232 -0
- data/vendor/libgit2/src/revparse.c +94 -80
- data/vendor/libgit2/src/revwalk.c +427 -194
- data/vendor/libgit2/src/revwalk.h +14 -5
- data/vendor/libgit2/src/settings.c +290 -0
- data/vendor/libgit2/src/sha1_lookup.c +16 -159
- data/vendor/libgit2/src/sha1_lookup.h +5 -4
- data/vendor/libgit2/src/signature.c +138 -26
- data/vendor/libgit2/src/signature.h +5 -0
- data/vendor/libgit2/src/sortedcache.c +395 -0
- data/vendor/libgit2/src/sortedcache.h +180 -0
- data/vendor/libgit2/src/stash.c +629 -168
- data/vendor/libgit2/src/status.c +125 -75
- data/vendor/libgit2/src/status.h +4 -2
- data/vendor/libgit2/src/stdalloc.c +120 -0
- data/vendor/libgit2/src/stdalloc.h +17 -0
- data/vendor/libgit2/src/stream.h +86 -0
- data/vendor/libgit2/src/streams/mbedtls.c +483 -0
- data/vendor/libgit2/src/streams/mbedtls.h +23 -0
- data/vendor/libgit2/src/streams/openssl.c +789 -0
- data/vendor/libgit2/src/streams/openssl.h +23 -0
- data/vendor/libgit2/src/streams/registry.c +118 -0
- data/vendor/libgit2/src/streams/registry.h +19 -0
- data/vendor/libgit2/src/streams/socket.c +235 -0
- data/vendor/libgit2/src/streams/socket.h +23 -0
- data/vendor/libgit2/src/streams/stransport.c +323 -0
- data/vendor/libgit2/src/streams/stransport.h +21 -0
- data/vendor/libgit2/src/streams/tls.c +73 -0
- data/vendor/libgit2/src/streams/tls.h +31 -0
- data/vendor/libgit2/src/strmap.c +147 -0
- data/vendor/libgit2/src/strmap.h +46 -51
- data/vendor/libgit2/src/strnlen.h +24 -0
- data/vendor/libgit2/src/submodule.c +1633 -877
- data/vendor/libgit2/src/submodule.h +83 -21
- data/vendor/libgit2/src/sysdir.c +355 -0
- data/vendor/libgit2/src/sysdir.h +119 -0
- data/vendor/libgit2/src/tag.c +87 -62
- data/vendor/libgit2/src/tag.h +4 -1
- data/vendor/libgit2/src/thread-utils.c +3 -0
- data/vendor/libgit2/src/thread-utils.h +71 -35
- data/vendor/libgit2/src/trace.c +4 -4
- data/vendor/libgit2/src/trace.h +11 -3
- data/vendor/libgit2/src/trailer.c +416 -0
- data/vendor/libgit2/src/transaction.c +382 -0
- data/vendor/libgit2/src/transaction.h +14 -0
- data/vendor/libgit2/src/transport.c +133 -67
- data/vendor/libgit2/src/transports/auth.c +75 -0
- data/vendor/libgit2/src/transports/auth.h +64 -0
- data/vendor/libgit2/src/transports/auth_negotiate.c +277 -0
- data/vendor/libgit2/src/transports/auth_negotiate.h +27 -0
- data/vendor/libgit2/src/transports/cred.c +296 -68
- data/vendor/libgit2/src/transports/cred.h +16 -0
- data/vendor/libgit2/src/transports/cred_helpers.c +4 -0
- data/vendor/libgit2/src/transports/git.c +108 -90
- data/vendor/libgit2/src/transports/http.c +803 -258
- data/vendor/libgit2/src/transports/http.h +25 -0
- data/vendor/libgit2/src/transports/local.c +265 -169
- data/vendor/libgit2/src/transports/smart.c +255 -45
- data/vendor/libgit2/src/transports/smart.h +42 -22
- data/vendor/libgit2/src/transports/smart_pkt.c +250 -159
- data/vendor/libgit2/src/transports/smart_protocol.c +414 -196
- data/vendor/libgit2/src/transports/ssh.c +645 -236
- data/vendor/libgit2/src/transports/ssh.h +14 -0
- data/vendor/libgit2/src/transports/winhttp.c +809 -353
- data/vendor/libgit2/src/tree-cache.c +138 -52
- data/vendor/libgit2/src/tree-cache.h +14 -7
- data/vendor/libgit2/src/tree.c +620 -259
- data/vendor/libgit2/src/tree.h +12 -19
- data/vendor/libgit2/src/tsort.c +3 -2
- data/vendor/libgit2/src/unix/map.c +25 -7
- data/vendor/libgit2/src/unix/posix.h +77 -12
- data/vendor/libgit2/src/unix/pthread.h +56 -0
- data/vendor/libgit2/src/unix/realpath.c +12 -8
- data/vendor/libgit2/src/userdiff.h +208 -0
- data/vendor/libgit2/src/util.c +349 -165
- data/vendor/libgit2/src/util.h +167 -85
- data/vendor/libgit2/src/varint.c +43 -0
- data/vendor/libgit2/src/varint.h +17 -0
- data/vendor/libgit2/src/vector.c +156 -33
- data/vendor/libgit2/src/vector.h +41 -5
- data/vendor/libgit2/src/win32/dir.c +22 -42
- data/vendor/libgit2/src/win32/dir.h +7 -5
- data/vendor/libgit2/src/win32/error.c +6 -32
- data/vendor/libgit2/src/win32/error.h +4 -2
- data/vendor/libgit2/src/win32/findfile.c +62 -69
- data/vendor/libgit2/src/win32/findfile.h +5 -13
- data/vendor/libgit2/src/win32/git2.rc +44 -0
- data/vendor/libgit2/src/win32/map.c +39 -11
- data/vendor/libgit2/src/win32/mingw-compat.h +10 -11
- data/vendor/libgit2/src/win32/msvc-compat.h +10 -33
- data/vendor/libgit2/src/win32/path_w32.c +476 -0
- data/vendor/libgit2/src/win32/path_w32.h +104 -0
- data/vendor/libgit2/src/win32/posix.h +35 -30
- data/vendor/libgit2/src/win32/posix_w32.c +659 -327
- data/vendor/libgit2/src/win32/precompiled.h +7 -2
- data/vendor/libgit2/src/win32/reparse.h +57 -0
- data/vendor/libgit2/src/win32/thread.c +258 -0
- data/vendor/libgit2/src/win32/thread.h +64 -0
- data/vendor/libgit2/src/win32/utf-conv.c +127 -62
- data/vendor/libgit2/src/win32/utf-conv.h +47 -6
- data/vendor/libgit2/src/win32/version.h +21 -4
- data/vendor/libgit2/src/win32/w32_buffer.c +54 -0
- data/vendor/libgit2/src/win32/w32_buffer.h +20 -0
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +438 -0
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +129 -0
- data/vendor/libgit2/src/win32/w32_stack.c +193 -0
- data/vendor/libgit2/src/win32/w32_stack.h +140 -0
- data/vendor/libgit2/src/win32/w32_util.c +95 -0
- data/vendor/libgit2/src/win32/w32_util.h +170 -0
- data/vendor/libgit2/src/win32/win32-compat.h +52 -0
- data/vendor/libgit2/src/worktree.c +578 -0
- data/vendor/libgit2/src/worktree.h +39 -0
- data/vendor/libgit2/src/xdiff/xdiff.h +33 -18
- data/vendor/libgit2/src/xdiff/xdiffi.c +578 -88
- data/vendor/libgit2/src/xdiff/xdiffi.h +3 -2
- data/vendor/libgit2/src/xdiff/xemit.c +106 -45
- data/vendor/libgit2/src/xdiff/xemit.h +3 -3
- data/vendor/libgit2/src/xdiff/xhistogram.c +5 -4
- data/vendor/libgit2/src/xdiff/xinclude.h +3 -2
- data/vendor/libgit2/src/xdiff/xmacros.h +2 -2
- data/vendor/libgit2/src/xdiff/xmerge.c +167 -48
- data/vendor/libgit2/src/xdiff/xpatience.c +42 -10
- data/vendor/libgit2/src/xdiff/xprepare.c +14 -14
- data/vendor/libgit2/src/xdiff/xprepare.h +2 -2
- data/vendor/libgit2/src/xdiff/xtypes.h +2 -2
- data/vendor/libgit2/src/xdiff/xutils.c +60 -56
- data/vendor/libgit2/src/xdiff/xutils.h +3 -5
- data/vendor/libgit2/src/zstream.c +205 -0
- data/vendor/libgit2/src/zstream.h +53 -0
- metadata +281 -233
- data/Rakefile +0 -61
- data/ext/rugged/rugged_diff_patch.c +0 -169
- data/lib/rugged/diff/patch.rb +0 -28
- data/test/blob_test.rb +0 -341
- data/test/branch_test.rb +0 -199
- data/test/commit_test.rb +0 -104
- data/test/config_test.rb +0 -45
- data/test/coverage/cover.rb +0 -133
- data/test/diff_test.rb +0 -777
- data/test/errors_test.rb +0 -34
- data/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2 +0 -0
- data/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9 +0 -0
- data/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f +0 -0
- data/test/fixtures/archive.tar.gz +0 -0
- data/test/fixtures/attr/attr0 +0 -1
- data/test/fixtures/attr/attr1 +0 -29
- data/test/fixtures/attr/attr2 +0 -21
- data/test/fixtures/attr/attr3 +0 -4
- data/test/fixtures/attr/binfile +0 -1
- data/test/fixtures/attr/dir/file +0 -0
- data/test/fixtures/attr/file +0 -1
- data/test/fixtures/attr/gitattributes +0 -29
- data/test/fixtures/attr/gitignore +0 -2
- data/test/fixtures/attr/ign +0 -1
- data/test/fixtures/attr/macro_bad +0 -1
- data/test/fixtures/attr/macro_test +0 -1
- data/test/fixtures/attr/root_test1 +0 -1
- data/test/fixtures/attr/root_test2 +0 -6
- data/test/fixtures/attr/root_test3 +0 -19
- data/test/fixtures/attr/root_test4.txt +0 -14
- data/test/fixtures/attr/sub/abc +0 -37
- data/test/fixtures/attr/sub/dir/file +0 -0
- data/test/fixtures/attr/sub/file +0 -1
- data/test/fixtures/attr/sub/ign/file +0 -1
- data/test/fixtures/attr/sub/ign/sub/file +0 -1
- data/test/fixtures/attr/sub/sub/dir +0 -0
- data/test/fixtures/attr/sub/sub/file +0 -1
- data/test/fixtures/attr/sub/sub/subsub.txt +0 -1
- data/test/fixtures/attr/sub/subdir_test1 +0 -2
- data/test/fixtures/attr/sub/subdir_test2.txt +0 -1
- data/test/fixtures/diff/another.txt +0 -38
- data/test/fixtures/diff/readme.txt +0 -36
- data/test/fixtures/mergedrepo/conflicts-one.txt +0 -5
- data/test/fixtures/mergedrepo/conflicts-two.txt +0 -5
- data/test/fixtures/mergedrepo/one.txt +0 -10
- data/test/fixtures/mergedrepo/two.txt +0 -12
- data/test/fixtures/status/current_file +0 -1
- data/test/fixtures/status/ignored_file +0 -1
- data/test/fixtures/status/modified_file +0 -2
- data/test/fixtures/status/new_file +0 -1
- data/test/fixtures/status/staged_changes +0 -2
- data/test/fixtures/status/staged_changes_modified_file +0 -3
- data/test/fixtures/status/staged_delete_modified_file +0 -1
- data/test/fixtures/status/staged_new_file +0 -1
- data/test/fixtures/status/staged_new_file_modified_file +0 -2
- data/test/fixtures/status/subdir/current_file +0 -1
- data/test/fixtures/status/subdir/modified_file +0 -2
- data/test/fixtures/status/subdir/new_file +0 -1
- data/test/fixtures/status/subdir.txt +0 -2
- data/test/fixtures/status//350/277/231 +0 -1
- data/test/fixtures/testrepo.git/HEAD +0 -1
- data/test/fixtures/testrepo.git/config +0 -13
- data/test/fixtures/testrepo.git/description +0 -1
- data/test/fixtures/testrepo.git/index +0 -0
- data/test/fixtures/testrepo.git/info/exclude +0 -6
- data/test/fixtures/testrepo.git/logs/HEAD +0 -3
- data/test/fixtures/testrepo.git/logs/refs/heads/master +0 -3
- data/test/fixtures/testrepo.git/logs/refs/notes/commits +0 -1
- data/test/fixtures/testrepo.git/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1d +0 -0
- data/test/fixtures/testrepo.git/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 +0 -0
- data/test/fixtures/testrepo.git/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 +0 -0
- data/test/fixtures/testrepo.git/objects/18/10dff58d8a660512d4832e740f692884338ccd +0 -0
- data/test/fixtures/testrepo.git/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2 +0 -0
- data/test/fixtures/testrepo.git/objects/36/060c58702ed4c2a40832c51758d5344201d89a +0 -2
- data/test/fixtures/testrepo.git/objects/44/1034f860c1d5d90e4188d11ae0d325176869a8 +0 -1
- data/test/fixtures/testrepo.git/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 +0 -0
- data/test/fixtures/testrepo.git/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 +0 -2
- data/test/fixtures/testrepo.git/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 +0 -2
- data/test/fixtures/testrepo.git/objects/60/d415052a33de2150bf68757f6461df4f563ae4 +0 -0
- data/test/fixtures/testrepo.git/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96 +0 -0
- data/test/fixtures/testrepo.git/objects/68/8a8f4ef7496901d15322972f96e212a9e466cc +0 -1
- data/test/fixtures/testrepo.git/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a +0 -0
- data/test/fixtures/testrepo.git/objects/77/71329dfa3002caf8c61a0ceb62a31d09023f37 +0 -0
- data/test/fixtures/testrepo.git/objects/81/4889a078c031f61ed08ab5fa863aea9314344d +0 -0
- data/test/fixtures/testrepo.git/objects/84/96071c1b46c854b31185ea97743be6a8774479 +0 -0
- data/test/fixtures/testrepo.git/objects/94/eca2de348d5f672faf56b0decafa5937e3235e +0 -0
- data/test/fixtures/testrepo.git/objects/9b/7384fe1676186192842f5d3e129457b62db9e3 +0 -0
- data/test/fixtures/testrepo.git/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a +0 -3
- data/test/fixtures/testrepo.git/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f +0 -2
- data/test/fixtures/testrepo.git/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd +0 -0
- data/test/fixtures/testrepo.git/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 +0 -0
- data/test/fixtures/testrepo.git/objects/b7/4713326bc972cc15751ed504dca6f6f3b91f7a +0 -3
- data/test/fixtures/testrepo.git/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644 +0 -3
- data/test/fixtures/testrepo.git/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd +0 -3
- data/test/fixtures/testrepo.git/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b +0 -0
- data/test/fixtures/testrepo.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 +0 -0
- data/test/fixtures/testrepo.git/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 +0 -0
- data/test/fixtures/testrepo.git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 +0 -0
- data/test/fixtures/testrepo.git/objects/fd/093bff70906175335656e6ce6ae05783708765 +0 -0
- data/test/fixtures/testrepo.git/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx +0 -0
- data/test/fixtures/testrepo.git/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack +0 -0
- data/test/fixtures/testrepo.git/packed-refs +0 -2
- data/test/fixtures/testrepo.git/refs/heads/master +0 -1
- data/test/fixtures/testrepo.git/refs/notes/commits +0 -1
- data/test/fixtures/testrepo.git/refs/tags/v0.9 +0 -1
- data/test/fixtures/testrepo.git/refs/tags/v1.0 +0 -1
- data/test/fixtures/text_file.md +0 -464
- data/test/fixtures/unsymlinked.git/HEAD +0 -1
- data/test/fixtures/unsymlinked.git/config +0 -6
- data/test/fixtures/unsymlinked.git/description +0 -1
- data/test/fixtures/unsymlinked.git/info/exclude +0 -2
- data/test/fixtures/unsymlinked.git/objects/08/8b64704e0d6b8bd061dea879418cb5442a3fbf +0 -0
- data/test/fixtures/unsymlinked.git/objects/13/a5e939bca25940c069fd2169d993dba328e30b +0 -0
- data/test/fixtures/unsymlinked.git/objects/19/bf568e59e3a0b363cafb4106226e62d4a4c41c +0 -0
- data/test/fixtures/unsymlinked.git/objects/58/1fadd35b4cf320d102a152f918729011604773 +0 -0
- data/test/fixtures/unsymlinked.git/objects/5c/87b6791e8b13da658a14d1ef7e09b5dc3bac8c +0 -0
- data/test/fixtures/unsymlinked.git/objects/6f/e5f5398af85fb3de8a6aba0339b6d3bfa26a27 +0 -0
- data/test/fixtures/unsymlinked.git/objects/7f/ccd75616ec188b8f1b23d67506a334cc34a49d +0 -0
- data/test/fixtures/unsymlinked.git/objects/80/6999882bf91d24241e4077906b9017605eb1f3 +0 -0
- data/test/fixtures/unsymlinked.git/objects/83/7d176303c5005505ec1e4a30231c40930c0230 +0 -0
- data/test/fixtures/unsymlinked.git/objects/a8/595ccca04f40818ae0155c8f9c77a230e597b6 +0 -2
- data/test/fixtures/unsymlinked.git/objects/cf/8f1cf5cce859c438d6cc067284cb5e161206e7 +0 -0
- data/test/fixtures/unsymlinked.git/objects/d5/278d05c8607ec420bfee4cf219fbc0eeebfd6a +0 -0
- data/test/fixtures/unsymlinked.git/objects/f4/e16fb76536591a41454194058d048d8e4dd2e9 +0 -0
- data/test/fixtures/unsymlinked.git/objects/f9/e65619d93fdf2673882e0a261c5e93b1a84006 +0 -0
- data/test/fixtures/unsymlinked.git/refs/heads/exe-file +0 -1
- data/test/fixtures/unsymlinked.git/refs/heads/master +0 -1
- data/test/fixtures/unsymlinked.git/refs/heads/reg-file +0 -1
- data/test/index_test.rb +0 -333
- data/test/lib_test.rb +0 -127
- data/test/note_test.rb +0 -158
- data/test/object_test.rb +0 -43
- data/test/reference_test.rb +0 -207
- data/test/remote_test.rb +0 -324
- data/test/repo_pack_test.rb +0 -24
- data/test/repo_reset_test.rb +0 -82
- data/test/repo_test.rb +0 -402
- data/test/tag_test.rb +0 -68
- data/test/test_helper.rb +0 -92
- data/test/tree_test.rb +0 -91
- data/test/walker_test.rb +0 -88
- data/vendor/libgit2/Makefile.embed +0 -42
- data/vendor/libgit2/include/git2/push.h +0 -131
- data/vendor/libgit2/include/git2/threads.h +0 -50
- data/vendor/libgit2/src/amiga/map.c +0 -48
- data/vendor/libgit2/src/bswap.h +0 -97
- data/vendor/libgit2/src/compress.c +0 -53
- data/vendor/libgit2/src/config_file.h +0 -60
- data/vendor/libgit2/src/delta-apply.c +0 -134
- data/vendor/libgit2/src/delta-apply.h +0 -50
- data/vendor/libgit2/src/diff_patch.c +0 -995
- data/vendor/libgit2/src/diff_patch.h +0 -46
- data/vendor/libgit2/src/hashsig.h +0 -72
- data/vendor/libgit2/src/merge_file.h +0 -71
- data/vendor/libgit2/src/win32/pthread.c +0 -144
- data/vendor/libgit2/src/win32/pthread.h +0 -50
@@ -4,28 +4,67 @@
|
|
4
4
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
6
6
|
*/
|
7
|
-
|
7
|
+
|
8
|
+
#include "repository.h"
|
9
|
+
|
8
10
|
#include <ctype.h>
|
9
11
|
|
10
12
|
#include "git2/object.h"
|
11
|
-
#include "git2/refdb.h"
|
12
13
|
#include "git2/sys/repository.h"
|
13
14
|
|
14
15
|
#include "common.h"
|
15
|
-
#include "repository.h"
|
16
16
|
#include "commit.h"
|
17
17
|
#include "tag.h"
|
18
18
|
#include "blob.h"
|
19
19
|
#include "fileops.h"
|
20
|
+
#include "sysdir.h"
|
20
21
|
#include "filebuf.h"
|
21
22
|
#include "index.h"
|
22
23
|
#include "config.h"
|
23
24
|
#include "refs.h"
|
24
25
|
#include "filter.h"
|
25
26
|
#include "odb.h"
|
27
|
+
#include "refdb.h"
|
26
28
|
#include "remote.h"
|
27
29
|
#include "merge.h"
|
28
30
|
#include "diff_driver.h"
|
31
|
+
#include "annotated_commit.h"
|
32
|
+
#include "submodule.h"
|
33
|
+
#include "worktree.h"
|
34
|
+
|
35
|
+
#include "strmap.h"
|
36
|
+
|
37
|
+
#ifdef GIT_WIN32
|
38
|
+
# include "win32/w32_util.h"
|
39
|
+
#endif
|
40
|
+
|
41
|
+
bool git_repository__fsync_gitdir = false;
|
42
|
+
|
43
|
+
static const struct {
|
44
|
+
git_repository_item_t parent;
|
45
|
+
const char *name;
|
46
|
+
bool directory;
|
47
|
+
} items[] = {
|
48
|
+
{ GIT_REPOSITORY_ITEM_GITDIR, NULL, true },
|
49
|
+
{ GIT_REPOSITORY_ITEM_WORKDIR, NULL, true },
|
50
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, NULL, true },
|
51
|
+
{ GIT_REPOSITORY_ITEM_GITDIR, "index", false },
|
52
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "objects", true },
|
53
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "refs", true },
|
54
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "packed-refs", false },
|
55
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "remotes", true },
|
56
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "config", false },
|
57
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "info", true },
|
58
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "hooks", true },
|
59
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "logs", true },
|
60
|
+
{ GIT_REPOSITORY_ITEM_GITDIR, "modules", true },
|
61
|
+
{ GIT_REPOSITORY_ITEM_COMMONDIR, "worktrees", true }
|
62
|
+
};
|
63
|
+
|
64
|
+
static int check_repositoryformatversion(git_config *config);
|
65
|
+
|
66
|
+
#define GIT_COMMONDIR_FILE "commondir"
|
67
|
+
#define GIT_GITDIR_FILE "gitdir"
|
29
68
|
|
30
69
|
#define GIT_FILE_CONTENT_PREFIX "gitdir:"
|
31
70
|
|
@@ -33,7 +72,16 @@
|
|
33
72
|
|
34
73
|
#define GIT_REPO_VERSION 0
|
35
74
|
|
36
|
-
|
75
|
+
git_buf git_repository__reserved_names_win32[] = {
|
76
|
+
{ DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
|
77
|
+
{ GIT_DIR_SHORTNAME, 0, CONST_STRLEN(GIT_DIR_SHORTNAME) }
|
78
|
+
};
|
79
|
+
size_t git_repository__reserved_names_win32_len = 2;
|
80
|
+
|
81
|
+
git_buf git_repository__reserved_names_posix[] = {
|
82
|
+
{ DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
|
83
|
+
};
|
84
|
+
size_t git_repository__reserved_names_posix_len = 1;
|
37
85
|
|
38
86
|
static void set_odb(git_repository *repo, git_odb *odb)
|
39
87
|
{
|
@@ -93,6 +141,7 @@ void git_repository__cleanup(git_repository *repo)
|
|
93
141
|
{
|
94
142
|
assert(repo);
|
95
143
|
|
144
|
+
git_repository_submodule_cache_clear(repo);
|
96
145
|
git_cache_clear(&repo->objects);
|
97
146
|
git_attr_cache_flush(repo);
|
98
147
|
|
@@ -104,20 +153,29 @@ void git_repository__cleanup(git_repository *repo)
|
|
104
153
|
|
105
154
|
void git_repository_free(git_repository *repo)
|
106
155
|
{
|
156
|
+
size_t i;
|
157
|
+
|
107
158
|
if (repo == NULL)
|
108
159
|
return;
|
109
160
|
|
110
161
|
git_repository__cleanup(repo);
|
111
162
|
|
112
163
|
git_cache_free(&repo->objects);
|
113
|
-
git_submodule_config_free(repo);
|
114
164
|
|
115
165
|
git_diff_driver_registry_free(repo->diff_drivers);
|
116
166
|
repo->diff_drivers = NULL;
|
117
167
|
|
118
|
-
|
168
|
+
for (i = 0; i < repo->reserved_names.size; i++)
|
169
|
+
git_buf_dispose(git_array_get(repo->reserved_names, i));
|
170
|
+
git_array_clear(repo->reserved_names);
|
171
|
+
|
172
|
+
git__free(repo->gitlink);
|
173
|
+
git__free(repo->gitdir);
|
174
|
+
git__free(repo->commondir);
|
119
175
|
git__free(repo->workdir);
|
120
176
|
git__free(repo->namespace);
|
177
|
+
git__free(repo->ident_name);
|
178
|
+
git__free(repo->ident_email);
|
121
179
|
|
122
180
|
git__memzero(repo, sizeof(*repo));
|
123
181
|
git__free(repo);
|
@@ -128,17 +186,41 @@ void git_repository_free(git_repository *repo)
|
|
128
186
|
*
|
129
187
|
* Open a repository object from its path
|
130
188
|
*/
|
131
|
-
static bool valid_repository_path(git_buf *repository_path)
|
189
|
+
static bool valid_repository_path(git_buf *repository_path, git_buf *common_path)
|
132
190
|
{
|
133
|
-
/* Check
|
134
|
-
|
135
|
-
|
191
|
+
/* Check if we have a separate commondir (e.g. we have a
|
192
|
+
* worktree) */
|
193
|
+
if (git_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) {
|
194
|
+
git_buf common_link = GIT_BUF_INIT;
|
195
|
+
git_buf_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE);
|
196
|
+
|
197
|
+
git_futils_readbuffer(&common_link, common_link.ptr);
|
198
|
+
git_buf_rtrim(&common_link);
|
199
|
+
|
200
|
+
if (git_path_is_relative(common_link.ptr)) {
|
201
|
+
git_buf_joinpath(common_path, repository_path->ptr, common_link.ptr);
|
202
|
+
} else {
|
203
|
+
git_buf_swap(common_path, &common_link);
|
204
|
+
}
|
205
|
+
|
206
|
+
git_buf_dispose(&common_link);
|
207
|
+
}
|
208
|
+
else {
|
209
|
+
git_buf_set(common_path, repository_path->ptr, repository_path->size);
|
210
|
+
}
|
211
|
+
|
212
|
+
/* Make sure the commondir path always has a trailing * slash */
|
213
|
+
if (git_buf_rfind(common_path, '/') != (ssize_t)common_path->size - 1)
|
214
|
+
git_buf_putc(common_path, '/');
|
136
215
|
|
137
216
|
/* Ensure HEAD file exists */
|
138
217
|
if (git_path_contains_file(repository_path, GIT_HEAD_FILE) == false)
|
139
218
|
return false;
|
140
219
|
|
141
|
-
|
220
|
+
/* Check files in common dir */
|
221
|
+
if (git_path_contains_dir(common_path, GIT_OBJECTS_DIR) == false)
|
222
|
+
return false;
|
223
|
+
if (git_path_contains_dir(common_path, GIT_REFS_DIR) == false)
|
142
224
|
return false;
|
143
225
|
|
144
226
|
return true;
|
@@ -147,81 +229,113 @@ static bool valid_repository_path(git_buf *repository_path)
|
|
147
229
|
static git_repository *repository_alloc(void)
|
148
230
|
{
|
149
231
|
git_repository *repo = git__calloc(1, sizeof(git_repository));
|
150
|
-
if (!repo)
|
151
|
-
return NULL;
|
152
232
|
|
153
|
-
if (
|
154
|
-
|
155
|
-
|
156
|
-
|
233
|
+
if (repo == NULL ||
|
234
|
+
git_cache_init(&repo->objects) < 0)
|
235
|
+
goto on_error;
|
236
|
+
|
237
|
+
git_array_init_to_size(repo->reserved_names, 4);
|
238
|
+
if (!repo->reserved_names.ptr)
|
239
|
+
goto on_error;
|
157
240
|
|
158
241
|
/* set all the entries in the cvar cache to `unset` */
|
159
242
|
git_repository__cvar_cache_clear(repo);
|
160
243
|
|
161
244
|
return repo;
|
245
|
+
|
246
|
+
on_error:
|
247
|
+
if (repo)
|
248
|
+
git_cache_free(&repo->objects);
|
249
|
+
|
250
|
+
git__free(repo);
|
251
|
+
return NULL;
|
162
252
|
}
|
163
253
|
|
164
254
|
int git_repository_new(git_repository **out)
|
165
255
|
{
|
166
|
-
*
|
256
|
+
git_repository *repo;
|
257
|
+
|
258
|
+
*out = repo = repository_alloc();
|
259
|
+
GIT_ERROR_CHECK_ALLOC(repo);
|
260
|
+
|
261
|
+
repo->is_bare = 1;
|
262
|
+
repo->is_worktree = 0;
|
263
|
+
|
167
264
|
return 0;
|
168
265
|
}
|
169
266
|
|
170
|
-
static int load_config_data(git_repository *repo)
|
267
|
+
static int load_config_data(git_repository *repo, const git_config *config)
|
171
268
|
{
|
172
269
|
int is_bare;
|
173
|
-
git_config *config;
|
174
270
|
|
175
|
-
|
176
|
-
|
271
|
+
int err = git_config_get_bool(&is_bare, config, "core.bare");
|
272
|
+
if (err < 0 && err != GIT_ENOTFOUND)
|
273
|
+
return err;
|
177
274
|
|
178
275
|
/* Try to figure out if it's bare, default to non-bare if it's not set */
|
179
|
-
if (
|
180
|
-
repo->is_bare =
|
276
|
+
if (err != GIT_ENOTFOUND)
|
277
|
+
repo->is_bare = is_bare && !repo->is_worktree;
|
181
278
|
else
|
182
|
-
repo->is_bare =
|
279
|
+
repo->is_bare = 0;
|
183
280
|
|
184
281
|
return 0;
|
185
282
|
}
|
186
283
|
|
187
|
-
static int load_workdir(git_repository *repo, git_buf *parent_path)
|
284
|
+
static int load_workdir(git_repository *repo, git_config *config, git_buf *parent_path)
|
188
285
|
{
|
189
|
-
int
|
190
|
-
|
191
|
-
|
192
|
-
git_buf
|
286
|
+
int error;
|
287
|
+
git_config_entry *ce;
|
288
|
+
git_buf worktree = GIT_BUF_INIT;
|
289
|
+
git_buf path = GIT_BUF_INIT;
|
193
290
|
|
194
291
|
if (repo->is_bare)
|
195
292
|
return 0;
|
196
293
|
|
197
|
-
if (
|
198
|
-
|
199
|
-
|
200
|
-
error = git_config_get_string(&worktree, config, "core.worktree");
|
201
|
-
if (!error && worktree != NULL) {
|
202
|
-
error = git_path_prettify_dir(
|
203
|
-
&worktree_buf, worktree, repo->path_repository);
|
204
|
-
if (error < 0)
|
205
|
-
return error;
|
206
|
-
repo->workdir = git_buf_detach(&worktree_buf);
|
207
|
-
}
|
208
|
-
else if (error != GIT_ENOTFOUND)
|
294
|
+
if ((error = git_config__lookup_entry(
|
295
|
+
&ce, config, "core.worktree", false)) < 0)
|
209
296
|
return error;
|
210
|
-
else {
|
211
|
-
giterr_clear();
|
212
297
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
repo->workdir = git_buf_detach(&worktree_buf);
|
298
|
+
if (repo->is_worktree) {
|
299
|
+
char *gitlink = git_worktree__read_link(repo->gitdir, GIT_GITDIR_FILE);
|
300
|
+
if (!gitlink) {
|
301
|
+
error = -1;
|
302
|
+
goto cleanup;
|
219
303
|
}
|
304
|
+
|
305
|
+
git_buf_attach(&worktree, gitlink, 0);
|
306
|
+
|
307
|
+
if ((git_path_dirname_r(&worktree, worktree.ptr)) < 0 ||
|
308
|
+
git_path_to_dir(&worktree) < 0) {
|
309
|
+
error = -1;
|
310
|
+
goto cleanup;
|
311
|
+
}
|
312
|
+
|
313
|
+
repo->workdir = git_buf_detach(&worktree);
|
314
|
+
}
|
315
|
+
else if (ce && ce->value) {
|
316
|
+
if ((error = git_path_prettify_dir(
|
317
|
+
&worktree, ce->value, repo->gitdir)) < 0)
|
318
|
+
goto cleanup;
|
319
|
+
|
320
|
+
repo->workdir = git_buf_detach(&worktree);
|
220
321
|
}
|
322
|
+
else if (parent_path && git_path_isdir(parent_path->ptr))
|
323
|
+
repo->workdir = git_buf_detach(parent_path);
|
324
|
+
else {
|
325
|
+
if (git_path_dirname_r(&worktree, repo->gitdir) < 0 ||
|
326
|
+
git_path_to_dir(&worktree) < 0) {
|
327
|
+
error = -1;
|
328
|
+
goto cleanup;
|
329
|
+
}
|
221
330
|
|
222
|
-
|
331
|
+
repo->workdir = git_buf_detach(&worktree);
|
332
|
+
}
|
223
333
|
|
224
|
-
|
334
|
+
GIT_ERROR_CHECK_ALLOC(repo->workdir);
|
335
|
+
cleanup:
|
336
|
+
git_buf_dispose(&path);
|
337
|
+
git_config_entry_free(ce);
|
338
|
+
return error;
|
225
339
|
}
|
226
340
|
|
227
341
|
/*
|
@@ -232,7 +346,7 @@ static int load_workdir(git_repository *repo, git_buf *parent_path)
|
|
232
346
|
* the stack could remove directories name limits, but at the cost of doing
|
233
347
|
* repeated malloc/frees inside the loop below, so let's not do it now.
|
234
348
|
*/
|
235
|
-
static
|
349
|
+
static size_t find_ceiling_dir_offset(
|
236
350
|
const char *path,
|
237
351
|
const char *ceiling_directories)
|
238
352
|
{
|
@@ -246,7 +360,7 @@ static int find_ceiling_dir_offset(
|
|
246
360
|
min_len = (size_t)(git_path_root(path) + 1);
|
247
361
|
|
248
362
|
if (ceiling_directories == NULL || min_len == 0)
|
249
|
-
return
|
363
|
+
return min_len;
|
250
364
|
|
251
365
|
for (sep = ceil = ceiling_directories; *sep; ceil = sep + 1) {
|
252
366
|
for (sep = ceil; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++);
|
@@ -266,14 +380,14 @@ static int find_ceiling_dir_offset(
|
|
266
380
|
buf[--len] = '\0';
|
267
381
|
|
268
382
|
if (!strncmp(path, buf2, len) &&
|
269
|
-
path[len] == '/' &&
|
383
|
+
(path[len] == '/' || !path[len]) &&
|
270
384
|
len > max_len)
|
271
385
|
{
|
272
386
|
max_len = len;
|
273
387
|
}
|
274
388
|
}
|
275
389
|
|
276
|
-
return (
|
390
|
+
return (max_len <= min_len ? min_len : max_len);
|
277
391
|
}
|
278
392
|
|
279
393
|
/*
|
@@ -293,116 +407,158 @@ static int read_gitfile(git_buf *path_out, const char *file_path)
|
|
293
407
|
return -1;
|
294
408
|
|
295
409
|
git_buf_rtrim(&file);
|
410
|
+
/* apparently on Windows, some people use backslashes in paths */
|
411
|
+
git_path_mkposix(file.ptr);
|
296
412
|
|
297
413
|
if (git_buf_len(&file) <= prefix_len ||
|
298
414
|
memcmp(git_buf_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0)
|
299
415
|
{
|
300
|
-
|
416
|
+
git_error_set(GIT_ERROR_REPOSITORY,
|
417
|
+
"the `.git` file at '%s' is malformed", file_path);
|
301
418
|
error = -1;
|
302
419
|
}
|
303
420
|
else if ((error = git_path_dirname_r(path_out, file_path)) >= 0) {
|
304
421
|
const char *gitlink = git_buf_cstr(&file) + prefix_len;
|
305
422
|
while (*gitlink && git__isspace(*gitlink)) gitlink++;
|
423
|
+
|
306
424
|
error = git_path_prettify_dir(
|
307
425
|
path_out, gitlink, git_buf_cstr(path_out));
|
308
426
|
}
|
309
427
|
|
310
|
-
|
428
|
+
git_buf_dispose(&file);
|
311
429
|
return error;
|
312
430
|
}
|
313
431
|
|
314
432
|
static int find_repo(
|
315
|
-
git_buf *
|
316
|
-
git_buf *
|
433
|
+
git_buf *gitdir_path,
|
434
|
+
git_buf *workdir_path,
|
435
|
+
git_buf *gitlink_path,
|
436
|
+
git_buf *commondir_path,
|
317
437
|
const char *start_path,
|
318
438
|
uint32_t flags,
|
319
439
|
const char *ceiling_dirs)
|
320
440
|
{
|
321
441
|
int error;
|
322
442
|
git_buf path = GIT_BUF_INIT;
|
443
|
+
git_buf repo_link = GIT_BUF_INIT;
|
444
|
+
git_buf common_link = GIT_BUF_INIT;
|
323
445
|
struct stat st;
|
324
446
|
dev_t initial_device = 0;
|
325
|
-
|
326
|
-
|
447
|
+
int min_iterations;
|
448
|
+
bool in_dot_git;
|
449
|
+
size_t ceiling_offset = 0;
|
327
450
|
|
328
|
-
|
451
|
+
git_buf_clear(gitdir_path);
|
329
452
|
|
330
|
-
|
453
|
+
error = git_path_prettify(&path, start_path, NULL);
|
454
|
+
if (error < 0)
|
331
455
|
return error;
|
332
456
|
|
333
|
-
|
457
|
+
/* in_dot_git toggles each loop:
|
458
|
+
* /a/b/c/.git, /a/b/c, /a/b/.git, /a/b, /a/.git, /a
|
459
|
+
* With GIT_REPOSITORY_OPEN_BARE or GIT_REPOSITORY_OPEN_NO_DOTGIT, we
|
460
|
+
* assume we started with /a/b/c.git and don't append .git the first
|
461
|
+
* time through.
|
462
|
+
* min_iterations indicates the number of iterations left before going
|
463
|
+
* further counts as a search. */
|
464
|
+
if (flags & (GIT_REPOSITORY_OPEN_BARE | GIT_REPOSITORY_OPEN_NO_DOTGIT)) {
|
465
|
+
in_dot_git = true;
|
466
|
+
min_iterations = 1;
|
467
|
+
} else {
|
468
|
+
in_dot_git = false;
|
469
|
+
min_iterations = 2;
|
470
|
+
}
|
334
471
|
|
335
|
-
|
336
|
-
|
472
|
+
for (;;) {
|
473
|
+
if (!(flags & GIT_REPOSITORY_OPEN_NO_DOTGIT)) {
|
474
|
+
if (!in_dot_git) {
|
475
|
+
error = git_buf_joinpath(&path, path.ptr, DOT_GIT);
|
476
|
+
if (error < 0)
|
477
|
+
break;
|
478
|
+
}
|
479
|
+
in_dot_git = !in_dot_git;
|
480
|
+
}
|
337
481
|
|
338
|
-
while (!error && !git_buf_len(repo_path)) {
|
339
482
|
if (p_stat(path.ptr, &st) == 0) {
|
340
483
|
/* check that we have not crossed device boundaries */
|
341
484
|
if (initial_device == 0)
|
342
485
|
initial_device = st.st_dev;
|
343
486
|
else if (st.st_dev != initial_device &&
|
344
|
-
|
487
|
+
!(flags & GIT_REPOSITORY_OPEN_CROSS_FS))
|
345
488
|
break;
|
346
489
|
|
347
490
|
if (S_ISDIR(st.st_mode)) {
|
348
|
-
if (valid_repository_path(&path)) {
|
491
|
+
if (valid_repository_path(&path, &common_link)) {
|
349
492
|
git_path_to_dir(&path);
|
350
|
-
git_buf_set(
|
493
|
+
git_buf_set(gitdir_path, path.ptr, path.size);
|
494
|
+
|
495
|
+
if (gitlink_path)
|
496
|
+
git_buf_attach(gitlink_path,
|
497
|
+
git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0);
|
498
|
+
if (commondir_path)
|
499
|
+
git_buf_swap(&common_link, commondir_path);
|
500
|
+
|
351
501
|
break;
|
352
502
|
}
|
353
503
|
}
|
354
|
-
else if (S_ISREG(st.st_mode)) {
|
355
|
-
|
356
|
-
|
357
|
-
if (!(error = read_gitfile(&repo_link, path.ptr))) {
|
358
|
-
if (valid_repository_path(&repo_link))
|
359
|
-
git_buf_swap(repo_path, &repo_link);
|
360
|
-
|
361
|
-
git_buf_free(&repo_link);
|
504
|
+
else if (S_ISREG(st.st_mode) && git__suffixcmp(path.ptr, "/" DOT_GIT) == 0) {
|
505
|
+
error = read_gitfile(&repo_link, path.ptr);
|
506
|
+
if (error < 0)
|
362
507
|
break;
|
508
|
+
if (valid_repository_path(&repo_link, &common_link)) {
|
509
|
+
git_buf_swap(gitdir_path, &repo_link);
|
510
|
+
|
511
|
+
if (gitlink_path)
|
512
|
+
error = git_buf_put(gitlink_path, path.ptr, path.size);
|
513
|
+
if (commondir_path)
|
514
|
+
git_buf_swap(&common_link, commondir_path);
|
363
515
|
}
|
364
|
-
|
516
|
+
break;
|
365
517
|
}
|
366
518
|
}
|
367
519
|
|
368
|
-
/*
|
520
|
+
/* Move up one directory. If we're in_dot_git, we'll search the
|
521
|
+
* parent itself next. If we're !in_dot_git, we'll search .git
|
522
|
+
* in the parent directory next (added at the top of the loop). */
|
369
523
|
if (git_path_dirname_r(&path, path.ptr) < 0) {
|
370
524
|
error = -1;
|
371
525
|
break;
|
372
526
|
}
|
373
527
|
|
374
|
-
if
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
try_with_dot_git = !try_with_dot_git;
|
528
|
+
/* Once we've checked the directory (and .git if applicable),
|
529
|
+
* find the ceiling for a search. */
|
530
|
+
if (min_iterations && (--min_iterations == 0))
|
531
|
+
ceiling_offset = find_ceiling_dir_offset(path.ptr, ceiling_dirs);
|
532
|
+
|
533
|
+
/* Check if we should stop searching here. */
|
534
|
+
if (min_iterations == 0
|
535
|
+
&& (path.ptr[ceiling_offset] == 0
|
536
|
+
|| (flags & GIT_REPOSITORY_OPEN_NO_SEARCH)))
|
537
|
+
break;
|
385
538
|
}
|
386
539
|
|
387
|
-
if (!error &&
|
388
|
-
if (!git_buf_len(
|
389
|
-
git_buf_clear(
|
540
|
+
if (!error && workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) {
|
541
|
+
if (!git_buf_len(gitdir_path))
|
542
|
+
git_buf_clear(workdir_path);
|
390
543
|
else {
|
391
|
-
git_path_dirname_r(
|
392
|
-
git_path_to_dir(
|
544
|
+
git_path_dirname_r(workdir_path, path.ptr);
|
545
|
+
git_path_to_dir(workdir_path);
|
393
546
|
}
|
394
|
-
if (git_buf_oom(
|
547
|
+
if (git_buf_oom(workdir_path))
|
395
548
|
return -1;
|
396
549
|
}
|
397
550
|
|
398
|
-
|
399
|
-
|
400
|
-
if (!git_buf_len(
|
401
|
-
|
402
|
-
"
|
551
|
+
/* If we didn't find the repository, and we don't have any other error
|
552
|
+
* to report, report that. */
|
553
|
+
if (!git_buf_len(gitdir_path) && !error) {
|
554
|
+
git_error_set(GIT_ERROR_REPOSITORY,
|
555
|
+
"could not find repository from '%s'", start_path);
|
403
556
|
error = GIT_ENOTFOUND;
|
404
557
|
}
|
405
558
|
|
559
|
+
git_buf_dispose(&path);
|
560
|
+
git_buf_dispose(&repo_link);
|
561
|
+
git_buf_dispose(&common_link);
|
406
562
|
return error;
|
407
563
|
}
|
408
564
|
|
@@ -411,32 +567,228 @@ int git_repository_open_bare(
|
|
411
567
|
const char *bare_path)
|
412
568
|
{
|
413
569
|
int error;
|
414
|
-
git_buf path = GIT_BUF_INIT;
|
570
|
+
git_buf path = GIT_BUF_INIT, common_path = GIT_BUF_INIT;
|
415
571
|
git_repository *repo = NULL;
|
416
572
|
|
417
573
|
if ((error = git_path_prettify_dir(&path, bare_path, NULL)) < 0)
|
418
574
|
return error;
|
419
575
|
|
420
|
-
if (!valid_repository_path(&path)) {
|
421
|
-
|
422
|
-
|
576
|
+
if (!valid_repository_path(&path, &common_path)) {
|
577
|
+
git_buf_dispose(&path);
|
578
|
+
git_buf_dispose(&common_path);
|
579
|
+
git_error_set(GIT_ERROR_REPOSITORY, "path is not a repository: %s", bare_path);
|
423
580
|
return GIT_ENOTFOUND;
|
424
581
|
}
|
425
582
|
|
426
583
|
repo = repository_alloc();
|
427
|
-
|
584
|
+
GIT_ERROR_CHECK_ALLOC(repo);
|
428
585
|
|
429
|
-
repo->
|
430
|
-
|
586
|
+
repo->gitdir = git_buf_detach(&path);
|
587
|
+
GIT_ERROR_CHECK_ALLOC(repo->gitdir);
|
588
|
+
repo->commondir = git_buf_detach(&common_path);
|
589
|
+
GIT_ERROR_CHECK_ALLOC(repo->commondir);
|
431
590
|
|
432
591
|
/* of course we're bare! */
|
433
592
|
repo->is_bare = 1;
|
593
|
+
repo->is_worktree = 0;
|
434
594
|
repo->workdir = NULL;
|
435
595
|
|
436
596
|
*repo_ptr = repo;
|
437
597
|
return 0;
|
438
598
|
}
|
439
599
|
|
600
|
+
static int _git_repository_open_ext_from_env(
|
601
|
+
git_repository **out,
|
602
|
+
const char *start_path)
|
603
|
+
{
|
604
|
+
git_repository *repo = NULL;
|
605
|
+
git_index *index = NULL;
|
606
|
+
git_odb *odb = NULL;
|
607
|
+
git_buf dir_buf = GIT_BUF_INIT;
|
608
|
+
git_buf ceiling_dirs_buf = GIT_BUF_INIT;
|
609
|
+
git_buf across_fs_buf = GIT_BUF_INIT;
|
610
|
+
git_buf index_file_buf = GIT_BUF_INIT;
|
611
|
+
git_buf namespace_buf = GIT_BUF_INIT;
|
612
|
+
git_buf object_dir_buf = GIT_BUF_INIT;
|
613
|
+
git_buf alts_buf = GIT_BUF_INIT;
|
614
|
+
git_buf work_tree_buf = GIT_BUF_INIT;
|
615
|
+
git_buf common_dir_buf = GIT_BUF_INIT;
|
616
|
+
const char *ceiling_dirs = NULL;
|
617
|
+
unsigned flags = 0;
|
618
|
+
int error;
|
619
|
+
|
620
|
+
if (!start_path) {
|
621
|
+
error = git__getenv(&dir_buf, "GIT_DIR");
|
622
|
+
if (error == GIT_ENOTFOUND) {
|
623
|
+
git_error_clear();
|
624
|
+
start_path = ".";
|
625
|
+
} else if (error < 0)
|
626
|
+
goto error;
|
627
|
+
else {
|
628
|
+
start_path = git_buf_cstr(&dir_buf);
|
629
|
+
flags |= GIT_REPOSITORY_OPEN_NO_SEARCH;
|
630
|
+
flags |= GIT_REPOSITORY_OPEN_NO_DOTGIT;
|
631
|
+
}
|
632
|
+
}
|
633
|
+
|
634
|
+
error = git__getenv(&ceiling_dirs_buf, "GIT_CEILING_DIRECTORIES");
|
635
|
+
if (error == GIT_ENOTFOUND)
|
636
|
+
git_error_clear();
|
637
|
+
else if (error < 0)
|
638
|
+
goto error;
|
639
|
+
else
|
640
|
+
ceiling_dirs = git_buf_cstr(&ceiling_dirs_buf);
|
641
|
+
|
642
|
+
error = git__getenv(&across_fs_buf, "GIT_DISCOVERY_ACROSS_FILESYSTEM");
|
643
|
+
if (error == GIT_ENOTFOUND)
|
644
|
+
git_error_clear();
|
645
|
+
else if (error < 0)
|
646
|
+
goto error;
|
647
|
+
else {
|
648
|
+
int across_fs = 0;
|
649
|
+
error = git_config_parse_bool(&across_fs, git_buf_cstr(&across_fs_buf));
|
650
|
+
if (error < 0)
|
651
|
+
goto error;
|
652
|
+
if (across_fs)
|
653
|
+
flags |= GIT_REPOSITORY_OPEN_CROSS_FS;
|
654
|
+
}
|
655
|
+
|
656
|
+
error = git__getenv(&index_file_buf, "GIT_INDEX_FILE");
|
657
|
+
if (error == GIT_ENOTFOUND)
|
658
|
+
git_error_clear();
|
659
|
+
else if (error < 0)
|
660
|
+
goto error;
|
661
|
+
else {
|
662
|
+
error = git_index_open(&index, git_buf_cstr(&index_file_buf));
|
663
|
+
if (error < 0)
|
664
|
+
goto error;
|
665
|
+
}
|
666
|
+
|
667
|
+
error = git__getenv(&namespace_buf, "GIT_NAMESPACE");
|
668
|
+
if (error == GIT_ENOTFOUND)
|
669
|
+
git_error_clear();
|
670
|
+
else if (error < 0)
|
671
|
+
goto error;
|
672
|
+
|
673
|
+
error = git__getenv(&object_dir_buf, "GIT_OBJECT_DIRECTORY");
|
674
|
+
if (error == GIT_ENOTFOUND)
|
675
|
+
git_error_clear();
|
676
|
+
else if (error < 0)
|
677
|
+
goto error;
|
678
|
+
else {
|
679
|
+
error = git_odb_open(&odb, git_buf_cstr(&object_dir_buf));
|
680
|
+
if (error < 0)
|
681
|
+
goto error;
|
682
|
+
}
|
683
|
+
|
684
|
+
error = git__getenv(&work_tree_buf, "GIT_WORK_TREE");
|
685
|
+
if (error == GIT_ENOTFOUND)
|
686
|
+
git_error_clear();
|
687
|
+
else if (error < 0)
|
688
|
+
goto error;
|
689
|
+
else {
|
690
|
+
git_error_set(GIT_ERROR_INVALID, "GIT_WORK_TREE unimplemented");
|
691
|
+
error = GIT_ERROR;
|
692
|
+
goto error;
|
693
|
+
}
|
694
|
+
|
695
|
+
error = git__getenv(&work_tree_buf, "GIT_COMMON_DIR");
|
696
|
+
if (error == GIT_ENOTFOUND)
|
697
|
+
git_error_clear();
|
698
|
+
else if (error < 0)
|
699
|
+
goto error;
|
700
|
+
else {
|
701
|
+
git_error_set(GIT_ERROR_INVALID, "GIT_COMMON_DIR unimplemented");
|
702
|
+
error = GIT_ERROR;
|
703
|
+
goto error;
|
704
|
+
}
|
705
|
+
|
706
|
+
error = git_repository_open_ext(&repo, start_path, flags, ceiling_dirs);
|
707
|
+
if (error < 0)
|
708
|
+
goto error;
|
709
|
+
|
710
|
+
if (odb)
|
711
|
+
git_repository_set_odb(repo, odb);
|
712
|
+
|
713
|
+
error = git__getenv(&alts_buf, "GIT_ALTERNATE_OBJECT_DIRECTORIES");
|
714
|
+
if (error == GIT_ENOTFOUND) {
|
715
|
+
git_error_clear();
|
716
|
+
error = 0;
|
717
|
+
} else if (error < 0)
|
718
|
+
goto error;
|
719
|
+
else {
|
720
|
+
const char *end;
|
721
|
+
char *alt, *sep;
|
722
|
+
if (!odb) {
|
723
|
+
error = git_repository_odb(&odb, repo);
|
724
|
+
if (error < 0)
|
725
|
+
goto error;
|
726
|
+
}
|
727
|
+
|
728
|
+
end = git_buf_cstr(&alts_buf) + git_buf_len(&alts_buf);
|
729
|
+
for (sep = alt = alts_buf.ptr; sep != end; alt = sep+1) {
|
730
|
+
for (sep = alt; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++)
|
731
|
+
;
|
732
|
+
if (*sep)
|
733
|
+
*sep = '\0';
|
734
|
+
error = git_odb_add_disk_alternate(odb, alt);
|
735
|
+
if (error < 0)
|
736
|
+
goto error;
|
737
|
+
}
|
738
|
+
}
|
739
|
+
|
740
|
+
if (git_buf_len(&namespace_buf)) {
|
741
|
+
error = git_repository_set_namespace(repo, git_buf_cstr(&namespace_buf));
|
742
|
+
if (error < 0)
|
743
|
+
goto error;
|
744
|
+
}
|
745
|
+
|
746
|
+
git_repository_set_index(repo, index);
|
747
|
+
|
748
|
+
if (out) {
|
749
|
+
*out = repo;
|
750
|
+
goto success;
|
751
|
+
}
|
752
|
+
error:
|
753
|
+
git_repository_free(repo);
|
754
|
+
success:
|
755
|
+
git_odb_free(odb);
|
756
|
+
git_index_free(index);
|
757
|
+
git_buf_dispose(&common_dir_buf);
|
758
|
+
git_buf_dispose(&work_tree_buf);
|
759
|
+
git_buf_dispose(&alts_buf);
|
760
|
+
git_buf_dispose(&object_dir_buf);
|
761
|
+
git_buf_dispose(&namespace_buf);
|
762
|
+
git_buf_dispose(&index_file_buf);
|
763
|
+
git_buf_dispose(&across_fs_buf);
|
764
|
+
git_buf_dispose(&ceiling_dirs_buf);
|
765
|
+
git_buf_dispose(&dir_buf);
|
766
|
+
return error;
|
767
|
+
}
|
768
|
+
|
769
|
+
static int repo_is_worktree(unsigned *out, const git_repository *repo)
|
770
|
+
{
|
771
|
+
git_buf gitdir_link = GIT_BUF_INIT;
|
772
|
+
int error;
|
773
|
+
|
774
|
+
/* Worktrees cannot have the same commondir and gitdir */
|
775
|
+
if (repo->commondir && repo->gitdir
|
776
|
+
&& !strcmp(repo->commondir, repo->gitdir)) {
|
777
|
+
*out = 0;
|
778
|
+
return 0;
|
779
|
+
}
|
780
|
+
|
781
|
+
if ((error = git_buf_joinpath(&gitdir_link, repo->gitdir, "gitdir")) < 0)
|
782
|
+
return -1;
|
783
|
+
|
784
|
+
/* A 'gitdir' file inside a git directory is currently
|
785
|
+
* only used when the repository is a working tree. */
|
786
|
+
*out = !!git_path_exists(gitdir_link.ptr);
|
787
|
+
|
788
|
+
git_buf_dispose(&gitdir_link);
|
789
|
+
return error;
|
790
|
+
}
|
791
|
+
|
440
792
|
int git_repository_open_ext(
|
441
793
|
git_repository **repo_ptr,
|
442
794
|
const char *start_path,
|
@@ -444,32 +796,76 @@ int git_repository_open_ext(
|
|
444
796
|
const char *ceiling_dirs)
|
445
797
|
{
|
446
798
|
int error;
|
447
|
-
|
799
|
+
unsigned is_worktree;
|
800
|
+
git_buf gitdir = GIT_BUF_INIT, workdir = GIT_BUF_INIT,
|
801
|
+
gitlink = GIT_BUF_INIT, commondir = GIT_BUF_INIT;
|
448
802
|
git_repository *repo;
|
803
|
+
git_config *config = NULL;
|
804
|
+
|
805
|
+
if (flags & GIT_REPOSITORY_OPEN_FROM_ENV)
|
806
|
+
return _git_repository_open_ext_from_env(repo_ptr, start_path);
|
449
807
|
|
450
808
|
if (repo_ptr)
|
451
809
|
*repo_ptr = NULL;
|
452
810
|
|
453
|
-
error = find_repo(
|
811
|
+
error = find_repo(
|
812
|
+
&gitdir, &workdir, &gitlink, &commondir, start_path, flags, ceiling_dirs);
|
813
|
+
|
454
814
|
if (error < 0 || !repo_ptr)
|
455
815
|
return error;
|
456
816
|
|
457
817
|
repo = repository_alloc();
|
458
|
-
|
818
|
+
GIT_ERROR_CHECK_ALLOC(repo);
|
459
819
|
|
460
|
-
repo->
|
461
|
-
|
820
|
+
repo->gitdir = git_buf_detach(&gitdir);
|
821
|
+
GIT_ERROR_CHECK_ALLOC(repo->gitdir);
|
462
822
|
|
463
|
-
if (
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
823
|
+
if (gitlink.size) {
|
824
|
+
repo->gitlink = git_buf_detach(&gitlink);
|
825
|
+
GIT_ERROR_CHECK_ALLOC(repo->gitlink);
|
826
|
+
}
|
827
|
+
if (commondir.size) {
|
828
|
+
repo->commondir = git_buf_detach(&commondir);
|
829
|
+
GIT_ERROR_CHECK_ALLOC(repo->commondir);
|
468
830
|
}
|
469
831
|
|
470
|
-
|
471
|
-
|
472
|
-
|
832
|
+
if ((error = repo_is_worktree(&is_worktree, repo)) < 0)
|
833
|
+
goto cleanup;
|
834
|
+
repo->is_worktree = is_worktree;
|
835
|
+
|
836
|
+
/*
|
837
|
+
* We'd like to have the config, but git doesn't particularly
|
838
|
+
* care if it's not there, so we need to deal with that.
|
839
|
+
*/
|
840
|
+
|
841
|
+
error = git_repository_config_snapshot(&config, repo);
|
842
|
+
if (error < 0 && error != GIT_ENOTFOUND)
|
843
|
+
goto cleanup;
|
844
|
+
|
845
|
+
if (config && (error = check_repositoryformatversion(config)) < 0)
|
846
|
+
goto cleanup;
|
847
|
+
|
848
|
+
if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0)
|
849
|
+
repo->is_bare = 1;
|
850
|
+
else {
|
851
|
+
|
852
|
+
if (config &&
|
853
|
+
((error = load_config_data(repo, config)) < 0 ||
|
854
|
+
(error = load_workdir(repo, config, &workdir)) < 0))
|
855
|
+
goto cleanup;
|
856
|
+
}
|
857
|
+
|
858
|
+
cleanup:
|
859
|
+
git_buf_dispose(&gitdir);
|
860
|
+
git_buf_dispose(&workdir);
|
861
|
+
git_config_free(config);
|
862
|
+
|
863
|
+
if (error < 0)
|
864
|
+
git_repository_free(repo);
|
865
|
+
else
|
866
|
+
*repo_ptr = repo;
|
867
|
+
|
868
|
+
return error;
|
473
869
|
}
|
474
870
|
|
475
871
|
int git_repository_open(git_repository **repo_out, const char *path)
|
@@ -478,12 +874,42 @@ int git_repository_open(git_repository **repo_out, const char *path)
|
|
478
874
|
repo_out, path, GIT_REPOSITORY_OPEN_NO_SEARCH, NULL);
|
479
875
|
}
|
480
876
|
|
877
|
+
int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *wt)
|
878
|
+
{
|
879
|
+
git_buf path = GIT_BUF_INIT;
|
880
|
+
git_repository *repo = NULL;
|
881
|
+
int len, err;
|
882
|
+
|
883
|
+
assert(repo_out && wt);
|
884
|
+
|
885
|
+
*repo_out = NULL;
|
886
|
+
len = strlen(wt->gitlink_path);
|
887
|
+
|
888
|
+
if (len <= 4 || strcasecmp(wt->gitlink_path + len - 4, ".git")) {
|
889
|
+
err = -1;
|
890
|
+
goto out;
|
891
|
+
}
|
892
|
+
|
893
|
+
if ((err = git_buf_set(&path, wt->gitlink_path, len - 4)) < 0)
|
894
|
+
goto out;
|
895
|
+
|
896
|
+
if ((err = git_repository_open(&repo, path.ptr)) < 0)
|
897
|
+
goto out;
|
898
|
+
|
899
|
+
*repo_out = repo;
|
900
|
+
|
901
|
+
out:
|
902
|
+
git_buf_dispose(&path);
|
903
|
+
|
904
|
+
return err;
|
905
|
+
}
|
906
|
+
|
481
907
|
int git_repository_wrap_odb(git_repository **repo_out, git_odb *odb)
|
482
908
|
{
|
483
909
|
git_repository *repo;
|
484
910
|
|
485
911
|
repo = repository_alloc();
|
486
|
-
|
912
|
+
GIT_ERROR_CHECK_ALLOC(repo);
|
487
913
|
|
488
914
|
git_repository_set_odb(repo, odb);
|
489
915
|
*repo_out = repo;
|
@@ -492,34 +918,18 @@ int git_repository_wrap_odb(git_repository **repo_out, git_odb *odb)
|
|
492
918
|
}
|
493
919
|
|
494
920
|
int git_repository_discover(
|
495
|
-
|
496
|
-
size_t size,
|
921
|
+
git_buf *out,
|
497
922
|
const char *start_path,
|
498
923
|
int across_fs,
|
499
924
|
const char *ceiling_dirs)
|
500
925
|
{
|
501
|
-
git_buf path = GIT_BUF_INIT;
|
502
926
|
uint32_t flags = across_fs ? GIT_REPOSITORY_OPEN_CROSS_FS : 0;
|
503
|
-
int error;
|
504
|
-
|
505
|
-
assert(start_path && repository_path && size > 0);
|
506
927
|
|
507
|
-
|
928
|
+
assert(start_path);
|
508
929
|
|
509
|
-
|
510
|
-
return error != GIT_ENOTFOUND ? -1 : error;
|
511
|
-
|
512
|
-
if (size < (size_t)(path.size + 1)) {
|
513
|
-
giterr_set(GITERR_REPOSITORY,
|
514
|
-
"The given buffer is too small to store the discovered path");
|
515
|
-
git_buf_free(&path);
|
516
|
-
return -1;
|
517
|
-
}
|
930
|
+
git_buf_sanitize(out);
|
518
931
|
|
519
|
-
|
520
|
-
git_buf_copy_cstr(repository_path, size, &path);
|
521
|
-
git_buf_free(&path);
|
522
|
-
return 0;
|
932
|
+
return find_repo(out, NULL, NULL, NULL, start_path, flags, ceiling_dirs);
|
523
933
|
}
|
524
934
|
|
525
935
|
static int load_config(
|
@@ -527,54 +937,59 @@ static int load_config(
|
|
527
937
|
git_repository *repo,
|
528
938
|
const char *global_config_path,
|
529
939
|
const char *xdg_config_path,
|
530
|
-
const char *system_config_path
|
940
|
+
const char *system_config_path,
|
941
|
+
const char *programdata_path)
|
531
942
|
{
|
532
943
|
int error;
|
533
944
|
git_buf config_path = GIT_BUF_INIT;
|
534
945
|
git_config *cfg = NULL;
|
535
946
|
|
536
|
-
assert(
|
947
|
+
assert(out);
|
537
948
|
|
538
949
|
if ((error = git_config_new(&cfg)) < 0)
|
539
950
|
return error;
|
540
951
|
|
541
|
-
|
542
|
-
&config_path, repo
|
543
|
-
|
544
|
-
goto on_error;
|
952
|
+
if (repo) {
|
953
|
+
if ((error = git_repository_item_path(&config_path, repo, GIT_REPOSITORY_ITEM_CONFIG)) == 0)
|
954
|
+
error = git_config_add_file_ondisk(cfg, config_path.ptr, GIT_CONFIG_LEVEL_LOCAL, repo, 0);
|
545
955
|
|
546
|
-
|
547
|
-
|
548
|
-
error != GIT_ENOTFOUND)
|
549
|
-
goto on_error;
|
956
|
+
if (error && error != GIT_ENOTFOUND)
|
957
|
+
goto on_error;
|
550
958
|
|
551
|
-
|
959
|
+
git_buf_dispose(&config_path);
|
960
|
+
}
|
552
961
|
|
553
962
|
if (global_config_path != NULL &&
|
554
963
|
(error = git_config_add_file_ondisk(
|
555
|
-
cfg, global_config_path, GIT_CONFIG_LEVEL_GLOBAL, 0)) < 0 &&
|
964
|
+
cfg, global_config_path, GIT_CONFIG_LEVEL_GLOBAL, repo, 0)) < 0 &&
|
556
965
|
error != GIT_ENOTFOUND)
|
557
966
|
goto on_error;
|
558
967
|
|
559
968
|
if (xdg_config_path != NULL &&
|
560
969
|
(error = git_config_add_file_ondisk(
|
561
|
-
cfg, xdg_config_path, GIT_CONFIG_LEVEL_XDG, 0)) < 0 &&
|
970
|
+
cfg, xdg_config_path, GIT_CONFIG_LEVEL_XDG, repo, 0)) < 0 &&
|
562
971
|
error != GIT_ENOTFOUND)
|
563
972
|
goto on_error;
|
564
973
|
|
565
974
|
if (system_config_path != NULL &&
|
566
975
|
(error = git_config_add_file_ondisk(
|
567
|
-
cfg, system_config_path, GIT_CONFIG_LEVEL_SYSTEM, 0)) < 0 &&
|
976
|
+
cfg, system_config_path, GIT_CONFIG_LEVEL_SYSTEM, repo, 0)) < 0 &&
|
977
|
+
error != GIT_ENOTFOUND)
|
978
|
+
goto on_error;
|
979
|
+
|
980
|
+
if (programdata_path != NULL &&
|
981
|
+
(error = git_config_add_file_ondisk(
|
982
|
+
cfg, programdata_path, GIT_CONFIG_LEVEL_PROGRAMDATA, repo, 0)) < 0 &&
|
568
983
|
error != GIT_ENOTFOUND)
|
569
984
|
goto on_error;
|
570
985
|
|
571
|
-
|
986
|
+
git_error_clear(); /* clear any lingering ENOTFOUND errors */
|
572
987
|
|
573
988
|
*out = cfg;
|
574
989
|
return 0;
|
575
990
|
|
576
991
|
on_error:
|
577
|
-
|
992
|
+
git_buf_dispose(&config_path);
|
578
993
|
git_config_free(cfg);
|
579
994
|
*out = NULL;
|
580
995
|
return error;
|
@@ -593,11 +1008,13 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo)
|
|
593
1008
|
git_buf global_buf = GIT_BUF_INIT;
|
594
1009
|
git_buf xdg_buf = GIT_BUF_INIT;
|
595
1010
|
git_buf system_buf = GIT_BUF_INIT;
|
1011
|
+
git_buf programdata_buf = GIT_BUF_INIT;
|
596
1012
|
git_config *config;
|
597
1013
|
|
598
|
-
|
599
|
-
|
600
|
-
|
1014
|
+
git_config_find_global(&global_buf);
|
1015
|
+
git_config_find_xdg(&xdg_buf);
|
1016
|
+
git_config_find_system(&system_buf);
|
1017
|
+
git_config_find_programdata(&programdata_buf);
|
601
1018
|
|
602
1019
|
/* If there is no global file, open a backend for it anyway */
|
603
1020
|
if (git_buf_len(&global_buf) == 0)
|
@@ -607,7 +1024,8 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo)
|
|
607
1024
|
&config, repo,
|
608
1025
|
path_unless_empty(&global_buf),
|
609
1026
|
path_unless_empty(&xdg_buf),
|
610
|
-
path_unless_empty(&system_buf)
|
1027
|
+
path_unless_empty(&system_buf),
|
1028
|
+
path_unless_empty(&programdata_buf));
|
611
1029
|
if (!error) {
|
612
1030
|
GIT_REFCOUNT_OWN(config, repo);
|
613
1031
|
|
@@ -618,9 +1036,10 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo)
|
|
618
1036
|
}
|
619
1037
|
}
|
620
1038
|
|
621
|
-
|
622
|
-
|
623
|
-
|
1039
|
+
git_buf_dispose(&global_buf);
|
1040
|
+
git_buf_dispose(&xdg_buf);
|
1041
|
+
git_buf_dispose(&system_buf);
|
1042
|
+
git_buf_dispose(&programdata_buf);
|
624
1043
|
}
|
625
1044
|
|
626
1045
|
*out = repo->_config;
|
@@ -636,6 +1055,17 @@ int git_repository_config(git_config **out, git_repository *repo)
|
|
636
1055
|
return 0;
|
637
1056
|
}
|
638
1057
|
|
1058
|
+
int git_repository_config_snapshot(git_config **out, git_repository *repo)
|
1059
|
+
{
|
1060
|
+
int error;
|
1061
|
+
git_config *weak;
|
1062
|
+
|
1063
|
+
if ((error = git_repository_config__weakptr(&weak, repo)) < 0)
|
1064
|
+
return error;
|
1065
|
+
|
1066
|
+
return git_config_snapshot(out, weak);
|
1067
|
+
}
|
1068
|
+
|
639
1069
|
void git_repository_set_config(git_repository *repo, git_config *config)
|
640
1070
|
{
|
641
1071
|
assert(repo && config);
|
@@ -652,20 +1082,26 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
|
|
652
1082
|
git_buf odb_path = GIT_BUF_INIT;
|
653
1083
|
git_odb *odb;
|
654
1084
|
|
655
|
-
|
1085
|
+
if ((error = git_repository_item_path(&odb_path, repo,
|
1086
|
+
GIT_REPOSITORY_ITEM_OBJECTS)) < 0 ||
|
1087
|
+
(error = git_odb_new(&odb)) < 0)
|
1088
|
+
return error;
|
1089
|
+
|
1090
|
+
GIT_REFCOUNT_OWN(odb, repo);
|
656
1091
|
|
657
|
-
error =
|
658
|
-
|
659
|
-
|
1092
|
+
if ((error = git_odb__set_caps(odb, GIT_ODB_CAP_FROM_OWNER)) < 0 ||
|
1093
|
+
(error = git_odb__add_default_backends(odb, odb_path.ptr, 0, 0)) < 0) {
|
1094
|
+
git_odb_free(odb);
|
1095
|
+
return error;
|
1096
|
+
}
|
660
1097
|
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
}
|
1098
|
+
odb = git__compare_and_swap(&repo->_odb, NULL, odb);
|
1099
|
+
if (odb != NULL) {
|
1100
|
+
GIT_REFCOUNT_OWN(odb, NULL);
|
1101
|
+
git_odb_free(odb);
|
666
1102
|
}
|
667
1103
|
|
668
|
-
|
1104
|
+
git_buf_dispose(&odb_path);
|
669
1105
|
}
|
670
1106
|
|
671
1107
|
*out = repo->_odb;
|
@@ -737,7 +1173,8 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo)
|
|
737
1173
|
git_buf index_path = GIT_BUF_INIT;
|
738
1174
|
git_index *index;
|
739
1175
|
|
740
|
-
git_buf_joinpath(&index_path, repo->
|
1176
|
+
if ((error = git_buf_joinpath(&index_path, repo->gitdir, GIT_INDEX_FILE)) < 0)
|
1177
|
+
return error;
|
741
1178
|
|
742
1179
|
error = git_index_open(&index, index_path.ptr);
|
743
1180
|
if (!error) {
|
@@ -749,10 +1186,11 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo)
|
|
749
1186
|
git_index_free(index);
|
750
1187
|
}
|
751
1188
|
|
752
|
-
error = git_index_set_caps(repo->_index,
|
1189
|
+
error = git_index_set_caps(repo->_index,
|
1190
|
+
GIT_INDEX_CAPABILITY_FROM_OWNER);
|
753
1191
|
}
|
754
1192
|
|
755
|
-
|
1193
|
+
git_buf_dispose(&index_path);
|
756
1194
|
}
|
757
1195
|
|
758
1196
|
*out = repo->_index;
|
@@ -770,7 +1208,7 @@ int git_repository_index(git_index **out, git_repository *repo)
|
|
770
1208
|
|
771
1209
|
void git_repository_set_index(git_repository *repo, git_index *index)
|
772
1210
|
{
|
773
|
-
assert(repo
|
1211
|
+
assert(repo);
|
774
1212
|
set_index(repo, index);
|
775
1213
|
}
|
776
1214
|
|
@@ -791,31 +1229,138 @@ const char *git_repository_get_namespace(git_repository *repo)
|
|
791
1229
|
return repo->namespace;
|
792
1230
|
}
|
793
1231
|
|
794
|
-
|
1232
|
+
#ifdef GIT_WIN32
|
1233
|
+
static int reserved_names_add8dot3(git_repository *repo, const char *path)
|
795
1234
|
{
|
796
|
-
|
1235
|
+
char *name = git_win32_path_8dot3_name(path);
|
1236
|
+
const char *def = GIT_DIR_SHORTNAME;
|
1237
|
+
const char *def_dot_git = DOT_GIT;
|
1238
|
+
size_t name_len, def_len = CONST_STRLEN(GIT_DIR_SHORTNAME);
|
1239
|
+
size_t def_dot_git_len = CONST_STRLEN(DOT_GIT);
|
1240
|
+
git_buf *buf;
|
797
1241
|
|
798
|
-
if (
|
799
|
-
return
|
1242
|
+
if (!name)
|
1243
|
+
return 0;
|
800
1244
|
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
1245
|
+
name_len = strlen(name);
|
1246
|
+
|
1247
|
+
if ((name_len == def_len && memcmp(name, def, def_len) == 0) ||
|
1248
|
+
(name_len == def_dot_git_len && memcmp(name, def_dot_git, def_dot_git_len) == 0)) {
|
1249
|
+
git__free(name);
|
1250
|
+
return 0;
|
806
1251
|
}
|
807
1252
|
|
808
|
-
|
1253
|
+
if ((buf = git_array_alloc(repo->reserved_names)) == NULL)
|
1254
|
+
return -1;
|
1255
|
+
|
1256
|
+
git_buf_attach(buf, name, name_len);
|
1257
|
+
return true;
|
809
1258
|
}
|
810
1259
|
|
811
|
-
|
1260
|
+
bool git_repository__reserved_names(
|
1261
|
+
git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs)
|
812
1262
|
{
|
813
|
-
|
814
|
-
|
815
|
-
|
1263
|
+
GIT_UNUSED(include_ntfs);
|
1264
|
+
|
1265
|
+
if (repo->reserved_names.size == 0) {
|
1266
|
+
git_buf *buf;
|
1267
|
+
size_t i;
|
1268
|
+
|
1269
|
+
/* Add the static defaults */
|
1270
|
+
for (i = 0; i < git_repository__reserved_names_win32_len; i++) {
|
1271
|
+
if ((buf = git_array_alloc(repo->reserved_names)) == NULL)
|
1272
|
+
goto on_error;
|
1273
|
+
|
1274
|
+
buf->ptr = git_repository__reserved_names_win32[i].ptr;
|
1275
|
+
buf->size = git_repository__reserved_names_win32[i].size;
|
1276
|
+
}
|
1277
|
+
|
1278
|
+
/* Try to add any repo-specific reserved names - the gitlink file
|
1279
|
+
* within a submodule or the repository (if the repository directory
|
1280
|
+
* is beneath the workdir). These are typically `.git`, but should
|
1281
|
+
* be protected in case they are not. Note, repo and workdir paths
|
1282
|
+
* are always prettified to end in `/`, so a prefixcmp is safe.
|
1283
|
+
*/
|
1284
|
+
if (!repo->is_bare) {
|
1285
|
+
int (*prefixcmp)(const char *, const char *);
|
1286
|
+
int error, ignorecase;
|
1287
|
+
|
1288
|
+
error = git_repository__cvar(
|
1289
|
+
&ignorecase, repo, GIT_CVAR_IGNORECASE);
|
1290
|
+
prefixcmp = (error || ignorecase) ? git__prefixcmp_icase :
|
1291
|
+
git__prefixcmp;
|
1292
|
+
|
1293
|
+
if (repo->gitlink &&
|
1294
|
+
reserved_names_add8dot3(repo, repo->gitlink) < 0)
|
1295
|
+
goto on_error;
|
1296
|
+
|
1297
|
+
if (repo->gitdir &&
|
1298
|
+
prefixcmp(repo->gitdir, repo->workdir) == 0 &&
|
1299
|
+
reserved_names_add8dot3(repo, repo->gitdir) < 0)
|
1300
|
+
goto on_error;
|
1301
|
+
}
|
1302
|
+
}
|
1303
|
+
|
1304
|
+
*out = repo->reserved_names.ptr;
|
1305
|
+
*outlen = repo->reserved_names.size;
|
1306
|
+
|
1307
|
+
return true;
|
1308
|
+
|
1309
|
+
/* Always give good defaults, even on OOM */
|
1310
|
+
on_error:
|
1311
|
+
*out = git_repository__reserved_names_win32;
|
1312
|
+
*outlen = git_repository__reserved_names_win32_len;
|
1313
|
+
|
1314
|
+
return false;
|
1315
|
+
}
|
1316
|
+
#else
|
1317
|
+
bool git_repository__reserved_names(
|
1318
|
+
git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs)
|
1319
|
+
{
|
1320
|
+
GIT_UNUSED(repo);
|
1321
|
+
|
1322
|
+
if (include_ntfs) {
|
1323
|
+
*out = git_repository__reserved_names_win32;
|
1324
|
+
*outlen = git_repository__reserved_names_win32_len;
|
1325
|
+
} else {
|
1326
|
+
*out = git_repository__reserved_names_posix;
|
1327
|
+
*outlen = git_repository__reserved_names_posix_len;
|
1328
|
+
}
|
1329
|
+
|
1330
|
+
return true;
|
1331
|
+
}
|
1332
|
+
#endif
|
1333
|
+
|
1334
|
+
static int check_repositoryformatversion(git_config *config)
|
1335
|
+
{
|
1336
|
+
int version, error;
|
1337
|
+
|
1338
|
+
error = git_config_get_int32(&version, config, "core.repositoryformatversion");
|
1339
|
+
/* git ignores this if the config variable isn't there */
|
1340
|
+
if (error == GIT_ENOTFOUND)
|
1341
|
+
return 0;
|
1342
|
+
|
1343
|
+
if (error < 0)
|
1344
|
+
return -1;
|
1345
|
+
|
1346
|
+
if (GIT_REPO_VERSION < version) {
|
1347
|
+
git_error_set(GIT_ERROR_REPOSITORY,
|
1348
|
+
"unsupported repository version %d. Only versions up to %d are supported.",
|
1349
|
+
version, GIT_REPO_VERSION);
|
1350
|
+
return -1;
|
1351
|
+
}
|
1352
|
+
|
1353
|
+
return 0;
|
1354
|
+
}
|
1355
|
+
|
1356
|
+
int git_repository_create_head(const char *git_dir, const char *ref_name)
|
1357
|
+
{
|
1358
|
+
git_buf ref_path = GIT_BUF_INIT;
|
1359
|
+
git_filebuf ref = GIT_FILEBUF_INIT;
|
1360
|
+
const char *fmt;
|
816
1361
|
|
817
1362
|
if (git_buf_joinpath(&ref_path, git_dir, GIT_HEAD_FILE) < 0 ||
|
818
|
-
git_filebuf_open(&ref, ref_path.ptr, 0) < 0)
|
1363
|
+
git_filebuf_open(&ref, ref_path.ptr, 0, GIT_REFS_FILE_MODE) < 0)
|
819
1364
|
goto fail;
|
820
1365
|
|
821
1366
|
if (!ref_name)
|
@@ -827,14 +1372,14 @@ static int repo_init_create_head(const char *git_dir, const char *ref_name)
|
|
827
1372
|
fmt = "ref: " GIT_REFS_HEADS_DIR "%s\n";
|
828
1373
|
|
829
1374
|
if (git_filebuf_printf(&ref, fmt, ref_name) < 0 ||
|
830
|
-
git_filebuf_commit(&ref
|
1375
|
+
git_filebuf_commit(&ref) < 0)
|
831
1376
|
goto fail;
|
832
1377
|
|
833
|
-
|
1378
|
+
git_buf_dispose(&ref_path);
|
834
1379
|
return 0;
|
835
1380
|
|
836
1381
|
fail:
|
837
|
-
|
1382
|
+
git_buf_dispose(&ref_path);
|
838
1383
|
git_filebuf_cleanup(&ref);
|
839
1384
|
return -1;
|
840
1385
|
}
|
@@ -842,10 +1387,6 @@ fail:
|
|
842
1387
|
static bool is_chmod_supported(const char *file_path)
|
843
1388
|
{
|
844
1389
|
struct stat st1, st2;
|
845
|
-
static int _is_supported = -1;
|
846
|
-
|
847
|
-
if (_is_supported > -1)
|
848
|
-
return _is_supported;
|
849
1390
|
|
850
1391
|
if (p_stat(file_path, &st1) < 0)
|
851
1392
|
return false;
|
@@ -856,52 +1397,76 @@ static bool is_chmod_supported(const char *file_path)
|
|
856
1397
|
if (p_stat(file_path, &st2) < 0)
|
857
1398
|
return false;
|
858
1399
|
|
859
|
-
|
860
|
-
|
861
|
-
return _is_supported;
|
1400
|
+
return (st1.st_mode != st2.st_mode);
|
862
1401
|
}
|
863
1402
|
|
864
1403
|
static bool is_filesystem_case_insensitive(const char *gitdir_path)
|
865
1404
|
{
|
866
1405
|
git_buf path = GIT_BUF_INIT;
|
867
|
-
|
868
|
-
|
869
|
-
if (_is_insensitive > -1)
|
870
|
-
return _is_insensitive;
|
1406
|
+
int is_insensitive = -1;
|
871
1407
|
|
872
|
-
if (git_buf_joinpath(&path, gitdir_path, "CoNfIg")
|
873
|
-
|
874
|
-
|
875
|
-
_is_insensitive = git_path_exists(git_buf_cstr(&path));
|
1408
|
+
if (!git_buf_joinpath(&path, gitdir_path, "CoNfIg"))
|
1409
|
+
is_insensitive = git_path_exists(git_buf_cstr(&path));
|
876
1410
|
|
877
|
-
|
878
|
-
|
879
|
-
return _is_insensitive;
|
1411
|
+
git_buf_dispose(&path);
|
1412
|
+
return is_insensitive;
|
880
1413
|
}
|
881
1414
|
|
882
1415
|
static bool are_symlinks_supported(const char *wd_path)
|
883
1416
|
{
|
1417
|
+
git_config *config = NULL;
|
1418
|
+
git_buf global_buf = GIT_BUF_INIT;
|
1419
|
+
git_buf xdg_buf = GIT_BUF_INIT;
|
1420
|
+
git_buf system_buf = GIT_BUF_INIT;
|
1421
|
+
git_buf programdata_buf = GIT_BUF_INIT;
|
884
1422
|
git_buf path = GIT_BUF_INIT;
|
885
1423
|
int fd;
|
886
1424
|
struct stat st;
|
887
|
-
|
1425
|
+
int symlinks = 0;
|
1426
|
+
|
1427
|
+
/*
|
1428
|
+
* To emulate Git for Windows, symlinks on Windows must be explicitly
|
1429
|
+
* opted-in. We examine the system configuration for a core.symlinks
|
1430
|
+
* set to true. If found, we then examine the filesystem to see if
|
1431
|
+
* symlinks are _actually_ supported by the current user. If that is
|
1432
|
+
* _not_ set, then we do not test or enable symlink support.
|
1433
|
+
*/
|
1434
|
+
#ifdef GIT_WIN32
|
1435
|
+
git_config_find_global(&global_buf);
|
1436
|
+
git_config_find_xdg(&xdg_buf);
|
1437
|
+
git_config_find_system(&system_buf);
|
1438
|
+
git_config_find_programdata(&programdata_buf);
|
1439
|
+
|
1440
|
+
if (load_config(&config, NULL,
|
1441
|
+
path_unless_empty(&global_buf),
|
1442
|
+
path_unless_empty(&xdg_buf),
|
1443
|
+
path_unless_empty(&system_buf),
|
1444
|
+
path_unless_empty(&programdata_buf)) < 0)
|
1445
|
+
goto done;
|
1446
|
+
|
1447
|
+
if (git_config_get_bool(&symlinks, config, "core.symlinks") < 0 || !symlinks)
|
1448
|
+
goto done;
|
1449
|
+
#endif
|
888
1450
|
|
889
|
-
if (
|
890
|
-
|
1451
|
+
if ((fd = git_futils_mktmp(&path, wd_path, 0666)) < 0 ||
|
1452
|
+
p_close(fd) < 0 ||
|
1453
|
+
p_unlink(path.ptr) < 0 ||
|
1454
|
+
p_symlink("testing", path.ptr) < 0 ||
|
1455
|
+
p_lstat(path.ptr, &st) < 0)
|
1456
|
+
goto done;
|
891
1457
|
|
892
|
-
|
893
|
-
p_close(fd) < 0 ||
|
894
|
-
p_unlink(path.ptr) < 0 ||
|
895
|
-
p_symlink("testing", path.ptr) < 0 ||
|
896
|
-
p_lstat(path.ptr, &st) < 0)
|
897
|
-
_symlinks_supported = false;
|
898
|
-
else
|
899
|
-
_symlinks_supported = (S_ISLNK(st.st_mode) != 0);
|
1458
|
+
symlinks = (S_ISLNK(st.st_mode) != 0);
|
900
1459
|
|
901
1460
|
(void)p_unlink(path.ptr);
|
902
|
-
git_buf_free(&path);
|
903
1461
|
|
904
|
-
|
1462
|
+
done:
|
1463
|
+
git_buf_dispose(&global_buf);
|
1464
|
+
git_buf_dispose(&xdg_buf);
|
1465
|
+
git_buf_dispose(&system_buf);
|
1466
|
+
git_buf_dispose(&programdata_buf);
|
1467
|
+
git_buf_dispose(&path);
|
1468
|
+
git_config_free(config);
|
1469
|
+
return symlinks != 0;
|
905
1470
|
}
|
906
1471
|
|
907
1472
|
static int create_empty_file(const char *path, mode_t mode)
|
@@ -909,90 +1474,194 @@ static int create_empty_file(const char *path, mode_t mode)
|
|
909
1474
|
int fd;
|
910
1475
|
|
911
1476
|
if ((fd = p_creat(path, mode)) < 0) {
|
912
|
-
|
1477
|
+
git_error_set(GIT_ERROR_OS, "error while creating '%s'", path);
|
913
1478
|
return -1;
|
914
1479
|
}
|
915
1480
|
|
916
1481
|
if (p_close(fd) < 0) {
|
917
|
-
|
1482
|
+
git_error_set(GIT_ERROR_OS, "error while closing '%s'", path);
|
918
1483
|
return -1;
|
919
1484
|
}
|
920
1485
|
|
921
1486
|
return 0;
|
922
1487
|
}
|
923
1488
|
|
924
|
-
static int
|
1489
|
+
static int repo_local_config(
|
1490
|
+
git_config **out,
|
1491
|
+
git_buf *config_dir,
|
1492
|
+
git_repository *repo,
|
1493
|
+
const char *repo_dir)
|
1494
|
+
{
|
1495
|
+
int error = 0;
|
1496
|
+
git_config *parent;
|
1497
|
+
const char *cfg_path;
|
1498
|
+
|
1499
|
+
if (git_buf_joinpath(config_dir, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0)
|
1500
|
+
return -1;
|
1501
|
+
cfg_path = git_buf_cstr(config_dir);
|
1502
|
+
|
1503
|
+
/* make LOCAL config if missing */
|
1504
|
+
if (!git_path_isfile(cfg_path) &&
|
1505
|
+
(error = create_empty_file(cfg_path, GIT_CONFIG_FILE_MODE)) < 0)
|
1506
|
+
return error;
|
1507
|
+
|
1508
|
+
/* if no repo, just open that file directly */
|
1509
|
+
if (!repo)
|
1510
|
+
return git_config_open_ondisk(out, cfg_path);
|
1511
|
+
|
1512
|
+
/* otherwise, open parent config and get that level */
|
1513
|
+
if ((error = git_repository_config__weakptr(&parent, repo)) < 0)
|
1514
|
+
return error;
|
1515
|
+
|
1516
|
+
if (git_config_open_level(out, parent, GIT_CONFIG_LEVEL_LOCAL) < 0) {
|
1517
|
+
git_error_clear();
|
1518
|
+
|
1519
|
+
if (!(error = git_config_add_file_ondisk(
|
1520
|
+
parent, cfg_path, GIT_CONFIG_LEVEL_LOCAL, repo, false)))
|
1521
|
+
error = git_config_open_level(out, parent, GIT_CONFIG_LEVEL_LOCAL);
|
1522
|
+
}
|
1523
|
+
|
1524
|
+
git_config_free(parent);
|
1525
|
+
|
1526
|
+
return error;
|
1527
|
+
}
|
1528
|
+
|
1529
|
+
static int repo_init_fs_configs(
|
1530
|
+
git_config *cfg,
|
1531
|
+
const char *cfg_path,
|
925
1532
|
const char *repo_dir,
|
926
1533
|
const char *work_dir,
|
927
|
-
|
1534
|
+
bool update_ignorecase)
|
928
1535
|
{
|
929
1536
|
int error = 0;
|
930
|
-
git_buf cfg_path = GIT_BUF_INIT;
|
931
|
-
git_config *config = NULL;
|
932
1537
|
|
933
|
-
|
934
|
-
|
935
|
-
goto cleanup; } while (0)
|
1538
|
+
if (!work_dir)
|
1539
|
+
work_dir = repo_dir;
|
936
1540
|
|
937
|
-
if (
|
938
|
-
|
1541
|
+
if ((error = git_config_set_bool(
|
1542
|
+
cfg, "core.filemode", is_chmod_supported(cfg_path))) < 0)
|
1543
|
+
return error;
|
939
1544
|
|
940
|
-
if (!
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
1545
|
+
if (!are_symlinks_supported(work_dir)) {
|
1546
|
+
if ((error = git_config_set_bool(cfg, "core.symlinks", false)) < 0)
|
1547
|
+
return error;
|
1548
|
+
} else if (git_config_delete_entry(cfg, "core.symlinks") < 0)
|
1549
|
+
git_error_clear();
|
945
1550
|
|
946
|
-
if (
|
947
|
-
|
948
|
-
|
1551
|
+
if (update_ignorecase) {
|
1552
|
+
if (is_filesystem_case_insensitive(repo_dir)) {
|
1553
|
+
if ((error = git_config_set_bool(cfg, "core.ignorecase", true)) < 0)
|
1554
|
+
return error;
|
1555
|
+
} else if (git_config_delete_entry(cfg, "core.ignorecase") < 0)
|
1556
|
+
git_error_clear();
|
949
1557
|
}
|
950
1558
|
|
951
|
-
|
952
|
-
|
1559
|
+
#ifdef GIT_USE_ICONV
|
1560
|
+
if ((error = git_config_set_bool(
|
1561
|
+
cfg, "core.precomposeunicode",
|
1562
|
+
git_path_does_fs_decompose_unicode(work_dir))) < 0)
|
1563
|
+
return error;
|
1564
|
+
/* on non-iconv platforms, don't even set core.precomposeunicode */
|
1565
|
+
#endif
|
1566
|
+
|
1567
|
+
return 0;
|
1568
|
+
}
|
1569
|
+
|
1570
|
+
static int repo_init_config(
|
1571
|
+
const char *repo_dir,
|
1572
|
+
const char *work_dir,
|
1573
|
+
uint32_t flags,
|
1574
|
+
uint32_t mode)
|
1575
|
+
{
|
1576
|
+
int error = 0;
|
1577
|
+
git_buf cfg_path = GIT_BUF_INIT, worktree_path = GIT_BUF_INIT;
|
1578
|
+
git_config *config = NULL;
|
1579
|
+
bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0);
|
1580
|
+
bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0);
|
1581
|
+
|
1582
|
+
if ((error = repo_local_config(&config, &cfg_path, NULL, repo_dir)) < 0)
|
1583
|
+
goto cleanup;
|
1584
|
+
|
1585
|
+
if (is_reinit && (error = check_repositoryformatversion(config)) < 0)
|
953
1586
|
goto cleanup;
|
954
1587
|
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
SET_REPO_CONFIG(
|
960
|
-
|
1588
|
+
#define SET_REPO_CONFIG(TYPE, NAME, VAL) do { \
|
1589
|
+
if ((error = git_config_set_##TYPE(config, NAME, VAL)) < 0) \
|
1590
|
+
goto cleanup; } while (0)
|
1591
|
+
|
1592
|
+
SET_REPO_CONFIG(bool, "core.bare", is_bare);
|
1593
|
+
SET_REPO_CONFIG(int32, "core.repositoryformatversion", GIT_REPO_VERSION);
|
961
1594
|
|
962
|
-
if (
|
1595
|
+
if ((error = repo_init_fs_configs(
|
1596
|
+
config, cfg_path.ptr, repo_dir, work_dir, !is_reinit)) < 0)
|
1597
|
+
goto cleanup;
|
1598
|
+
|
1599
|
+
if (!is_bare) {
|
963
1600
|
SET_REPO_CONFIG(bool, "core.logallrefupdates", true);
|
964
1601
|
|
965
|
-
if (!
|
966
|
-
|
1602
|
+
if (!(flags & GIT_REPOSITORY_INIT__NATURAL_WD)) {
|
1603
|
+
if ((error = git_buf_sets(&worktree_path, work_dir)) < 0)
|
1604
|
+
goto cleanup;
|
967
1605
|
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
1606
|
+
if ((flags & GIT_REPOSITORY_INIT_RELATIVE_GITLINK))
|
1607
|
+
if ((error = git_path_make_relative(&worktree_path, repo_dir)) < 0)
|
1608
|
+
goto cleanup;
|
1609
|
+
|
1610
|
+
SET_REPO_CONFIG(string, "core.worktree", worktree_path.ptr);
|
1611
|
+
} else if (is_reinit) {
|
972
1612
|
if (git_config_delete_entry(config, "core.worktree") < 0)
|
973
|
-
|
1613
|
+
git_error_clear();
|
974
1614
|
}
|
975
|
-
} else {
|
976
|
-
if (!are_symlinks_supported(repo_dir))
|
977
|
-
SET_REPO_CONFIG(bool, "core.symlinks", false);
|
978
1615
|
}
|
979
1616
|
|
980
|
-
if (
|
981
|
-
is_filesystem_case_insensitive(repo_dir))
|
982
|
-
SET_REPO_CONFIG(bool, "core.ignorecase", true);
|
983
|
-
|
984
|
-
if (opts->mode == GIT_REPOSITORY_INIT_SHARED_GROUP) {
|
1617
|
+
if (mode == GIT_REPOSITORY_INIT_SHARED_GROUP) {
|
985
1618
|
SET_REPO_CONFIG(int32, "core.sharedrepository", 1);
|
986
1619
|
SET_REPO_CONFIG(bool, "receive.denyNonFastforwards", true);
|
987
1620
|
}
|
988
|
-
else if (
|
1621
|
+
else if (mode == GIT_REPOSITORY_INIT_SHARED_ALL) {
|
989
1622
|
SET_REPO_CONFIG(int32, "core.sharedrepository", 2);
|
990
1623
|
SET_REPO_CONFIG(bool, "receive.denyNonFastforwards", true);
|
991
1624
|
}
|
992
1625
|
|
993
1626
|
cleanup:
|
994
|
-
|
1627
|
+
git_buf_dispose(&cfg_path);
|
1628
|
+
git_buf_dispose(&worktree_path);
|
1629
|
+
git_config_free(config);
|
1630
|
+
|
1631
|
+
return error;
|
1632
|
+
}
|
1633
|
+
|
1634
|
+
static int repo_reinit_submodule_fs(git_submodule *sm, const char *n, void *p)
|
1635
|
+
{
|
1636
|
+
git_repository *smrepo = NULL;
|
1637
|
+
GIT_UNUSED(n); GIT_UNUSED(p);
|
1638
|
+
|
1639
|
+
if (git_submodule_open(&smrepo, sm) < 0 ||
|
1640
|
+
git_repository_reinit_filesystem(smrepo, true) < 0)
|
1641
|
+
git_error_clear();
|
1642
|
+
git_repository_free(smrepo);
|
1643
|
+
|
1644
|
+
return 0;
|
1645
|
+
}
|
1646
|
+
|
1647
|
+
int git_repository_reinit_filesystem(git_repository *repo, int recurse)
|
1648
|
+
{
|
1649
|
+
int error = 0;
|
1650
|
+
git_buf path = GIT_BUF_INIT;
|
1651
|
+
git_config *config = NULL;
|
1652
|
+
const char *repo_dir = git_repository_path(repo);
|
1653
|
+
|
1654
|
+
if (!(error = repo_local_config(&config, &path, repo, repo_dir)))
|
1655
|
+
error = repo_init_fs_configs(
|
1656
|
+
config, path.ptr, repo_dir, git_repository_workdir(repo), true);
|
1657
|
+
|
995
1658
|
git_config_free(config);
|
1659
|
+
git_buf_dispose(&path);
|
1660
|
+
|
1661
|
+
git_repository__cvar_cache_clear(repo);
|
1662
|
+
|
1663
|
+
if (!repo->is_bare && recurse)
|
1664
|
+
(void)git_submodule_foreach(repo, repo_reinit_submodule_fs, NULL);
|
996
1665
|
|
997
1666
|
return error;
|
998
1667
|
}
|
@@ -1028,27 +1697,28 @@ static int repo_write_template(
|
|
1028
1697
|
|
1029
1698
|
#ifdef GIT_WIN32
|
1030
1699
|
if (!error && hidden) {
|
1031
|
-
if (
|
1700
|
+
if (git_win32__set_hidden(path.ptr, true) < 0)
|
1032
1701
|
error = -1;
|
1033
1702
|
}
|
1034
1703
|
#else
|
1035
1704
|
GIT_UNUSED(hidden);
|
1036
1705
|
#endif
|
1037
1706
|
|
1038
|
-
|
1707
|
+
git_buf_dispose(&path);
|
1039
1708
|
|
1040
1709
|
if (error)
|
1041
|
-
|
1042
|
-
"
|
1710
|
+
git_error_set(GIT_ERROR_OS,
|
1711
|
+
"failed to initialize repository with template '%s'", file);
|
1043
1712
|
|
1044
1713
|
return error;
|
1045
1714
|
}
|
1046
1715
|
|
1047
1716
|
static int repo_write_gitlink(
|
1048
|
-
const char *in_dir, const char *to_repo)
|
1717
|
+
const char *in_dir, const char *to_repo, bool use_relative_path)
|
1049
1718
|
{
|
1050
1719
|
int error;
|
1051
1720
|
git_buf buf = GIT_BUF_INIT;
|
1721
|
+
git_buf path_to_repo = GIT_BUF_INIT;
|
1052
1722
|
struct stat st;
|
1053
1723
|
|
1054
1724
|
git_path_dirname_r(&buf, to_repo);
|
@@ -1068,21 +1738,28 @@ static int repo_write_gitlink(
|
|
1068
1738
|
goto cleanup;
|
1069
1739
|
|
1070
1740
|
if (!p_stat(buf.ptr, &st) && !S_ISREG(st.st_mode)) {
|
1071
|
-
|
1072
|
-
"
|
1741
|
+
git_error_set(GIT_ERROR_REPOSITORY,
|
1742
|
+
"cannot overwrite gitlink file into path '%s'", in_dir);
|
1073
1743
|
error = GIT_EEXISTS;
|
1074
1744
|
goto cleanup;
|
1075
1745
|
}
|
1076
1746
|
|
1077
1747
|
git_buf_clear(&buf);
|
1078
1748
|
|
1079
|
-
error =
|
1749
|
+
error = git_buf_sets(&path_to_repo, to_repo);
|
1750
|
+
|
1751
|
+
if (!error && use_relative_path)
|
1752
|
+
error = git_path_make_relative(&path_to_repo, in_dir);
|
1753
|
+
|
1754
|
+
if (!error)
|
1755
|
+
error = git_buf_join(&buf, ' ', GIT_FILE_CONTENT_PREFIX, path_to_repo.ptr);
|
1080
1756
|
|
1081
1757
|
if (!error)
|
1082
1758
|
error = repo_write_template(in_dir, true, DOT_GIT, 0666, true, buf.ptr);
|
1083
1759
|
|
1084
1760
|
cleanup:
|
1085
|
-
|
1761
|
+
git_buf_dispose(&buf);
|
1762
|
+
git_buf_dispose(&path_to_repo);
|
1086
1763
|
return error;
|
1087
1764
|
}
|
1088
1765
|
|
@@ -1109,13 +1786,14 @@ static int repo_init_structure(
|
|
1109
1786
|
bool external_tpl =
|
1110
1787
|
((opts->flags & GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE) != 0);
|
1111
1788
|
mode_t dmode = pick_dir_mode(opts);
|
1789
|
+
bool chmod = opts->mode != GIT_REPOSITORY_INIT_SHARED_UMASK;
|
1112
1790
|
|
1113
1791
|
/* Hide the ".git" directory */
|
1114
1792
|
#ifdef GIT_WIN32
|
1115
1793
|
if ((opts->flags & GIT_REPOSITORY_INIT__HAS_DOTGIT) != 0) {
|
1116
|
-
if (
|
1117
|
-
|
1118
|
-
"
|
1794
|
+
if (git_win32__set_hidden(repo_dir, true) < 0) {
|
1795
|
+
git_error_set(GIT_ERROR_OS,
|
1796
|
+
"failed to mark Git repository folder as hidden");
|
1119
1797
|
return -1;
|
1120
1798
|
}
|
1121
1799
|
}
|
@@ -1125,41 +1803,55 @@ static int repo_init_structure(
|
|
1125
1803
|
if ((opts->flags & GIT_REPOSITORY_INIT_BARE) == 0 &&
|
1126
1804
|
(opts->flags & GIT_REPOSITORY_INIT__NATURAL_WD) == 0)
|
1127
1805
|
{
|
1128
|
-
if (repo_write_gitlink(work_dir, repo_dir) < 0)
|
1806
|
+
if (repo_write_gitlink(work_dir, repo_dir, opts->flags & GIT_REPOSITORY_INIT_RELATIVE_GITLINK) < 0)
|
1129
1807
|
return -1;
|
1130
1808
|
}
|
1131
1809
|
|
1132
1810
|
/* Copy external template if requested */
|
1133
1811
|
if (external_tpl) {
|
1134
|
-
git_config *cfg;
|
1135
|
-
const char *tdir;
|
1812
|
+
git_config *cfg = NULL;
|
1813
|
+
const char *tdir = NULL;
|
1814
|
+
bool default_template = false;
|
1815
|
+
git_buf template_buf = GIT_BUF_INIT;
|
1136
1816
|
|
1137
1817
|
if (opts->template_path)
|
1138
1818
|
tdir = opts->template_path;
|
1139
|
-
else if ((error = git_config_open_default(&cfg))
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
git_config_free(cfg);
|
1819
|
+
else if ((error = git_config_open_default(&cfg)) >= 0) {
|
1820
|
+
if (!git_config_get_path(&template_buf, cfg, "init.templatedir"))
|
1821
|
+
tdir = template_buf.ptr;
|
1822
|
+
git_error_clear();
|
1823
|
+
}
|
1145
1824
|
|
1146
|
-
|
1147
|
-
|
1825
|
+
if (!tdir) {
|
1826
|
+
if (!(error = git_sysdir_find_template_dir(&template_buf)))
|
1827
|
+
tdir = template_buf.ptr;
|
1828
|
+
default_template = true;
|
1829
|
+
}
|
1148
1830
|
|
1149
|
-
|
1150
|
-
|
1831
|
+
/*
|
1832
|
+
* If tdir was the empty string, treat it like tdir was a path to an
|
1833
|
+
* empty directory (so, don't do any copying). This is the behavior
|
1834
|
+
* that git(1) exhibits, although it doesn't seem to be officially
|
1835
|
+
* documented.
|
1836
|
+
*/
|
1837
|
+
if (tdir && git__strcmp(tdir, "") != 0) {
|
1838
|
+
uint32_t cpflags = GIT_CPDIR_COPY_SYMLINKS |
|
1839
|
+
GIT_CPDIR_SIMPLE_TO_MODE |
|
1840
|
+
GIT_CPDIR_COPY_DOTFILES;
|
1841
|
+
if (opts->mode != GIT_REPOSITORY_INIT_SHARED_UMASK)
|
1842
|
+
cpflags |= GIT_CPDIR_CHMOD_DIRS;
|
1843
|
+
error = git_futils_cp_r(tdir, repo_dir, cpflags, dmode);
|
1151
1844
|
}
|
1152
1845
|
|
1153
|
-
|
1154
|
-
|
1155
|
-
GIT_CPDIR_SIMPLE_TO_MODE, dmode);
|
1846
|
+
git_buf_dispose(&template_buf);
|
1847
|
+
git_config_free(cfg);
|
1156
1848
|
|
1157
1849
|
if (error < 0) {
|
1158
|
-
if (
|
1850
|
+
if (!default_template)
|
1159
1851
|
return error;
|
1160
1852
|
|
1161
1853
|
/* if template was default, ignore error and use internal */
|
1162
|
-
|
1854
|
+
git_error_clear();
|
1163
1855
|
external_tpl = false;
|
1164
1856
|
error = 0;
|
1165
1857
|
}
|
@@ -1170,9 +1862,14 @@ static int repo_init_structure(
|
|
1170
1862
|
* - only create files if no external template was specified
|
1171
1863
|
*/
|
1172
1864
|
for (tpl = repo_template; !error && tpl->path; ++tpl) {
|
1173
|
-
if (!tpl->content)
|
1174
|
-
|
1175
|
-
|
1865
|
+
if (!tpl->content) {
|
1866
|
+
uint32_t mkdir_flags = GIT_MKDIR_PATH;
|
1867
|
+
if (chmod)
|
1868
|
+
mkdir_flags |= GIT_MKDIR_CHMOD;
|
1869
|
+
|
1870
|
+
error = git_futils_mkdir_relative(
|
1871
|
+
tpl->path, repo_dir, dmode, mkdir_flags, NULL);
|
1872
|
+
}
|
1176
1873
|
else if (!external_tpl) {
|
1177
1874
|
const char *content = tpl->content;
|
1178
1875
|
|
@@ -1193,7 +1890,7 @@ static int mkdir_parent(git_buf *buf, uint32_t mode, bool skip2)
|
|
1193
1890
|
* don't try to set gid or grant world write access
|
1194
1891
|
*/
|
1195
1892
|
return git_futils_mkdir(
|
1196
|
-
buf->ptr,
|
1893
|
+
buf->ptr, mode & ~(S_ISGID | 0002),
|
1197
1894
|
GIT_MKDIR_PATH | GIT_MKDIR_VERIFY_DIR |
|
1198
1895
|
(skip2 ? GIT_MKDIR_SKIP_LAST2 : GIT_MKDIR_SKIP_LAST));
|
1199
1896
|
}
|
@@ -1256,7 +1953,7 @@ static int repo_init_directories(
|
|
1256
1953
|
if (git_path_dirname_r(wd_path, repo_path->ptr) < 0)
|
1257
1954
|
return -1;
|
1258
1955
|
} else {
|
1259
|
-
|
1956
|
+
git_error_set(GIT_ERROR_REPOSITORY, "cannot pick working directory"
|
1260
1957
|
" for non-bare repository that isn't a '.git' directory");
|
1261
1958
|
return -1;
|
1262
1959
|
}
|
@@ -1297,14 +1994,14 @@ static int repo_init_directories(
|
|
1297
1994
|
/* create path #4 */
|
1298
1995
|
if (wd_path->size > 0 &&
|
1299
1996
|
(error = git_futils_mkdir(
|
1300
|
-
wd_path->ptr,
|
1997
|
+
wd_path->ptr, dirmode & ~S_ISGID,
|
1301
1998
|
GIT_MKDIR_VERIFY_DIR)) < 0)
|
1302
1999
|
return error;
|
1303
2000
|
|
1304
2001
|
/* create path #2 (if not the same as #4) */
|
1305
2002
|
if (!natural_wd &&
|
1306
2003
|
(error = git_futils_mkdir(
|
1307
|
-
repo_path->ptr,
|
2004
|
+
repo_path->ptr, dirmode & ~S_ISGID,
|
1308
2005
|
GIT_MKDIR_VERIFY_DIR | GIT_MKDIR_SKIP_LAST)) < 0)
|
1309
2006
|
return error;
|
1310
2007
|
}
|
@@ -1314,7 +2011,7 @@ static int repo_init_directories(
|
|
1314
2011
|
has_dotgit)
|
1315
2012
|
{
|
1316
2013
|
/* create path #1 */
|
1317
|
-
error = git_futils_mkdir(repo_path->ptr,
|
2014
|
+
error = git_futils_mkdir(repo_path->ptr, dirmode,
|
1318
2015
|
GIT_MKDIR_VERIFY_DIR | ((dirmode & S_ISGID) ? GIT_MKDIR_CHMOD : 0));
|
1319
2016
|
}
|
1320
2017
|
|
@@ -1360,21 +2057,24 @@ int git_repository_init_ext(
|
|
1360
2057
|
git_repository_init_options *opts)
|
1361
2058
|
{
|
1362
2059
|
int error;
|
1363
|
-
git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT
|
2060
|
+
git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT,
|
2061
|
+
common_path = GIT_BUF_INIT;
|
2062
|
+
const char *wd;
|
1364
2063
|
|
1365
2064
|
assert(out && given_repo && opts);
|
1366
2065
|
|
1367
|
-
|
2066
|
+
GIT_ERROR_CHECK_VERSION(opts, GIT_REPOSITORY_INIT_OPTIONS_VERSION, "git_repository_init_options");
|
1368
2067
|
|
1369
2068
|
error = repo_init_directories(&repo_path, &wd_path, given_repo, opts);
|
1370
2069
|
if (error < 0)
|
1371
2070
|
goto cleanup;
|
1372
2071
|
|
1373
|
-
|
2072
|
+
wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_buf_cstr(&wd_path);
|
2073
|
+
if (valid_repository_path(&repo_path, &common_path)) {
|
1374
2074
|
|
1375
2075
|
if ((opts->flags & GIT_REPOSITORY_INIT_NO_REINIT) != 0) {
|
1376
|
-
|
1377
|
-
"
|
2076
|
+
git_error_set(GIT_ERROR_REPOSITORY,
|
2077
|
+
"attempt to reinitialize '%s'", given_repo);
|
1378
2078
|
error = GIT_EEXISTS;
|
1379
2079
|
goto cleanup;
|
1380
2080
|
}
|
@@ -1382,29 +2082,30 @@ int git_repository_init_ext(
|
|
1382
2082
|
opts->flags |= GIT_REPOSITORY_INIT__IS_REINIT;
|
1383
2083
|
|
1384
2084
|
error = repo_init_config(
|
1385
|
-
|
2085
|
+
repo_path.ptr, wd, opts->flags, opts->mode);
|
1386
2086
|
|
1387
2087
|
/* TODO: reinitialize the templates */
|
1388
2088
|
}
|
1389
2089
|
else {
|
1390
2090
|
if (!(error = repo_init_structure(
|
1391
|
-
|
2091
|
+
repo_path.ptr, wd, opts)) &&
|
1392
2092
|
!(error = repo_init_config(
|
1393
|
-
|
1394
|
-
error =
|
1395
|
-
|
2093
|
+
repo_path.ptr, wd, opts->flags, opts->mode)))
|
2094
|
+
error = git_repository_create_head(
|
2095
|
+
repo_path.ptr, opts->initial_head);
|
1396
2096
|
}
|
1397
2097
|
if (error < 0)
|
1398
2098
|
goto cleanup;
|
1399
2099
|
|
1400
|
-
error = git_repository_open(out,
|
2100
|
+
error = git_repository_open(out, repo_path.ptr);
|
1401
2101
|
|
1402
2102
|
if (!error && opts->origin_url)
|
1403
2103
|
error = repo_init_create_origin(*out, opts->origin_url);
|
1404
2104
|
|
1405
2105
|
cleanup:
|
1406
|
-
|
1407
|
-
|
2106
|
+
git_buf_dispose(&common_path);
|
2107
|
+
git_buf_dispose(&repo_path);
|
2108
|
+
git_buf_dispose(&wd_path);
|
1408
2109
|
|
1409
2110
|
return error;
|
1410
2111
|
}
|
@@ -1421,7 +2122,7 @@ int git_repository_head_detached(git_repository *repo)
|
|
1421
2122
|
if (git_reference_lookup(&ref, repo, GIT_HEAD_FILE) < 0)
|
1422
2123
|
return -1;
|
1423
2124
|
|
1424
|
-
if (git_reference_type(ref) ==
|
2125
|
+
if (git_reference_type(ref) == GIT_REFERENCE_SYMBOLIC) {
|
1425
2126
|
git_reference_free(ref);
|
1426
2127
|
return 0;
|
1427
2128
|
}
|
@@ -1432,15 +2133,40 @@ int git_repository_head_detached(git_repository *repo)
|
|
1432
2133
|
return exists;
|
1433
2134
|
}
|
1434
2135
|
|
2136
|
+
static int get_worktree_file_path(git_buf *out, git_repository *repo, const char *worktree, const char *file)
|
2137
|
+
{
|
2138
|
+
git_buf_clear(out);
|
2139
|
+
return git_buf_printf(out, "%s/worktrees/%s/%s", repo->commondir, worktree, file);
|
2140
|
+
}
|
2141
|
+
|
2142
|
+
int git_repository_head_detached_for_worktree(git_repository *repo, const char *name)
|
2143
|
+
{
|
2144
|
+
git_reference *ref = NULL;
|
2145
|
+
int error;
|
2146
|
+
|
2147
|
+
assert(repo && name);
|
2148
|
+
|
2149
|
+
if ((error = git_repository_head_for_worktree(&ref, repo, name)) < 0)
|
2150
|
+
goto out;
|
2151
|
+
|
2152
|
+
error = (git_reference_type(ref) != GIT_REFERENCE_SYMBOLIC);
|
2153
|
+
out:
|
2154
|
+
git_reference_free(ref);
|
2155
|
+
|
2156
|
+
return error;
|
2157
|
+
}
|
2158
|
+
|
1435
2159
|
int git_repository_head(git_reference **head_out, git_repository *repo)
|
1436
2160
|
{
|
1437
2161
|
git_reference *head;
|
1438
2162
|
int error;
|
1439
2163
|
|
2164
|
+
assert(head_out);
|
2165
|
+
|
1440
2166
|
if ((error = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0)
|
1441
2167
|
return error;
|
1442
2168
|
|
1443
|
-
if (git_reference_type(head) ==
|
2169
|
+
if (git_reference_type(head) == GIT_REFERENCE_DIRECT) {
|
1444
2170
|
*head_out = head;
|
1445
2171
|
return 0;
|
1446
2172
|
}
|
@@ -1448,10 +2174,75 @@ int git_repository_head(git_reference **head_out, git_repository *repo)
|
|
1448
2174
|
error = git_reference_lookup_resolved(head_out, repo, git_reference_symbolic_target(head), -1);
|
1449
2175
|
git_reference_free(head);
|
1450
2176
|
|
1451
|
-
return error == GIT_ENOTFOUND ?
|
2177
|
+
return error == GIT_ENOTFOUND ? GIT_EUNBORNBRANCH : error;
|
2178
|
+
}
|
2179
|
+
|
2180
|
+
int git_repository_head_for_worktree(git_reference **out, git_repository *repo, const char *name)
|
2181
|
+
{
|
2182
|
+
git_buf path = GIT_BUF_INIT;
|
2183
|
+
git_reference *head = NULL;
|
2184
|
+
int error;
|
2185
|
+
|
2186
|
+
assert(out && repo && name);
|
2187
|
+
|
2188
|
+
*out = NULL;
|
2189
|
+
|
2190
|
+
if ((error = get_worktree_file_path(&path, repo, name, GIT_HEAD_FILE)) < 0 ||
|
2191
|
+
(error = git_reference__read_head(&head, repo, path.ptr)) < 0)
|
2192
|
+
goto out;
|
2193
|
+
|
2194
|
+
if (git_reference_type(head) != GIT_REFERENCE_DIRECT) {
|
2195
|
+
git_reference *resolved;
|
2196
|
+
|
2197
|
+
error = git_reference_lookup_resolved(&resolved, repo, git_reference_symbolic_target(head), -1);
|
2198
|
+
git_reference_free(head);
|
2199
|
+
head = resolved;
|
2200
|
+
}
|
2201
|
+
|
2202
|
+
*out = head;
|
2203
|
+
|
2204
|
+
out:
|
2205
|
+
if (error)
|
2206
|
+
git_reference_free(head);
|
2207
|
+
|
2208
|
+
git_buf_dispose(&path);
|
2209
|
+
|
2210
|
+
return error;
|
1452
2211
|
}
|
1453
2212
|
|
1454
|
-
int
|
2213
|
+
int git_repository_foreach_head(git_repository *repo, git_repository_foreach_head_cb cb, void *payload)
|
2214
|
+
{
|
2215
|
+
git_strarray worktrees = GIT_VECTOR_INIT;
|
2216
|
+
git_buf path = GIT_BUF_INIT;
|
2217
|
+
int error;
|
2218
|
+
size_t i;
|
2219
|
+
|
2220
|
+
/* Execute callback for HEAD of commondir */
|
2221
|
+
if ((error = git_buf_joinpath(&path, repo->commondir, GIT_HEAD_FILE)) < 0 ||
|
2222
|
+
(error = cb(repo, path.ptr, payload) != 0))
|
2223
|
+
goto out;
|
2224
|
+
|
2225
|
+
if ((error = git_worktree_list(&worktrees, repo)) < 0) {
|
2226
|
+
error = 0;
|
2227
|
+
goto out;
|
2228
|
+
}
|
2229
|
+
|
2230
|
+
/* Execute callback for all worktree HEADs */
|
2231
|
+
for (i = 0; i < worktrees.count; i++) {
|
2232
|
+
if (get_worktree_file_path(&path, repo, worktrees.strings[i], GIT_HEAD_FILE) < 0)
|
2233
|
+
continue;
|
2234
|
+
|
2235
|
+
if ((error = cb(repo, path.ptr, payload)) != 0)
|
2236
|
+
goto out;
|
2237
|
+
}
|
2238
|
+
|
2239
|
+
out:
|
2240
|
+
git_buf_dispose(&path);
|
2241
|
+
git_strarray_free(&worktrees);
|
2242
|
+
return error;
|
2243
|
+
}
|
2244
|
+
|
2245
|
+
int git_repository_head_unborn(git_repository *repo)
|
1455
2246
|
{
|
1456
2247
|
git_reference *ref = NULL;
|
1457
2248
|
int error;
|
@@ -1459,8 +2250,10 @@ int git_repository_head_orphan(git_repository *repo)
|
|
1459
2250
|
error = git_repository_head(&ref, repo);
|
1460
2251
|
git_reference_free(ref);
|
1461
2252
|
|
1462
|
-
if (error ==
|
2253
|
+
if (error == GIT_EUNBORNBRANCH) {
|
2254
|
+
git_error_clear();
|
1463
2255
|
return 1;
|
2256
|
+
}
|
1464
2257
|
|
1465
2258
|
if (error < 0)
|
1466
2259
|
return -1;
|
@@ -1472,15 +2265,14 @@ static int at_least_one_cb(const char *refname, void *payload)
|
|
1472
2265
|
{
|
1473
2266
|
GIT_UNUSED(refname);
|
1474
2267
|
GIT_UNUSED(payload);
|
1475
|
-
|
1476
|
-
return GIT_EUSER;
|
2268
|
+
return GIT_PASSTHROUGH;
|
1477
2269
|
}
|
1478
2270
|
|
1479
2271
|
static int repo_contains_no_reference(git_repository *repo)
|
1480
2272
|
{
|
1481
2273
|
int error = git_reference_foreach_name(repo, &at_least_one_cb, NULL);
|
1482
2274
|
|
1483
|
-
if (error ==
|
2275
|
+
if (error == GIT_PASSTHROUGH)
|
1484
2276
|
return 0;
|
1485
2277
|
|
1486
2278
|
if (!error)
|
@@ -1492,33 +2284,69 @@ static int repo_contains_no_reference(git_repository *repo)
|
|
1492
2284
|
int git_repository_is_empty(git_repository *repo)
|
1493
2285
|
{
|
1494
2286
|
git_reference *head = NULL;
|
1495
|
-
int
|
2287
|
+
int is_empty = 0;
|
1496
2288
|
|
1497
2289
|
if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0)
|
1498
2290
|
return -1;
|
1499
2291
|
|
1500
|
-
if (
|
1501
|
-
|
2292
|
+
if (git_reference_type(head) == GIT_REFERENCE_SYMBOLIC)
|
2293
|
+
is_empty =
|
2294
|
+
(strcmp(git_reference_symbolic_target(head),
|
2295
|
+
GIT_REFS_HEADS_DIR "master") == 0) &&
|
2296
|
+
repo_contains_no_reference(repo);
|
1502
2297
|
|
1503
|
-
|
1504
|
-
git_reference_symbolic_target(head),
|
1505
|
-
GIT_REFS_HEADS_DIR "master") == 0))
|
1506
|
-
goto cleanup;
|
2298
|
+
git_reference_free(head);
|
1507
2299
|
|
1508
|
-
|
2300
|
+
return is_empty;
|
2301
|
+
}
|
1509
2302
|
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
2303
|
+
int git_repository_item_path(git_buf *out, const git_repository *repo, git_repository_item_t item)
|
2304
|
+
{
|
2305
|
+
const char *parent;
|
2306
|
+
|
2307
|
+
switch (items[item].parent) {
|
2308
|
+
case GIT_REPOSITORY_ITEM_GITDIR:
|
2309
|
+
parent = git_repository_path(repo);
|
2310
|
+
break;
|
2311
|
+
case GIT_REPOSITORY_ITEM_WORKDIR:
|
2312
|
+
parent = git_repository_workdir(repo);
|
2313
|
+
break;
|
2314
|
+
case GIT_REPOSITORY_ITEM_COMMONDIR:
|
2315
|
+
parent = git_repository_commondir(repo);
|
2316
|
+
break;
|
2317
|
+
default:
|
2318
|
+
git_error_set(GIT_ERROR_INVALID, "invalid item directory");
|
2319
|
+
return -1;
|
2320
|
+
}
|
2321
|
+
|
2322
|
+
if (parent == NULL) {
|
2323
|
+
git_error_set(GIT_ERROR_INVALID, "path cannot exist in repository");
|
2324
|
+
return GIT_ENOTFOUND;
|
2325
|
+
}
|
2326
|
+
|
2327
|
+
if (git_buf_sets(out, parent) < 0)
|
2328
|
+
return -1;
|
2329
|
+
|
2330
|
+
if (items[item].name) {
|
2331
|
+
if (git_buf_joinpath(out, parent, items[item].name) < 0)
|
2332
|
+
return -1;
|
2333
|
+
}
|
2334
|
+
|
2335
|
+
if (items[item].directory) {
|
2336
|
+
if (git_path_to_dir(out) < 0)
|
2337
|
+
return -1;
|
2338
|
+
}
|
2339
|
+
|
2340
|
+
return 0;
|
1513
2341
|
}
|
1514
2342
|
|
1515
|
-
const char *git_repository_path(git_repository *repo)
|
2343
|
+
const char *git_repository_path(const git_repository *repo)
|
1516
2344
|
{
|
1517
2345
|
assert(repo);
|
1518
|
-
return repo->
|
2346
|
+
return repo->gitdir;
|
1519
2347
|
}
|
1520
2348
|
|
1521
|
-
const char *git_repository_workdir(git_repository *repo)
|
2349
|
+
const char *git_repository_workdir(const git_repository *repo)
|
1522
2350
|
{
|
1523
2351
|
assert(repo);
|
1524
2352
|
|
@@ -1528,6 +2356,12 @@ const char *git_repository_workdir(git_repository *repo)
|
|
1528
2356
|
return repo->workdir;
|
1529
2357
|
}
|
1530
2358
|
|
2359
|
+
const char *git_repository_commondir(const git_repository *repo)
|
2360
|
+
{
|
2361
|
+
assert(repo);
|
2362
|
+
return repo->commondir;
|
2363
|
+
}
|
2364
|
+
|
1531
2365
|
int git_repository_set_workdir(
|
1532
2366
|
git_repository *repo, const char *workdir, int update_gitlink)
|
1533
2367
|
{
|
@@ -1548,7 +2382,7 @@ int git_repository_set_workdir(
|
|
1548
2382
|
if (git_repository_config__weakptr(&config, repo) < 0)
|
1549
2383
|
return -1;
|
1550
2384
|
|
1551
|
-
error = repo_write_gitlink(path.ptr, git_repository_path(repo));
|
2385
|
+
error = repo_write_gitlink(path.ptr, git_repository_path(repo), false);
|
1552
2386
|
|
1553
2387
|
/* passthrough error means gitlink is unnecessary */
|
1554
2388
|
if (error == GIT_PASSTHROUGH)
|
@@ -1572,12 +2406,44 @@ int git_repository_set_workdir(
|
|
1572
2406
|
return error;
|
1573
2407
|
}
|
1574
2408
|
|
1575
|
-
int git_repository_is_bare(git_repository *repo)
|
2409
|
+
int git_repository_is_bare(const git_repository *repo)
|
1576
2410
|
{
|
1577
2411
|
assert(repo);
|
1578
2412
|
return repo->is_bare;
|
1579
2413
|
}
|
1580
2414
|
|
2415
|
+
int git_repository_is_worktree(const git_repository *repo)
|
2416
|
+
{
|
2417
|
+
assert(repo);
|
2418
|
+
return repo->is_worktree;
|
2419
|
+
}
|
2420
|
+
|
2421
|
+
int git_repository_set_bare(git_repository *repo)
|
2422
|
+
{
|
2423
|
+
int error;
|
2424
|
+
git_config *config;
|
2425
|
+
|
2426
|
+
assert(repo);
|
2427
|
+
|
2428
|
+
if (repo->is_bare)
|
2429
|
+
return 0;
|
2430
|
+
|
2431
|
+
if ((error = git_repository_config__weakptr(&config, repo)) < 0)
|
2432
|
+
return error;
|
2433
|
+
|
2434
|
+
if ((error = git_config_set_bool(config, "core.bare", true)) < 0)
|
2435
|
+
return error;
|
2436
|
+
|
2437
|
+
if ((error = git_config__update_entry(config, "core.worktree", NULL, true, true)) < 0)
|
2438
|
+
return error;
|
2439
|
+
|
2440
|
+
git__free(repo->workdir);
|
2441
|
+
repo->workdir = NULL;
|
2442
|
+
repo->is_bare = 1;
|
2443
|
+
|
2444
|
+
return 0;
|
2445
|
+
}
|
2446
|
+
|
1581
2447
|
int git_repository_head_tree(git_tree **tree, git_repository *repo)
|
1582
2448
|
{
|
1583
2449
|
git_reference *head;
|
@@ -1587,7 +2453,7 @@ int git_repository_head_tree(git_tree **tree, git_repository *repo)
|
|
1587
2453
|
if ((error = git_repository_head(&head, repo)) < 0)
|
1588
2454
|
return error;
|
1589
2455
|
|
1590
|
-
if ((error = git_reference_peel(&obj, head,
|
2456
|
+
if ((error = git_reference_peel(&obj, head, GIT_OBJECT_TREE)) < 0)
|
1591
2457
|
goto cleanup;
|
1592
2458
|
|
1593
2459
|
*tree = (git_tree *)obj;
|
@@ -1597,33 +2463,48 @@ cleanup:
|
|
1597
2463
|
return error;
|
1598
2464
|
}
|
1599
2465
|
|
1600
|
-
int
|
2466
|
+
int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head)
|
1601
2467
|
{
|
1602
|
-
|
2468
|
+
git_filebuf file = GIT_FILEBUF_INIT;
|
2469
|
+
git_buf file_path = GIT_BUF_INIT;
|
2470
|
+
char orig_head_str[GIT_OID_HEXSZ];
|
2471
|
+
int error = 0;
|
2472
|
+
|
2473
|
+
git_oid_fmt(orig_head_str, orig_head);
|
2474
|
+
|
2475
|
+
if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_ORIG_HEAD_FILE)) == 0 &&
|
2476
|
+
(error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_FORCE, GIT_MERGE_FILE_MODE)) == 0 &&
|
2477
|
+
(error = git_filebuf_printf(&file, "%.*s\n", GIT_OID_HEXSZ, orig_head_str)) == 0)
|
2478
|
+
error = git_filebuf_commit(&file);
|
2479
|
+
|
2480
|
+
if (error < 0)
|
2481
|
+
git_filebuf_cleanup(&file);
|
2482
|
+
|
2483
|
+
git_buf_dispose(&file_path);
|
2484
|
+
|
2485
|
+
return error;
|
2486
|
+
}
|
2487
|
+
|
2488
|
+
int git_repository_message(git_buf *out, git_repository *repo)
|
2489
|
+
{
|
2490
|
+
git_buf path = GIT_BUF_INIT;
|
1603
2491
|
struct stat st;
|
1604
2492
|
int error;
|
1605
2493
|
|
1606
|
-
|
1607
|
-
*buffer = '\0';
|
2494
|
+
git_buf_sanitize(out);
|
1608
2495
|
|
1609
|
-
if (git_buf_joinpath(&path, repo->
|
2496
|
+
if (git_buf_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0)
|
1610
2497
|
return -1;
|
1611
2498
|
|
1612
2499
|
if ((error = p_stat(git_buf_cstr(&path), &st)) < 0) {
|
1613
2500
|
if (errno == ENOENT)
|
1614
2501
|
error = GIT_ENOTFOUND;
|
1615
|
-
|
1616
|
-
}
|
1617
|
-
|
1618
|
-
error = git_futils_readbuffer(&buf, git_buf_cstr(&path));
|
1619
|
-
git_buf_copy_cstr(buffer, len, &buf);
|
2502
|
+
git_error_set(GIT_ERROR_OS, "could not access message file");
|
2503
|
+
} else {
|
2504
|
+
error = git_futils_readbuffer(out, git_buf_cstr(&path));
|
1620
2505
|
}
|
1621
2506
|
|
1622
|
-
|
1623
|
-
git_buf_free(&buf);
|
1624
|
-
|
1625
|
-
if (!error)
|
1626
|
-
error = (int)st.st_size + 1; /* add 1 for NUL byte */
|
2507
|
+
git_buf_dispose(&path);
|
1627
2508
|
|
1628
2509
|
return error;
|
1629
2510
|
}
|
@@ -1633,11 +2514,11 @@ int git_repository_message_remove(git_repository *repo)
|
|
1633
2514
|
git_buf path = GIT_BUF_INIT;
|
1634
2515
|
int error;
|
1635
2516
|
|
1636
|
-
if (git_buf_joinpath(&path, repo->
|
2517
|
+
if (git_buf_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0)
|
1637
2518
|
return -1;
|
1638
2519
|
|
1639
2520
|
error = p_unlink(git_buf_cstr(&path));
|
1640
|
-
|
2521
|
+
git_buf_dispose(&path);
|
1641
2522
|
|
1642
2523
|
return error;
|
1643
2524
|
}
|
@@ -1646,11 +2527,11 @@ int git_repository_hashfile(
|
|
1646
2527
|
git_oid *out,
|
1647
2528
|
git_repository *repo,
|
1648
2529
|
const char *path,
|
1649
|
-
|
2530
|
+
git_object_t type,
|
1650
2531
|
const char *as_path)
|
1651
2532
|
{
|
1652
2533
|
int error;
|
1653
|
-
|
2534
|
+
git_filter_list *fl = NULL;
|
1654
2535
|
git_file fd = -1;
|
1655
2536
|
git_off_t len;
|
1656
2537
|
git_buf full_path = GIT_BUF_INIT;
|
@@ -1663,7 +2544,7 @@ int git_repository_hashfile(
|
|
1663
2544
|
*/
|
1664
2545
|
|
1665
2546
|
error = git_path_join_unrooted(
|
1666
|
-
&full_path, path,
|
2547
|
+
&full_path, path, git_repository_workdir(repo), NULL);
|
1667
2548
|
if (error < 0)
|
1668
2549
|
return error;
|
1669
2550
|
|
@@ -1672,7 +2553,9 @@ int git_repository_hashfile(
|
|
1672
2553
|
|
1673
2554
|
/* passing empty string for "as_path" indicated --no-filters */
|
1674
2555
|
if (strlen(as_path) > 0) {
|
1675
|
-
error =
|
2556
|
+
error = git_filter_list_load(
|
2557
|
+
&fl, repo, NULL, as_path,
|
2558
|
+
GIT_FILTER_TO_ODB, GIT_FILTER_DEFAULT);
|
1676
2559
|
if (error < 0)
|
1677
2560
|
return error;
|
1678
2561
|
} else {
|
@@ -1694,49 +2577,125 @@ int git_repository_hashfile(
|
|
1694
2577
|
}
|
1695
2578
|
|
1696
2579
|
if (!git__is_sizet(len)) {
|
1697
|
-
|
2580
|
+
git_error_set(GIT_ERROR_OS, "file size overflow for 32-bit systems");
|
1698
2581
|
error = -1;
|
1699
2582
|
goto cleanup;
|
1700
2583
|
}
|
1701
2584
|
|
1702
|
-
error = git_odb__hashfd_filtered(out, fd, (size_t)len, type,
|
2585
|
+
error = git_odb__hashfd_filtered(out, fd, (size_t)len, type, fl);
|
1703
2586
|
|
1704
2587
|
cleanup:
|
1705
2588
|
if (fd >= 0)
|
1706
2589
|
p_close(fd);
|
1707
|
-
|
1708
|
-
|
2590
|
+
git_filter_list_free(fl);
|
2591
|
+
git_buf_dispose(&full_path);
|
1709
2592
|
|
1710
2593
|
return error;
|
1711
2594
|
}
|
1712
2595
|
|
1713
|
-
static
|
2596
|
+
static int checkout_message(git_buf *out, git_reference *old, const char *new)
|
2597
|
+
{
|
2598
|
+
git_buf_puts(out, "checkout: moving from ");
|
2599
|
+
|
2600
|
+
if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC)
|
2601
|
+
git_buf_puts(out, git_reference__shorthand(git_reference_symbolic_target(old)));
|
2602
|
+
else
|
2603
|
+
git_buf_puts(out, git_oid_tostr_s(git_reference_target(old)));
|
2604
|
+
|
2605
|
+
git_buf_puts(out, " to ");
|
2606
|
+
|
2607
|
+
if (git_reference__is_branch(new) ||
|
2608
|
+
git_reference__is_tag(new) ||
|
2609
|
+
git_reference__is_remote(new))
|
2610
|
+
git_buf_puts(out, git_reference__shorthand(new));
|
2611
|
+
else
|
2612
|
+
git_buf_puts(out, new);
|
2613
|
+
|
2614
|
+
if (git_buf_oom(out))
|
2615
|
+
return -1;
|
2616
|
+
|
2617
|
+
return 0;
|
2618
|
+
}
|
2619
|
+
|
2620
|
+
static int detach(git_repository *repo, const git_oid *id, const char *new)
|
1714
2621
|
{
|
1715
|
-
|
2622
|
+
int error;
|
2623
|
+
git_buf log_message = GIT_BUF_INIT;
|
2624
|
+
git_object *object = NULL, *peeled = NULL;
|
2625
|
+
git_reference *new_head = NULL, *current = NULL;
|
2626
|
+
|
2627
|
+
assert(repo && id);
|
2628
|
+
|
2629
|
+
if ((error = git_reference_lookup(¤t, repo, GIT_HEAD_FILE)) < 0)
|
2630
|
+
return error;
|
2631
|
+
|
2632
|
+
if ((error = git_object_lookup(&object, repo, id, GIT_OBJECT_ANY)) < 0)
|
2633
|
+
goto cleanup;
|
2634
|
+
|
2635
|
+
if ((error = git_object_peel(&peeled, object, GIT_OBJECT_COMMIT)) < 0)
|
2636
|
+
goto cleanup;
|
2637
|
+
|
2638
|
+
if (new == NULL)
|
2639
|
+
new = git_oid_tostr_s(git_object_id(peeled));
|
2640
|
+
|
2641
|
+
if ((error = checkout_message(&log_message, current, new)) < 0)
|
2642
|
+
goto cleanup;
|
2643
|
+
|
2644
|
+
error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, git_buf_cstr(&log_message));
|
2645
|
+
|
2646
|
+
cleanup:
|
2647
|
+
git_buf_dispose(&log_message);
|
2648
|
+
git_object_free(object);
|
2649
|
+
git_object_free(peeled);
|
2650
|
+
git_reference_free(current);
|
2651
|
+
git_reference_free(new_head);
|
2652
|
+
return error;
|
1716
2653
|
}
|
1717
2654
|
|
1718
2655
|
int git_repository_set_head(
|
1719
2656
|
git_repository* repo,
|
1720
2657
|
const char* refname)
|
1721
2658
|
{
|
1722
|
-
git_reference *ref,
|
1723
|
-
|
2659
|
+
git_reference *ref = NULL, *current = NULL, *new_head = NULL;
|
2660
|
+
git_buf log_message = GIT_BUF_INIT;
|
1724
2661
|
int error;
|
1725
2662
|
|
1726
2663
|
assert(repo && refname);
|
1727
2664
|
|
2665
|
+
if ((error = git_reference_lookup(¤t, repo, GIT_HEAD_FILE)) < 0)
|
2666
|
+
return error;
|
2667
|
+
|
2668
|
+
if ((error = checkout_message(&log_message, current, refname)) < 0)
|
2669
|
+
goto cleanup;
|
2670
|
+
|
1728
2671
|
error = git_reference_lookup(&ref, repo, refname);
|
1729
2672
|
if (error < 0 && error != GIT_ENOTFOUND)
|
1730
|
-
|
2673
|
+
goto cleanup;
|
2674
|
+
|
2675
|
+
if (ref && current->type == GIT_REFERENCE_SYMBOLIC && git__strcmp(current->target.symbolic, ref->name) &&
|
2676
|
+
git_reference_is_branch(ref) && git_branch_is_checked_out(ref)) {
|
2677
|
+
git_error_set(GIT_ERROR_REPOSITORY, "cannot set HEAD to reference '%s' as it is the current HEAD "
|
2678
|
+
"of a linked repository.", git_reference_name(ref));
|
2679
|
+
error = -1;
|
2680
|
+
goto cleanup;
|
2681
|
+
}
|
1731
2682
|
|
1732
2683
|
if (!error) {
|
1733
|
-
if (git_reference_is_branch(ref))
|
1734
|
-
error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE,
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
2684
|
+
if (git_reference_is_branch(ref)) {
|
2685
|
+
error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE,
|
2686
|
+
git_reference_name(ref), true, git_buf_cstr(&log_message));
|
2687
|
+
} else {
|
2688
|
+
error = detach(repo, git_reference_target(ref),
|
2689
|
+
git_reference_is_tag(ref) || git_reference_is_remote(ref) ? refname : NULL);
|
2690
|
+
}
|
2691
|
+
} else if (git_reference__is_branch(refname)) {
|
2692
|
+
error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname,
|
2693
|
+
true, git_buf_cstr(&log_message));
|
2694
|
+
}
|
1739
2695
|
|
2696
|
+
cleanup:
|
2697
|
+
git_buf_dispose(&log_message);
|
2698
|
+
git_reference_free(current);
|
1740
2699
|
git_reference_free(ref);
|
1741
2700
|
git_reference_free(new_head);
|
1742
2701
|
return error;
|
@@ -1746,50 +2705,48 @@ int git_repository_set_head_detached(
|
|
1746
2705
|
git_repository* repo,
|
1747
2706
|
const git_oid* commitish)
|
1748
2707
|
{
|
1749
|
-
|
1750
|
-
|
1751
|
-
*peeled = NULL;
|
1752
|
-
git_reference *new_head = NULL;
|
2708
|
+
return detach(repo, commitish, NULL);
|
2709
|
+
}
|
1753
2710
|
|
2711
|
+
int git_repository_set_head_detached_from_annotated(
|
2712
|
+
git_repository *repo,
|
2713
|
+
const git_annotated_commit *commitish)
|
2714
|
+
{
|
1754
2715
|
assert(repo && commitish);
|
1755
2716
|
|
1756
|
-
|
1757
|
-
return error;
|
1758
|
-
|
1759
|
-
if ((error = git_object_peel(&peeled, object, GIT_OBJ_COMMIT)) < 0)
|
1760
|
-
goto cleanup;
|
1761
|
-
|
1762
|
-
error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), 1);
|
1763
|
-
|
1764
|
-
cleanup:
|
1765
|
-
git_object_free(object);
|
1766
|
-
git_object_free(peeled);
|
1767
|
-
git_reference_free(new_head);
|
1768
|
-
return error;
|
2717
|
+
return detach(repo, git_annotated_commit_id(commitish), commitish->description);
|
1769
2718
|
}
|
1770
2719
|
|
1771
|
-
int git_repository_detach_head(
|
1772
|
-
git_repository* repo)
|
2720
|
+
int git_repository_detach_head(git_repository* repo)
|
1773
2721
|
{
|
1774
|
-
git_reference *old_head = NULL,
|
1775
|
-
*new_head = NULL;
|
2722
|
+
git_reference *old_head = NULL, *new_head = NULL, *current = NULL;
|
1776
2723
|
git_object *object = NULL;
|
2724
|
+
git_buf log_message = GIT_BUF_INIT;
|
1777
2725
|
int error;
|
1778
2726
|
|
1779
2727
|
assert(repo);
|
1780
2728
|
|
1781
|
-
if ((error =
|
2729
|
+
if ((error = git_reference_lookup(¤t, repo, GIT_HEAD_FILE)) < 0)
|
1782
2730
|
return error;
|
1783
2731
|
|
1784
|
-
if ((error =
|
2732
|
+
if ((error = git_repository_head(&old_head, repo)) < 0)
|
1785
2733
|
goto cleanup;
|
1786
2734
|
|
1787
|
-
error =
|
2735
|
+
if ((error = git_object_lookup(&object, repo, git_reference_target(old_head), GIT_OBJECT_COMMIT)) < 0)
|
2736
|
+
goto cleanup;
|
2737
|
+
|
2738
|
+
if ((error = checkout_message(&log_message, current, git_oid_tostr_s(git_object_id(object)))) < 0)
|
2739
|
+
goto cleanup;
|
2740
|
+
|
2741
|
+
error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head),
|
2742
|
+
1, git_buf_cstr(&log_message));
|
1788
2743
|
|
1789
2744
|
cleanup:
|
2745
|
+
git_buf_dispose(&log_message);
|
1790
2746
|
git_object_free(object);
|
1791
2747
|
git_reference_free(old_head);
|
1792
2748
|
git_reference_free(new_head);
|
2749
|
+
git_reference_free(current);
|
1793
2750
|
return error;
|
1794
2751
|
}
|
1795
2752
|
|
@@ -1804,7 +2761,7 @@ int git_repository_state(git_repository *repo)
|
|
1804
2761
|
|
1805
2762
|
assert(repo);
|
1806
2763
|
|
1807
|
-
if (git_buf_puts(&repo_path, repo->
|
2764
|
+
if (git_buf_puts(&repo_path, repo->gitdir) < 0)
|
1808
2765
|
return -1;
|
1809
2766
|
|
1810
2767
|
if (git_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE))
|
@@ -1819,30 +2776,157 @@ int git_repository_state(git_repository *repo)
|
|
1819
2776
|
state = GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE;
|
1820
2777
|
else if (git_path_contains_file(&repo_path, GIT_MERGE_HEAD_FILE))
|
1821
2778
|
state = GIT_REPOSITORY_STATE_MERGE;
|
1822
|
-
else if(git_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE))
|
2779
|
+
else if (git_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE)) {
|
1823
2780
|
state = GIT_REPOSITORY_STATE_REVERT;
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
2781
|
+
if (git_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) {
|
2782
|
+
state = GIT_REPOSITORY_STATE_REVERT_SEQUENCE;
|
2783
|
+
}
|
2784
|
+
} else if (git_path_contains_file(&repo_path, GIT_CHERRYPICK_HEAD_FILE)) {
|
2785
|
+
state = GIT_REPOSITORY_STATE_CHERRYPICK;
|
2786
|
+
if (git_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) {
|
2787
|
+
state = GIT_REPOSITORY_STATE_CHERRYPICK_SEQUENCE;
|
2788
|
+
}
|
2789
|
+
} else if (git_path_contains_file(&repo_path, GIT_BISECT_LOG_FILE))
|
1827
2790
|
state = GIT_REPOSITORY_STATE_BISECT;
|
1828
2791
|
|
1829
|
-
|
2792
|
+
git_buf_dispose(&repo_path);
|
1830
2793
|
return state;
|
1831
2794
|
}
|
1832
2795
|
|
2796
|
+
int git_repository__cleanup_files(
|
2797
|
+
git_repository *repo, const char *files[], size_t files_len)
|
2798
|
+
{
|
2799
|
+
git_buf buf = GIT_BUF_INIT;
|
2800
|
+
size_t i;
|
2801
|
+
int error;
|
2802
|
+
|
2803
|
+
for (error = 0, i = 0; !error && i < files_len; ++i) {
|
2804
|
+
const char *path;
|
2805
|
+
|
2806
|
+
if (git_buf_joinpath(&buf, repo->gitdir, files[i]) < 0)
|
2807
|
+
return -1;
|
2808
|
+
|
2809
|
+
path = git_buf_cstr(&buf);
|
2810
|
+
|
2811
|
+
if (git_path_isfile(path)) {
|
2812
|
+
error = p_unlink(path);
|
2813
|
+
} else if (git_path_isdir(path)) {
|
2814
|
+
error = git_futils_rmdir_r(path, NULL,
|
2815
|
+
GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_REMOVE_BLOCKERS);
|
2816
|
+
}
|
2817
|
+
|
2818
|
+
git_buf_clear(&buf);
|
2819
|
+
}
|
2820
|
+
|
2821
|
+
git_buf_dispose(&buf);
|
2822
|
+
return error;
|
2823
|
+
}
|
2824
|
+
|
2825
|
+
static const char *state_files[] = {
|
2826
|
+
GIT_MERGE_HEAD_FILE,
|
2827
|
+
GIT_MERGE_MODE_FILE,
|
2828
|
+
GIT_MERGE_MSG_FILE,
|
2829
|
+
GIT_REVERT_HEAD_FILE,
|
2830
|
+
GIT_CHERRYPICK_HEAD_FILE,
|
2831
|
+
GIT_BISECT_LOG_FILE,
|
2832
|
+
GIT_REBASE_MERGE_DIR,
|
2833
|
+
GIT_REBASE_APPLY_DIR,
|
2834
|
+
GIT_SEQUENCER_DIR,
|
2835
|
+
};
|
2836
|
+
|
2837
|
+
int git_repository_state_cleanup(git_repository *repo)
|
2838
|
+
{
|
2839
|
+
assert(repo);
|
2840
|
+
|
2841
|
+
return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files));
|
2842
|
+
}
|
2843
|
+
|
1833
2844
|
int git_repository_is_shallow(git_repository *repo)
|
1834
2845
|
{
|
1835
2846
|
git_buf path = GIT_BUF_INIT;
|
1836
2847
|
struct stat st;
|
1837
2848
|
int error;
|
1838
2849
|
|
1839
|
-
git_buf_joinpath(&path, repo->
|
2850
|
+
if ((error = git_buf_joinpath(&path, repo->gitdir, "shallow")) < 0)
|
2851
|
+
return error;
|
2852
|
+
|
1840
2853
|
error = git_path_lstat(path.ptr, &st);
|
1841
|
-
|
2854
|
+
git_buf_dispose(&path);
|
1842
2855
|
|
1843
|
-
if (error == GIT_ENOTFOUND)
|
2856
|
+
if (error == GIT_ENOTFOUND) {
|
2857
|
+
git_error_clear();
|
1844
2858
|
return 0;
|
2859
|
+
}
|
2860
|
+
|
1845
2861
|
if (error < 0)
|
1846
|
-
return
|
2862
|
+
return error;
|
1847
2863
|
return st.st_size == 0 ? 0 : 1;
|
1848
2864
|
}
|
2865
|
+
|
2866
|
+
int git_repository_init_init_options(
|
2867
|
+
git_repository_init_options *opts, unsigned int version)
|
2868
|
+
{
|
2869
|
+
GIT_INIT_STRUCTURE_FROM_TEMPLATE(
|
2870
|
+
opts, version, git_repository_init_options,
|
2871
|
+
GIT_REPOSITORY_INIT_OPTIONS_INIT);
|
2872
|
+
return 0;
|
2873
|
+
}
|
2874
|
+
|
2875
|
+
int git_repository_ident(const char **name, const char **email, const git_repository *repo)
|
2876
|
+
{
|
2877
|
+
*name = repo->ident_name;
|
2878
|
+
*email = repo->ident_email;
|
2879
|
+
|
2880
|
+
return 0;
|
2881
|
+
}
|
2882
|
+
|
2883
|
+
int git_repository_set_ident(git_repository *repo, const char *name, const char *email)
|
2884
|
+
{
|
2885
|
+
char *tmp_name = NULL, *tmp_email = NULL;
|
2886
|
+
|
2887
|
+
if (name) {
|
2888
|
+
tmp_name = git__strdup(name);
|
2889
|
+
GIT_ERROR_CHECK_ALLOC(tmp_name);
|
2890
|
+
}
|
2891
|
+
|
2892
|
+
if (email) {
|
2893
|
+
tmp_email = git__strdup(email);
|
2894
|
+
GIT_ERROR_CHECK_ALLOC(tmp_email);
|
2895
|
+
}
|
2896
|
+
|
2897
|
+
tmp_name = git__swap(repo->ident_name, tmp_name);
|
2898
|
+
tmp_email = git__swap(repo->ident_email, tmp_email);
|
2899
|
+
|
2900
|
+
git__free(tmp_name);
|
2901
|
+
git__free(tmp_email);
|
2902
|
+
|
2903
|
+
return 0;
|
2904
|
+
}
|
2905
|
+
|
2906
|
+
int git_repository_submodule_cache_all(git_repository *repo)
|
2907
|
+
{
|
2908
|
+
int error;
|
2909
|
+
|
2910
|
+
assert(repo);
|
2911
|
+
|
2912
|
+
if ((error = git_strmap_alloc(&repo->submodule_cache)))
|
2913
|
+
return error;
|
2914
|
+
|
2915
|
+
error = git_submodule__map(repo, repo->submodule_cache);
|
2916
|
+
return error;
|
2917
|
+
}
|
2918
|
+
|
2919
|
+
int git_repository_submodule_cache_clear(git_repository *repo)
|
2920
|
+
{
|
2921
|
+
git_submodule *sm;
|
2922
|
+
assert(repo);
|
2923
|
+
if (repo->submodule_cache == NULL) {
|
2924
|
+
return 0;
|
2925
|
+
}
|
2926
|
+
git_strmap_foreach_value(repo->submodule_cache, sm, {
|
2927
|
+
git_submodule_free(sm);
|
2928
|
+
});
|
2929
|
+
git_strmap_free(repo->submodule_cache);
|
2930
|
+
repo->submodule_cache = 0;
|
2931
|
+
return 0;
|
2932
|
+
}
|