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