rugged 0.26.7 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/ext/rugged/rugged_blame.c +6 -3
- data/ext/rugged/rugged_branch_collection.c +3 -6
- data/ext/rugged/rugged_commit.c +56 -0
- data/ext/rugged/rugged_config.c +44 -9
- data/ext/rugged/rugged_diff.c +3 -14
- data/ext/rugged/rugged_diff_hunk.c +1 -3
- data/ext/rugged/rugged_index.c +1 -5
- data/ext/rugged/rugged_note.c +1 -4
- data/ext/rugged/rugged_patch.c +1 -4
- data/ext/rugged/rugged_reference_collection.c +1 -7
- data/ext/rugged/rugged_remote.c +5 -8
- data/ext/rugged/rugged_remote_collection.c +1 -6
- data/ext/rugged/rugged_repo.c +16 -48
- data/ext/rugged/rugged_revwalk.c +7 -16
- data/ext/rugged/rugged_settings.c +28 -0
- data/ext/rugged/rugged_submodule_collection.c +3 -4
- data/ext/rugged/rugged_tag_collection.c +1 -5
- data/ext/rugged/rugged_tree.c +2 -3
- data/lib/rugged/repository.rb +43 -0
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/AUTHORS +1 -0
- data/vendor/libgit2/CMakeLists.txt +61 -510
- data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +14 -0
- data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +25 -8
- data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +27 -8
- data/vendor/libgit2/cmake/Modules/FindStatNsec.cmake +20 -0
- data/vendor/libgit2/cmake/Modules/IdeSplitSources.cmake +22 -0
- data/vendor/libgit2/deps/http-parser/CMakeLists.txt +3 -0
- data/vendor/libgit2/deps/regex/CMakeLists.txt +2 -0
- data/vendor/libgit2/deps/winhttp/CMakeLists.txt +26 -0
- data/vendor/libgit2/deps/zlib/CMakeLists.txt +4 -0
- data/vendor/libgit2/include/git2/config.h +29 -2
- data/vendor/libgit2/include/git2/describe.h +1 -1
- data/vendor/libgit2/include/git2/diff.h +59 -8
- data/vendor/libgit2/include/git2/graph.h +3 -0
- data/vendor/libgit2/include/git2/merge.h +6 -0
- data/vendor/libgit2/include/git2/message.h +43 -3
- data/vendor/libgit2/include/git2/notes.h +89 -0
- data/vendor/libgit2/include/git2/odb.h +8 -1
- data/vendor/libgit2/include/git2/patch.h +2 -2
- data/vendor/libgit2/include/git2/pathspec.h +35 -18
- data/vendor/libgit2/include/git2/refs.h +3 -0
- data/vendor/libgit2/include/git2/remote.h +34 -4
- data/vendor/libgit2/include/git2/repository.h +6 -6
- data/vendor/libgit2/include/git2/reset.h +4 -4
- data/vendor/libgit2/include/git2/status.h +4 -0
- data/vendor/libgit2/include/git2/sys/config.h +4 -1
- data/vendor/libgit2/include/git2/sys/odb_backend.h +2 -1
- data/vendor/libgit2/include/git2/tree.h +4 -3
- data/vendor/libgit2/include/git2/types.h +1 -0
- data/vendor/libgit2/include/git2/version.h +4 -4
- data/vendor/libgit2/include/git2/worktree.h +1 -1
- data/vendor/libgit2/src/CMakeLists.txt +463 -0
- data/vendor/libgit2/src/annotated_commit.c +1 -1
- data/vendor/libgit2/src/annotated_commit.h +2 -0
- data/vendor/libgit2/src/apply.c +2 -1
- data/vendor/libgit2/src/apply.h +2 -0
- data/vendor/libgit2/src/attr.c +24 -4
- data/vendor/libgit2/src/attr.h +2 -0
- data/vendor/libgit2/src/attr_file.c +9 -2
- data/vendor/libgit2/src/attr_file.h +2 -0
- data/vendor/libgit2/src/attrcache.c +9 -1
- data/vendor/libgit2/src/attrcache.h +2 -0
- data/vendor/libgit2/src/blame.c +1 -0
- data/vendor/libgit2/src/blame.h +2 -1
- data/vendor/libgit2/src/blame_git.c +1 -0
- data/vendor/libgit2/src/blame_git.h +2 -0
- data/vendor/libgit2/src/blob.c +2 -2
- data/vendor/libgit2/src/blob.h +2 -0
- data/vendor/libgit2/src/branch.c +8 -1
- data/vendor/libgit2/src/branch.h +2 -0
- data/vendor/libgit2/src/buf_text.c +7 -7
- data/vendor/libgit2/src/buf_text.h +3 -3
- data/vendor/libgit2/src/buffer.c +31 -1
- data/vendor/libgit2/src/buffer.h +3 -0
- data/vendor/libgit2/src/cache.c +2 -2
- data/vendor/libgit2/src/cache.h +2 -0
- data/vendor/libgit2/src/cc-compat.h +3 -3
- data/vendor/libgit2/src/checkout.c +30 -19
- data/vendor/libgit2/src/checkout.h +2 -0
- data/vendor/libgit2/src/cherrypick.c +1 -0
- data/vendor/libgit2/src/clone.c +2 -1
- data/vendor/libgit2/src/clone.h +4 -0
- data/vendor/libgit2/src/commit.c +2 -1
- data/vendor/libgit2/src/commit.h +2 -0
- data/vendor/libgit2/src/commit_list.c +1 -1
- data/vendor/libgit2/src/commit_list.h +2 -0
- data/vendor/libgit2/src/common.h +11 -5
- data/vendor/libgit2/src/config.c +12 -10
- data/vendor/libgit2/src/config.h +2 -0
- data/vendor/libgit2/src/config_cache.c +1 -0
- data/vendor/libgit2/src/config_file.c +287 -786
- data/vendor/libgit2/src/config_file.h +4 -3
- data/vendor/libgit2/src/config_parse.c +525 -0
- data/vendor/libgit2/src/config_parse.h +64 -0
- data/vendor/libgit2/src/crlf.c +2 -1
- data/vendor/libgit2/src/delta.c +28 -30
- data/vendor/libgit2/src/delta.h +1 -0
- data/vendor/libgit2/src/describe.c +3 -1
- data/vendor/libgit2/src/diff.c +148 -2
- data/vendor/libgit2/src/diff.h +3 -1
- data/vendor/libgit2/src/diff_driver.c +12 -9
- data/vendor/libgit2/src/diff_driver.h +4 -1
- data/vendor/libgit2/src/diff_file.c +7 -4
- data/vendor/libgit2/src/diff_file.h +1 -0
- data/vendor/libgit2/src/diff_generate.c +6 -3
- data/vendor/libgit2/src/diff_generate.h +6 -1
- data/vendor/libgit2/src/diff_parse.c +5 -4
- data/vendor/libgit2/src/diff_parse.h +2 -0
- data/vendor/libgit2/src/diff_print.c +2 -0
- data/vendor/libgit2/src/diff_stats.c +2 -0
- data/vendor/libgit2/src/diff_tform.c +2 -1
- data/vendor/libgit2/src/diff_tform.h +4 -1
- data/vendor/libgit2/src/diff_xdiff.c +5 -2
- data/vendor/libgit2/src/diff_xdiff.h +2 -0
- data/vendor/libgit2/src/errors.c +2 -0
- data/vendor/libgit2/src/features.h.in +36 -0
- data/vendor/libgit2/src/fetch.c +2 -2
- data/vendor/libgit2/src/fetch.h +4 -0
- data/vendor/libgit2/src/fetchhead.c +3 -3
- data/vendor/libgit2/src/fetchhead.h +3 -0
- data/vendor/libgit2/src/filebuf.c +2 -1
- data/vendor/libgit2/src/filebuf.h +2 -0
- data/vendor/libgit2/src/fileops.c +12 -1
- data/vendor/libgit2/src/fileops.h +7 -1
- data/vendor/libgit2/src/filter.c +2 -1
- data/vendor/libgit2/src/filter.h +1 -0
- data/vendor/libgit2/src/fnmatch.c +2 -2
- data/vendor/libgit2/src/fnmatch.h +3 -4
- data/vendor/libgit2/src/global.c +4 -3
- data/vendor/libgit2/src/global.h +1 -5
- data/vendor/libgit2/src/graph.c +2 -0
- data/vendor/libgit2/src/hash.c +0 -1
- data/vendor/libgit2/src/hash.h +3 -1
- data/vendor/libgit2/src/hash/hash_collisiondetect.h +3 -3
- data/vendor/libgit2/src/hash/hash_common_crypto.h +18 -5
- data/vendor/libgit2/src/hash/hash_generic.c +2 -2
- data/vendor/libgit2/src/hash/hash_generic.h +5 -3
- data/vendor/libgit2/src/hash/hash_openssl.h +3 -3
- data/vendor/libgit2/src/hash/hash_win32.c +57 -14
- data/vendor/libgit2/src/hash/hash_win32.h +4 -3
- data/vendor/libgit2/src/hashsig.c +3 -0
- data/vendor/libgit2/src/ident.c +2 -0
- data/vendor/libgit2/src/idxmap.h +2 -1
- data/vendor/libgit2/src/ignore.c +14 -2
- data/vendor/libgit2/src/ignore.h +2 -0
- data/vendor/libgit2/src/index.c +20 -40
- data/vendor/libgit2/src/index.h +2 -0
- data/vendor/libgit2/src/indexer.c +13 -5
- data/vendor/libgit2/src/indexer.h +5 -1
- data/vendor/libgit2/src/integer.h +1 -1
- data/vendor/libgit2/src/iterator.c +44 -3
- data/vendor/libgit2/src/iterator.h +3 -0
- data/vendor/libgit2/src/map.h +1 -1
- data/vendor/libgit2/src/merge.c +155 -33
- data/vendor/libgit2/src/merge.h +2 -0
- data/vendor/libgit2/src/merge_driver.c +2 -2
- data/vendor/libgit2/src/merge_driver.h +2 -0
- data/vendor/libgit2/src/merge_file.c +3 -0
- data/vendor/libgit2/src/message.h +3 -1
- data/vendor/libgit2/src/mwindow.c +1 -1
- data/vendor/libgit2/src/mwindow.h +2 -0
- data/vendor/libgit2/src/netops.c +75 -62
- data/vendor/libgit2/src/netops.h +2 -1
- data/vendor/libgit2/src/notes.c +164 -48
- data/vendor/libgit2/src/notes.h +1 -1
- data/vendor/libgit2/src/object.c +14 -3
- data/vendor/libgit2/src/object.h +4 -0
- data/vendor/libgit2/src/object_api.c +3 -2
- data/vendor/libgit2/src/odb.c +104 -38
- data/vendor/libgit2/src/odb.h +3 -1
- data/vendor/libgit2/src/odb_loose.c +414 -267
- data/vendor/libgit2/src/odb_mempack.c +1 -0
- data/vendor/libgit2/src/odb_pack.c +2 -1
- data/vendor/libgit2/src/offmap.h +1 -0
- data/vendor/libgit2/src/oid.c +2 -1
- data/vendor/libgit2/src/oid.h +3 -8
- data/vendor/libgit2/src/oidarray.c +2 -1
- data/vendor/libgit2/src/oidarray.h +1 -0
- data/vendor/libgit2/src/oidmap.h +1 -0
- data/vendor/libgit2/src/pack-objects.c +5 -1
- data/vendor/libgit2/src/pack-objects.h +1 -1
- data/vendor/libgit2/src/pack.c +2 -6
- data/vendor/libgit2/src/pack.h +2 -1
- data/vendor/libgit2/src/parse.c +121 -0
- data/vendor/libgit2/src/parse.h +61 -0
- data/vendor/libgit2/src/patch.c +9 -2
- data/vendor/libgit2/src/patch.h +2 -0
- data/vendor/libgit2/src/patch_generate.c +6 -5
- data/vendor/libgit2/src/patch_generate.h +1 -0
- data/vendor/libgit2/src/patch_parse.c +265 -276
- data/vendor/libgit2/src/patch_parse.h +6 -11
- data/vendor/libgit2/src/path.c +24 -181
- data/vendor/libgit2/src/path.h +14 -73
- data/vendor/libgit2/src/pathspec.c +2 -1
- data/vendor/libgit2/src/pathspec.h +2 -1
- data/vendor/libgit2/src/pool.c +8 -0
- data/vendor/libgit2/src/pool.h +1 -0
- data/vendor/libgit2/src/posix.c +2 -1
- data/vendor/libgit2/src/posix.h +1 -0
- data/vendor/libgit2/src/pqueue.c +1 -0
- data/vendor/libgit2/src/pqueue.h +2 -0
- data/vendor/libgit2/src/proxy.c +2 -1
- data/vendor/libgit2/src/proxy.h +3 -1
- data/vendor/libgit2/src/push.c +4 -171
- data/vendor/libgit2/src/push.h +2 -0
- data/vendor/libgit2/src/rebase.c +1 -0
- data/vendor/libgit2/src/refdb.c +2 -3
- data/vendor/libgit2/src/refdb.h +2 -0
- data/vendor/libgit2/src/refdb_fs.c +5 -3
- data/vendor/libgit2/src/refdb_fs.h +4 -0
- data/vendor/libgit2/src/reflog.c +1 -0
- data/vendor/libgit2/src/reflog.h +2 -1
- data/vendor/libgit2/src/refs.c +1 -0
- data/vendor/libgit2/src/refs.h +2 -1
- data/vendor/libgit2/src/refspec.c +2 -2
- data/vendor/libgit2/src/refspec.h +2 -0
- data/vendor/libgit2/src/remote.c +56 -10
- data/vendor/libgit2/src/remote.h +2 -0
- data/vendor/libgit2/src/repository.c +16 -14
- data/vendor/libgit2/src/repository.h +2 -0
- data/vendor/libgit2/src/reset.c +6 -5
- data/vendor/libgit2/src/revert.c +1 -0
- data/vendor/libgit2/src/revparse.c +3 -5
- data/vendor/libgit2/src/revwalk.c +2 -2
- data/vendor/libgit2/src/revwalk.h +2 -0
- data/vendor/libgit2/src/settings.c +6 -8
- data/vendor/libgit2/src/sha1_lookup.c +2 -216
- data/vendor/libgit2/src/sha1_lookup.h +2 -6
- data/vendor/libgit2/src/signature.c +8 -3
- data/vendor/libgit2/src/signature.h +2 -0
- data/vendor/libgit2/src/sortedcache.c +7 -0
- data/vendor/libgit2/src/sortedcache.h +2 -0
- data/vendor/libgit2/src/stash.c +1 -0
- data/vendor/libgit2/src/status.c +14 -9
- data/vendor/libgit2/src/status.h +2 -0
- data/vendor/libgit2/src/{curl_stream.c → streams/curl.c} +2 -0
- data/vendor/libgit2/src/{curl_stream.h → streams/curl.h} +4 -2
- data/vendor/libgit2/src/{openssl_stream.c → streams/openssl.c} +47 -18
- data/vendor/libgit2/src/{openssl_stream.h → streams/openssl.h} +6 -2
- data/vendor/libgit2/src/{socket_stream.c → streams/socket.c} +2 -2
- data/vendor/libgit2/src/{socket_stream.h → streams/socket.h} +4 -2
- data/vendor/libgit2/src/{stransport_stream.c → streams/stransport.c} +4 -2
- data/vendor/libgit2/src/{stransport_stream.h → streams/stransport.h} +4 -2
- data/vendor/libgit2/src/{tls_stream.c → streams/tls.c} +4 -3
- data/vendor/libgit2/src/{tls_stream.h → streams/tls.h} +4 -2
- data/vendor/libgit2/src/submodule.c +28 -80
- data/vendor/libgit2/src/submodule.h +2 -13
- data/vendor/libgit2/src/sysdir.c +75 -8
- data/vendor/libgit2/src/sysdir.h +2 -1
- data/vendor/libgit2/src/tag.c +2 -2
- data/vendor/libgit2/src/tag.h +2 -0
- data/vendor/libgit2/src/thread-utils.c +1 -0
- data/vendor/libgit2/src/thread-utils.h +1 -1
- data/vendor/libgit2/src/trace.c +2 -2
- data/vendor/libgit2/src/trace.h +2 -0
- data/vendor/libgit2/src/trailer.c +416 -0
- data/vendor/libgit2/src/transaction.c +2 -1
- data/vendor/libgit2/src/transport.c +2 -0
- data/vendor/libgit2/src/transports/auth.c +2 -1
- data/vendor/libgit2/src/transports/auth.h +4 -3
- data/vendor/libgit2/src/transports/auth_negotiate.c +2 -1
- data/vendor/libgit2/src/transports/auth_negotiate.h +3 -3
- data/vendor/libgit2/src/transports/cred.c +2 -0
- data/vendor/libgit2/src/transports/cred.h +4 -2
- data/vendor/libgit2/src/transports/cred_helpers.c +1 -0
- data/vendor/libgit2/src/transports/git.c +3 -1
- data/vendor/libgit2/src/transports/http.c +10 -14
- data/vendor/libgit2/src/transports/http.h +23 -0
- data/vendor/libgit2/src/transports/local.c +23 -5
- data/vendor/libgit2/src/transports/smart.c +3 -1
- data/vendor/libgit2/src/transports/smart.h +23 -16
- data/vendor/libgit2/src/transports/smart_pkt.c +114 -130
- data/vendor/libgit2/src/transports/smart_protocol.c +26 -22
- data/vendor/libgit2/src/transports/ssh.c +12 -7
- data/vendor/libgit2/src/transports/ssh.h +4 -2
- data/vendor/libgit2/src/transports/winhttp.c +19 -21
- data/vendor/libgit2/src/tree-cache.c +1 -0
- data/vendor/libgit2/src/tree-cache.h +1 -0
- data/vendor/libgit2/src/tree.c +20 -14
- data/vendor/libgit2/src/tree.h +2 -0
- data/vendor/libgit2/src/tsort.c +0 -1
- data/vendor/libgit2/src/unix/map.c +4 -1
- data/vendor/libgit2/src/unix/posix.h +8 -4
- data/vendor/libgit2/src/unix/pthread.h +1 -1
- data/vendor/libgit2/src/unix/realpath.c +4 -1
- data/vendor/libgit2/src/util.c +6 -5
- data/vendor/libgit2/src/util.h +39 -111
- data/vendor/libgit2/src/varint.c +0 -1
- data/vendor/libgit2/src/varint.h +2 -0
- data/vendor/libgit2/src/vector.c +1 -1
- data/vendor/libgit2/src/win32/dir.c +3 -0
- data/vendor/libgit2/src/win32/dir.h +4 -3
- data/vendor/libgit2/src/win32/error.c +1 -1
- data/vendor/libgit2/src/win32/error.h +4 -2
- data/vendor/libgit2/src/win32/findfile.c +2 -1
- data/vendor/libgit2/src/win32/findfile.h +4 -2
- data/vendor/libgit2/src/win32/map.c +2 -0
- data/vendor/libgit2/src/win32/mingw-compat.h +3 -3
- data/vendor/libgit2/src/win32/msvc-compat.h +3 -3
- data/vendor/libgit2/src/win32/path_w32.c +7 -12
- data/vendor/libgit2/src/win32/path_w32.h +3 -2
- data/vendor/libgit2/src/win32/posix.h +2 -2
- data/vendor/libgit2/src/win32/posix_w32.c +11 -5
- data/vendor/libgit2/src/win32/precompiled.h +2 -1
- data/vendor/libgit2/src/win32/reparse.h +2 -2
- data/vendor/libgit2/src/win32/thread.c +1 -0
- data/vendor/libgit2/src/win32/thread.h +2 -2
- data/vendor/libgit2/src/win32/utf-conv.c +0 -1
- data/vendor/libgit2/src/win32/utf-conv.h +4 -3
- data/vendor/libgit2/src/win32/w32_buffer.c +1 -1
- data/vendor/libgit2/src/win32/w32_buffer.h +4 -2
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +2 -1
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +85 -2
- data/vendor/libgit2/src/win32/w32_stack.c +2 -1
- data/vendor/libgit2/src/win32/w32_stack.h +5 -3
- data/vendor/libgit2/src/win32/w32_util.h +4 -2
- data/vendor/libgit2/src/win32/win32-compat.h +3 -3
- data/vendor/libgit2/src/worktree.c +4 -5
- data/vendor/libgit2/src/worktree.h +2 -0
- data/vendor/libgit2/src/xdiff/xdiff.h +22 -13
- data/vendor/libgit2/src/xdiff/xdiffi.c +523 -81
- data/vendor/libgit2/src/xdiff/xdiffi.h +2 -2
- data/vendor/libgit2/src/xdiff/xemit.c +63 -39
- data/vendor/libgit2/src/xdiff/xemit.h +2 -2
- data/vendor/libgit2/src/xdiff/xhistogram.c +0 -1
- 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 +80 -20
- data/vendor/libgit2/src/xdiff/xpatience.c +41 -9
- data/vendor/libgit2/src/xdiff/xprepare.c +2 -2
- 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 +47 -27
- data/vendor/libgit2/src/xdiff/xutils.h +2 -5
- data/vendor/libgit2/src/zstream.c +65 -45
- data/vendor/libgit2/src/zstream.h +9 -2
- metadata +27 -13
- data/vendor/libgit2/include/git2/sys/remote.h +0 -16
data/vendor/libgit2/src/clone.c
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
#include "clone.h"
|
|
9
|
+
|
|
8
10
|
#include <assert.h>
|
|
9
11
|
|
|
10
12
|
#include "git2/clone.h"
|
|
@@ -16,7 +18,6 @@
|
|
|
16
18
|
#include "git2/commit.h"
|
|
17
19
|
#include "git2/tree.h"
|
|
18
20
|
|
|
19
|
-
#include "common.h"
|
|
20
21
|
#include "remote.h"
|
|
21
22
|
#include "fileops.h"
|
|
22
23
|
#include "refs.h"
|
data/vendor/libgit2/src/clone.h
CHANGED
data/vendor/libgit2/src/commit.c
CHANGED
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
#include "commit.h"
|
|
9
|
+
|
|
8
10
|
#include "git2/common.h"
|
|
9
11
|
#include "git2/object.h"
|
|
10
12
|
#include "git2/repository.h"
|
|
11
13
|
#include "git2/signature.h"
|
|
12
14
|
#include "git2/sys/commit.h"
|
|
13
15
|
|
|
14
|
-
#include "common.h"
|
|
15
16
|
#include "odb.h"
|
|
16
17
|
#include "commit.h"
|
|
17
18
|
#include "signature.h"
|
data/vendor/libgit2/src/commit.h
CHANGED
data/vendor/libgit2/src/common.h
CHANGED
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
#ifndef INCLUDE_common_h__
|
|
8
8
|
#define INCLUDE_common_h__
|
|
9
9
|
|
|
10
|
+
#ifndef LIBGIT2_NO_FEATURES_H
|
|
11
|
+
# include "git2/sys/features.h"
|
|
12
|
+
#endif
|
|
13
|
+
|
|
10
14
|
#include "git2/common.h"
|
|
11
15
|
#include "cc-compat.h"
|
|
12
16
|
|
|
@@ -47,10 +51,6 @@
|
|
|
47
51
|
# ifdef GIT_THREADS
|
|
48
52
|
# include "win32/thread.h"
|
|
49
53
|
# endif
|
|
50
|
-
# if defined(GIT_MSVC_CRTDBG)
|
|
51
|
-
# include "win32/w32_stack.h"
|
|
52
|
-
# include "win32/w32_crtdbg_stacktrace.h"
|
|
53
|
-
# endif
|
|
54
54
|
|
|
55
55
|
#else
|
|
56
56
|
|
|
@@ -230,6 +230,12 @@ GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int v
|
|
|
230
230
|
GIT_ADD_SIZET_OVERFLOW(out, *(out), three) || \
|
|
231
231
|
GIT_ADD_SIZET_OVERFLOW(out, *(out), four)) { return -1; }
|
|
232
232
|
|
|
233
|
+
#define GITERR_CHECK_ALLOC_ADD5(out, one, two, three, four, five) \
|
|
234
|
+
if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \
|
|
235
|
+
GIT_ADD_SIZET_OVERFLOW(out, *(out), three) || \
|
|
236
|
+
GIT_ADD_SIZET_OVERFLOW(out, *(out), four) || \
|
|
237
|
+
GIT_ADD_SIZET_OVERFLOW(out, *(out), five)) { return -1; }
|
|
238
|
+
|
|
233
239
|
/** Check for multiplicative overflow, failing if it would occur. */
|
|
234
240
|
#define GITERR_CHECK_ALLOC_MULTIPLY(out, nelem, elsize) \
|
|
235
241
|
if (GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize)) { return -1; }
|
|
@@ -238,4 +244,4 @@ GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int v
|
|
|
238
244
|
|
|
239
245
|
#include "util.h"
|
|
240
246
|
|
|
241
|
-
#endif
|
|
247
|
+
#endif
|
data/vendor/libgit2/src/config.c
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
#include "common.h"
|
|
9
|
-
#include "sysdir.h"
|
|
10
8
|
#include "config.h"
|
|
9
|
+
|
|
10
|
+
#include "sysdir.h"
|
|
11
11
|
#include "git2/config.h"
|
|
12
12
|
#include "git2/sys/config.h"
|
|
13
13
|
#include "vector.h"
|
|
@@ -99,6 +99,7 @@ int git_config_add_file_ondisk(
|
|
|
99
99
|
git_config *cfg,
|
|
100
100
|
const char *path,
|
|
101
101
|
git_config_level_t level,
|
|
102
|
+
const git_repository *repo,
|
|
102
103
|
int force)
|
|
103
104
|
{
|
|
104
105
|
git_config_backend *file = NULL;
|
|
@@ -116,7 +117,7 @@ int git_config_add_file_ondisk(
|
|
|
116
117
|
if (git_config_file__ondisk(&file, path) < 0)
|
|
117
118
|
return -1;
|
|
118
119
|
|
|
119
|
-
if ((res = git_config_add_backend(cfg, file, level, force)) < 0) {
|
|
120
|
+
if ((res = git_config_add_backend(cfg, file, level, repo, force)) < 0) {
|
|
120
121
|
/*
|
|
121
122
|
* free manually; the file is not owned by the config
|
|
122
123
|
* instance yet and will not be freed on cleanup
|
|
@@ -138,7 +139,7 @@ int git_config_open_ondisk(git_config **out, const char *path)
|
|
|
138
139
|
if (git_config_new(&config) < 0)
|
|
139
140
|
return -1;
|
|
140
141
|
|
|
141
|
-
if ((error = git_config_add_file_ondisk(config, path, GIT_CONFIG_LEVEL_LOCAL, 0)) < 0)
|
|
142
|
+
if ((error = git_config_add_file_ondisk(config, path, GIT_CONFIG_LEVEL_LOCAL, NULL, 0)) < 0)
|
|
142
143
|
git_config_free(config);
|
|
143
144
|
else
|
|
144
145
|
*out = config;
|
|
@@ -164,7 +165,7 @@ int git_config_snapshot(git_config **out, git_config *in)
|
|
|
164
165
|
if ((error = internal->file->snapshot(&b, internal->file)) < 0)
|
|
165
166
|
break;
|
|
166
167
|
|
|
167
|
-
if ((error = git_config_add_backend(config, b, internal->level, 0)) < 0) {
|
|
168
|
+
if ((error = git_config_add_backend(config, b, internal->level, NULL, 0)) < 0) {
|
|
168
169
|
b->free(b);
|
|
169
170
|
break;
|
|
170
171
|
}
|
|
@@ -307,6 +308,7 @@ int git_config_add_backend(
|
|
|
307
308
|
git_config *cfg,
|
|
308
309
|
git_config_backend *file,
|
|
309
310
|
git_config_level_t level,
|
|
311
|
+
const git_repository *repo,
|
|
310
312
|
int force)
|
|
311
313
|
{
|
|
312
314
|
file_internal *internal;
|
|
@@ -316,7 +318,7 @@ int git_config_add_backend(
|
|
|
316
318
|
|
|
317
319
|
GITERR_CHECK_VERSION(file, GIT_CONFIG_BACKEND_VERSION, "git_config_backend");
|
|
318
320
|
|
|
319
|
-
if ((result = file->open(file, level)) < 0)
|
|
321
|
+
if ((result = file->open(file, level, repo)) < 0)
|
|
320
322
|
return result;
|
|
321
323
|
|
|
322
324
|
internal = git__malloc(sizeof(file_internal));
|
|
@@ -1147,20 +1149,20 @@ int git_config_open_default(git_config **out)
|
|
|
1147
1149
|
|
|
1148
1150
|
if (!git_config_find_global(&buf) || !git_config__global_location(&buf)) {
|
|
1149
1151
|
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
|
1150
|
-
GIT_CONFIG_LEVEL_GLOBAL, 0);
|
|
1152
|
+
GIT_CONFIG_LEVEL_GLOBAL, NULL, 0);
|
|
1151
1153
|
}
|
|
1152
1154
|
|
|
1153
1155
|
if (!error && !git_config_find_xdg(&buf))
|
|
1154
1156
|
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
|
1155
|
-
GIT_CONFIG_LEVEL_XDG, 0);
|
|
1157
|
+
GIT_CONFIG_LEVEL_XDG, NULL, 0);
|
|
1156
1158
|
|
|
1157
1159
|
if (!error && !git_config_find_system(&buf))
|
|
1158
1160
|
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
|
1159
|
-
GIT_CONFIG_LEVEL_SYSTEM, 0);
|
|
1161
|
+
GIT_CONFIG_LEVEL_SYSTEM, NULL, 0);
|
|
1160
1162
|
|
|
1161
1163
|
if (!error && !git_config_find_programdata(&buf))
|
|
1162
1164
|
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
|
1163
|
-
GIT_CONFIG_LEVEL_PROGRAMDATA, 0);
|
|
1165
|
+
GIT_CONFIG_LEVEL_PROGRAMDATA, NULL, 0);
|
|
1164
1166
|
|
|
1165
1167
|
git_buf_free(&buf);
|
|
1166
1168
|
|
data/vendor/libgit2/src/config.h
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
#include "
|
|
8
|
+
#include "config_file.h"
|
|
9
|
+
|
|
9
10
|
#include "config.h"
|
|
10
11
|
#include "filebuf.h"
|
|
11
12
|
#include "sysdir.h"
|
|
@@ -16,6 +17,7 @@
|
|
|
16
17
|
#include "git2/types.h"
|
|
17
18
|
#include "strmap.h"
|
|
18
19
|
#include "array.h"
|
|
20
|
+
#include "config_parse.h"
|
|
19
21
|
|
|
20
22
|
#include <ctype.h>
|
|
21
23
|
#include <sys/types.h>
|
|
@@ -74,15 +76,6 @@ typedef struct git_config_file_iter {
|
|
|
74
76
|
(iter) && (((tmp) = CVAR_LIST_NEXT(iter) || 1));\
|
|
75
77
|
(iter) = (tmp))
|
|
76
78
|
|
|
77
|
-
struct reader {
|
|
78
|
-
git_oid checksum;
|
|
79
|
-
char *file_path;
|
|
80
|
-
git_buf buffer;
|
|
81
|
-
char *read_ptr;
|
|
82
|
-
int line_number;
|
|
83
|
-
int eof;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
79
|
typedef struct {
|
|
87
80
|
git_atomic refcount;
|
|
88
81
|
git_strmap *values;
|
|
@@ -93,20 +86,20 @@ typedef struct {
|
|
|
93
86
|
/* mutex to coordinate accessing the values */
|
|
94
87
|
git_mutex values_mutex;
|
|
95
88
|
refcounted_strmap *values;
|
|
89
|
+
const git_repository *repo;
|
|
90
|
+
git_config_level_t level;
|
|
96
91
|
} diskfile_header;
|
|
97
92
|
|
|
98
93
|
typedef struct {
|
|
99
94
|
diskfile_header header;
|
|
100
95
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
git_array_t(struct reader) readers;
|
|
96
|
+
git_array_t(git_config_parser) readers;
|
|
104
97
|
|
|
105
98
|
bool locked;
|
|
106
99
|
git_filebuf locked_buf;
|
|
107
100
|
git_buf locked_content;
|
|
108
101
|
|
|
109
|
-
|
|
102
|
+
struct config_file file;
|
|
110
103
|
} diskfile_backend;
|
|
111
104
|
|
|
112
105
|
typedef struct {
|
|
@@ -115,19 +108,13 @@ typedef struct {
|
|
|
115
108
|
diskfile_backend *snapshot_from;
|
|
116
109
|
} diskfile_readonly_backend;
|
|
117
110
|
|
|
118
|
-
static int config_read(git_strmap *values,
|
|
119
|
-
static int config_write(diskfile_backend *cfg, const char *key, const regex_t *preg, const char *value);
|
|
111
|
+
static int config_read(git_strmap *values, const git_repository *repo, git_config_file *file, git_config_level_t level, int depth);
|
|
112
|
+
static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const regex_t *preg, const char *value);
|
|
120
113
|
static char *escape_value(const char *ptr);
|
|
121
114
|
|
|
122
115
|
int git_config_file__snapshot(git_config_backend **out, diskfile_backend *in);
|
|
123
116
|
static int config_snapshot(git_config_backend **out, git_config_backend *in);
|
|
124
117
|
|
|
125
|
-
static void set_parse_error(struct reader *reader, int col, const char *error_str)
|
|
126
|
-
{
|
|
127
|
-
giterr_set(GITERR_CONFIG, "failed to parse config file: %s (in %s:%d, column %d)",
|
|
128
|
-
error_str, reader->file_path, reader->line_number, col);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
118
|
static int config_error_readonly(void)
|
|
132
119
|
{
|
|
133
120
|
giterr_set(GITERR_CONFIG, "this backend is read-only");
|
|
@@ -261,123 +248,131 @@ static int refcounted_strmap_alloc(refcounted_strmap **out)
|
|
|
261
248
|
return error;
|
|
262
249
|
}
|
|
263
250
|
|
|
264
|
-
static
|
|
251
|
+
static void config_file_clear(struct config_file *file)
|
|
252
|
+
{
|
|
253
|
+
struct config_file *include;
|
|
254
|
+
uint32_t i;
|
|
255
|
+
|
|
256
|
+
if (file == NULL)
|
|
257
|
+
return;
|
|
258
|
+
|
|
259
|
+
git_array_foreach(file->includes, i, include) {
|
|
260
|
+
config_file_clear(include);
|
|
261
|
+
}
|
|
262
|
+
git_array_clear(file->includes);
|
|
263
|
+
|
|
264
|
+
git__free(file->path);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
static int config_open(git_config_backend *cfg, git_config_level_t level, const git_repository *repo)
|
|
265
268
|
{
|
|
266
269
|
int res;
|
|
267
|
-
struct reader *reader;
|
|
268
270
|
diskfile_backend *b = (diskfile_backend *)cfg;
|
|
269
271
|
|
|
270
|
-
b->level = level;
|
|
272
|
+
b->header.level = level;
|
|
273
|
+
b->header.repo = repo;
|
|
271
274
|
|
|
272
275
|
if ((res = refcounted_strmap_alloc(&b->header.values)) < 0)
|
|
273
276
|
return res;
|
|
274
277
|
|
|
275
|
-
|
|
276
|
-
reader = git_array_alloc(b->readers);
|
|
277
|
-
if (!reader) {
|
|
278
|
-
refcounted_strmap_free(b->header.values);
|
|
279
|
-
return -1;
|
|
280
|
-
}
|
|
281
|
-
memset(reader, 0, sizeof(struct reader));
|
|
282
|
-
|
|
283
|
-
reader->file_path = git__strdup(b->file_path);
|
|
284
|
-
GITERR_CHECK_ALLOC(reader->file_path);
|
|
285
|
-
|
|
286
|
-
git_buf_init(&reader->buffer, 0);
|
|
287
|
-
res = git_futils_readbuffer_updated(
|
|
288
|
-
&reader->buffer, b->file_path, &reader->checksum, NULL);
|
|
289
|
-
|
|
290
|
-
/* It's fine if the file doesn't exist */
|
|
291
|
-
if (res == GIT_ENOTFOUND)
|
|
278
|
+
if (!git_path_exists(b->file.path))
|
|
292
279
|
return 0;
|
|
293
280
|
|
|
294
|
-
if (res < 0 || (res = config_read(b->header.values->values,
|
|
281
|
+
if (res < 0 || (res = config_read(b->header.values->values, repo, &b->file, level, 0)) < 0) {
|
|
295
282
|
refcounted_strmap_free(b->header.values);
|
|
296
283
|
b->header.values = NULL;
|
|
297
284
|
}
|
|
298
285
|
|
|
299
|
-
reader = git_array_get(b->readers, 0);
|
|
300
|
-
git_buf_free(&reader->buffer);
|
|
301
|
-
|
|
302
286
|
return res;
|
|
303
287
|
}
|
|
304
288
|
|
|
305
|
-
|
|
306
|
-
static int config__refresh(git_config_backend *cfg)
|
|
289
|
+
static int config_is_modified(int *modified, struct config_file *file)
|
|
307
290
|
{
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
291
|
+
git_config_file *include;
|
|
292
|
+
git_buf buf = GIT_BUF_INIT;
|
|
293
|
+
git_oid hash;
|
|
294
|
+
uint32_t i;
|
|
311
295
|
int error = 0;
|
|
312
296
|
|
|
313
|
-
|
|
314
|
-
goto out;
|
|
297
|
+
*modified = 0;
|
|
315
298
|
|
|
316
|
-
|
|
317
|
-
|
|
299
|
+
if ((error = git_futils_readbuffer(&buf, file->path)) < 0)
|
|
300
|
+
goto out;
|
|
318
301
|
|
|
319
|
-
if ((error =
|
|
302
|
+
if ((error = git_hash_buf(&hash, buf.ptr, buf.size)) < 0)
|
|
320
303
|
goto out;
|
|
321
304
|
|
|
322
|
-
if ((
|
|
323
|
-
|
|
305
|
+
if (!git_oid_equal(&hash, &file->checksum)) {
|
|
306
|
+
*modified = 1;
|
|
324
307
|
goto out;
|
|
325
308
|
}
|
|
326
309
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
git_mutex_unlock(&b->header.values_mutex);
|
|
310
|
+
git_array_foreach(file->includes, i, include) {
|
|
311
|
+
if ((error = config_is_modified(modified, include)) < 0 || *modified)
|
|
312
|
+
goto out;
|
|
313
|
+
}
|
|
332
314
|
|
|
333
315
|
out:
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
git_buf_free(&reader->buffer);
|
|
316
|
+
git_buf_free(&buf);
|
|
317
|
+
|
|
337
318
|
return error;
|
|
338
319
|
}
|
|
339
320
|
|
|
340
321
|
static int config_refresh(git_config_backend *cfg)
|
|
341
322
|
{
|
|
342
|
-
int error = 0, updated = 0, any_updated = 0;
|
|
343
323
|
diskfile_backend *b = (diskfile_backend *)cfg;
|
|
344
|
-
|
|
324
|
+
refcounted_strmap *values = NULL, *tmp;
|
|
325
|
+
git_config_file *include;
|
|
326
|
+
int error, modified;
|
|
345
327
|
uint32_t i;
|
|
346
328
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
329
|
+
if (b->header.parent.readonly)
|
|
330
|
+
return config_error_readonly();
|
|
331
|
+
|
|
332
|
+
error = config_is_modified(&modified, &b->file);
|
|
333
|
+
if (error < 0 && error != GIT_ENOTFOUND)
|
|
334
|
+
goto out;
|
|
335
|
+
|
|
336
|
+
if (!modified)
|
|
337
|
+
return 0;
|
|
352
338
|
|
|
353
|
-
|
|
354
|
-
|
|
339
|
+
if ((error = refcounted_strmap_alloc(&values)) < 0)
|
|
340
|
+
goto out;
|
|
341
|
+
|
|
342
|
+
/* Reparse the current configuration */
|
|
343
|
+
git_array_foreach(b->file.includes, i, include) {
|
|
344
|
+
config_file_clear(include);
|
|
345
|
+
}
|
|
346
|
+
git_array_clear(b->file.includes);
|
|
347
|
+
|
|
348
|
+
if ((error = config_read(values->values, b->header.repo, &b->file, b->header.level, 0)) < 0)
|
|
349
|
+
goto out;
|
|
355
350
|
|
|
356
|
-
|
|
357
|
-
|
|
351
|
+
if ((error = git_mutex_lock(&b->header.values_mutex)) < 0) {
|
|
352
|
+
giterr_set(GITERR_OS, "failed to lock config backend");
|
|
353
|
+
goto out;
|
|
358
354
|
}
|
|
359
355
|
|
|
360
|
-
|
|
361
|
-
|
|
356
|
+
tmp = b->header.values;
|
|
357
|
+
b->header.values = values;
|
|
358
|
+
values = tmp;
|
|
359
|
+
|
|
360
|
+
git_mutex_unlock(&b->header.values_mutex);
|
|
361
|
+
|
|
362
|
+
out:
|
|
363
|
+
refcounted_strmap_free(values);
|
|
362
364
|
|
|
363
|
-
return
|
|
365
|
+
return (error == GIT_ENOTFOUND) ? 0 : error;
|
|
364
366
|
}
|
|
365
367
|
|
|
366
368
|
static void backend_free(git_config_backend *_backend)
|
|
367
369
|
{
|
|
368
370
|
diskfile_backend *backend = (diskfile_backend *)_backend;
|
|
369
|
-
uint32_t i;
|
|
370
371
|
|
|
371
372
|
if (backend == NULL)
|
|
372
373
|
return;
|
|
373
374
|
|
|
374
|
-
|
|
375
|
-
struct reader *r = git_array_get(backend->readers, i);
|
|
376
|
-
git__free(r->file_path);
|
|
377
|
-
}
|
|
378
|
-
git_array_clear(backend->readers);
|
|
379
|
-
|
|
380
|
-
git__free(backend->file_path);
|
|
375
|
+
config_file_clear(&backend->file);
|
|
381
376
|
refcounted_strmap_free(backend->header.values);
|
|
382
377
|
git_mutex_free(&backend->header.values_mutex);
|
|
383
378
|
git__free(backend);
|
|
@@ -424,13 +419,13 @@ static int config_iterator_new(
|
|
|
424
419
|
diskfile_header *h;
|
|
425
420
|
git_config_file_iter *it;
|
|
426
421
|
git_config_backend *snapshot;
|
|
427
|
-
|
|
422
|
+
diskfile_header *bh = (diskfile_header *) backend;
|
|
428
423
|
int error;
|
|
429
424
|
|
|
430
425
|
if ((error = config_snapshot(&snapshot, backend)) < 0)
|
|
431
426
|
return error;
|
|
432
427
|
|
|
433
|
-
if ((error = snapshot->open(snapshot,
|
|
428
|
+
if ((error = snapshot->open(snapshot, bh->level, bh->repo)) < 0)
|
|
434
429
|
return error;
|
|
435
430
|
|
|
436
431
|
it = git__calloc(1, sizeof(git_config_file_iter));
|
|
@@ -482,6 +477,12 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
|
|
|
482
477
|
goto out;
|
|
483
478
|
}
|
|
484
479
|
|
|
480
|
+
if (existing->included) {
|
|
481
|
+
giterr_set(GITERR_CONFIG, "modifying included variable is not supported");
|
|
482
|
+
ret = -1;
|
|
483
|
+
goto out;
|
|
484
|
+
}
|
|
485
|
+
|
|
485
486
|
/* don't update if old and new values already match */
|
|
486
487
|
if ((!existing->entry->value && !value) ||
|
|
487
488
|
(existing->entry->value && value &&
|
|
@@ -498,7 +499,7 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
|
|
|
498
499
|
GITERR_CHECK_ALLOC(esc_value);
|
|
499
500
|
}
|
|
500
501
|
|
|
501
|
-
if ((ret = config_write(b, key, NULL, esc_value)) < 0)
|
|
502
|
+
if ((ret = config_write(b, name, key, NULL, esc_value)) < 0)
|
|
502
503
|
goto out;
|
|
503
504
|
|
|
504
505
|
ret = config_refresh(cfg);
|
|
@@ -576,7 +577,7 @@ static int config_set_multivar(
|
|
|
576
577
|
}
|
|
577
578
|
|
|
578
579
|
/* If we do have it, set call config_write() and reload */
|
|
579
|
-
if ((result = config_write(b, key, &preg, value)) < 0)
|
|
580
|
+
if ((result = config_write(b, name, key, &preg, value)) < 0)
|
|
580
581
|
goto out;
|
|
581
582
|
|
|
582
583
|
result = config_refresh(cfg);
|
|
@@ -616,12 +617,17 @@ static int config_delete(git_config_backend *cfg, const char *name)
|
|
|
616
617
|
var = git_strmap_value_at(values, pos);
|
|
617
618
|
refcounted_strmap_free(map);
|
|
618
619
|
|
|
620
|
+
if (var->included) {
|
|
621
|
+
giterr_set(GITERR_CONFIG, "cannot delete included variable");
|
|
622
|
+
return -1;
|
|
623
|
+
}
|
|
624
|
+
|
|
619
625
|
if (var->next != NULL) {
|
|
620
626
|
giterr_set(GITERR_CONFIG, "cannot delete multivar with a single delete");
|
|
621
627
|
return -1;
|
|
622
628
|
}
|
|
623
629
|
|
|
624
|
-
if ((result = config_write(b, var->entry->name, NULL, NULL)) < 0)
|
|
630
|
+
if ((result = config_write(b, name, var->entry->name, NULL, NULL)) < 0)
|
|
625
631
|
return result;
|
|
626
632
|
|
|
627
633
|
return config_refresh(cfg);
|
|
@@ -662,7 +668,7 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
|
|
|
662
668
|
goto out;
|
|
663
669
|
}
|
|
664
670
|
|
|
665
|
-
if ((result = config_write(b, key, &preg, NULL)) < 0)
|
|
671
|
+
if ((result = config_write(b, name, key, &preg, NULL)) < 0)
|
|
666
672
|
goto out;
|
|
667
673
|
|
|
668
674
|
result = config_refresh(cfg);
|
|
@@ -685,10 +691,10 @@ static int config_lock(git_config_backend *_cfg)
|
|
|
685
691
|
diskfile_backend *cfg = (diskfile_backend *) _cfg;
|
|
686
692
|
int error;
|
|
687
693
|
|
|
688
|
-
if ((error = git_filebuf_open(&cfg->locked_buf, cfg->
|
|
694
|
+
if ((error = git_filebuf_open(&cfg->locked_buf, cfg->file.path, 0, GIT_CONFIG_FILE_MODE)) < 0)
|
|
689
695
|
return error;
|
|
690
696
|
|
|
691
|
-
error = git_futils_readbuffer(&cfg->locked_content, cfg->
|
|
697
|
+
error = git_futils_readbuffer(&cfg->locked_content, cfg->file.path);
|
|
692
698
|
if (error < 0 && error != GIT_ENOTFOUND) {
|
|
693
699
|
git_filebuf_cleanup(&cfg->locked_buf);
|
|
694
700
|
return error;
|
|
@@ -726,8 +732,9 @@ int git_config_file__ondisk(git_config_backend **out, const char *path)
|
|
|
726
732
|
backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
|
|
727
733
|
git_mutex_init(&backend->header.values_mutex);
|
|
728
734
|
|
|
729
|
-
backend->
|
|
730
|
-
GITERR_CHECK_ALLOC(backend->
|
|
735
|
+
backend->file.path = git__strdup(path);
|
|
736
|
+
GITERR_CHECK_ALLOC(backend->file.path);
|
|
737
|
+
git_array_init(backend->file.includes);
|
|
731
738
|
|
|
732
739
|
backend->header.parent.open = config_open;
|
|
733
740
|
backend->header.parent.get = config_get;
|
|
@@ -810,7 +817,7 @@ static void backend_readonly_free(git_config_backend *_backend)
|
|
|
810
817
|
git__free(backend);
|
|
811
818
|
}
|
|
812
819
|
|
|
813
|
-
static int config_readonly_open(git_config_backend *cfg, git_config_level_t level)
|
|
820
|
+
static int config_readonly_open(git_config_backend *cfg, git_config_level_t level, const git_repository *repo)
|
|
814
821
|
{
|
|
815
822
|
diskfile_readonly_backend *b = (diskfile_readonly_backend *) cfg;
|
|
816
823
|
diskfile_backend *src = b->snapshot_from;
|
|
@@ -821,8 +828,9 @@ static int config_readonly_open(git_config_backend *cfg, git_config_level_t leve
|
|
|
821
828
|
if (!src_header->parent.readonly && (error = config_refresh(&src_header->parent)) < 0)
|
|
822
829
|
return error;
|
|
823
830
|
|
|
824
|
-
/* We're just copying data, don't care about the level */
|
|
831
|
+
/* We're just copying data, don't care about the level or repo*/
|
|
825
832
|
GIT_UNUSED(level);
|
|
833
|
+
GIT_UNUSED(repo);
|
|
826
834
|
|
|
827
835
|
if ((src_map = refcounted_strmap_take(src_header)) == NULL)
|
|
828
836
|
return -1;
|
|
@@ -861,397 +869,6 @@ int git_config_file__snapshot(git_config_backend **out, diskfile_backend *in)
|
|
|
861
869
|
return 0;
|
|
862
870
|
}
|
|
863
871
|
|
|
864
|
-
static int reader_getchar_raw(struct reader *reader)
|
|
865
|
-
{
|
|
866
|
-
int c;
|
|
867
|
-
|
|
868
|
-
c = *reader->read_ptr++;
|
|
869
|
-
|
|
870
|
-
/*
|
|
871
|
-
Win 32 line breaks: if we find a \r\n sequence,
|
|
872
|
-
return only the \n as a newline
|
|
873
|
-
*/
|
|
874
|
-
if (c == '\r' && *reader->read_ptr == '\n') {
|
|
875
|
-
reader->read_ptr++;
|
|
876
|
-
c = '\n';
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
if (c == '\n')
|
|
880
|
-
reader->line_number++;
|
|
881
|
-
|
|
882
|
-
if (c == 0) {
|
|
883
|
-
reader->eof = 1;
|
|
884
|
-
c = '\0';
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
return c;
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
#define SKIP_WHITESPACE (1 << 1)
|
|
891
|
-
#define SKIP_COMMENTS (1 << 2)
|
|
892
|
-
|
|
893
|
-
static int reader_getchar(struct reader *reader, int flags)
|
|
894
|
-
{
|
|
895
|
-
const int skip_whitespace = (flags & SKIP_WHITESPACE);
|
|
896
|
-
const int skip_comments = (flags & SKIP_COMMENTS);
|
|
897
|
-
int c;
|
|
898
|
-
|
|
899
|
-
assert(reader->read_ptr);
|
|
900
|
-
|
|
901
|
-
do {
|
|
902
|
-
c = reader_getchar_raw(reader);
|
|
903
|
-
} while (c != '\n' && c != '\0' && skip_whitespace && git__isspace(c));
|
|
904
|
-
|
|
905
|
-
if (skip_comments && (c == '#' || c == ';')) {
|
|
906
|
-
do {
|
|
907
|
-
c = reader_getchar_raw(reader);
|
|
908
|
-
} while (c != '\n' && c != '\0');
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
return c;
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
/*
|
|
915
|
-
* Read the next char, but don't move the reading pointer.
|
|
916
|
-
*/
|
|
917
|
-
static int reader_peek(struct reader *reader, int flags)
|
|
918
|
-
{
|
|
919
|
-
void *old_read_ptr;
|
|
920
|
-
int old_lineno, old_eof;
|
|
921
|
-
int ret;
|
|
922
|
-
|
|
923
|
-
assert(reader->read_ptr);
|
|
924
|
-
|
|
925
|
-
old_read_ptr = reader->read_ptr;
|
|
926
|
-
old_lineno = reader->line_number;
|
|
927
|
-
old_eof = reader->eof;
|
|
928
|
-
|
|
929
|
-
ret = reader_getchar(reader, flags);
|
|
930
|
-
|
|
931
|
-
reader->read_ptr = old_read_ptr;
|
|
932
|
-
reader->line_number = old_lineno;
|
|
933
|
-
reader->eof = old_eof;
|
|
934
|
-
|
|
935
|
-
return ret;
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
/*
|
|
939
|
-
* Read and consume a line, returning it in newly-allocated memory.
|
|
940
|
-
*/
|
|
941
|
-
static char *reader_readline(struct reader *reader, bool skip_whitespace)
|
|
942
|
-
{
|
|
943
|
-
char *line = NULL;
|
|
944
|
-
char *line_src, *line_end;
|
|
945
|
-
size_t line_len, alloc_len;
|
|
946
|
-
|
|
947
|
-
line_src = reader->read_ptr;
|
|
948
|
-
|
|
949
|
-
if (skip_whitespace) {
|
|
950
|
-
/* Skip empty empty lines */
|
|
951
|
-
while (git__isspace(*line_src))
|
|
952
|
-
++line_src;
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
line_end = strchr(line_src, '\n');
|
|
956
|
-
|
|
957
|
-
/* no newline at EOF */
|
|
958
|
-
if (line_end == NULL)
|
|
959
|
-
line_end = strchr(line_src, 0);
|
|
960
|
-
|
|
961
|
-
line_len = line_end - line_src;
|
|
962
|
-
|
|
963
|
-
if (GIT_ADD_SIZET_OVERFLOW(&alloc_len, line_len, 1) ||
|
|
964
|
-
(line = git__malloc(alloc_len)) == NULL) {
|
|
965
|
-
return NULL;
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
memcpy(line, line_src, line_len);
|
|
969
|
-
|
|
970
|
-
do line[line_len] = '\0';
|
|
971
|
-
while (line_len-- > 0 && git__isspace(line[line_len]));
|
|
972
|
-
|
|
973
|
-
if (*line_end == '\n')
|
|
974
|
-
line_end++;
|
|
975
|
-
|
|
976
|
-
if (*line_end == '\0')
|
|
977
|
-
reader->eof = 1;
|
|
978
|
-
|
|
979
|
-
reader->line_number++;
|
|
980
|
-
reader->read_ptr = line_end;
|
|
981
|
-
|
|
982
|
-
return line;
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
/*
|
|
986
|
-
* Consume a line, without storing it anywhere
|
|
987
|
-
*/
|
|
988
|
-
static void reader_consume_line(struct reader *reader)
|
|
989
|
-
{
|
|
990
|
-
char *line_start, *line_end;
|
|
991
|
-
|
|
992
|
-
line_start = reader->read_ptr;
|
|
993
|
-
line_end = strchr(line_start, '\n');
|
|
994
|
-
/* No newline at EOF */
|
|
995
|
-
if(line_end == NULL){
|
|
996
|
-
line_end = strchr(line_start, '\0');
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
if (*line_end == '\n')
|
|
1000
|
-
line_end++;
|
|
1001
|
-
|
|
1002
|
-
if (*line_end == '\0')
|
|
1003
|
-
reader->eof = 1;
|
|
1004
|
-
|
|
1005
|
-
reader->line_number++;
|
|
1006
|
-
reader->read_ptr = line_end;
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
GIT_INLINE(int) config_keychar(int c)
|
|
1010
|
-
{
|
|
1011
|
-
return isalnum(c) || c == '-';
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
static int parse_section_header_ext(struct reader *reader, const char *line, const char *base_name, char **section_name)
|
|
1015
|
-
{
|
|
1016
|
-
int c, rpos;
|
|
1017
|
-
char *first_quote, *last_quote;
|
|
1018
|
-
git_buf buf = GIT_BUF_INIT;
|
|
1019
|
-
size_t quoted_len, alloc_len, base_name_len = strlen(base_name);
|
|
1020
|
-
|
|
1021
|
-
/*
|
|
1022
|
-
* base_name is what came before the space. We should be at the
|
|
1023
|
-
* first quotation mark, except for now, line isn't being kept in
|
|
1024
|
-
* sync so we only really use it to calculate the length.
|
|
1025
|
-
*/
|
|
1026
|
-
|
|
1027
|
-
first_quote = strchr(line, '"');
|
|
1028
|
-
if (first_quote == NULL) {
|
|
1029
|
-
set_parse_error(reader, 0, "Missing quotation marks in section header");
|
|
1030
|
-
goto end_error;
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
last_quote = strrchr(line, '"');
|
|
1034
|
-
quoted_len = last_quote - first_quote;
|
|
1035
|
-
|
|
1036
|
-
if (quoted_len == 0) {
|
|
1037
|
-
set_parse_error(reader, 0, "Missing closing quotation mark in section header");
|
|
1038
|
-
goto end_error;
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
GITERR_CHECK_ALLOC_ADD(&alloc_len, base_name_len, quoted_len);
|
|
1042
|
-
GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
|
|
1043
|
-
|
|
1044
|
-
if (git_buf_grow(&buf, alloc_len) < 0 ||
|
|
1045
|
-
git_buf_printf(&buf, "%s.", base_name) < 0)
|
|
1046
|
-
goto end_error;
|
|
1047
|
-
|
|
1048
|
-
rpos = 0;
|
|
1049
|
-
|
|
1050
|
-
line = first_quote;
|
|
1051
|
-
c = line[++rpos];
|
|
1052
|
-
|
|
1053
|
-
/*
|
|
1054
|
-
* At the end of each iteration, whatever is stored in c will be
|
|
1055
|
-
* added to the string. In case of error, jump to out
|
|
1056
|
-
*/
|
|
1057
|
-
do {
|
|
1058
|
-
|
|
1059
|
-
switch (c) {
|
|
1060
|
-
case 0:
|
|
1061
|
-
set_parse_error(reader, 0, "Unexpected end-of-line in section header");
|
|
1062
|
-
goto end_error;
|
|
1063
|
-
|
|
1064
|
-
case '"':
|
|
1065
|
-
goto end_parse;
|
|
1066
|
-
|
|
1067
|
-
case '\\':
|
|
1068
|
-
c = line[++rpos];
|
|
1069
|
-
|
|
1070
|
-
if (c == 0) {
|
|
1071
|
-
set_parse_error(reader, rpos, "Unexpected end-of-line in section header");
|
|
1072
|
-
goto end_error;
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
default:
|
|
1076
|
-
break;
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
git_buf_putc(&buf, (char)c);
|
|
1080
|
-
c = line[++rpos];
|
|
1081
|
-
} while (line + rpos < last_quote);
|
|
1082
|
-
|
|
1083
|
-
end_parse:
|
|
1084
|
-
if (git_buf_oom(&buf))
|
|
1085
|
-
goto end_error;
|
|
1086
|
-
|
|
1087
|
-
if (line[rpos] != '"' || line[rpos + 1] != ']') {
|
|
1088
|
-
set_parse_error(reader, rpos, "Unexpected text after closing quotes");
|
|
1089
|
-
git_buf_free(&buf);
|
|
1090
|
-
return -1;
|
|
1091
|
-
}
|
|
1092
|
-
|
|
1093
|
-
*section_name = git_buf_detach(&buf);
|
|
1094
|
-
return 0;
|
|
1095
|
-
|
|
1096
|
-
end_error:
|
|
1097
|
-
git_buf_free(&buf);
|
|
1098
|
-
|
|
1099
|
-
return -1;
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
static int parse_section_header(struct reader *reader, char **section_out)
|
|
1103
|
-
{
|
|
1104
|
-
char *name, *name_end;
|
|
1105
|
-
int name_length, c, pos;
|
|
1106
|
-
int result;
|
|
1107
|
-
char *line;
|
|
1108
|
-
size_t line_len;
|
|
1109
|
-
|
|
1110
|
-
line = reader_readline(reader, true);
|
|
1111
|
-
if (line == NULL)
|
|
1112
|
-
return -1;
|
|
1113
|
-
|
|
1114
|
-
/* find the end of the variable's name */
|
|
1115
|
-
name_end = strrchr(line, ']');
|
|
1116
|
-
if (name_end == NULL) {
|
|
1117
|
-
git__free(line);
|
|
1118
|
-
set_parse_error(reader, 0, "Missing ']' in section header");
|
|
1119
|
-
return -1;
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
GITERR_CHECK_ALLOC_ADD(&line_len, (size_t)(name_end - line), 1);
|
|
1123
|
-
name = git__malloc(line_len);
|
|
1124
|
-
GITERR_CHECK_ALLOC(name);
|
|
1125
|
-
|
|
1126
|
-
name_length = 0;
|
|
1127
|
-
pos = 0;
|
|
1128
|
-
|
|
1129
|
-
/* Make sure we were given a section header */
|
|
1130
|
-
c = line[pos++];
|
|
1131
|
-
assert(c == '[');
|
|
1132
|
-
|
|
1133
|
-
c = line[pos++];
|
|
1134
|
-
|
|
1135
|
-
do {
|
|
1136
|
-
if (git__isspace(c)){
|
|
1137
|
-
name[name_length] = '\0';
|
|
1138
|
-
result = parse_section_header_ext(reader, line, name, section_out);
|
|
1139
|
-
git__free(line);
|
|
1140
|
-
git__free(name);
|
|
1141
|
-
return result;
|
|
1142
|
-
}
|
|
1143
|
-
|
|
1144
|
-
if (!config_keychar(c) && c != '.') {
|
|
1145
|
-
set_parse_error(reader, pos, "Unexpected character in header");
|
|
1146
|
-
goto fail_parse;
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
name[name_length++] = (char)git__tolower(c);
|
|
1150
|
-
|
|
1151
|
-
} while ((c = line[pos++]) != ']');
|
|
1152
|
-
|
|
1153
|
-
if (line[pos - 1] != ']') {
|
|
1154
|
-
set_parse_error(reader, pos, "Unexpected end of file");
|
|
1155
|
-
goto fail_parse;
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
git__free(line);
|
|
1159
|
-
|
|
1160
|
-
name[name_length] = 0;
|
|
1161
|
-
*section_out = name;
|
|
1162
|
-
|
|
1163
|
-
return 0;
|
|
1164
|
-
|
|
1165
|
-
fail_parse:
|
|
1166
|
-
git__free(line);
|
|
1167
|
-
git__free(name);
|
|
1168
|
-
return -1;
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
static int skip_bom(struct reader *reader)
|
|
1172
|
-
{
|
|
1173
|
-
git_bom_t bom;
|
|
1174
|
-
int bom_offset = git_buf_text_detect_bom(&bom,
|
|
1175
|
-
&reader->buffer, reader->read_ptr - reader->buffer.ptr);
|
|
1176
|
-
|
|
1177
|
-
if (bom == GIT_BOM_UTF8)
|
|
1178
|
-
reader->read_ptr += bom_offset;
|
|
1179
|
-
|
|
1180
|
-
/* TODO: reference implementation is pretty stupid with BoM */
|
|
1181
|
-
|
|
1182
|
-
return 0;
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
/*
|
|
1186
|
-
(* basic types *)
|
|
1187
|
-
digit = "0".."9"
|
|
1188
|
-
integer = digit { digit }
|
|
1189
|
-
alphabet = "a".."z" + "A" .. "Z"
|
|
1190
|
-
|
|
1191
|
-
section_char = alphabet | "." | "-"
|
|
1192
|
-
extension_char = (* any character except newline *)
|
|
1193
|
-
any_char = (* any character *)
|
|
1194
|
-
variable_char = "alphabet" | "-"
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
(* actual grammar *)
|
|
1198
|
-
config = { section }
|
|
1199
|
-
|
|
1200
|
-
section = header { definition }
|
|
1201
|
-
|
|
1202
|
-
header = "[" section [subsection | subsection_ext] "]"
|
|
1203
|
-
|
|
1204
|
-
subsection = "." section
|
|
1205
|
-
subsection_ext = "\"" extension "\""
|
|
1206
|
-
|
|
1207
|
-
section = section_char { section_char }
|
|
1208
|
-
extension = extension_char { extension_char }
|
|
1209
|
-
|
|
1210
|
-
definition = variable_name ["=" variable_value] "\n"
|
|
1211
|
-
|
|
1212
|
-
variable_name = variable_char { variable_char }
|
|
1213
|
-
variable_value = string | boolean | integer
|
|
1214
|
-
|
|
1215
|
-
string = quoted_string | plain_string
|
|
1216
|
-
quoted_string = "\"" plain_string "\""
|
|
1217
|
-
plain_string = { any_char }
|
|
1218
|
-
|
|
1219
|
-
boolean = boolean_true | boolean_false
|
|
1220
|
-
boolean_true = "yes" | "1" | "true" | "on"
|
|
1221
|
-
boolean_false = "no" | "0" | "false" | "off"
|
|
1222
|
-
*/
|
|
1223
|
-
|
|
1224
|
-
static int strip_comments(char *line, int in_quotes)
|
|
1225
|
-
{
|
|
1226
|
-
int quote_count = in_quotes, backslash_count = 0;
|
|
1227
|
-
char *ptr;
|
|
1228
|
-
|
|
1229
|
-
for (ptr = line; *ptr; ++ptr) {
|
|
1230
|
-
if (ptr[0] == '"' && ptr > line && ptr[-1] != '\\')
|
|
1231
|
-
quote_count++;
|
|
1232
|
-
|
|
1233
|
-
if ((ptr[0] == ';' || ptr[0] == '#') &&
|
|
1234
|
-
(quote_count % 2) == 0 &&
|
|
1235
|
-
(backslash_count % 2) == 0) {
|
|
1236
|
-
ptr[0] = '\0';
|
|
1237
|
-
break;
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
|
-
if (ptr[0] == '\\')
|
|
1241
|
-
backslash_count++;
|
|
1242
|
-
else
|
|
1243
|
-
backslash_count = 0;
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
/* skip any space at the end */
|
|
1247
|
-
while (ptr > line && git__isspace(ptr[-1])) {
|
|
1248
|
-
ptr--;
|
|
1249
|
-
}
|
|
1250
|
-
ptr[0] = '\0';
|
|
1251
|
-
|
|
1252
|
-
return quote_count;
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1255
872
|
static int included_path(git_buf *out, const char *dir, const char *path)
|
|
1256
873
|
{
|
|
1257
874
|
/* From the user's home */
|
|
@@ -1261,9 +878,6 @@ static int included_path(git_buf *out, const char *dir, const char *path)
|
|
|
1261
878
|
return git_path_join_unrooted(out, path, dir, NULL);
|
|
1262
879
|
}
|
|
1263
880
|
|
|
1264
|
-
static const char *escapes = "ntb\"\\";
|
|
1265
|
-
static const char *escaped = "\n\t\b\"\\";
|
|
1266
|
-
|
|
1267
881
|
/* Escape the values to write them to the file */
|
|
1268
882
|
static char *escape_value(const char *ptr)
|
|
1269
883
|
{
|
|
@@ -1281,9 +895,9 @@ static char *escape_value(const char *ptr)
|
|
|
1281
895
|
return NULL;
|
|
1282
896
|
|
|
1283
897
|
while (*ptr != '\0') {
|
|
1284
|
-
if ((esc = strchr(
|
|
898
|
+
if ((esc = strchr(git_config_escaped, *ptr)) != NULL) {
|
|
1285
899
|
git_buf_putc(&buf, '\\');
|
|
1286
|
-
git_buf_putc(&buf,
|
|
900
|
+
git_buf_putc(&buf, git_config_escapes[esc - git_config_escaped]);
|
|
1287
901
|
} else {
|
|
1288
902
|
git_buf_putc(&buf, *ptr);
|
|
1289
903
|
}
|
|
@@ -1298,266 +912,151 @@ static char *escape_value(const char *ptr)
|
|
|
1298
912
|
return git_buf_detach(&buf);
|
|
1299
913
|
}
|
|
1300
914
|
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
*is_multi = false;
|
|
1309
|
-
|
|
1310
|
-
if (GIT_ADD_SIZET_OVERFLOW(&alloc_len, ptr_len, 1) ||
|
|
1311
|
-
(str = git__malloc(alloc_len)) == NULL) {
|
|
1312
|
-
return -1;
|
|
1313
|
-
}
|
|
1314
|
-
|
|
1315
|
-
fixed = str;
|
|
1316
|
-
|
|
1317
|
-
while (*ptr != '\0') {
|
|
1318
|
-
if (*ptr == '"') {
|
|
1319
|
-
quote_count++;
|
|
1320
|
-
} else if (*ptr != '\\') {
|
|
1321
|
-
*fixed++ = *ptr;
|
|
1322
|
-
} else {
|
|
1323
|
-
/* backslash, check the next char */
|
|
1324
|
-
ptr++;
|
|
1325
|
-
/* if we're at the end, it's a multiline, so keep the backslash */
|
|
1326
|
-
if (*ptr == '\0') {
|
|
1327
|
-
*is_multi = true;
|
|
1328
|
-
goto done;
|
|
1329
|
-
}
|
|
1330
|
-
if ((esc = strchr(escapes, *ptr)) != NULL) {
|
|
1331
|
-
*fixed++ = escaped[esc - escapes];
|
|
1332
|
-
} else {
|
|
1333
|
-
git__free(str);
|
|
1334
|
-
giterr_set(GITERR_CONFIG, "invalid escape at %s", ptr);
|
|
1335
|
-
return -1;
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
|
-
ptr++;
|
|
1339
|
-
}
|
|
1340
|
-
|
|
1341
|
-
done:
|
|
1342
|
-
*fixed = '\0';
|
|
1343
|
-
*out = str;
|
|
1344
|
-
|
|
1345
|
-
return 0;
|
|
1346
|
-
}
|
|
915
|
+
struct parse_data {
|
|
916
|
+
const git_repository *repo;
|
|
917
|
+
const char *file_path;
|
|
918
|
+
git_strmap *values;
|
|
919
|
+
git_config_level_t level;
|
|
920
|
+
int depth;
|
|
921
|
+
};
|
|
1347
922
|
|
|
1348
|
-
static int
|
|
923
|
+
static int parse_include(git_config_parser *reader,
|
|
924
|
+
struct parse_data *parse_data, const char *file)
|
|
1349
925
|
{
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
char *line = NULL, *proc_line = NULL;
|
|
1355
|
-
int error;
|
|
1356
|
-
|
|
1357
|
-
/* Check that the next line exists */
|
|
1358
|
-
line = reader_readline(reader, false);
|
|
1359
|
-
GITERR_CHECK_ALLOC(line);
|
|
1360
|
-
|
|
1361
|
-
/*
|
|
1362
|
-
* We've reached the end of the file, there is no continuation.
|
|
1363
|
-
* (this is not an error).
|
|
1364
|
-
*/
|
|
1365
|
-
if (line[0] == '\0') {
|
|
1366
|
-
error = 0;
|
|
1367
|
-
goto out;
|
|
1368
|
-
}
|
|
926
|
+
struct config_file *include;
|
|
927
|
+
git_buf path = GIT_BUF_INIT;
|
|
928
|
+
char *dir;
|
|
929
|
+
int result;
|
|
1369
930
|
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
if (line[0] == '\0')
|
|
1373
|
-
goto next;
|
|
931
|
+
if ((result = git_path_dirname_r(&path, reader->file->path)) < 0)
|
|
932
|
+
return result;
|
|
1374
933
|
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
934
|
+
dir = git_buf_detach(&path);
|
|
935
|
+
result = included_path(&path, dir, file);
|
|
936
|
+
git__free(dir);
|
|
1378
937
|
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
goto out;
|
|
938
|
+
if (result < 0)
|
|
939
|
+
return result;
|
|
1382
940
|
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
continue;
|
|
941
|
+
include = git_array_alloc(reader->file->includes);
|
|
942
|
+
memset(include, 0, sizeof(*include));
|
|
943
|
+
git_array_init(include->includes);
|
|
944
|
+
include->path = git_buf_detach(&path);
|
|
1388
945
|
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
git__free(proc_line);
|
|
1392
|
-
return error;
|
|
1393
|
-
}
|
|
946
|
+
result = config_read(parse_data->values, parse_data->repo,
|
|
947
|
+
include, parse_data->level, parse_data->depth+1);
|
|
1394
948
|
|
|
1395
|
-
|
|
1396
|
-
|
|
949
|
+
if (result == GIT_ENOTFOUND) {
|
|
950
|
+
giterr_clear();
|
|
951
|
+
result = 0;
|
|
952
|
+
}
|
|
1397
953
|
|
|
1398
|
-
|
|
1399
|
-
{
|
|
1400
|
-
return isalnum(c) || c == '-';
|
|
954
|
+
return result;
|
|
1401
955
|
}
|
|
1402
956
|
|
|
1403
|
-
static int
|
|
1404
|
-
|
|
957
|
+
static int do_match_gitdir(
|
|
958
|
+
int *matches,
|
|
959
|
+
const git_repository *repo,
|
|
960
|
+
const char *cfg_file,
|
|
961
|
+
const char *value,
|
|
962
|
+
bool case_insensitive)
|
|
1405
963
|
{
|
|
1406
|
-
|
|
964
|
+
git_buf path = GIT_BUF_INIT;
|
|
965
|
+
int error, fnmatch_flags;
|
|
1407
966
|
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
967
|
+
if (value[0] == '.' && git_path_is_dirsep(value[1])) {
|
|
968
|
+
git_path_dirname_r(&path, cfg_file);
|
|
969
|
+
git_buf_joinpath(&path, path.ptr, value + 2);
|
|
970
|
+
} else if (value[0] == '~' && git_path_is_dirsep(value[1]))
|
|
971
|
+
git_sysdir_expand_global_file(&path, value + 1);
|
|
972
|
+
else if (!git_path_is_absolute(value))
|
|
973
|
+
git_buf_joinpath(&path, "**", value);
|
|
974
|
+
else
|
|
975
|
+
git_buf_sets(&path, value);
|
|
1413
976
|
|
|
1414
|
-
if (
|
|
1415
|
-
|
|
1416
|
-
|
|
977
|
+
if (git_buf_oom(&path)) {
|
|
978
|
+
error = -1;
|
|
979
|
+
goto out;
|
|
1417
980
|
}
|
|
1418
981
|
|
|
1419
|
-
|
|
982
|
+
if (git_path_is_dirsep(value[strlen(value) - 1]))
|
|
983
|
+
git_buf_puts(&path, "**");
|
|
1420
984
|
|
|
1421
|
-
|
|
1422
|
-
|
|
985
|
+
fnmatch_flags = FNM_PATHNAME|FNM_LEADING_DIR;
|
|
986
|
+
if (case_insensitive)
|
|
987
|
+
fnmatch_flags |= FNM_IGNORECASE;
|
|
1423
988
|
|
|
1424
|
-
if (
|
|
1425
|
-
|
|
1426
|
-
} else if (*value_start) {
|
|
1427
|
-
set_parse_error(reader, 0, "Invalid configuration key");
|
|
1428
|
-
return -1;
|
|
1429
|
-
}
|
|
989
|
+
if ((error = p_fnmatch(path.ptr, git_repository_path(repo), fnmatch_flags)) < 0)
|
|
990
|
+
goto out;
|
|
1430
991
|
|
|
1431
|
-
|
|
1432
|
-
return -1;
|
|
992
|
+
*matches = (error == 0);
|
|
1433
993
|
|
|
1434
|
-
|
|
994
|
+
out:
|
|
995
|
+
git_buf_free(&path);
|
|
996
|
+
return error;
|
|
1435
997
|
}
|
|
1436
998
|
|
|
1437
|
-
static int
|
|
999
|
+
static int conditional_match_gitdir(
|
|
1000
|
+
int *matches,
|
|
1001
|
+
const git_repository *repo,
|
|
1002
|
+
const char *cfg_file,
|
|
1003
|
+
const char *value)
|
|
1438
1004
|
{
|
|
1439
|
-
|
|
1440
|
-
char *line;
|
|
1441
|
-
int quote_count;
|
|
1442
|
-
bool multiline;
|
|
1443
|
-
|
|
1444
|
-
line = reader_readline(reader, true);
|
|
1445
|
-
if (line == NULL)
|
|
1446
|
-
return -1;
|
|
1447
|
-
|
|
1448
|
-
quote_count = strip_comments(line, 0);
|
|
1449
|
-
|
|
1450
|
-
/* If there is no value, boolean true is assumed */
|
|
1451
|
-
*var_value = NULL;
|
|
1452
|
-
|
|
1453
|
-
if (parse_name(var_name, &value_start, reader, line) < 0)
|
|
1454
|
-
goto on_error;
|
|
1455
|
-
|
|
1456
|
-
/*
|
|
1457
|
-
* Now, let's try to parse the value
|
|
1458
|
-
*/
|
|
1459
|
-
if (value_start != NULL) {
|
|
1460
|
-
while (git__isspace(value_start[0]))
|
|
1461
|
-
value_start++;
|
|
1462
|
-
|
|
1463
|
-
if (unescape_line(var_value, &multiline, value_start, 0) < 0)
|
|
1464
|
-
goto on_error;
|
|
1465
|
-
|
|
1466
|
-
if (multiline) {
|
|
1467
|
-
git_buf multi_value = GIT_BUF_INIT;
|
|
1468
|
-
git_buf_attach(&multi_value, *var_value, 0);
|
|
1469
|
-
|
|
1470
|
-
if (parse_multiline_variable(reader, &multi_value, quote_count) < 0 ||
|
|
1471
|
-
git_buf_oom(&multi_value)) {
|
|
1472
|
-
git_buf_free(&multi_value);
|
|
1473
|
-
goto on_error;
|
|
1474
|
-
}
|
|
1475
|
-
|
|
1476
|
-
*var_value = git_buf_detach(&multi_value);
|
|
1477
|
-
}
|
|
1478
|
-
}
|
|
1479
|
-
|
|
1480
|
-
git__free(line);
|
|
1481
|
-
return 0;
|
|
1482
|
-
|
|
1483
|
-
on_error:
|
|
1484
|
-
git__free(*var_name);
|
|
1485
|
-
git__free(line);
|
|
1486
|
-
return -1;
|
|
1005
|
+
return do_match_gitdir(matches, repo, cfg_file, value, false);
|
|
1487
1006
|
}
|
|
1488
1007
|
|
|
1489
|
-
static int
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
int (*on_eof)(struct reader **reader, const char *current_section, void *data),
|
|
1495
|
-
void *data)
|
|
1008
|
+
static int conditional_match_gitdir_i(
|
|
1009
|
+
int *matches,
|
|
1010
|
+
const git_repository *repo,
|
|
1011
|
+
const char *cfg_file,
|
|
1012
|
+
const char *value)
|
|
1496
1013
|
{
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
size_t line_len;
|
|
1500
|
-
int result = 0;
|
|
1014
|
+
return do_match_gitdir(matches, repo, cfg_file, value, true);
|
|
1015
|
+
}
|
|
1501
1016
|
|
|
1502
|
-
|
|
1017
|
+
static const struct {
|
|
1018
|
+
const char *prefix;
|
|
1019
|
+
int (*matches)(int *matches, const git_repository *repo, const char *cfg, const char *value);
|
|
1020
|
+
} conditions[] = {
|
|
1021
|
+
{ "gitdir:", conditional_match_gitdir },
|
|
1022
|
+
{ "gitdir/i:", conditional_match_gitdir_i }
|
|
1023
|
+
};
|
|
1503
1024
|
|
|
1504
|
-
|
|
1505
|
-
|
|
1025
|
+
static int parse_conditional_include(git_config_parser *reader,
|
|
1026
|
+
struct parse_data *parse_data, const char *section, const char *file)
|
|
1027
|
+
{
|
|
1028
|
+
char *condition;
|
|
1029
|
+
size_t i;
|
|
1030
|
+
int error = 0, matches;
|
|
1506
1031
|
|
|
1507
|
-
|
|
1032
|
+
if (!parse_data->repo)
|
|
1033
|
+
return 0;
|
|
1508
1034
|
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
reader->eof = 1;
|
|
1512
|
-
break;
|
|
1035
|
+
condition = git__substrdup(section + strlen("includeIf."),
|
|
1036
|
+
strlen(section) - strlen("includeIf.") - strlen(".path"));
|
|
1513
1037
|
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1038
|
+
for (i = 0; i < ARRAY_SIZE(conditions); i++) {
|
|
1039
|
+
if (git__prefixcmp(condition, conditions[i].prefix))
|
|
1040
|
+
continue;
|
|
1517
1041
|
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1042
|
+
if ((error = conditions[i].matches(&matches,
|
|
1043
|
+
parse_data->repo,
|
|
1044
|
+
parse_data->file_path,
|
|
1045
|
+
condition + strlen(conditions[i].prefix))) < 0)
|
|
1522
1046
|
break;
|
|
1523
1047
|
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
case '#':
|
|
1527
|
-
reader_consume_line(reader);
|
|
1048
|
+
if (matches)
|
|
1049
|
+
error = parse_include(reader, parse_data, file);
|
|
1528
1050
|
|
|
1529
|
-
|
|
1530
|
-
line_len = reader->read_ptr - line_start;
|
|
1531
|
-
result = on_comment(&reader, line_start, line_len, data);
|
|
1532
|
-
}
|
|
1533
|
-
break;
|
|
1534
|
-
|
|
1535
|
-
default: /* assume variable declaration */
|
|
1536
|
-
if ((result = parse_variable(reader, &var_name, &var_value)) == 0 && on_variable) {
|
|
1537
|
-
line_len = reader->read_ptr - line_start;
|
|
1538
|
-
result = on_variable(&reader, current_section, var_name, var_value, line_start, line_len, data);
|
|
1539
|
-
}
|
|
1540
|
-
break;
|
|
1541
|
-
}
|
|
1051
|
+
break;
|
|
1542
1052
|
}
|
|
1543
1053
|
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
git__free(current_section);
|
|
1548
|
-
return result;
|
|
1054
|
+
git__free(condition);
|
|
1055
|
+
return error;
|
|
1549
1056
|
}
|
|
1550
1057
|
|
|
1551
|
-
struct parse_data {
|
|
1552
|
-
git_strmap *values;
|
|
1553
|
-
diskfile_backend *cfg_file;
|
|
1554
|
-
uint32_t reader_idx;
|
|
1555
|
-
git_config_level_t level;
|
|
1556
|
-
int depth;
|
|
1557
|
-
};
|
|
1558
|
-
|
|
1559
1058
|
static int read_on_variable(
|
|
1560
|
-
|
|
1059
|
+
git_config_parser *reader,
|
|
1561
1060
|
const char *current_section,
|
|
1562
1061
|
char *var_name,
|
|
1563
1062
|
char *var_value,
|
|
@@ -1598,74 +1097,61 @@ static int read_on_variable(
|
|
|
1598
1097
|
result = 0;
|
|
1599
1098
|
|
|
1600
1099
|
/* Add or append the new config option */
|
|
1601
|
-
if (!git__strcmp(var->entry->name, "include.path")
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
r = git_array_alloc(parse_data->cfg_file->readers);
|
|
1608
|
-
/* The reader may have been reallocated */
|
|
1609
|
-
*reader = git_array_get(parse_data->cfg_file->readers, parse_data->reader_idx);
|
|
1610
|
-
memset(r, 0, sizeof(struct reader));
|
|
1611
|
-
|
|
1612
|
-
if ((result = git_path_dirname_r(&path, (*reader)->file_path)) < 0)
|
|
1613
|
-
return result;
|
|
1100
|
+
if (!git__strcmp(var->entry->name, "include.path"))
|
|
1101
|
+
result = parse_include(reader, parse_data, var->entry->value);
|
|
1102
|
+
else if (!git__prefixcmp(var->entry->name, "includeif.") &&
|
|
1103
|
+
!git__suffixcmp(var->entry->name, ".path"))
|
|
1104
|
+
result = parse_conditional_include(reader, parse_data,
|
|
1105
|
+
var->entry->name, var->entry->value);
|
|
1614
1106
|
|
|
1615
|
-
/* We need to know our index in the array, as the next config_parse call may realloc */
|
|
1616
|
-
index = git_array_size(parse_data->cfg_file->readers) - 1;
|
|
1617
|
-
dir = git_buf_detach(&path);
|
|
1618
|
-
result = included_path(&path, dir, var->entry->value);
|
|
1619
|
-
git__free(dir);
|
|
1620
|
-
|
|
1621
|
-
if (result < 0)
|
|
1622
|
-
return result;
|
|
1623
|
-
|
|
1624
|
-
r->file_path = git_buf_detach(&path);
|
|
1625
|
-
git_buf_init(&r->buffer, 0);
|
|
1626
|
-
|
|
1627
|
-
result = git_futils_readbuffer_updated(
|
|
1628
|
-
&r->buffer, r->file_path, &r->checksum, NULL);
|
|
1629
|
-
|
|
1630
|
-
if (result == 0) {
|
|
1631
|
-
result = config_read(parse_data->values, parse_data->cfg_file, r, parse_data->level, parse_data->depth+1);
|
|
1632
|
-
r = git_array_get(parse_data->cfg_file->readers, index);
|
|
1633
|
-
*reader = git_array_get(parse_data->cfg_file->readers, parse_data->reader_idx);
|
|
1634
|
-
} else if (result == GIT_ENOTFOUND) {
|
|
1635
|
-
giterr_clear();
|
|
1636
|
-
result = 0;
|
|
1637
|
-
}
|
|
1638
|
-
|
|
1639
|
-
git_buf_free(&r->buffer);
|
|
1640
|
-
}
|
|
1641
1107
|
|
|
1642
1108
|
return result;
|
|
1643
1109
|
}
|
|
1644
1110
|
|
|
1645
|
-
static int config_read(
|
|
1111
|
+
static int config_read(
|
|
1112
|
+
git_strmap *values,
|
|
1113
|
+
const git_repository *repo,
|
|
1114
|
+
git_config_file *file,
|
|
1115
|
+
git_config_level_t level,
|
|
1116
|
+
int depth)
|
|
1646
1117
|
{
|
|
1647
1118
|
struct parse_data parse_data;
|
|
1119
|
+
git_config_parser reader;
|
|
1120
|
+
git_buf contents = GIT_BUF_INIT;
|
|
1121
|
+
int error;
|
|
1648
1122
|
|
|
1649
1123
|
if (depth >= MAX_INCLUDE_DEPTH) {
|
|
1650
1124
|
giterr_set(GITERR_CONFIG, "maximum config include depth reached");
|
|
1651
1125
|
return -1;
|
|
1652
1126
|
}
|
|
1653
1127
|
|
|
1128
|
+
if ((error = git_futils_readbuffer(&contents, file->path)) < 0)
|
|
1129
|
+
goto out;
|
|
1130
|
+
|
|
1131
|
+
git_parse_ctx_init(&reader.ctx, contents.ptr, contents.size);
|
|
1132
|
+
|
|
1133
|
+
if ((error = git_hash_buf(&file->checksum, contents.ptr, contents.size)) < 0)
|
|
1134
|
+
goto out;
|
|
1135
|
+
|
|
1654
1136
|
/* Initialize the reading position */
|
|
1655
|
-
reader
|
|
1656
|
-
reader
|
|
1137
|
+
reader.file = file;
|
|
1138
|
+
git_parse_ctx_init(&reader.ctx, contents.ptr, contents.size);
|
|
1657
1139
|
|
|
1658
1140
|
/* If the file is empty, there's nothing for us to do */
|
|
1659
|
-
if (*reader
|
|
1660
|
-
|
|
1141
|
+
if (!reader.ctx.content || *reader.ctx.content == '\0')
|
|
1142
|
+
goto out;
|
|
1661
1143
|
|
|
1144
|
+
parse_data.repo = repo;
|
|
1145
|
+
parse_data.file_path = file->path;
|
|
1662
1146
|
parse_data.values = values;
|
|
1663
|
-
parse_data.cfg_file = cfg_file;
|
|
1664
|
-
parse_data.reader_idx = git_array_size(cfg_file->readers) - 1;
|
|
1665
1147
|
parse_data.level = level;
|
|
1666
1148
|
parse_data.depth = depth;
|
|
1667
1149
|
|
|
1668
|
-
|
|
1150
|
+
error = git_config_parse(&reader, NULL, read_on_variable, NULL, NULL, &parse_data);
|
|
1151
|
+
|
|
1152
|
+
out:
|
|
1153
|
+
git_buf_free(&contents);
|
|
1154
|
+
return error;
|
|
1669
1155
|
}
|
|
1670
1156
|
|
|
1671
1157
|
static int write_section(git_buf *fbuf, const char *key)
|
|
@@ -1721,7 +1207,9 @@ struct write_data {
|
|
|
1721
1207
|
git_buf buffered_comment;
|
|
1722
1208
|
unsigned int in_section : 1,
|
|
1723
1209
|
preg_replaced : 1;
|
|
1210
|
+
const char *orig_section;
|
|
1724
1211
|
const char *section;
|
|
1212
|
+
const char *orig_name;
|
|
1725
1213
|
const char *name;
|
|
1726
1214
|
const regex_t *preg;
|
|
1727
1215
|
const char *value;
|
|
@@ -1749,7 +1237,7 @@ static int write_value(struct write_data *write_data)
|
|
|
1749
1237
|
|
|
1750
1238
|
q = quotes_for_value(write_data->value);
|
|
1751
1239
|
result = git_buf_printf(write_data->buf,
|
|
1752
|
-
"\t%s = %s%s%s\n", write_data->
|
|
1240
|
+
"\t%s = %s%s%s\n", write_data->orig_name, q, write_data->value, q);
|
|
1753
1241
|
|
|
1754
1242
|
/* If we are updating a single name/value, we're done. Setting `value`
|
|
1755
1243
|
* to `NULL` will prevent us from trying to write it again later (in
|
|
@@ -1762,7 +1250,7 @@ static int write_value(struct write_data *write_data)
|
|
|
1762
1250
|
}
|
|
1763
1251
|
|
|
1764
1252
|
static int write_on_section(
|
|
1765
|
-
|
|
1253
|
+
git_config_parser *reader,
|
|
1766
1254
|
const char *current_section,
|
|
1767
1255
|
const char *line,
|
|
1768
1256
|
size_t line_len,
|
|
@@ -1798,7 +1286,7 @@ static int write_on_section(
|
|
|
1798
1286
|
}
|
|
1799
1287
|
|
|
1800
1288
|
static int write_on_variable(
|
|
1801
|
-
|
|
1289
|
+
git_config_parser *reader,
|
|
1802
1290
|
const char *current_section,
|
|
1803
1291
|
char *var_name,
|
|
1804
1292
|
char *var_value,
|
|
@@ -1848,7 +1336,7 @@ static int write_on_variable(
|
|
|
1848
1336
|
return write_value(write_data);
|
|
1849
1337
|
}
|
|
1850
1338
|
|
|
1851
|
-
static int write_on_comment(
|
|
1339
|
+
static int write_on_comment(git_config_parser *reader, const char *line, size_t line_len, void *data)
|
|
1852
1340
|
{
|
|
1853
1341
|
struct write_data *write_data;
|
|
1854
1342
|
|
|
@@ -1859,7 +1347,7 @@ static int write_on_comment(struct reader **reader, const char *line, size_t lin
|
|
|
1859
1347
|
}
|
|
1860
1348
|
|
|
1861
1349
|
static int write_on_eof(
|
|
1862
|
-
|
|
1350
|
+
git_config_parser *reader, const char *current_section, void *data)
|
|
1863
1351
|
{
|
|
1864
1352
|
struct write_data *write_data = (struct write_data *)data;
|
|
1865
1353
|
int result = 0;
|
|
@@ -1880,7 +1368,7 @@ static int write_on_eof(
|
|
|
1880
1368
|
if ((!write_data->preg || !write_data->preg_replaced) && write_data->value) {
|
|
1881
1369
|
/* write the section header unless we're already in it */
|
|
1882
1370
|
if (!current_section || strcmp(current_section, write_data->section))
|
|
1883
|
-
result = write_section(write_data->buf, write_data->
|
|
1371
|
+
result = write_section(write_data->buf, write_data->orig_section);
|
|
1884
1372
|
|
|
1885
1373
|
if (!result)
|
|
1886
1374
|
result = write_value(write_data);
|
|
@@ -1892,37 +1380,35 @@ static int write_on_eof(
|
|
|
1892
1380
|
/*
|
|
1893
1381
|
* This is pretty much the parsing, except we write out anything we don't have
|
|
1894
1382
|
*/
|
|
1895
|
-
static int config_write(diskfile_backend *cfg, const char *key, const regex_t *preg, const char* value)
|
|
1383
|
+
static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const regex_t *preg, const char* value)
|
|
1896
1384
|
{
|
|
1897
1385
|
int result;
|
|
1898
|
-
char *section, *name, *ldot;
|
|
1386
|
+
char *orig_section, *section, *orig_name, *name, *ldot;
|
|
1899
1387
|
git_filebuf file = GIT_FILEBUF_INIT;
|
|
1900
|
-
git_buf buf = GIT_BUF_INIT;
|
|
1901
|
-
|
|
1388
|
+
git_buf buf = GIT_BUF_INIT, contents = GIT_BUF_INIT;
|
|
1389
|
+
git_config_parser reader;
|
|
1902
1390
|
struct write_data write_data;
|
|
1903
1391
|
|
|
1392
|
+
memset(&reader, 0, sizeof(reader));
|
|
1393
|
+
reader.file = &cfg->file;
|
|
1394
|
+
|
|
1904
1395
|
if (cfg->locked) {
|
|
1905
|
-
result = git_buf_puts(&
|
|
1396
|
+
result = git_buf_puts(&contents, git_buf_cstr(&cfg->locked_content));
|
|
1906
1397
|
} else {
|
|
1907
1398
|
/* Lock the file */
|
|
1908
1399
|
if ((result = git_filebuf_open(
|
|
1909
|
-
&file, cfg->
|
|
1910
|
-
git_buf_free(&
|
|
1400
|
+
&file, cfg->file.path, GIT_FILEBUF_HASH_CONTENTS, GIT_CONFIG_FILE_MODE)) < 0) {
|
|
1401
|
+
git_buf_free(&contents);
|
|
1911
1402
|
return result;
|
|
1912
1403
|
}
|
|
1913
1404
|
|
|
1914
1405
|
/* We need to read in our own config file */
|
|
1915
|
-
result = git_futils_readbuffer(&
|
|
1406
|
+
result = git_futils_readbuffer(&contents, cfg->file.path);
|
|
1916
1407
|
}
|
|
1917
1408
|
|
|
1918
1409
|
/* Initialise the reading position */
|
|
1919
|
-
if (result == GIT_ENOTFOUND) {
|
|
1920
|
-
reader
|
|
1921
|
-
reader->eof = 1;
|
|
1922
|
-
git_buf_clear(&reader->buffer);
|
|
1923
|
-
} else if (result == 0) {
|
|
1924
|
-
reader->read_ptr = reader->buffer.ptr;
|
|
1925
|
-
reader->eof = 0;
|
|
1410
|
+
if (result == 0 || result == GIT_ENOTFOUND) {
|
|
1411
|
+
git_parse_ctx_init(&reader.ctx, contents.ptr, contents.size);
|
|
1926
1412
|
} else {
|
|
1927
1413
|
git_filebuf_cleanup(&file);
|
|
1928
1414
|
return -1; /* OS error when reading the file */
|
|
@@ -1931,18 +1417,32 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
|
|
|
1931
1417
|
ldot = strrchr(key, '.');
|
|
1932
1418
|
name = ldot + 1;
|
|
1933
1419
|
section = git__strndup(key, ldot - key);
|
|
1420
|
+
GITERR_CHECK_ALLOC(section);
|
|
1421
|
+
|
|
1422
|
+
ldot = strrchr(orig_key, '.');
|
|
1423
|
+
orig_name = ldot + 1;
|
|
1424
|
+
orig_section = git__strndup(orig_key, ldot - orig_key);
|
|
1425
|
+
GITERR_CHECK_ALLOC(orig_section);
|
|
1934
1426
|
|
|
1935
1427
|
write_data.buf = &buf;
|
|
1936
1428
|
git_buf_init(&write_data.buffered_comment, 0);
|
|
1429
|
+
write_data.orig_section = orig_section;
|
|
1937
1430
|
write_data.section = section;
|
|
1938
1431
|
write_data.in_section = 0;
|
|
1939
1432
|
write_data.preg_replaced = 0;
|
|
1433
|
+
write_data.orig_name = orig_name;
|
|
1940
1434
|
write_data.name = name;
|
|
1941
1435
|
write_data.preg = preg;
|
|
1942
1436
|
write_data.value = value;
|
|
1943
1437
|
|
|
1944
|
-
result =
|
|
1438
|
+
result = git_config_parse(&reader,
|
|
1439
|
+
write_on_section,
|
|
1440
|
+
write_on_variable,
|
|
1441
|
+
write_on_comment,
|
|
1442
|
+
write_on_eof,
|
|
1443
|
+
&write_data);
|
|
1945
1444
|
git__free(section);
|
|
1445
|
+
git__free(orig_section);
|
|
1946
1446
|
git_buf_free(&write_data.buffered_comment);
|
|
1947
1447
|
|
|
1948
1448
|
if (result < 0) {
|
|
@@ -1962,6 +1462,7 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
|
|
|
1962
1462
|
|
|
1963
1463
|
done:
|
|
1964
1464
|
git_buf_free(&buf);
|
|
1965
|
-
git_buf_free(&
|
|
1465
|
+
git_buf_free(&contents);
|
|
1466
|
+
git_parse_ctx_clear(&reader.ctx);
|
|
1966
1467
|
return result;
|
|
1967
1468
|
}
|