rugged 1.3.2.3 → 1.4.2
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/ext/rugged/extconf.rb +1 -1
- data/ext/rugged/rugged_config.c +7 -2
- data/ext/rugged/rugged_remote.c +17 -0
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +103 -276
- data/vendor/libgit2/COPYING +36 -19
- data/vendor/libgit2/cmake/AddCFlagIfSupported.cmake +21 -21
- data/vendor/libgit2/cmake/DefaultCFlags.cmake +154 -0
- data/vendor/libgit2/cmake/EnableWarnings.cmake +13 -13
- data/vendor/libgit2/cmake/FindCoreFoundation.cmake +13 -13
- data/vendor/libgit2/cmake/FindGSSAPI.cmake +171 -287
- data/vendor/libgit2/cmake/FindGSSFramework.cmake +13 -13
- data/vendor/libgit2/cmake/{FindHTTP_Parser.cmake → FindHTTPParser.cmake} +17 -17
- data/vendor/libgit2/cmake/FindIconv.cmake +27 -27
- data/vendor/libgit2/cmake/FindLibSSH2.cmake +5 -5
- data/vendor/libgit2/cmake/FindPCRE.cmake +13 -13
- data/vendor/libgit2/cmake/FindPCRE2.cmake +12 -12
- data/vendor/libgit2/cmake/FindPkgLibraries.cmake +19 -19
- data/vendor/libgit2/cmake/FindSecurity.cmake +14 -14
- data/vendor/libgit2/cmake/FindStatNsec.cmake +12 -18
- data/vendor/libgit2/cmake/Findfutimens.cmake +8 -8
- data/vendor/libgit2/cmake/FindmbedTLS.cmake +63 -70
- data/vendor/libgit2/cmake/IdeSplitSources.cmake +18 -18
- data/vendor/libgit2/cmake/PkgBuildConfig.cmake +60 -60
- data/vendor/libgit2/cmake/SanitizeBool.cmake +20 -20
- data/vendor/libgit2/cmake/SelectGSSAPI.cmake +37 -37
- data/vendor/libgit2/cmake/SelectHTTPParser.cmake +19 -0
- data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +100 -100
- data/vendor/libgit2/cmake/SelectHashes.cmake +39 -49
- data/vendor/libgit2/cmake/SelectRegex.cmake +51 -0
- data/vendor/libgit2/cmake/SelectSSH.cmake +41 -0
- data/vendor/libgit2/cmake/SelectWinHTTP.cmake +17 -0
- data/vendor/libgit2/cmake/SelectZlib.cmake +34 -0
- data/vendor/libgit2/deps/chromium-zlib/CMakeLists.txt +6 -6
- data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +31 -31
- data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +1 -1
- data/vendor/libgit2/deps/ntlmclient/ntlm.c +4 -4
- data/vendor/libgit2/deps/ntlmclient/ntlm.h +4 -4
- data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +2 -2
- data/vendor/libgit2/deps/pcre/CMakeLists.txt +88 -88
- data/vendor/libgit2/deps/winhttp/CMakeLists.txt +14 -16
- data/vendor/libgit2/deps/zlib/adler32.c +0 -7
- data/vendor/libgit2/deps/zlib/crc32.c +288 -975
- data/vendor/libgit2/deps/zlib/crc32.h +436 -9441
- data/vendor/libgit2/deps/zlib/deflate.c +31 -83
- data/vendor/libgit2/deps/zlib/deflate.h +15 -12
- data/vendor/libgit2/deps/zlib/gzguts.h +2 -3
- data/vendor/libgit2/deps/zlib/infback.c +1 -2
- data/vendor/libgit2/deps/zlib/inffast.c +14 -14
- data/vendor/libgit2/deps/zlib/inflate.c +8 -39
- data/vendor/libgit2/deps/zlib/inflate.h +2 -3
- data/vendor/libgit2/deps/zlib/inftrees.c +3 -3
- data/vendor/libgit2/deps/zlib/trees.c +48 -27
- data/vendor/libgit2/deps/zlib/zlib.h +100 -126
- data/vendor/libgit2/deps/zlib/zutil.c +2 -2
- data/vendor/libgit2/deps/zlib/zutil.h +9 -12
- data/vendor/libgit2/include/git2/apply.h +16 -2
- data/vendor/libgit2/include/git2/attr.h +11 -2
- data/vendor/libgit2/include/git2/blame.h +4 -1
- data/vendor/libgit2/include/git2/blob.h +14 -1
- data/vendor/libgit2/include/git2/branch.h +2 -0
- data/vendor/libgit2/include/git2/buffer.h +18 -78
- data/vendor/libgit2/include/git2/cert.h +2 -2
- data/vendor/libgit2/include/git2/checkout.h +5 -2
- data/vendor/libgit2/include/git2/clone.h +3 -3
- data/vendor/libgit2/include/git2/commit.h +2 -0
- data/vendor/libgit2/include/git2/common.h +5 -12
- data/vendor/libgit2/include/git2/config.h +19 -3
- data/vendor/libgit2/include/git2/credential.h +2 -1
- data/vendor/libgit2/include/git2/credential_helpers.h +1 -0
- data/vendor/libgit2/include/git2/deprecated.h +1 -1
- data/vendor/libgit2/include/git2/describe.h +7 -2
- data/vendor/libgit2/include/git2/diff.h +17 -9
- data/vendor/libgit2/include/git2/email.h +1 -1
- data/vendor/libgit2/include/git2/errors.h +1 -2
- data/vendor/libgit2/include/git2/filter.h +7 -2
- data/vendor/libgit2/include/git2/graph.h +1 -0
- data/vendor/libgit2/include/git2/ignore.h +1 -1
- data/vendor/libgit2/include/git2/index.h +11 -5
- data/vendor/libgit2/include/git2/indexer.h +19 -0
- data/vendor/libgit2/include/git2/merge.h +23 -3
- data/vendor/libgit2/include/git2/message.h +2 -0
- data/vendor/libgit2/include/git2/object.h +23 -0
- data/vendor/libgit2/include/git2/odb.h +37 -7
- data/vendor/libgit2/include/git2/odb_backend.h +1 -1
- data/vendor/libgit2/include/git2/pack.h +24 -8
- data/vendor/libgit2/include/git2/patch.h +8 -0
- data/vendor/libgit2/include/git2/pathspec.h +1 -1
- data/vendor/libgit2/include/git2/proxy.h +1 -1
- data/vendor/libgit2/include/git2/rebase.h +9 -1
- data/vendor/libgit2/include/git2/refdb.h +3 -0
- data/vendor/libgit2/include/git2/reflog.h +1 -1
- data/vendor/libgit2/include/git2/refs.h +2 -2
- data/vendor/libgit2/include/git2/remote.h +184 -37
- data/vendor/libgit2/include/git2/repository.h +14 -9
- data/vendor/libgit2/include/git2/reset.h +2 -2
- data/vendor/libgit2/include/git2/revparse.h +1 -1
- data/vendor/libgit2/include/git2/revwalk.h +4 -1
- data/vendor/libgit2/include/git2/signature.h +1 -1
- data/vendor/libgit2/include/git2/stash.h +3 -3
- data/vendor/libgit2/include/git2/status.h +9 -3
- data/vendor/libgit2/include/git2/submodule.h +7 -2
- data/vendor/libgit2/include/git2/sys/commit_graph.h +1 -1
- data/vendor/libgit2/include/git2/sys/odb_backend.h +2 -5
- data/vendor/libgit2/include/git2/sys/remote.h +31 -0
- data/vendor/libgit2/include/git2/sys/stream.h +1 -1
- data/vendor/libgit2/include/git2/sys/transport.h +25 -34
- data/vendor/libgit2/include/git2/tag.h +1 -0
- data/vendor/libgit2/include/git2/tree.h +4 -3
- data/vendor/libgit2/include/git2/types.h +7 -7
- data/vendor/libgit2/include/git2/version.h +3 -3
- data/vendor/libgit2/include/git2/worktree.h +12 -2
- data/vendor/libgit2/src/CMakeLists.txt +189 -315
- data/vendor/libgit2/src/annotated_commit.h +1 -1
- data/vendor/libgit2/src/apply.c +18 -18
- data/vendor/libgit2/src/apply.h +2 -2
- data/vendor/libgit2/src/attr.c +18 -18
- data/vendor/libgit2/src/attr_file.c +17 -17
- data/vendor/libgit2/src/attr_file.h +4 -4
- data/vendor/libgit2/src/attrcache.c +17 -12
- data/vendor/libgit2/src/blame_git.c +1 -1
- data/vendor/libgit2/src/blob.c +33 -26
- data/vendor/libgit2/src/blob.h +1 -1
- data/vendor/libgit2/src/branch.c +150 -109
- data/vendor/libgit2/src/branch.h +15 -3
- data/vendor/libgit2/src/buf.c +126 -0
- data/vendor/libgit2/src/buf.h +50 -0
- data/vendor/libgit2/src/cc-compat.h +1 -1
- data/vendor/libgit2/src/checkout.c +74 -68
- data/vendor/libgit2/src/cherrypick.c +10 -10
- data/vendor/libgit2/src/clone.c +66 -66
- data/vendor/libgit2/src/commit.c +128 -58
- data/vendor/libgit2/src/commit.h +24 -1
- data/vendor/libgit2/src/commit_graph.c +68 -53
- data/vendor/libgit2/src/commit_graph.h +10 -3
- data/vendor/libgit2/src/commit_list.c +2 -3
- data/vendor/libgit2/src/common.h +10 -3
- data/vendor/libgit2/src/config.c +99 -77
- data/vendor/libgit2/src/config.h +15 -2
- data/vendor/libgit2/src/config_file.c +103 -91
- data/vendor/libgit2/src/config_mem.c +9 -9
- data/vendor/libgit2/src/config_parse.c +27 -23
- data/vendor/libgit2/src/crlf.c +24 -21
- data/vendor/libgit2/src/date.c +10 -17
- data/vendor/libgit2/src/date.h +33 -0
- data/vendor/libgit2/src/describe.c +27 -19
- data/vendor/libgit2/src/diff.c +25 -8
- data/vendor/libgit2/src/diff.h +2 -4
- data/vendor/libgit2/src/diff_driver.c +34 -36
- data/vendor/libgit2/src/diff_driver.h +3 -3
- data/vendor/libgit2/src/diff_file.c +29 -20
- data/vendor/libgit2/src/diff_generate.c +30 -6
- data/vendor/libgit2/src/diff_generate.h +5 -3
- data/vendor/libgit2/src/diff_print.c +102 -95
- data/vendor/libgit2/src/diff_stats.c +40 -29
- data/vendor/libgit2/src/{message.h → diff_stats.h} +7 -6
- data/vendor/libgit2/src/diff_tform.c +9 -8
- data/vendor/libgit2/src/diff_xdiff.c +3 -8
- data/vendor/libgit2/src/email.c +54 -38
- data/vendor/libgit2/src/email.h +1 -1
- data/vendor/libgit2/src/errors.c +18 -18
- data/vendor/libgit2/src/features.h.in +6 -1
- data/vendor/libgit2/src/fetch.c +69 -24
- data/vendor/libgit2/src/fetch.h +1 -1
- data/vendor/libgit2/src/fetchhead.c +19 -19
- data/vendor/libgit2/src/filebuf.c +28 -28
- data/vendor/libgit2/src/filebuf.h +1 -1
- data/vendor/libgit2/src/filter.c +96 -52
- data/vendor/libgit2/src/filter.h +26 -5
- data/vendor/libgit2/src/fs_path.c +1912 -0
- data/vendor/libgit2/src/fs_path.h +752 -0
- data/vendor/libgit2/src/futils.c +91 -85
- data/vendor/libgit2/src/futils.h +26 -14
- data/vendor/libgit2/src/hash/sha1/collisiondetect.c +2 -2
- data/vendor/libgit2/src/hash/sha1/common_crypto.c +2 -2
- data/vendor/libgit2/src/hash/sha1/generic.c +2 -2
- data/vendor/libgit2/src/hash/sha1/mbedtls.c +2 -2
- data/vendor/libgit2/src/hash/sha1/openssl.c +2 -2
- data/vendor/libgit2/src/hash/sha1/sha1dc/sha1.c +1 -1
- data/vendor/libgit2/src/hash/sha1/win32.c +6 -6
- data/vendor/libgit2/src/hash/sha1.h +3 -1
- data/vendor/libgit2/src/hash.c +67 -35
- data/vendor/libgit2/src/hash.h +12 -12
- data/vendor/libgit2/src/ident.c +18 -18
- data/vendor/libgit2/src/ignore.c +35 -34
- data/vendor/libgit2/src/ignore.h +2 -2
- data/vendor/libgit2/src/index.c +79 -80
- data/vendor/libgit2/src/index.h +6 -3
- data/vendor/libgit2/src/indexer.c +75 -57
- data/vendor/libgit2/src/iterator.c +64 -56
- data/vendor/libgit2/src/iterator.h +5 -5
- data/vendor/libgit2/src/khash.h +1 -1
- data/vendor/libgit2/src/libgit2.c +22 -19
- data/vendor/libgit2/src/mailmap.c +38 -36
- data/vendor/libgit2/src/merge.c +27 -27
- data/vendor/libgit2/src/merge.h +1 -14
- data/vendor/libgit2/src/merge_driver.c +2 -2
- data/vendor/libgit2/src/merge_file.c +13 -3
- data/vendor/libgit2/src/message.c +21 -10
- data/vendor/libgit2/src/midx.c +83 -66
- data/vendor/libgit2/src/midx.h +3 -3
- data/vendor/libgit2/src/mwindow.c +1 -1
- data/vendor/libgit2/src/net.c +278 -68
- data/vendor/libgit2/src/net.h +10 -3
- data/vendor/libgit2/src/netops.c +1 -1
- data/vendor/libgit2/src/netops.h +1 -1
- data/vendor/libgit2/src/notes.c +20 -29
- data/vendor/libgit2/src/object.c +49 -9
- data/vendor/libgit2/src/object.h +1 -1
- data/vendor/libgit2/src/odb.c +35 -32
- data/vendor/libgit2/src/odb.h +1 -1
- data/vendor/libgit2/src/odb_loose.c +68 -68
- data/vendor/libgit2/src/odb_mempack.c +18 -5
- data/vendor/libgit2/src/odb_pack.c +43 -43
- data/vendor/libgit2/src/oid.c +11 -4
- data/vendor/libgit2/src/oid.h +15 -0
- data/vendor/libgit2/src/pack-objects.c +41 -26
- data/vendor/libgit2/src/pack-objects.h +11 -6
- data/vendor/libgit2/src/pack.c +10 -10
- data/vendor/libgit2/src/patch.c +3 -3
- data/vendor/libgit2/src/patch.h +1 -0
- data/vendor/libgit2/src/patch_generate.c +27 -11
- data/vendor/libgit2/src/patch_generate.h +5 -5
- data/vendor/libgit2/src/patch_parse.c +24 -24
- data/vendor/libgit2/src/path.c +76 -1951
- data/vendor/libgit2/src/path.h +34 -741
- data/vendor/libgit2/src/pathspec.c +6 -6
- data/vendor/libgit2/src/pathspec.h +2 -2
- data/vendor/libgit2/src/posix.c +3 -3
- data/vendor/libgit2/src/posix.h +1 -0
- data/vendor/libgit2/src/pqueue.h +1 -1
- data/vendor/libgit2/src/proxy.c +4 -1
- data/vendor/libgit2/src/proxy.h +1 -1
- data/vendor/libgit2/src/push.c +30 -35
- data/vendor/libgit2/src/push.h +4 -16
- data/vendor/libgit2/src/rand.c +226 -0
- data/vendor/libgit2/src/rand.h +37 -0
- data/vendor/libgit2/src/reader.c +8 -8
- data/vendor/libgit2/src/reader.h +2 -2
- data/vendor/libgit2/src/rebase.c +89 -88
- data/vendor/libgit2/src/refdb_fs.c +447 -173
- data/vendor/libgit2/src/refs.c +32 -32
- data/vendor/libgit2/src/refs.h +2 -2
- data/vendor/libgit2/src/refspec.c +32 -37
- data/vendor/libgit2/src/refspec.h +5 -2
- data/vendor/libgit2/src/regexp.c +1 -1
- data/vendor/libgit2/src/remote.c +713 -419
- data/vendor/libgit2/src/remote.h +15 -10
- data/vendor/libgit2/src/repository.c +350 -467
- data/vendor/libgit2/src/repository.h +11 -10
- data/vendor/libgit2/src/reset.c +8 -5
- data/vendor/libgit2/src/revert.c +10 -10
- data/vendor/libgit2/src/revparse.c +48 -35
- data/vendor/libgit2/src/revwalk.c +7 -7
- data/vendor/libgit2/src/signature.c +12 -6
- data/vendor/libgit2/src/signature.h +1 -1
- data/vendor/libgit2/src/sortedcache.c +1 -1
- data/vendor/libgit2/src/sortedcache.h +1 -1
- data/vendor/libgit2/src/stash.c +36 -37
- data/vendor/libgit2/src/status.c +4 -1
- data/vendor/libgit2/src/{buffer.c → str.c} +157 -151
- data/vendor/libgit2/src/str.h +357 -0
- data/vendor/libgit2/src/streams/mbedtls.c +8 -6
- data/vendor/libgit2/src/streams/openssl_dynamic.h +3 -3
- data/vendor/libgit2/src/submodule.c +171 -159
- data/vendor/libgit2/src/submodule.h +1 -1
- data/vendor/libgit2/src/sysdir.c +68 -52
- data/vendor/libgit2/src/sysdir.h +15 -10
- data/vendor/libgit2/src/tag.c +29 -27
- data/vendor/libgit2/src/thread.h +3 -3
- data/vendor/libgit2/src/threadstate.c +3 -3
- data/vendor/libgit2/src/threadstate.h +1 -1
- data/vendor/libgit2/src/trace.c +1 -14
- data/vendor/libgit2/src/trace.h +5 -22
- data/vendor/libgit2/src/trailer.c +1 -1
- data/vendor/libgit2/src/transaction.c +1 -1
- data/vendor/libgit2/src/transport.c +10 -10
- data/vendor/libgit2/src/transports/auth.c +7 -9
- data/vendor/libgit2/src/transports/auth.h +2 -3
- data/vendor/libgit2/src/transports/auth_negotiate.c +12 -13
- data/vendor/libgit2/src/transports/auth_ntlm.c +10 -10
- data/vendor/libgit2/src/transports/auth_ntlm.h +0 -1
- data/vendor/libgit2/src/transports/git.c +9 -11
- data/vendor/libgit2/src/transports/http.c +37 -17
- data/vendor/libgit2/src/transports/http.h +2 -3
- data/vendor/libgit2/src/transports/httpclient.c +65 -65
- data/vendor/libgit2/src/transports/local.c +124 -116
- data/vendor/libgit2/src/transports/smart.c +51 -139
- data/vendor/libgit2/src/transports/smart.h +25 -31
- data/vendor/libgit2/src/transports/smart_pkt.c +33 -33
- data/vendor/libgit2/src/transports/smart_protocol.c +57 -39
- data/vendor/libgit2/src/transports/ssh.c +47 -112
- data/vendor/libgit2/src/transports/winhttp.c +50 -56
- data/vendor/libgit2/src/tree-cache.c +5 -5
- data/vendor/libgit2/src/tree-cache.h +2 -2
- data/vendor/libgit2/src/tree.c +59 -48
- data/vendor/libgit2/src/tree.h +1 -1
- data/vendor/libgit2/src/unix/map.c +0 -2
- data/vendor/libgit2/src/unix/posix.h +1 -4
- data/vendor/libgit2/src/unix/realpath.c +0 -2
- data/vendor/libgit2/src/util.c +14 -14
- data/vendor/libgit2/src/util.h +2 -28
- data/vendor/libgit2/src/vector.h +1 -1
- data/vendor/libgit2/src/win32/findfile.c +172 -116
- data/vendor/libgit2/src/win32/findfile.h +7 -4
- data/vendor/libgit2/src/win32/path_w32.c +140 -9
- data/vendor/libgit2/src/win32/path_w32.h +2 -0
- data/vendor/libgit2/src/win32/posix.h +0 -1
- data/vendor/libgit2/src/win32/posix_w32.c +11 -27
- data/vendor/libgit2/src/win32/w32_buffer.c +2 -3
- data/vendor/libgit2/src/win32/w32_buffer.h +2 -3
- data/vendor/libgit2/src/win32/w32_leakcheck.c +1 -1
- data/vendor/libgit2/src/worktree.c +116 -94
- data/vendor/libgit2/src/worktree.h +1 -1
- data/vendor/libgit2/src/xdiff/git-xdiff.h +53 -0
- data/vendor/libgit2/src/xdiff/xdiff.h +15 -15
- data/vendor/libgit2/src/xdiff/xdiffi.c +134 -108
- data/vendor/libgit2/src/xdiff/xemit.c +23 -7
- data/vendor/libgit2/src/xdiff/xhistogram.c +87 -78
- data/vendor/libgit2/src/xdiff/xinclude.h +1 -12
- data/vendor/libgit2/src/xdiff/xmerge.c +104 -117
- data/vendor/libgit2/src/xdiff/xpatience.c +6 -17
- data/vendor/libgit2/src/xdiff/xprepare.c +15 -20
- data/vendor/libgit2/src/xdiff/xutils.c +18 -7
- data/vendor/libgit2/src/zstream.c +5 -5
- data/vendor/libgit2/src/zstream.h +4 -4
- metadata +25 -10
- data/vendor/libgit2/src/buffer.h +0 -374
data/vendor/libgit2/src/remote.c
CHANGED
|
@@ -7,11 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
#include "remote.h"
|
|
9
9
|
|
|
10
|
-
#include "
|
|
11
|
-
#include "
|
|
12
|
-
#include "git2/oid.h"
|
|
13
|
-
#include "git2/net.h"
|
|
14
|
-
|
|
10
|
+
#include "buf.h"
|
|
11
|
+
#include "branch.h"
|
|
15
12
|
#include "config.h"
|
|
16
13
|
#include "repository.h"
|
|
17
14
|
#include "fetch.h"
|
|
@@ -19,6 +16,12 @@
|
|
|
19
16
|
#include "refspec.h"
|
|
20
17
|
#include "fetchhead.h"
|
|
21
18
|
#include "push.h"
|
|
19
|
+
#include "proxy.h"
|
|
20
|
+
|
|
21
|
+
#include "git2/config.h"
|
|
22
|
+
#include "git2/types.h"
|
|
23
|
+
#include "git2/oid.h"
|
|
24
|
+
#include "git2/net.h"
|
|
22
25
|
|
|
23
26
|
#define CONFIG_URL_FMT "remote.%s.url"
|
|
24
27
|
#define CONFIG_PUSHURL_FMT "remote.%s.pushurl"
|
|
@@ -28,7 +31,7 @@
|
|
|
28
31
|
|
|
29
32
|
static int dwim_refspecs(git_vector *out, git_vector *refspecs, git_vector *refs);
|
|
30
33
|
static int lookup_remote_prune_config(git_remote *remote, git_config *config, const char *name);
|
|
31
|
-
|
|
34
|
+
static int apply_insteadof(char **out, git_config *config, const char *url, int direction, bool use_default_if_empty);
|
|
32
35
|
|
|
33
36
|
static int add_refspec_to(git_vector *vector, const char *string, bool is_fetch)
|
|
34
37
|
{
|
|
@@ -60,14 +63,14 @@ static int add_refspec(git_remote *remote, const char *string, bool is_fetch)
|
|
|
60
63
|
static int download_tags_value(git_remote *remote, git_config *cfg)
|
|
61
64
|
{
|
|
62
65
|
git_config_entry *ce;
|
|
63
|
-
|
|
66
|
+
git_str buf = GIT_STR_INIT;
|
|
64
67
|
int error;
|
|
65
68
|
|
|
66
|
-
if (
|
|
69
|
+
if (git_str_printf(&buf, "remote.%s.tagopt", remote->name) < 0)
|
|
67
70
|
return -1;
|
|
68
71
|
|
|
69
|
-
error = git_config__lookup_entry(&ce, cfg,
|
|
70
|
-
|
|
72
|
+
error = git_config__lookup_entry(&ce, cfg, git_str_cstr(&buf), false);
|
|
73
|
+
git_str_dispose(&buf);
|
|
71
74
|
|
|
72
75
|
if (!error && ce && ce->value) {
|
|
73
76
|
if (!strcmp(ce->value, "--no-tags"))
|
|
@@ -99,7 +102,7 @@ static int ensure_remote_name_is_valid(const char *name)
|
|
|
99
102
|
static int write_add_refspec(git_repository *repo, const char *name, const char *refspec, bool fetch)
|
|
100
103
|
{
|
|
101
104
|
git_config *cfg;
|
|
102
|
-
|
|
105
|
+
git_str var = GIT_STR_INIT;
|
|
103
106
|
git_refspec spec;
|
|
104
107
|
const char *fmt;
|
|
105
108
|
int error;
|
|
@@ -117,7 +120,7 @@ static int write_add_refspec(git_repository *repo, const char *name, const char
|
|
|
117
120
|
|
|
118
121
|
git_refspec__dispose(&spec);
|
|
119
122
|
|
|
120
|
-
if ((error =
|
|
123
|
+
if ((error = git_str_printf(&var, fmt, name)) < 0)
|
|
121
124
|
return error;
|
|
122
125
|
|
|
123
126
|
/*
|
|
@@ -130,11 +133,11 @@ static int write_add_refspec(git_repository *repo, const char *name, const char
|
|
|
130
133
|
}
|
|
131
134
|
|
|
132
135
|
cleanup:
|
|
133
|
-
|
|
136
|
+
git_str_dispose(&var);
|
|
134
137
|
return 0;
|
|
135
138
|
}
|
|
136
139
|
|
|
137
|
-
static int canonicalize_url(
|
|
140
|
+
static int canonicalize_url(git_str *out, const char *in)
|
|
138
141
|
{
|
|
139
142
|
if (in == NULL || strlen(in) == 0) {
|
|
140
143
|
git_error_set(GIT_ERROR_INVALID, "cannot set empty URL");
|
|
@@ -149,18 +152,18 @@ static int canonicalize_url(git_buf *out, const char *in)
|
|
|
149
152
|
(git__isalpha(in[2]) || git__isdigit(in[2]))) {
|
|
150
153
|
const char *c;
|
|
151
154
|
for (c = in; *c; c++)
|
|
152
|
-
|
|
155
|
+
git_str_putc(out, *c == '\\' ? '/' : *c);
|
|
153
156
|
|
|
154
|
-
return
|
|
157
|
+
return git_str_oom(out) ? -1 : 0;
|
|
155
158
|
}
|
|
156
159
|
#endif
|
|
157
160
|
|
|
158
|
-
return
|
|
161
|
+
return git_str_puts(out, in);
|
|
159
162
|
}
|
|
160
163
|
|
|
161
|
-
static int default_fetchspec_for_name(
|
|
164
|
+
static int default_fetchspec_for_name(git_str *buf, const char *name)
|
|
162
165
|
{
|
|
163
|
-
if (
|
|
166
|
+
if (git_str_printf(buf, "+refs/heads/*:refs/remotes/%s/*", name) < 0)
|
|
164
167
|
return -1;
|
|
165
168
|
|
|
166
169
|
return 0;
|
|
@@ -204,9 +207,9 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem
|
|
|
204
207
|
{
|
|
205
208
|
git_remote *remote = NULL;
|
|
206
209
|
git_config *config_ro = NULL, *config_rw;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
+
git_str canonical_url = GIT_STR_INIT;
|
|
211
|
+
git_str var = GIT_STR_INIT;
|
|
212
|
+
git_str specbuf = GIT_STR_INIT;
|
|
210
213
|
const git_remote_create_options dummy_opts = GIT_REMOTE_CREATE_OPTIONS_INIT;
|
|
211
214
|
int error = -1;
|
|
212
215
|
|
|
@@ -243,18 +246,20 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem
|
|
|
243
246
|
goto on_error;
|
|
244
247
|
|
|
245
248
|
if (opts->repository && !(opts->flags & GIT_REMOTE_CREATE_SKIP_INSTEADOF)) {
|
|
246
|
-
|
|
249
|
+
if ((error = apply_insteadof(&remote->url, config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH, true)) < 0 ||
|
|
250
|
+
(error = apply_insteadof(&remote->pushurl, config_ro, canonical_url.ptr, GIT_DIRECTION_PUSH, false)) < 0)
|
|
251
|
+
goto on_error;
|
|
247
252
|
} else {
|
|
248
253
|
remote->url = git__strdup(canonical_url.ptr);
|
|
254
|
+
GIT_ERROR_CHECK_ALLOC(remote->url);
|
|
249
255
|
}
|
|
250
|
-
GIT_ERROR_CHECK_ALLOC(remote->url);
|
|
251
256
|
|
|
252
257
|
if (opts->name != NULL) {
|
|
253
258
|
remote->name = git__strdup(opts->name);
|
|
254
259
|
GIT_ERROR_CHECK_ALLOC(remote->name);
|
|
255
260
|
|
|
256
261
|
if (opts->repository &&
|
|
257
|
-
((error =
|
|
262
|
+
((error = git_str_printf(&var, CONFIG_URL_FMT, opts->name)) < 0 ||
|
|
258
263
|
(error = git_repository_config__weakptr(&config_rw, opts->repository)) < 0 ||
|
|
259
264
|
(error = git_config_set_string(config_rw, var.ptr, canonical_url.ptr)) < 0))
|
|
260
265
|
goto on_error;
|
|
@@ -269,7 +274,7 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem
|
|
|
269
274
|
if ((error = default_fetchspec_for_name(&specbuf, opts->name)) < 0)
|
|
270
275
|
goto on_error;
|
|
271
276
|
|
|
272
|
-
fetch =
|
|
277
|
+
fetch = git_str_cstr(&specbuf);
|
|
273
278
|
}
|
|
274
279
|
|
|
275
280
|
if ((error = add_refspec(remote, fetch, true)) < 0)
|
|
@@ -293,7 +298,7 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem
|
|
|
293
298
|
remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
|
|
294
299
|
|
|
295
300
|
|
|
296
|
-
|
|
301
|
+
git_str_dispose(&var);
|
|
297
302
|
|
|
298
303
|
*out = remote;
|
|
299
304
|
error = 0;
|
|
@@ -303,15 +308,15 @@ on_error:
|
|
|
303
308
|
git_remote_free(remote);
|
|
304
309
|
|
|
305
310
|
git_config_free(config_ro);
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
311
|
+
git_str_dispose(&specbuf);
|
|
312
|
+
git_str_dispose(&canonical_url);
|
|
313
|
+
git_str_dispose(&var);
|
|
309
314
|
return error;
|
|
310
315
|
}
|
|
311
316
|
|
|
312
317
|
int git_remote_create(git_remote **out, git_repository *repo, const char *name, const char *url)
|
|
313
318
|
{
|
|
314
|
-
|
|
319
|
+
git_str buf = GIT_STR_INIT;
|
|
315
320
|
int error;
|
|
316
321
|
git_remote_create_options opts = GIT_REMOTE_CREATE_OPTIONS_INIT;
|
|
317
322
|
|
|
@@ -322,14 +327,14 @@ int git_remote_create(git_remote **out, git_repository *repo, const char *name,
|
|
|
322
327
|
if (canonicalize_url(&buf, url) < 0)
|
|
323
328
|
return GIT_ERROR;
|
|
324
329
|
|
|
325
|
-
|
|
330
|
+
git_str_clear(&buf);
|
|
326
331
|
|
|
327
332
|
opts.repository = repo;
|
|
328
333
|
opts.name = name;
|
|
329
334
|
|
|
330
335
|
error = git_remote_create_with_opts(out, url, &opts);
|
|
331
336
|
|
|
332
|
-
|
|
337
|
+
git_str_dispose(&buf);
|
|
333
338
|
|
|
334
339
|
return error;
|
|
335
340
|
}
|
|
@@ -425,13 +430,13 @@ static int refspec_cb(const git_config_entry *entry, void *payload)
|
|
|
425
430
|
}
|
|
426
431
|
|
|
427
432
|
static int get_optional_config(
|
|
428
|
-
bool *found, git_config *config,
|
|
433
|
+
bool *found, git_config *config, git_str *buf,
|
|
429
434
|
git_config_foreach_cb cb, void *payload)
|
|
430
435
|
{
|
|
431
436
|
int error = 0;
|
|
432
|
-
const char *key =
|
|
437
|
+
const char *key = git_str_cstr(buf);
|
|
433
438
|
|
|
434
|
-
if (
|
|
439
|
+
if (git_str_oom(buf))
|
|
435
440
|
return -1;
|
|
436
441
|
|
|
437
442
|
if (cb != NULL)
|
|
@@ -453,7 +458,7 @@ static int get_optional_config(
|
|
|
453
458
|
int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
|
|
454
459
|
{
|
|
455
460
|
git_remote *remote = NULL;
|
|
456
|
-
|
|
461
|
+
git_str buf = GIT_STR_INIT;
|
|
457
462
|
const char *val;
|
|
458
463
|
int error = 0;
|
|
459
464
|
git_config *config;
|
|
@@ -484,7 +489,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
|
|
|
484
489
|
goto cleanup;
|
|
485
490
|
}
|
|
486
491
|
|
|
487
|
-
if ((error =
|
|
492
|
+
if ((error = git_str_printf(&buf, "remote.%s.url", name)) < 0)
|
|
488
493
|
goto cleanup;
|
|
489
494
|
|
|
490
495
|
if ((error = get_optional_config(&found, config, &buf, NULL, (void *)&val)) < 0)
|
|
@@ -496,13 +501,14 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
|
|
|
496
501
|
remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
|
|
497
502
|
|
|
498
503
|
if (found && strlen(val) > 0) {
|
|
499
|
-
|
|
500
|
-
|
|
504
|
+
if ((error = apply_insteadof(&remote->url, config, val, GIT_DIRECTION_FETCH, true)) < 0 ||
|
|
505
|
+
(error = apply_insteadof(&remote->pushurl, config, val, GIT_DIRECTION_PUSH, false)) < 0)
|
|
506
|
+
goto cleanup;
|
|
501
507
|
}
|
|
502
508
|
|
|
503
509
|
val = NULL;
|
|
504
|
-
|
|
505
|
-
|
|
510
|
+
git_str_clear(&buf);
|
|
511
|
+
git_str_printf(&buf, "remote.%s.pushurl", name);
|
|
506
512
|
|
|
507
513
|
if ((error = get_optional_config(&found, config, &buf, NULL, (void *)&val)) < 0)
|
|
508
514
|
goto cleanup;
|
|
@@ -516,22 +522,25 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
|
|
|
516
522
|
}
|
|
517
523
|
|
|
518
524
|
if (found && strlen(val) > 0) {
|
|
519
|
-
remote->pushurl
|
|
520
|
-
|
|
525
|
+
if (remote->pushurl)
|
|
526
|
+
git__free(remote->pushurl);
|
|
527
|
+
|
|
528
|
+
if ((error = apply_insteadof(&remote->pushurl, config, val, GIT_DIRECTION_FETCH, true)) < 0)
|
|
529
|
+
goto cleanup;
|
|
521
530
|
}
|
|
522
531
|
|
|
523
532
|
data.remote = remote;
|
|
524
533
|
data.fetch = true;
|
|
525
534
|
|
|
526
|
-
|
|
527
|
-
|
|
535
|
+
git_str_clear(&buf);
|
|
536
|
+
git_str_printf(&buf, "remote.%s.fetch", name);
|
|
528
537
|
|
|
529
538
|
if ((error = get_optional_config(NULL, config, &buf, refspec_cb, &data)) < 0)
|
|
530
539
|
goto cleanup;
|
|
531
540
|
|
|
532
541
|
data.fetch = false;
|
|
533
|
-
|
|
534
|
-
|
|
542
|
+
git_str_clear(&buf);
|
|
543
|
+
git_str_printf(&buf, "remote.%s.push", name);
|
|
535
544
|
|
|
536
545
|
if ((error = get_optional_config(NULL, config, &buf, refspec_cb, &data)) < 0)
|
|
537
546
|
goto cleanup;
|
|
@@ -550,7 +559,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
|
|
|
550
559
|
|
|
551
560
|
cleanup:
|
|
552
561
|
git_config_free(config);
|
|
553
|
-
|
|
562
|
+
git_str_dispose(&buf);
|
|
554
563
|
|
|
555
564
|
if (error < 0)
|
|
556
565
|
git_remote_free(remote);
|
|
@@ -560,12 +569,12 @@ cleanup:
|
|
|
560
569
|
|
|
561
570
|
static int lookup_remote_prune_config(git_remote *remote, git_config *config, const char *name)
|
|
562
571
|
{
|
|
563
|
-
|
|
572
|
+
git_str buf = GIT_STR_INIT;
|
|
564
573
|
int error = 0;
|
|
565
574
|
|
|
566
|
-
|
|
575
|
+
git_str_printf(&buf, "remote.%s.prune", name);
|
|
567
576
|
|
|
568
|
-
if ((error = git_config_get_bool(&remote->prune_refs, config,
|
|
577
|
+
if ((error = git_config_get_bool(&remote->prune_refs, config, git_str_cstr(&buf))) < 0) {
|
|
569
578
|
if (error == GIT_ENOTFOUND) {
|
|
570
579
|
git_error_clear();
|
|
571
580
|
|
|
@@ -578,7 +587,7 @@ static int lookup_remote_prune_config(git_remote *remote, git_config *config, co
|
|
|
578
587
|
}
|
|
579
588
|
}
|
|
580
589
|
|
|
581
|
-
|
|
590
|
+
git_str_dispose(&buf);
|
|
582
591
|
return error;
|
|
583
592
|
}
|
|
584
593
|
|
|
@@ -619,7 +628,7 @@ int git_remote_set_instance_url(git_remote *remote, const char *url)
|
|
|
619
628
|
static int set_url(git_repository *repo, const char *remote, const char *pattern, const char *url)
|
|
620
629
|
{
|
|
621
630
|
git_config *cfg;
|
|
622
|
-
|
|
631
|
+
git_str buf = GIT_STR_INIT, canonical_url = GIT_STR_INIT;
|
|
623
632
|
int error;
|
|
624
633
|
|
|
625
634
|
GIT_ASSERT_ARG(repo);
|
|
@@ -631,7 +640,7 @@ static int set_url(git_repository *repo, const char *remote, const char *pattern
|
|
|
631
640
|
if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
|
|
632
641
|
return error;
|
|
633
642
|
|
|
634
|
-
if ((error =
|
|
643
|
+
if ((error = git_str_printf(&buf, pattern, remote)) < 0)
|
|
635
644
|
return error;
|
|
636
645
|
|
|
637
646
|
if (url) {
|
|
@@ -644,8 +653,8 @@ static int set_url(git_repository *repo, const char *remote, const char *pattern
|
|
|
644
653
|
}
|
|
645
654
|
|
|
646
655
|
cleanup:
|
|
647
|
-
|
|
648
|
-
|
|
656
|
+
git_str_dispose(&canonical_url);
|
|
657
|
+
git_str_dispose(&buf);
|
|
649
658
|
|
|
650
659
|
return error;
|
|
651
660
|
}
|
|
@@ -683,7 +692,7 @@ int git_remote_set_pushurl(git_repository *repo, const char *remote, const char
|
|
|
683
692
|
}
|
|
684
693
|
|
|
685
694
|
static int resolve_url(
|
|
686
|
-
|
|
695
|
+
git_str *resolved_url,
|
|
687
696
|
const char *url,
|
|
688
697
|
int direction,
|
|
689
698
|
const git_remote_callbacks *callbacks)
|
|
@@ -692,27 +701,28 @@ static int resolve_url(
|
|
|
692
701
|
GIT_UNUSED(direction);
|
|
693
702
|
GIT_UNUSED(callbacks);
|
|
694
703
|
#else
|
|
695
|
-
|
|
704
|
+
git_buf buf = GIT_BUF_INIT;
|
|
705
|
+
int error;
|
|
696
706
|
|
|
697
707
|
if (callbacks && callbacks->resolve_url) {
|
|
698
|
-
|
|
699
|
-
status = callbacks->resolve_url(resolved_url, url, direction, callbacks->payload);
|
|
700
|
-
if (status != GIT_PASSTHROUGH) {
|
|
701
|
-
git_error_set_after_callback_function(status, "git_resolve_url_cb");
|
|
708
|
+
error = callbacks->resolve_url(&buf, url, direction, callbacks->payload);
|
|
702
709
|
|
|
703
|
-
|
|
704
|
-
|
|
710
|
+
if (error != GIT_PASSTHROUGH) {
|
|
711
|
+
git_error_set_after_callback_function(error, "git_resolve_url_cb");
|
|
705
712
|
|
|
706
|
-
|
|
713
|
+
git_str_set(resolved_url, buf.ptr, buf.size);
|
|
714
|
+
git_buf_dispose(&buf);
|
|
715
|
+
|
|
716
|
+
return error;
|
|
707
717
|
}
|
|
708
718
|
}
|
|
709
719
|
#endif
|
|
710
720
|
|
|
711
|
-
return
|
|
721
|
+
return git_str_sets(resolved_url, url);
|
|
712
722
|
}
|
|
713
723
|
|
|
714
724
|
int git_remote__urlfordirection(
|
|
715
|
-
|
|
725
|
+
git_str *url_out,
|
|
716
726
|
struct git_remote *remote,
|
|
717
727
|
int direction,
|
|
718
728
|
const git_remote_callbacks *callbacks)
|
|
@@ -747,54 +757,200 @@ int git_remote__urlfordirection(
|
|
|
747
757
|
return resolve_url(url_out, url, direction, callbacks);
|
|
748
758
|
}
|
|
749
759
|
|
|
750
|
-
|
|
760
|
+
int git_remote_connect_options_init(
|
|
761
|
+
git_remote_connect_options *opts,
|
|
762
|
+
unsigned int version)
|
|
763
|
+
{
|
|
764
|
+
GIT_INIT_STRUCTURE_FROM_TEMPLATE(
|
|
765
|
+
opts, version, git_remote_connect_options, GIT_REMOTE_CONNECT_OPTIONS_INIT);
|
|
766
|
+
return 0;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
int git_remote_connect_options_dup(
|
|
770
|
+
git_remote_connect_options *dst,
|
|
771
|
+
const git_remote_connect_options *src)
|
|
772
|
+
{
|
|
773
|
+
memcpy(dst, src, sizeof(git_remote_connect_options));
|
|
774
|
+
|
|
775
|
+
if (git_proxy_options_dup(&dst->proxy_opts, &src->proxy_opts) < 0 ||
|
|
776
|
+
git_strarray_copy(&dst->custom_headers, &src->custom_headers) < 0)
|
|
777
|
+
return -1;
|
|
778
|
+
|
|
779
|
+
return 0;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
void git_remote_connect_options_dispose(git_remote_connect_options *opts)
|
|
783
|
+
{
|
|
784
|
+
if (!opts)
|
|
785
|
+
return;
|
|
786
|
+
|
|
787
|
+
git_strarray_dispose(&opts->custom_headers);
|
|
788
|
+
git_proxy_options_dispose(&opts->proxy_opts);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
static size_t http_header_name_length(const char *http_header)
|
|
792
|
+
{
|
|
793
|
+
const char *colon = strchr(http_header, ':');
|
|
794
|
+
if (!colon)
|
|
795
|
+
return 0;
|
|
796
|
+
return colon - http_header;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
static bool is_malformed_http_header(const char *http_header)
|
|
800
|
+
{
|
|
801
|
+
const char *c;
|
|
802
|
+
size_t name_len;
|
|
803
|
+
|
|
804
|
+
/* Disallow \r and \n */
|
|
805
|
+
if ((c = strchr(http_header, '\r')) != NULL)
|
|
806
|
+
return true;
|
|
807
|
+
if ((c = strchr(http_header, '\n')) != NULL)
|
|
808
|
+
return true;
|
|
809
|
+
|
|
810
|
+
/* Require a header name followed by : */
|
|
811
|
+
if ((name_len = http_header_name_length(http_header)) < 1)
|
|
812
|
+
return true;
|
|
813
|
+
|
|
814
|
+
return false;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
static char *forbidden_custom_headers[] = {
|
|
818
|
+
"User-Agent",
|
|
819
|
+
"Host",
|
|
820
|
+
"Accept",
|
|
821
|
+
"Content-Type",
|
|
822
|
+
"Transfer-Encoding",
|
|
823
|
+
"Content-Length",
|
|
824
|
+
};
|
|
825
|
+
|
|
826
|
+
static bool is_forbidden_custom_header(const char *custom_header)
|
|
751
827
|
{
|
|
752
|
-
|
|
828
|
+
unsigned long i;
|
|
829
|
+
size_t name_len = http_header_name_length(custom_header);
|
|
830
|
+
|
|
831
|
+
/* Disallow headers that we set */
|
|
832
|
+
for (i = 0; i < ARRAY_SIZE(forbidden_custom_headers); i++)
|
|
833
|
+
if (strncmp(forbidden_custom_headers[i], custom_header, name_len) == 0)
|
|
834
|
+
return true;
|
|
835
|
+
|
|
836
|
+
return false;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
static int validate_custom_headers(const git_strarray *custom_headers)
|
|
840
|
+
{
|
|
841
|
+
size_t i;
|
|
842
|
+
|
|
843
|
+
if (!custom_headers)
|
|
753
844
|
return 0;
|
|
754
845
|
|
|
755
|
-
|
|
756
|
-
|
|
846
|
+
for (i = 0; i < custom_headers->count; i++) {
|
|
847
|
+
if (is_malformed_http_header(custom_headers->strings[i])) {
|
|
848
|
+
git_error_set(GIT_ERROR_INVALID, "custom HTTP header '%s' is malformed", custom_headers->strings[i]);
|
|
849
|
+
return -1;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
if (is_forbidden_custom_header(custom_headers->strings[i])) {
|
|
853
|
+
git_error_set(GIT_ERROR_INVALID, "custom HTTP header '%s' is already set by libgit2", custom_headers->strings[i]);
|
|
854
|
+
return -1;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
return 0;
|
|
757
859
|
}
|
|
758
860
|
|
|
759
|
-
static int
|
|
861
|
+
static int lookup_redirect_config(
|
|
862
|
+
git_remote_redirect_t *out,
|
|
863
|
+
git_repository *repo)
|
|
760
864
|
{
|
|
761
|
-
|
|
865
|
+
git_config *config;
|
|
866
|
+
const char *value;
|
|
867
|
+
int bool_value, error = 0;
|
|
868
|
+
|
|
869
|
+
if (!repo) {
|
|
870
|
+
*out = GIT_REMOTE_REDIRECT_INITIAL;
|
|
762
871
|
return 0;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
if ((error = git_repository_config_snapshot(&config, repo)) < 0)
|
|
875
|
+
goto done;
|
|
876
|
+
|
|
877
|
+
if ((error = git_config_get_string(&value, config, "http.followRedirects")) < 0) {
|
|
878
|
+
if (error == GIT_ENOTFOUND) {
|
|
879
|
+
*out = GIT_REMOTE_REDIRECT_INITIAL;
|
|
880
|
+
error = 0;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
goto done;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
if (git_config_parse_bool(&bool_value, value) == 0) {
|
|
887
|
+
*out = bool_value ? GIT_REMOTE_REDIRECT_ALL :
|
|
888
|
+
GIT_REMOTE_REDIRECT_NONE;
|
|
889
|
+
} else if (strcasecmp(value, "initial") == 0) {
|
|
890
|
+
*out = GIT_REMOTE_REDIRECT_INITIAL;
|
|
891
|
+
} else {
|
|
892
|
+
git_error_set(GIT_ERROR_CONFIG, "invalid configuration setting '%s' for 'http.followRedirects'", value);
|
|
893
|
+
error = -1;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
done:
|
|
897
|
+
git_config_free(config);
|
|
898
|
+
return error;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
int git_remote_connect_options_normalize(
|
|
902
|
+
git_remote_connect_options *dst,
|
|
903
|
+
git_repository *repo,
|
|
904
|
+
const git_remote_connect_options *src)
|
|
905
|
+
{
|
|
906
|
+
git_remote_connect_options_dispose(dst);
|
|
907
|
+
git_remote_connect_options_init(dst, GIT_REMOTE_CONNECT_OPTIONS_VERSION);
|
|
908
|
+
|
|
909
|
+
if (src) {
|
|
910
|
+
GIT_ERROR_CHECK_VERSION(src, GIT_REMOTE_CONNECT_OPTIONS_VERSION, "git_remote_connect_options");
|
|
911
|
+
GIT_ERROR_CHECK_VERSION(&src->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks");
|
|
912
|
+
GIT_ERROR_CHECK_VERSION(&src->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options");
|
|
913
|
+
|
|
914
|
+
if (validate_custom_headers(&src->custom_headers) < 0 ||
|
|
915
|
+
git_remote_connect_options_dup(dst, src) < 0)
|
|
916
|
+
return -1;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
if (dst->follow_redirects == 0) {
|
|
920
|
+
if (lookup_redirect_config(&dst->follow_redirects, repo) < 0)
|
|
921
|
+
return -1;
|
|
922
|
+
}
|
|
763
923
|
|
|
764
|
-
return
|
|
924
|
+
return 0;
|
|
765
925
|
}
|
|
766
926
|
|
|
767
|
-
int
|
|
927
|
+
int git_remote_connect_ext(
|
|
928
|
+
git_remote *remote,
|
|
929
|
+
git_direction direction,
|
|
930
|
+
const git_remote_connect_options *given_opts)
|
|
768
931
|
{
|
|
932
|
+
git_remote_connect_options opts = GIT_REMOTE_CONNECT_OPTIONS_INIT;
|
|
933
|
+
git_str url = GIT_STR_INIT;
|
|
769
934
|
git_transport *t;
|
|
770
|
-
git_buf url = GIT_BUF_INIT;
|
|
771
|
-
int flags = GIT_TRANSPORTFLAGS_NONE;
|
|
772
935
|
int error;
|
|
773
|
-
void *payload = NULL;
|
|
774
|
-
git_credential_acquire_cb credentials = NULL;
|
|
775
|
-
git_transport_cb transport = NULL;
|
|
776
936
|
|
|
777
937
|
GIT_ASSERT_ARG(remote);
|
|
778
938
|
|
|
779
|
-
if (
|
|
780
|
-
|
|
781
|
-
credentials = callbacks->credentials;
|
|
782
|
-
transport = callbacks->transport;
|
|
783
|
-
payload = callbacks->payload;
|
|
784
|
-
}
|
|
939
|
+
if (given_opts)
|
|
940
|
+
memcpy(&opts, given_opts, sizeof(git_remote_connect_options));
|
|
785
941
|
|
|
786
|
-
|
|
787
|
-
|
|
942
|
+
GIT_ERROR_CHECK_VERSION(&opts.callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks");
|
|
943
|
+
GIT_ERROR_CHECK_VERSION(&opts.proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options");
|
|
788
944
|
|
|
789
945
|
t = remote->transport;
|
|
790
946
|
|
|
791
|
-
if ((error = git_remote__urlfordirection(&url, remote, direction, callbacks)) < 0)
|
|
947
|
+
if ((error = git_remote__urlfordirection(&url, remote, direction, &opts.callbacks)) < 0)
|
|
792
948
|
goto on_error;
|
|
793
949
|
|
|
794
950
|
/* If we don't have a transport object yet, and the caller specified a
|
|
795
951
|
* custom transport factory, use that */
|
|
796
|
-
if (!t && transport &&
|
|
797
|
-
|
|
952
|
+
if (!t && opts.callbacks.transport &&
|
|
953
|
+
(error = opts.callbacks.transport(&t, remote, opts.callbacks.payload)) < 0)
|
|
798
954
|
goto on_error;
|
|
799
955
|
|
|
800
956
|
/* If we still don't have a transport, then use the global
|
|
@@ -802,16 +958,12 @@ int git_remote__connect(git_remote *remote, git_direction direction, const git_r
|
|
|
802
958
|
if (!t && (error = git_transport_new(&t, remote, url.ptr)) < 0)
|
|
803
959
|
goto on_error;
|
|
804
960
|
|
|
805
|
-
if ((error =
|
|
806
|
-
goto on_error;
|
|
807
|
-
|
|
808
|
-
if ((error = remote_transport_set_callbacks(t, callbacks)) < 0 ||
|
|
809
|
-
(error = t->connect(t, url.ptr, credentials, payload, conn->proxy, direction, flags)) != 0)
|
|
961
|
+
if ((error = t->connect(t, url.ptr, direction, &opts)) != 0)
|
|
810
962
|
goto on_error;
|
|
811
963
|
|
|
812
964
|
remote->transport = t;
|
|
813
965
|
|
|
814
|
-
|
|
966
|
+
git_str_dispose(&url);
|
|
815
967
|
|
|
816
968
|
return 0;
|
|
817
969
|
|
|
@@ -819,7 +971,7 @@ on_error:
|
|
|
819
971
|
if (t)
|
|
820
972
|
t->free(t);
|
|
821
973
|
|
|
822
|
-
|
|
974
|
+
git_str_dispose(&url);
|
|
823
975
|
|
|
824
976
|
if (t == remote->transport)
|
|
825
977
|
remote->transport = NULL;
|
|
@@ -827,14 +979,25 @@ on_error:
|
|
|
827
979
|
return error;
|
|
828
980
|
}
|
|
829
981
|
|
|
830
|
-
int git_remote_connect(
|
|
982
|
+
int git_remote_connect(
|
|
983
|
+
git_remote *remote,
|
|
984
|
+
git_direction direction,
|
|
985
|
+
const git_remote_callbacks *callbacks,
|
|
986
|
+
const git_proxy_options *proxy,
|
|
987
|
+
const git_strarray *custom_headers)
|
|
831
988
|
{
|
|
832
|
-
|
|
989
|
+
git_remote_connect_options opts = GIT_REMOTE_CONNECT_OPTIONS_INIT;
|
|
990
|
+
|
|
991
|
+
if (callbacks)
|
|
992
|
+
memcpy(&opts.callbacks, callbacks, sizeof(git_remote_callbacks));
|
|
833
993
|
|
|
834
|
-
|
|
835
|
-
|
|
994
|
+
if (proxy)
|
|
995
|
+
memcpy(&opts.proxy_opts, proxy, sizeof(git_proxy_options));
|
|
836
996
|
|
|
837
|
-
|
|
997
|
+
if (custom_headers)
|
|
998
|
+
memcpy(&opts.custom_headers, custom_headers, sizeof(git_strarray));
|
|
999
|
+
|
|
1000
|
+
return git_remote_connect_ext(remote, direction, &opts);
|
|
838
1001
|
}
|
|
839
1002
|
|
|
840
1003
|
int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote)
|
|
@@ -849,6 +1012,20 @@ int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote
|
|
|
849
1012
|
return remote->transport->ls(out, size, remote->transport);
|
|
850
1013
|
}
|
|
851
1014
|
|
|
1015
|
+
int git_remote_capabilities(unsigned int *out, git_remote *remote)
|
|
1016
|
+
{
|
|
1017
|
+
GIT_ASSERT_ARG(remote);
|
|
1018
|
+
|
|
1019
|
+
*out = 0;
|
|
1020
|
+
|
|
1021
|
+
if (!remote->transport) {
|
|
1022
|
+
git_error_set(GIT_ERROR_NET, "this remote has never connected");
|
|
1023
|
+
return -1;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
return remote->transport->capabilities(out, remote->transport);
|
|
1027
|
+
}
|
|
1028
|
+
|
|
852
1029
|
static int lookup_config(char **out, git_config *cfg, const char *name)
|
|
853
1030
|
{
|
|
854
1031
|
git_config_entry *ce = NULL;
|
|
@@ -885,7 +1062,7 @@ static void url_config_trim(git_net_url *url)
|
|
|
885
1062
|
static int http_proxy_config(char **out, git_remote *remote, git_net_url *url)
|
|
886
1063
|
{
|
|
887
1064
|
git_config *cfg = NULL;
|
|
888
|
-
|
|
1065
|
+
git_str buf = GIT_STR_INIT;
|
|
889
1066
|
git_net_url lookup_url = GIT_NET_URL_INIT;
|
|
890
1067
|
int error;
|
|
891
1068
|
|
|
@@ -902,19 +1079,19 @@ static int http_proxy_config(char **out, git_remote *remote, git_net_url *url)
|
|
|
902
1079
|
|
|
903
1080
|
/* remote.<name>.proxy config setting */
|
|
904
1081
|
if (remote->name && remote->name[0]) {
|
|
905
|
-
|
|
1082
|
+
git_str_clear(&buf);
|
|
906
1083
|
|
|
907
|
-
if ((error =
|
|
1084
|
+
if ((error = git_str_printf(&buf, "remote.%s.proxy", remote->name)) < 0 ||
|
|
908
1085
|
(error = lookup_config(out, cfg, buf.ptr)) != GIT_ENOTFOUND)
|
|
909
1086
|
goto done;
|
|
910
1087
|
}
|
|
911
1088
|
|
|
912
1089
|
while (true) {
|
|
913
|
-
|
|
1090
|
+
git_str_clear(&buf);
|
|
914
1091
|
|
|
915
|
-
if ((error =
|
|
1092
|
+
if ((error = git_str_puts(&buf, "http.")) < 0 ||
|
|
916
1093
|
(error = git_net_url_fmt(&buf, &lookup_url)) < 0 ||
|
|
917
|
-
(error =
|
|
1094
|
+
(error = git_str_puts(&buf, ".proxy")) < 0 ||
|
|
918
1095
|
(error = lookup_config(out, cfg, buf.ptr)) != GIT_ENOTFOUND)
|
|
919
1096
|
goto done;
|
|
920
1097
|
|
|
@@ -924,20 +1101,20 @@ static int http_proxy_config(char **out, git_remote *remote, git_net_url *url)
|
|
|
924
1101
|
url_config_trim(&lookup_url);
|
|
925
1102
|
}
|
|
926
1103
|
|
|
927
|
-
|
|
1104
|
+
git_str_clear(&buf);
|
|
928
1105
|
|
|
929
1106
|
error = lookup_config(out, cfg, "http.proxy");
|
|
930
1107
|
|
|
931
1108
|
done:
|
|
932
1109
|
git_config_free(cfg);
|
|
933
|
-
|
|
1110
|
+
git_str_dispose(&buf);
|
|
934
1111
|
git_net_url_dispose(&lookup_url);
|
|
935
1112
|
return error;
|
|
936
1113
|
}
|
|
937
1114
|
|
|
938
1115
|
static int http_proxy_env(char **out, git_remote *remote, git_net_url *url)
|
|
939
1116
|
{
|
|
940
|
-
|
|
1117
|
+
git_str proxy_env = GIT_STR_INIT, no_proxy_env = GIT_STR_INIT;
|
|
941
1118
|
bool use_ssl = (strcmp(url->scheme, "https") == 0);
|
|
942
1119
|
int error;
|
|
943
1120
|
|
|
@@ -963,13 +1140,13 @@ static int http_proxy_env(char **out, git_remote *remote, git_net_url *url)
|
|
|
963
1140
|
goto done;
|
|
964
1141
|
|
|
965
1142
|
if (!git_net_url_matches_pattern_list(url, no_proxy_env.ptr))
|
|
966
|
-
*out =
|
|
1143
|
+
*out = git_str_detach(&proxy_env);
|
|
967
1144
|
else
|
|
968
1145
|
error = GIT_ENOTFOUND;
|
|
969
1146
|
|
|
970
1147
|
done:
|
|
971
|
-
|
|
972
|
-
|
|
1148
|
+
git_str_dispose(&proxy_env);
|
|
1149
|
+
git_str_dispose(&no_proxy_env);
|
|
973
1150
|
return error;
|
|
974
1151
|
}
|
|
975
1152
|
|
|
@@ -1048,38 +1225,50 @@ static int ls_to_vector(git_vector *out, git_remote *remote)
|
|
|
1048
1225
|
return 0;
|
|
1049
1226
|
}
|
|
1050
1227
|
|
|
1051
|
-
|
|
1052
|
-
{
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
const git_strarray *custom_headers = NULL;
|
|
1058
|
-
const git_proxy_options *proxy = NULL;
|
|
1059
|
-
|
|
1060
|
-
GIT_ASSERT_ARG(remote);
|
|
1061
|
-
|
|
1062
|
-
if (!remote->repo) {
|
|
1063
|
-
git_error_set(GIT_ERROR_INVALID, "cannot download detached remote");
|
|
1064
|
-
return -1;
|
|
1228
|
+
#define copy_opts(out, in) \
|
|
1229
|
+
if (in) { \
|
|
1230
|
+
(out)->callbacks = (in)->callbacks; \
|
|
1231
|
+
(out)->proxy_opts = (in)->proxy_opts; \
|
|
1232
|
+
(out)->custom_headers = (in)->custom_headers; \
|
|
1233
|
+
(out)->follow_redirects = (in)->follow_redirects; \
|
|
1065
1234
|
}
|
|
1066
1235
|
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1236
|
+
GIT_INLINE(int) connect_opts_from_fetch_opts(
|
|
1237
|
+
git_remote_connect_options *out,
|
|
1238
|
+
git_remote *remote,
|
|
1239
|
+
const git_fetch_options *fetch_opts)
|
|
1240
|
+
{
|
|
1241
|
+
git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT;
|
|
1242
|
+
copy_opts(&tmp, fetch_opts);
|
|
1243
|
+
return git_remote_connect_options_normalize(out, remote->repo, &tmp);
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
static int connect_or_reset_options(
|
|
1247
|
+
git_remote *remote,
|
|
1248
|
+
int direction,
|
|
1249
|
+
git_remote_connect_options *opts)
|
|
1250
|
+
{
|
|
1251
|
+
if (!git_remote_connected(remote)) {
|
|
1252
|
+
return git_remote_connect_ext(remote, direction, opts);
|
|
1253
|
+
} else {
|
|
1254
|
+
return remote->transport->set_connect_opts(remote->transport, opts);
|
|
1073
1255
|
}
|
|
1256
|
+
}
|
|
1074
1257
|
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1258
|
+
/* Download from an already connected remote. */
|
|
1259
|
+
static int git_remote__download(
|
|
1260
|
+
git_remote *remote,
|
|
1261
|
+
const git_strarray *refspecs,
|
|
1262
|
+
const git_fetch_options *opts)
|
|
1263
|
+
{
|
|
1264
|
+
git_vector *to_active, specs = GIT_VECTOR_INIT, refs = GIT_VECTOR_INIT;
|
|
1265
|
+
size_t i;
|
|
1266
|
+
int error;
|
|
1078
1267
|
|
|
1079
1268
|
if (ls_to_vector(&refs, remote) < 0)
|
|
1080
1269
|
return -1;
|
|
1081
1270
|
|
|
1082
|
-
if ((git_vector_init(&specs, 0, NULL)) < 0)
|
|
1271
|
+
if ((error = git_vector_init(&specs, 0, NULL)) < 0)
|
|
1083
1272
|
goto on_error;
|
|
1084
1273
|
|
|
1085
1274
|
remote->passed_refspecs = 0;
|
|
@@ -1107,7 +1296,7 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const
|
|
|
1107
1296
|
git_vector_free(&specs);
|
|
1108
1297
|
|
|
1109
1298
|
if (error < 0)
|
|
1110
|
-
|
|
1299
|
+
goto on_error;
|
|
1111
1300
|
|
|
1112
1301
|
if (remote->push) {
|
|
1113
1302
|
git_push_free(remote->push);
|
|
@@ -1115,9 +1304,9 @@ int git_remote_download(git_remote *remote, const git_strarray *refspecs, const
|
|
|
1115
1304
|
}
|
|
1116
1305
|
|
|
1117
1306
|
if ((error = git_fetch_negotiate(remote, opts)) < 0)
|
|
1118
|
-
|
|
1307
|
+
goto on_error;
|
|
1119
1308
|
|
|
1120
|
-
|
|
1309
|
+
error = git_fetch_download_pack(remote);
|
|
1121
1310
|
|
|
1122
1311
|
on_error:
|
|
1123
1312
|
git_vector_free(&refs);
|
|
@@ -1126,55 +1315,83 @@ on_error:
|
|
|
1126
1315
|
return error;
|
|
1127
1316
|
}
|
|
1128
1317
|
|
|
1318
|
+
int git_remote_download(
|
|
1319
|
+
git_remote *remote,
|
|
1320
|
+
const git_strarray *refspecs,
|
|
1321
|
+
const git_fetch_options *opts)
|
|
1322
|
+
{
|
|
1323
|
+
git_remote_connect_options connect_opts = GIT_REMOTE_CONNECT_OPTIONS_INIT;
|
|
1324
|
+
int error;
|
|
1325
|
+
|
|
1326
|
+
GIT_ASSERT_ARG(remote);
|
|
1327
|
+
|
|
1328
|
+
if (!remote->repo) {
|
|
1329
|
+
git_error_set(GIT_ERROR_INVALID, "cannot download detached remote");
|
|
1330
|
+
return -1;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
if (connect_opts_from_fetch_opts(&connect_opts, remote, opts) < 0)
|
|
1334
|
+
return -1;
|
|
1335
|
+
|
|
1336
|
+
if ((error = connect_or_reset_options(remote, GIT_DIRECTION_FETCH, &connect_opts)) < 0)
|
|
1337
|
+
return error;
|
|
1338
|
+
|
|
1339
|
+
return git_remote__download(remote, refspecs, opts);
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1129
1342
|
int git_remote_fetch(
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1343
|
+
git_remote *remote,
|
|
1344
|
+
const git_strarray *refspecs,
|
|
1345
|
+
const git_fetch_options *opts,
|
|
1346
|
+
const char *reflog_message)
|
|
1134
1347
|
{
|
|
1135
1348
|
int error, update_fetchhead = 1;
|
|
1136
1349
|
git_remote_autotag_option_t tagopt = remote->download_tags;
|
|
1137
1350
|
bool prune = false;
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1351
|
+
git_str reflog_msg_buf = GIT_STR_INIT;
|
|
1352
|
+
git_remote_connect_options connect_opts = GIT_REMOTE_CONNECT_OPTIONS_INIT;
|
|
1353
|
+
|
|
1354
|
+
GIT_ASSERT_ARG(remote);
|
|
1355
|
+
|
|
1356
|
+
if (!remote->repo) {
|
|
1357
|
+
git_error_set(GIT_ERROR_INVALID, "cannot download detached remote");
|
|
1358
|
+
return -1;
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
if (connect_opts_from_fetch_opts(&connect_opts, remote, opts) < 0)
|
|
1362
|
+
return -1;
|
|
1363
|
+
|
|
1364
|
+
if ((error = connect_or_reset_options(remote, GIT_DIRECTION_FETCH, &connect_opts)) < 0)
|
|
1365
|
+
return error;
|
|
1141
1366
|
|
|
1142
1367
|
if (opts) {
|
|
1143
|
-
GIT_ERROR_CHECK_VERSION(&opts->callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks");
|
|
1144
|
-
cbs = &opts->callbacks;
|
|
1145
|
-
conn.custom_headers = &opts->custom_headers;
|
|
1146
1368
|
update_fetchhead = opts->update_fetchhead;
|
|
1147
1369
|
tagopt = opts->download_tags;
|
|
1148
|
-
GIT_ERROR_CHECK_VERSION(&opts->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options");
|
|
1149
|
-
conn.proxy = &opts->proxy_opts;
|
|
1150
1370
|
}
|
|
1151
1371
|
|
|
1152
1372
|
/* Connect and download everything */
|
|
1153
|
-
|
|
1154
|
-
return error;
|
|
1155
|
-
|
|
1156
|
-
error = git_remote_download(remote, refspecs, opts);
|
|
1373
|
+
error = git_remote__download(remote, refspecs, opts);
|
|
1157
1374
|
|
|
1158
1375
|
/* We don't need to be connected anymore */
|
|
1159
1376
|
git_remote_disconnect(remote);
|
|
1160
1377
|
|
|
1161
1378
|
/* If the download failed, return the error */
|
|
1162
1379
|
if (error != 0)
|
|
1163
|
-
|
|
1380
|
+
goto done;
|
|
1164
1381
|
|
|
1165
1382
|
/* Default reflog message */
|
|
1166
1383
|
if (reflog_message)
|
|
1167
|
-
|
|
1384
|
+
git_str_sets(&reflog_msg_buf, reflog_message);
|
|
1168
1385
|
else {
|
|
1169
|
-
|
|
1386
|
+
git_str_printf(&reflog_msg_buf, "fetch %s",
|
|
1170
1387
|
remote->name ? remote->name : remote->url);
|
|
1171
1388
|
}
|
|
1172
1389
|
|
|
1173
1390
|
/* Create "remote/foo" branches for all remote branches */
|
|
1174
|
-
error = git_remote_update_tips(remote,
|
|
1175
|
-
|
|
1391
|
+
error = git_remote_update_tips(remote, &connect_opts.callbacks, update_fetchhead, tagopt, git_str_cstr(&reflog_msg_buf));
|
|
1392
|
+
git_str_dispose(&reflog_msg_buf);
|
|
1176
1393
|
if (error < 0)
|
|
1177
|
-
|
|
1394
|
+
goto done;
|
|
1178
1395
|
|
|
1179
1396
|
if (opts && opts->prune == GIT_FETCH_PRUNE)
|
|
1180
1397
|
prune = true;
|
|
@@ -1186,8 +1403,10 @@ int git_remote_fetch(
|
|
|
1186
1403
|
prune = remote->prune_refs;
|
|
1187
1404
|
|
|
1188
1405
|
if (prune)
|
|
1189
|
-
error = git_remote_prune(remote,
|
|
1406
|
+
error = git_remote_prune(remote, &connect_opts.callbacks);
|
|
1190
1407
|
|
|
1408
|
+
done:
|
|
1409
|
+
git_remote_connect_options_dispose(&connect_opts);
|
|
1191
1410
|
return error;
|
|
1192
1411
|
}
|
|
1193
1412
|
|
|
@@ -1211,22 +1430,22 @@ static int remote_head_for_fetchspec_src(git_remote_head **out, git_vector *upda
|
|
|
1211
1430
|
return 0;
|
|
1212
1431
|
}
|
|
1213
1432
|
|
|
1214
|
-
static int ref_to_update(int *update,
|
|
1433
|
+
static int ref_to_update(int *update, git_str *remote_name, git_remote *remote, git_refspec *spec, const char *ref_name)
|
|
1215
1434
|
{
|
|
1216
1435
|
int error = 0;
|
|
1217
1436
|
git_repository *repo;
|
|
1218
|
-
|
|
1219
|
-
|
|
1437
|
+
git_str upstream_remote = GIT_STR_INIT;
|
|
1438
|
+
git_str upstream_name = GIT_STR_INIT;
|
|
1220
1439
|
|
|
1221
1440
|
repo = git_remote_owner(remote);
|
|
1222
1441
|
|
|
1223
1442
|
if ((!git_reference__is_branch(ref_name)) ||
|
|
1224
1443
|
!git_remote_name(remote) ||
|
|
1225
|
-
(error =
|
|
1226
|
-
git__strcmp(git_remote_name(remote),
|
|
1227
|
-
(error =
|
|
1228
|
-
!git_refspec_dst_matches(spec,
|
|
1229
|
-
(error =
|
|
1444
|
+
(error = git_branch__upstream_remote(&upstream_remote, repo, ref_name) < 0) ||
|
|
1445
|
+
git__strcmp(git_remote_name(remote), git_str_cstr(&upstream_remote)) ||
|
|
1446
|
+
(error = git_branch__upstream_name(&upstream_name, repo, ref_name)) < 0 ||
|
|
1447
|
+
!git_refspec_dst_matches(spec, git_str_cstr(&upstream_name)) ||
|
|
1448
|
+
(error = git_refspec__rtransform(remote_name, spec, upstream_name.ptr)) < 0) {
|
|
1230
1449
|
/* Not an error if there is no upstream */
|
|
1231
1450
|
if (error == GIT_ENOTFOUND) {
|
|
1232
1451
|
git_error_clear();
|
|
@@ -1238,15 +1457,15 @@ static int ref_to_update(int *update, git_buf *remote_name, git_remote *remote,
|
|
|
1238
1457
|
*update = 1;
|
|
1239
1458
|
}
|
|
1240
1459
|
|
|
1241
|
-
|
|
1242
|
-
|
|
1460
|
+
git_str_dispose(&upstream_remote);
|
|
1461
|
+
git_str_dispose(&upstream_name);
|
|
1243
1462
|
return error;
|
|
1244
1463
|
}
|
|
1245
1464
|
|
|
1246
1465
|
static int remote_head_for_ref(git_remote_head **out, git_remote *remote, git_refspec *spec, git_vector *update_heads, git_reference *ref)
|
|
1247
1466
|
{
|
|
1248
1467
|
git_reference *resolved_ref = NULL;
|
|
1249
|
-
|
|
1468
|
+
git_str remote_name = GIT_STR_INIT;
|
|
1250
1469
|
git_config *config = NULL;
|
|
1251
1470
|
const char *ref_name;
|
|
1252
1471
|
int error = 0, update;
|
|
@@ -1281,10 +1500,10 @@ static int remote_head_for_ref(git_remote_head **out, git_remote *remote, git_re
|
|
|
1281
1500
|
goto cleanup;
|
|
1282
1501
|
|
|
1283
1502
|
if (update)
|
|
1284
|
-
error = remote_head_for_fetchspec_src(out, update_heads,
|
|
1503
|
+
error = remote_head_for_fetchspec_src(out, update_heads, git_str_cstr(&remote_name));
|
|
1285
1504
|
|
|
1286
1505
|
cleanup:
|
|
1287
|
-
|
|
1506
|
+
git_str_dispose(&remote_name);
|
|
1288
1507
|
git_reference_free(resolved_ref);
|
|
1289
1508
|
git_config_free(config);
|
|
1290
1509
|
return error;
|
|
@@ -1422,7 +1641,7 @@ int git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks)
|
|
|
1422
1641
|
*/
|
|
1423
1642
|
git_vector_foreach(&candidates, i, refname) {
|
|
1424
1643
|
git_vector_foreach(&remote->active_refspecs, j, spec) {
|
|
1425
|
-
|
|
1644
|
+
git_str buf = GIT_STR_INIT;
|
|
1426
1645
|
size_t pos;
|
|
1427
1646
|
char *src_name;
|
|
1428
1647
|
git_remote_head key = {0};
|
|
@@ -1430,12 +1649,12 @@ int git_remote_prune(git_remote *remote, const git_remote_callbacks *callbacks)
|
|
|
1430
1649
|
if (!git_refspec_dst_matches(spec, refname))
|
|
1431
1650
|
continue;
|
|
1432
1651
|
|
|
1433
|
-
if ((error =
|
|
1652
|
+
if ((error = git_refspec__rtransform(&buf, spec, refname)) < 0)
|
|
1434
1653
|
goto cleanup;
|
|
1435
1654
|
|
|
1436
|
-
key.name = (char *)
|
|
1655
|
+
key.name = (char *) git_str_cstr(&buf);
|
|
1437
1656
|
error = git_vector_bsearch(&pos, &remote_refs, &key);
|
|
1438
|
-
|
|
1657
|
+
git_str_dispose(&buf);
|
|
1439
1658
|
|
|
1440
1659
|
if (error < 0 && error != GIT_ENOTFOUND)
|
|
1441
1660
|
goto cleanup;
|
|
@@ -1497,141 +1716,207 @@ cleanup:
|
|
|
1497
1716
|
return error;
|
|
1498
1717
|
}
|
|
1499
1718
|
|
|
1500
|
-
static int
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
git_vector *refs,
|
|
1507
|
-
const char *log_message)
|
|
1719
|
+
static int update_ref(
|
|
1720
|
+
const git_remote *remote,
|
|
1721
|
+
const char *ref_name,
|
|
1722
|
+
git_oid *id,
|
|
1723
|
+
const char *msg,
|
|
1724
|
+
const git_remote_callbacks *callbacks)
|
|
1508
1725
|
{
|
|
1509
|
-
int error = 0, autotag, valid;
|
|
1510
|
-
unsigned int i = 0;
|
|
1511
|
-
git_buf refname = GIT_BUF_INIT;
|
|
1512
|
-
git_oid old;
|
|
1513
|
-
git_odb *odb;
|
|
1514
|
-
git_remote_head *head;
|
|
1515
1726
|
git_reference *ref;
|
|
1516
|
-
|
|
1517
|
-
|
|
1727
|
+
git_oid old_id;
|
|
1728
|
+
int error;
|
|
1518
1729
|
|
|
1519
|
-
|
|
1730
|
+
error = git_reference_name_to_id(&old_id, remote->repo, ref_name);
|
|
1520
1731
|
|
|
1521
|
-
if (
|
|
1522
|
-
return
|
|
1732
|
+
if (error < 0 && error != GIT_ENOTFOUND)
|
|
1733
|
+
return error;
|
|
1734
|
+
else if (error == 0 && git_oid_equal(&old_id, id))
|
|
1735
|
+
return 0;
|
|
1523
1736
|
|
|
1524
|
-
|
|
1525
|
-
|
|
1737
|
+
/* If we did find a current reference, make sure we haven't lost a race */
|
|
1738
|
+
if (error)
|
|
1739
|
+
error = git_reference_create(&ref, remote->repo, ref_name, id, true, msg);
|
|
1740
|
+
else
|
|
1741
|
+
error = git_reference_create_matching(&ref, remote->repo, ref_name, id, true, &old_id, msg);
|
|
1526
1742
|
|
|
1527
|
-
|
|
1528
|
-
if (git_vector_init(&update_heads, 16, NULL) < 0)
|
|
1529
|
-
return -1;
|
|
1743
|
+
git_reference_free(ref);
|
|
1530
1744
|
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
autotag = 0;
|
|
1534
|
-
git_buf_clear(&refname);
|
|
1745
|
+
if (error < 0)
|
|
1746
|
+
return error;
|
|
1535
1747
|
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1748
|
+
if (callbacks && callbacks->update_tips &&
|
|
1749
|
+
(error = callbacks->update_tips(ref_name, &old_id, id, callbacks->payload)) < 0)
|
|
1750
|
+
return error;
|
|
1539
1751
|
|
|
1540
|
-
|
|
1541
|
-
|
|
1752
|
+
return 0;
|
|
1753
|
+
}
|
|
1542
1754
|
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1755
|
+
static int update_one_tip(
|
|
1756
|
+
git_vector *update_heads,
|
|
1757
|
+
git_remote *remote,
|
|
1758
|
+
git_refspec *spec,
|
|
1759
|
+
git_remote_head *head,
|
|
1760
|
+
git_refspec *tagspec,
|
|
1761
|
+
git_remote_autotag_option_t tagopt,
|
|
1762
|
+
const char *log_message,
|
|
1763
|
+
const git_remote_callbacks *callbacks)
|
|
1764
|
+
{
|
|
1765
|
+
git_odb *odb;
|
|
1766
|
+
git_str refname = GIT_STR_INIT;
|
|
1767
|
+
git_reference *ref = NULL;
|
|
1768
|
+
bool autotag = false;
|
|
1769
|
+
git_oid old;
|
|
1770
|
+
int valid;
|
|
1771
|
+
int error;
|
|
1546
1772
|
|
|
1547
|
-
|
|
1548
|
-
|
|
1773
|
+
if ((error = git_repository_odb__weakptr(&odb, remote->repo)) < 0)
|
|
1774
|
+
goto done;
|
|
1549
1775
|
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1776
|
+
/* Ignore malformed ref names (which also saves us from tag^{} */
|
|
1777
|
+
if ((error = git_reference_name_is_valid(&valid, head->name)) < 0)
|
|
1778
|
+
goto done;
|
|
1555
1779
|
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
if (spec->dst) {
|
|
1559
|
-
if (git_refspec_transform(&refname, spec, head->name) < 0)
|
|
1560
|
-
goto on_error;
|
|
1561
|
-
} else {
|
|
1562
|
-
/*
|
|
1563
|
-
* no rhs mans store it in FETCH_HEAD, even if we don't
|
|
1564
|
-
update anything else.
|
|
1565
|
-
*/
|
|
1566
|
-
if ((error = git_vector_insert(&update_heads, head)) < 0)
|
|
1567
|
-
goto on_error;
|
|
1780
|
+
if (!valid)
|
|
1781
|
+
goto done;
|
|
1568
1782
|
|
|
1569
|
-
|
|
1570
|
-
|
|
1783
|
+
/* If we have a tag, see if the auto-follow rules say to update it */
|
|
1784
|
+
if (git_refspec_src_matches(tagspec, head->name)) {
|
|
1785
|
+
if (tagopt == GIT_REMOTE_DOWNLOAD_TAGS_AUTO)
|
|
1786
|
+
autotag = true;
|
|
1787
|
+
|
|
1788
|
+
if (tagopt != GIT_REMOTE_DOWNLOAD_TAGS_NONE) {
|
|
1789
|
+
if (git_str_puts(&refname, head->name) < 0)
|
|
1790
|
+
goto done;
|
|
1571
1791
|
}
|
|
1792
|
+
}
|
|
1572
1793
|
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1794
|
+
/* If we didn't want to auto-follow the tag, check if the refspec matches */
|
|
1795
|
+
if (!autotag && git_refspec_src_matches(spec, head->name)) {
|
|
1796
|
+
if (spec->dst) {
|
|
1797
|
+
if ((error = git_refspec__transform(&refname, spec, head->name)) < 0)
|
|
1798
|
+
goto done;
|
|
1799
|
+
} else {
|
|
1800
|
+
/*
|
|
1801
|
+
* no rhs means store it in FETCH_HEAD, even if we don't
|
|
1802
|
+
* update anything else.
|
|
1803
|
+
*/
|
|
1804
|
+
error = git_vector_insert(update_heads, head);
|
|
1805
|
+
goto done;
|
|
1576
1806
|
}
|
|
1807
|
+
}
|
|
1577
1808
|
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1809
|
+
/* If we still don't have a refname, we don't want it */
|
|
1810
|
+
if (git_str_len(&refname) == 0)
|
|
1811
|
+
goto done;
|
|
1581
1812
|
|
|
1582
|
-
|
|
1583
|
-
|
|
1813
|
+
/* In autotag mode, only create tags for objects already in db */
|
|
1814
|
+
if (autotag && !git_odb_exists(odb, &head->oid))
|
|
1815
|
+
goto done;
|
|
1584
1816
|
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
goto on_error;
|
|
1817
|
+
if (!autotag && (error = git_vector_insert(update_heads, head)) < 0)
|
|
1818
|
+
goto done;
|
|
1588
1819
|
|
|
1589
|
-
|
|
1590
|
-
&& !spec->force
|
|
1591
|
-
&& !git_graph_descendant_of(remote->repo, &head->oid, &old))
|
|
1592
|
-
continue;
|
|
1820
|
+
error = git_reference_name_to_id(&old, remote->repo, refname.ptr);
|
|
1593
1821
|
|
|
1594
|
-
|
|
1595
|
-
|
|
1822
|
+
if (error < 0 && error != GIT_ENOTFOUND)
|
|
1823
|
+
goto done;
|
|
1596
1824
|
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1825
|
+
if (!(error || error == GIT_ENOTFOUND) &&
|
|
1826
|
+
!spec->force &&
|
|
1827
|
+
!git_graph_descendant_of(remote->repo, &head->oid, &old)) {
|
|
1828
|
+
error = 0;
|
|
1829
|
+
goto done;
|
|
1830
|
+
}
|
|
1600
1831
|
|
|
1601
|
-
|
|
1602
|
-
|
|
1832
|
+
if (error == GIT_ENOTFOUND) {
|
|
1833
|
+
memset(&old, 0, GIT_OID_RAWSZ);
|
|
1834
|
+
error = 0;
|
|
1835
|
+
|
|
1836
|
+
if (autotag && (error = git_vector_insert(update_heads, head)) < 0)
|
|
1837
|
+
goto done;
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
if (!git_oid__cmp(&old, &head->oid))
|
|
1841
|
+
goto done;
|
|
1603
1842
|
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1843
|
+
/* In autotag mode, don't overwrite any locally-existing tags */
|
|
1844
|
+
error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, !autotag,
|
|
1845
|
+
log_message);
|
|
1607
1846
|
|
|
1847
|
+
if (error < 0) {
|
|
1608
1848
|
if (error == GIT_EEXISTS)
|
|
1609
|
-
|
|
1849
|
+
error = 0;
|
|
1610
1850
|
|
|
1611
|
-
|
|
1851
|
+
goto done;
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
if (callbacks && callbacks->update_tips != NULL &&
|
|
1855
|
+
(error = callbacks->update_tips(refname.ptr, &old, &head->oid, callbacks->payload)) < 0)
|
|
1856
|
+
git_error_set_after_callback_function(error, "git_remote_fetch");
|
|
1857
|
+
|
|
1858
|
+
done:
|
|
1859
|
+
git_reference_free(ref);
|
|
1860
|
+
git_str_dispose(&refname);
|
|
1861
|
+
return error;
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
static int update_tips_for_spec(
|
|
1865
|
+
git_remote *remote,
|
|
1866
|
+
const git_remote_callbacks *callbacks,
|
|
1867
|
+
int update_fetchhead,
|
|
1868
|
+
git_remote_autotag_option_t tagopt,
|
|
1869
|
+
git_refspec *spec,
|
|
1870
|
+
git_vector *refs,
|
|
1871
|
+
const char *log_message)
|
|
1872
|
+
{
|
|
1873
|
+
git_refspec tagspec;
|
|
1874
|
+
git_remote_head *head, oid_head;
|
|
1875
|
+
git_vector update_heads;
|
|
1876
|
+
int error = 0;
|
|
1877
|
+
size_t i;
|
|
1878
|
+
|
|
1879
|
+
GIT_ASSERT_ARG(remote);
|
|
1880
|
+
|
|
1881
|
+
if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0)
|
|
1882
|
+
return -1;
|
|
1883
|
+
|
|
1884
|
+
/* Make a copy of the transport's refs */
|
|
1885
|
+
if (git_vector_init(&update_heads, 16, NULL) < 0)
|
|
1886
|
+
return -1;
|
|
1887
|
+
|
|
1888
|
+
/* Update tips based on the remote heads */
|
|
1889
|
+
git_vector_foreach(refs, i, head) {
|
|
1890
|
+
if (update_one_tip(&update_heads, remote, spec, head, &tagspec, tagopt, log_message, callbacks) < 0)
|
|
1612
1891
|
goto on_error;
|
|
1892
|
+
}
|
|
1613
1893
|
|
|
1614
|
-
|
|
1894
|
+
/* Handle specified oid sources */
|
|
1895
|
+
if (git_oid__is_hexstr(spec->src)) {
|
|
1896
|
+
git_oid id;
|
|
1615
1897
|
|
|
1616
|
-
if (
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1898
|
+
if ((error = git_oid_fromstr(&id, spec->src)) < 0 ||
|
|
1899
|
+
(error = update_ref(remote, spec->dst, &id, log_message, callbacks)) < 0)
|
|
1900
|
+
goto on_error;
|
|
1901
|
+
|
|
1902
|
+
git_oid_cpy(&oid_head.oid, &id);
|
|
1903
|
+
oid_head.name = spec->src;
|
|
1904
|
+
|
|
1905
|
+
if ((error = git_vector_insert(&update_heads, &oid_head)) < 0)
|
|
1906
|
+
goto on_error;
|
|
1620
1907
|
}
|
|
1621
1908
|
|
|
1622
1909
|
if (update_fetchhead &&
|
|
1623
1910
|
(error = git_remote_write_fetchhead(remote, spec, &update_heads)) < 0)
|
|
1624
1911
|
goto on_error;
|
|
1625
1912
|
|
|
1626
|
-
git_vector_free(&update_heads);
|
|
1627
1913
|
git_refspec__dispose(&tagspec);
|
|
1628
|
-
|
|
1914
|
+
git_vector_free(&update_heads);
|
|
1629
1915
|
return 0;
|
|
1630
1916
|
|
|
1631
1917
|
on_error:
|
|
1632
|
-
git_vector_free(&update_heads);
|
|
1633
1918
|
git_refspec__dispose(&tagspec);
|
|
1634
|
-
|
|
1919
|
+
git_vector_free(&update_heads);
|
|
1635
1920
|
return -1;
|
|
1636
1921
|
|
|
1637
1922
|
}
|
|
@@ -1697,20 +1982,22 @@ static int next_head(const git_remote *remote, git_vector *refs,
|
|
|
1697
1982
|
return GIT_ITEROVER;
|
|
1698
1983
|
}
|
|
1699
1984
|
|
|
1700
|
-
static int opportunistic_updates(
|
|
1701
|
-
|
|
1985
|
+
static int opportunistic_updates(
|
|
1986
|
+
const git_remote *remote,
|
|
1987
|
+
const git_remote_callbacks *callbacks,
|
|
1988
|
+
git_vector *refs,
|
|
1989
|
+
const char *msg)
|
|
1702
1990
|
{
|
|
1703
1991
|
size_t i, j, k;
|
|
1704
1992
|
git_refspec *spec;
|
|
1705
1993
|
git_remote_head *head;
|
|
1706
|
-
|
|
1707
|
-
git_buf refname = GIT_BUF_INIT;
|
|
1994
|
+
git_str refname = GIT_STR_INIT;
|
|
1708
1995
|
int error = 0;
|
|
1709
1996
|
|
|
1710
1997
|
i = j = k = 0;
|
|
1711
1998
|
|
|
1999
|
+
/* Handle refspecs matching remote heads */
|
|
1712
2000
|
while ((error = next_head(remote, refs, &spec, &head, &i, &j, &k)) == 0) {
|
|
1713
|
-
git_oid old = {{ 0 }};
|
|
1714
2001
|
/*
|
|
1715
2002
|
* If we got here, there is a refspec which was used
|
|
1716
2003
|
* for fetching which matches the source of one of the
|
|
@@ -1719,50 +2006,32 @@ static int opportunistic_updates(const git_remote *remote, const git_remote_call
|
|
|
1719
2006
|
* FETCH_HEAD
|
|
1720
2007
|
*/
|
|
1721
2008
|
|
|
1722
|
-
|
|
1723
|
-
if ((error =
|
|
2009
|
+
git_str_clear(&refname);
|
|
2010
|
+
if ((error = git_refspec__transform(&refname, spec, head->name)) < 0 ||
|
|
2011
|
+
(error = update_ref(remote, refname.ptr, &head->oid, msg, callbacks)) < 0)
|
|
1724
2012
|
goto cleanup;
|
|
1725
|
-
|
|
1726
|
-
error = git_reference_name_to_id(&old, remote->repo, refname.ptr);
|
|
1727
|
-
if (error < 0 && error != GIT_ENOTFOUND)
|
|
1728
|
-
goto cleanup;
|
|
1729
|
-
|
|
1730
|
-
if (!git_oid_cmp(&old, &head->oid))
|
|
1731
|
-
continue;
|
|
1732
|
-
|
|
1733
|
-
/* If we did find a current reference, make sure we haven't lost a race */
|
|
1734
|
-
if (error)
|
|
1735
|
-
error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, true, msg);
|
|
1736
|
-
else
|
|
1737
|
-
error = git_reference_create_matching(&ref, remote->repo, refname.ptr, &head->oid, true, &old, msg);
|
|
1738
|
-
git_reference_free(ref);
|
|
1739
|
-
if (error < 0)
|
|
1740
|
-
goto cleanup;
|
|
1741
|
-
|
|
1742
|
-
if (callbacks && callbacks->update_tips != NULL) {
|
|
1743
|
-
if (callbacks->update_tips(refname.ptr, &old, &head->oid, callbacks->payload) < 0)
|
|
1744
|
-
goto cleanup;
|
|
1745
|
-
}
|
|
1746
2013
|
}
|
|
1747
2014
|
|
|
1748
|
-
if (error
|
|
1749
|
-
|
|
2015
|
+
if (error != GIT_ITEROVER)
|
|
2016
|
+
goto cleanup;
|
|
2017
|
+
|
|
2018
|
+
error = 0;
|
|
1750
2019
|
|
|
1751
2020
|
cleanup:
|
|
1752
|
-
|
|
2021
|
+
git_str_dispose(&refname);
|
|
1753
2022
|
return error;
|
|
1754
2023
|
}
|
|
1755
2024
|
|
|
1756
2025
|
static int truncate_fetch_head(const char *gitdir)
|
|
1757
2026
|
{
|
|
1758
|
-
|
|
2027
|
+
git_str path = GIT_STR_INIT;
|
|
1759
2028
|
int error;
|
|
1760
2029
|
|
|
1761
|
-
if ((error =
|
|
2030
|
+
if ((error = git_str_joinpath(&path, gitdir, GIT_FETCH_HEAD_FILE)) < 0)
|
|
1762
2031
|
return error;
|
|
1763
2032
|
|
|
1764
2033
|
error = git_futils_truncate(path.ptr, GIT_REFS_FILE_MODE);
|
|
1765
|
-
|
|
2034
|
+
git_str_dispose(&path);
|
|
1766
2035
|
|
|
1767
2036
|
return error;
|
|
1768
2037
|
}
|
|
@@ -1813,7 +2082,7 @@ int git_remote_update_tips(
|
|
|
1813
2082
|
goto out;
|
|
1814
2083
|
}
|
|
1815
2084
|
|
|
1816
|
-
/* Only try to do opportunistic updates if the
|
|
2085
|
+
/* Only try to do opportunistic updates if the refspec lists differ. */
|
|
1817
2086
|
if (remote->passed_refspecs)
|
|
1818
2087
|
error = opportunistic_updates(remote, callbacks, &refs, reflog_message);
|
|
1819
2088
|
|
|
@@ -1854,6 +2123,17 @@ int git_remote_disconnect(git_remote *remote)
|
|
|
1854
2123
|
return 0;
|
|
1855
2124
|
}
|
|
1856
2125
|
|
|
2126
|
+
static void free_heads(git_vector *heads)
|
|
2127
|
+
{
|
|
2128
|
+
git_remote_head *head;
|
|
2129
|
+
size_t i;
|
|
2130
|
+
|
|
2131
|
+
git_vector_foreach(heads, i, head) {
|
|
2132
|
+
git__free(head->name);
|
|
2133
|
+
git__free(head);
|
|
2134
|
+
}
|
|
2135
|
+
}
|
|
2136
|
+
|
|
1857
2137
|
void git_remote_free(git_remote *remote)
|
|
1858
2138
|
{
|
|
1859
2139
|
if (remote == NULL)
|
|
@@ -1877,6 +2157,9 @@ void git_remote_free(git_remote *remote)
|
|
|
1877
2157
|
free_refspecs(&remote->passive_refspecs);
|
|
1878
2158
|
git_vector_free(&remote->passive_refspecs);
|
|
1879
2159
|
|
|
2160
|
+
free_heads(&remote->local_heads);
|
|
2161
|
+
git_vector_free(&remote->local_heads);
|
|
2162
|
+
|
|
1880
2163
|
git_push_free(remote->push);
|
|
1881
2164
|
git__free(remote->url);
|
|
1882
2165
|
git__free(remote->pushurl);
|
|
@@ -1943,7 +2226,7 @@ git_remote_autotag_option_t git_remote_autotag(const git_remote *remote)
|
|
|
1943
2226
|
|
|
1944
2227
|
int git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_autotag_option_t value)
|
|
1945
2228
|
{
|
|
1946
|
-
|
|
2229
|
+
git_str var = GIT_STR_INIT;
|
|
1947
2230
|
git_config *config;
|
|
1948
2231
|
int error;
|
|
1949
2232
|
|
|
@@ -1955,7 +2238,7 @@ int git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_
|
|
|
1955
2238
|
if ((error = git_repository_config__weakptr(&config, repo)) < 0)
|
|
1956
2239
|
return error;
|
|
1957
2240
|
|
|
1958
|
-
if ((error =
|
|
2241
|
+
if ((error = git_str_printf(&var, CONFIG_TAGOPT_FMT, remote)))
|
|
1959
2242
|
return error;
|
|
1960
2243
|
|
|
1961
2244
|
switch (value) {
|
|
@@ -1975,7 +2258,7 @@ int git_remote_set_autotag(git_repository *repo, const char *remote, git_remote_
|
|
|
1975
2258
|
error = -1;
|
|
1976
2259
|
}
|
|
1977
2260
|
|
|
1978
|
-
|
|
2261
|
+
git_str_dispose(&var);
|
|
1979
2262
|
return error;
|
|
1980
2263
|
}
|
|
1981
2264
|
|
|
@@ -1989,25 +2272,25 @@ static int rename_remote_config_section(
|
|
|
1989
2272
|
const char *old_name,
|
|
1990
2273
|
const char *new_name)
|
|
1991
2274
|
{
|
|
1992
|
-
|
|
1993
|
-
new_section_name =
|
|
2275
|
+
git_str old_section_name = GIT_STR_INIT,
|
|
2276
|
+
new_section_name = GIT_STR_INIT;
|
|
1994
2277
|
int error = -1;
|
|
1995
2278
|
|
|
1996
|
-
if (
|
|
2279
|
+
if (git_str_printf(&old_section_name, "remote.%s", old_name) < 0)
|
|
1997
2280
|
goto cleanup;
|
|
1998
2281
|
|
|
1999
2282
|
if (new_name &&
|
|
2000
|
-
(
|
|
2283
|
+
(git_str_printf(&new_section_name, "remote.%s", new_name) < 0))
|
|
2001
2284
|
goto cleanup;
|
|
2002
2285
|
|
|
2003
2286
|
error = git_config_rename_section(
|
|
2004
2287
|
repo,
|
|
2005
|
-
|
|
2006
|
-
new_name ?
|
|
2288
|
+
git_str_cstr(&old_section_name),
|
|
2289
|
+
new_name ? git_str_cstr(&new_section_name) : NULL);
|
|
2007
2290
|
|
|
2008
2291
|
cleanup:
|
|
2009
|
-
|
|
2010
|
-
|
|
2292
|
+
git_str_dispose(&old_section_name);
|
|
2293
|
+
git_str_dispose(&new_section_name);
|
|
2011
2294
|
|
|
2012
2295
|
return error;
|
|
2013
2296
|
}
|
|
@@ -2056,27 +2339,27 @@ static int rename_one_remote_reference(
|
|
|
2056
2339
|
{
|
|
2057
2340
|
int error;
|
|
2058
2341
|
git_reference *ref = NULL, *dummy = NULL;
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2342
|
+
git_str namespace = GIT_STR_INIT, old_namespace = GIT_STR_INIT;
|
|
2343
|
+
git_str new_name = GIT_STR_INIT;
|
|
2344
|
+
git_str log_message = GIT_STR_INIT;
|
|
2062
2345
|
size_t pfx_len;
|
|
2063
2346
|
const char *target;
|
|
2064
2347
|
|
|
2065
|
-
if ((error =
|
|
2348
|
+
if ((error = git_str_printf(&namespace, GIT_REFS_REMOTES_DIR "%s/", new_remote_name)) < 0)
|
|
2066
2349
|
return error;
|
|
2067
2350
|
|
|
2068
2351
|
pfx_len = strlen(GIT_REFS_REMOTES_DIR) + strlen(old_remote_name) + 1;
|
|
2069
|
-
|
|
2070
|
-
if ((error =
|
|
2352
|
+
git_str_puts(&new_name, namespace.ptr);
|
|
2353
|
+
if ((error = git_str_puts(&new_name, git_reference_name(reference_in) + pfx_len)) < 0)
|
|
2071
2354
|
goto cleanup;
|
|
2072
2355
|
|
|
2073
|
-
if ((error =
|
|
2356
|
+
if ((error = git_str_printf(&log_message,
|
|
2074
2357
|
"renamed remote %s to %s",
|
|
2075
2358
|
old_remote_name, new_remote_name)) < 0)
|
|
2076
2359
|
goto cleanup;
|
|
2077
2360
|
|
|
2078
|
-
if ((error = git_reference_rename(&ref, reference_in,
|
|
2079
|
-
|
|
2361
|
+
if ((error = git_reference_rename(&ref, reference_in, git_str_cstr(&new_name), 1,
|
|
2362
|
+
git_str_cstr(&log_message))) < 0)
|
|
2080
2363
|
goto cleanup;
|
|
2081
2364
|
|
|
2082
2365
|
if (git_reference_type(ref) != GIT_REFERENCE_SYMBOLIC)
|
|
@@ -2084,29 +2367,29 @@ static int rename_one_remote_reference(
|
|
|
2084
2367
|
|
|
2085
2368
|
/* Handle refs like origin/HEAD -> origin/master */
|
|
2086
2369
|
target = git_reference_symbolic_target(ref);
|
|
2087
|
-
if ((error =
|
|
2370
|
+
if ((error = git_str_printf(&old_namespace, GIT_REFS_REMOTES_DIR "%s/", old_remote_name)) < 0)
|
|
2088
2371
|
goto cleanup;
|
|
2089
2372
|
|
|
2090
2373
|
if (git__prefixcmp(target, old_namespace.ptr))
|
|
2091
2374
|
goto cleanup;
|
|
2092
2375
|
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
if ((error =
|
|
2376
|
+
git_str_clear(&new_name);
|
|
2377
|
+
git_str_puts(&new_name, namespace.ptr);
|
|
2378
|
+
if ((error = git_str_puts(&new_name, target + pfx_len)) < 0)
|
|
2096
2379
|
goto cleanup;
|
|
2097
2380
|
|
|
2098
|
-
error = git_reference_symbolic_set_target(&dummy, ref,
|
|
2099
|
-
|
|
2381
|
+
error = git_reference_symbolic_set_target(&dummy, ref, git_str_cstr(&new_name),
|
|
2382
|
+
git_str_cstr(&log_message));
|
|
2100
2383
|
|
|
2101
2384
|
git_reference_free(dummy);
|
|
2102
2385
|
|
|
2103
2386
|
cleanup:
|
|
2104
2387
|
git_reference_free(reference_in);
|
|
2105
2388
|
git_reference_free(ref);
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2389
|
+
git_str_dispose(&namespace);
|
|
2390
|
+
git_str_dispose(&old_namespace);
|
|
2391
|
+
git_str_dispose(&new_name);
|
|
2392
|
+
git_str_dispose(&log_message);
|
|
2110
2393
|
return error;
|
|
2111
2394
|
}
|
|
2112
2395
|
|
|
@@ -2116,15 +2399,15 @@ static int rename_remote_references(
|
|
|
2116
2399
|
const char *new_name)
|
|
2117
2400
|
{
|
|
2118
2401
|
int error;
|
|
2119
|
-
|
|
2402
|
+
git_str buf = GIT_STR_INIT;
|
|
2120
2403
|
git_reference *ref;
|
|
2121
2404
|
git_reference_iterator *iter;
|
|
2122
2405
|
|
|
2123
|
-
if ((error =
|
|
2406
|
+
if ((error = git_str_printf(&buf, GIT_REFS_REMOTES_DIR "%s/*", old_name)) < 0)
|
|
2124
2407
|
return error;
|
|
2125
2408
|
|
|
2126
|
-
error = git_reference_iterator_glob_new(&iter, repo,
|
|
2127
|
-
|
|
2409
|
+
error = git_reference_iterator_glob_new(&iter, repo, git_str_cstr(&buf));
|
|
2410
|
+
git_str_dispose(&buf);
|
|
2128
2411
|
|
|
2129
2412
|
if (error < 0)
|
|
2130
2413
|
return error;
|
|
@@ -2142,7 +2425,7 @@ static int rename_remote_references(
|
|
|
2142
2425
|
static int rename_fetch_refspecs(git_vector *problems, git_remote *remote, const char *new_name)
|
|
2143
2426
|
{
|
|
2144
2427
|
git_config *config;
|
|
2145
|
-
|
|
2428
|
+
git_str base = GIT_STR_INIT, var = GIT_STR_INIT, val = GIT_STR_INIT;
|
|
2146
2429
|
const git_refspec *spec;
|
|
2147
2430
|
size_t i;
|
|
2148
2431
|
int error = 0;
|
|
@@ -2161,7 +2444,7 @@ static int rename_fetch_refspecs(git_vector *problems, git_remote *remote, const
|
|
|
2161
2444
|
continue;
|
|
2162
2445
|
|
|
2163
2446
|
/* Does the dst part of the refspec follow the expected format? */
|
|
2164
|
-
if (strcmp(
|
|
2447
|
+
if (strcmp(git_str_cstr(&base), spec->string)) {
|
|
2165
2448
|
char *dup;
|
|
2166
2449
|
|
|
2167
2450
|
dup = git__strdup(spec->string);
|
|
@@ -2175,24 +2458,24 @@ static int rename_fetch_refspecs(git_vector *problems, git_remote *remote, const
|
|
|
2175
2458
|
|
|
2176
2459
|
/* If we do want to move it to the new section */
|
|
2177
2460
|
|
|
2178
|
-
|
|
2179
|
-
|
|
2461
|
+
git_str_clear(&val);
|
|
2462
|
+
git_str_clear(&var);
|
|
2180
2463
|
|
|
2181
2464
|
if (default_fetchspec_for_name(&val, new_name) < 0 ||
|
|
2182
|
-
|
|
2465
|
+
git_str_printf(&var, "remote.%s.fetch", new_name) < 0)
|
|
2183
2466
|
{
|
|
2184
2467
|
error = -1;
|
|
2185
2468
|
break;
|
|
2186
2469
|
}
|
|
2187
2470
|
|
|
2188
2471
|
if ((error = git_config_set_string(
|
|
2189
|
-
config,
|
|
2472
|
+
config, git_str_cstr(&var), git_str_cstr(&val))) < 0)
|
|
2190
2473
|
break;
|
|
2191
2474
|
}
|
|
2192
2475
|
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2476
|
+
git_str_dispose(&base);
|
|
2477
|
+
git_str_dispose(&var);
|
|
2478
|
+
git_str_dispose(&val);
|
|
2196
2479
|
|
|
2197
2480
|
if (error < 0) {
|
|
2198
2481
|
char *str;
|
|
@@ -2247,7 +2530,7 @@ cleanup:
|
|
|
2247
2530
|
|
|
2248
2531
|
int git_remote_name_is_valid(int *valid, const char *remote_name)
|
|
2249
2532
|
{
|
|
2250
|
-
|
|
2533
|
+
git_str buf = GIT_STR_INIT;
|
|
2251
2534
|
git_refspec refspec = {0};
|
|
2252
2535
|
int error;
|
|
2253
2536
|
|
|
@@ -2258,10 +2541,10 @@ int git_remote_name_is_valid(int *valid, const char *remote_name)
|
|
|
2258
2541
|
if (!remote_name || *remote_name == '\0')
|
|
2259
2542
|
return 0;
|
|
2260
2543
|
|
|
2261
|
-
if ((error =
|
|
2544
|
+
if ((error = git_str_printf(&buf, "refs/heads/test:refs/remotes/%s/test", remote_name)) < 0)
|
|
2262
2545
|
goto done;
|
|
2263
2546
|
|
|
2264
|
-
error = git_refspec__parse(&refspec,
|
|
2547
|
+
error = git_refspec__parse(&refspec, git_str_cstr(&buf), true);
|
|
2265
2548
|
|
|
2266
2549
|
if (!error)
|
|
2267
2550
|
*valid = 1;
|
|
@@ -2269,7 +2552,7 @@ int git_remote_name_is_valid(int *valid, const char *remote_name)
|
|
|
2269
2552
|
error = 0;
|
|
2270
2553
|
|
|
2271
2554
|
done:
|
|
2272
|
-
|
|
2555
|
+
git_str_dispose(&buf);
|
|
2273
2556
|
git_refspec__dispose(&refspec);
|
|
2274
2557
|
|
|
2275
2558
|
return error;
|
|
@@ -2401,7 +2684,7 @@ static int remove_branch_config_related_entries(
|
|
|
2401
2684
|
git_config *config;
|
|
2402
2685
|
git_config_entry *entry;
|
|
2403
2686
|
git_config_iterator *iter;
|
|
2404
|
-
|
|
2687
|
+
git_str buf = GIT_STR_INIT;
|
|
2405
2688
|
|
|
2406
2689
|
if ((error = git_repository_config__weakptr(&config, repo)) < 0)
|
|
2407
2690
|
return error;
|
|
@@ -2422,21 +2705,21 @@ static int remove_branch_config_related_entries(
|
|
|
2422
2705
|
break;
|
|
2423
2706
|
}
|
|
2424
2707
|
|
|
2425
|
-
|
|
2426
|
-
if ((error =
|
|
2708
|
+
git_str_clear(&buf);
|
|
2709
|
+
if ((error = git_str_printf(&buf, "branch.%.*s.merge", (int)branch_len, branch)) < 0)
|
|
2427
2710
|
break;
|
|
2428
2711
|
|
|
2429
|
-
if ((error = git_config_delete_entry(config,
|
|
2712
|
+
if ((error = git_config_delete_entry(config, git_str_cstr(&buf))) < 0) {
|
|
2430
2713
|
if (error != GIT_ENOTFOUND)
|
|
2431
2714
|
break;
|
|
2432
2715
|
git_error_clear();
|
|
2433
2716
|
}
|
|
2434
2717
|
|
|
2435
|
-
|
|
2436
|
-
if ((error =
|
|
2718
|
+
git_str_clear(&buf);
|
|
2719
|
+
if ((error = git_str_printf(&buf, "branch.%.*s.remote", (int)branch_len, branch)) < 0)
|
|
2437
2720
|
break;
|
|
2438
2721
|
|
|
2439
|
-
if ((error = git_config_delete_entry(config,
|
|
2722
|
+
if ((error = git_config_delete_entry(config, git_str_cstr(&buf))) < 0) {
|
|
2440
2723
|
if (error != GIT_ENOTFOUND)
|
|
2441
2724
|
break;
|
|
2442
2725
|
git_error_clear();
|
|
@@ -2446,7 +2729,7 @@ static int remove_branch_config_related_entries(
|
|
|
2446
2729
|
if (error == GIT_ITEROVER)
|
|
2447
2730
|
error = 0;
|
|
2448
2731
|
|
|
2449
|
-
|
|
2732
|
+
git_str_dispose(&buf);
|
|
2450
2733
|
git_config_iterator_free(iter);
|
|
2451
2734
|
return error;
|
|
2452
2735
|
}
|
|
@@ -2540,12 +2823,17 @@ int git_remote_delete(git_repository *repo, const char *name)
|
|
|
2540
2823
|
}
|
|
2541
2824
|
|
|
2542
2825
|
int git_remote_default_branch(git_buf *out, git_remote *remote)
|
|
2826
|
+
{
|
|
2827
|
+
GIT_BUF_WRAP_PRIVATE(out, git_remote__default_branch, remote);
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
int git_remote__default_branch(git_str *out, git_remote *remote)
|
|
2543
2831
|
{
|
|
2544
2832
|
const git_remote_head **heads;
|
|
2545
2833
|
const git_remote_head *guess = NULL;
|
|
2546
2834
|
const git_oid *head_id;
|
|
2547
2835
|
size_t heads_len, i;
|
|
2548
|
-
|
|
2836
|
+
git_str local_default = GIT_STR_INIT;
|
|
2549
2837
|
int error;
|
|
2550
2838
|
|
|
2551
2839
|
GIT_ASSERT_ARG(out);
|
|
@@ -2558,12 +2846,9 @@ int git_remote_default_branch(git_buf *out, git_remote *remote)
|
|
|
2558
2846
|
goto done;
|
|
2559
2847
|
}
|
|
2560
2848
|
|
|
2561
|
-
if ((error = git_buf_sanitize(out)) < 0)
|
|
2562
|
-
return error;
|
|
2563
|
-
|
|
2564
2849
|
/* the first one must be HEAD so if that has the symref info, we're done */
|
|
2565
2850
|
if (heads[0]->symref_target) {
|
|
2566
|
-
error =
|
|
2851
|
+
error = git_str_puts(out, heads[0]->symref_target);
|
|
2567
2852
|
goto done;
|
|
2568
2853
|
}
|
|
2569
2854
|
|
|
@@ -2601,21 +2886,33 @@ int git_remote_default_branch(git_buf *out, git_remote *remote)
|
|
|
2601
2886
|
goto done;
|
|
2602
2887
|
}
|
|
2603
2888
|
|
|
2604
|
-
error =
|
|
2889
|
+
error = git_str_puts(out, guess->name);
|
|
2605
2890
|
|
|
2606
2891
|
done:
|
|
2607
|
-
|
|
2892
|
+
git_str_dispose(&local_default);
|
|
2608
2893
|
return error;
|
|
2609
2894
|
}
|
|
2610
2895
|
|
|
2611
|
-
int
|
|
2896
|
+
GIT_INLINE(int) connect_opts_from_push_opts(
|
|
2897
|
+
git_remote_connect_options *out,
|
|
2898
|
+
git_remote *remote,
|
|
2899
|
+
const git_push_options *push_opts)
|
|
2612
2900
|
{
|
|
2613
|
-
|
|
2614
|
-
|
|
2901
|
+
git_remote_connect_options tmp = GIT_REMOTE_CONNECT_OPTIONS_INIT;
|
|
2902
|
+
copy_opts(&tmp, push_opts);
|
|
2903
|
+
return git_remote_connect_options_normalize(out, remote->repo, &tmp);
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2906
|
+
int git_remote_upload(
|
|
2907
|
+
git_remote *remote,
|
|
2908
|
+
const git_strarray *refspecs,
|
|
2909
|
+
const git_push_options *opts)
|
|
2910
|
+
{
|
|
2911
|
+
git_remote_connect_options connect_opts = GIT_REMOTE_CONNECT_OPTIONS_INIT;
|
|
2615
2912
|
git_push *push;
|
|
2616
2913
|
git_refspec *spec;
|
|
2617
|
-
|
|
2618
|
-
|
|
2914
|
+
size_t i;
|
|
2915
|
+
int error;
|
|
2619
2916
|
|
|
2620
2917
|
GIT_ASSERT_ARG(remote);
|
|
2621
2918
|
|
|
@@ -2624,14 +2921,10 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi
|
|
|
2624
2921
|
return -1;
|
|
2625
2922
|
}
|
|
2626
2923
|
|
|
2627
|
-
if (opts)
|
|
2628
|
-
|
|
2629
|
-
conn.custom_headers = &opts->custom_headers;
|
|
2630
|
-
conn.proxy = &opts->proxy_opts;
|
|
2631
|
-
}
|
|
2924
|
+
if ((error = connect_opts_from_push_opts(&connect_opts, remote, opts)) < 0)
|
|
2925
|
+
goto cleanup;
|
|
2632
2926
|
|
|
2633
|
-
if (
|
|
2634
|
-
(error = git_remote__connect(remote, GIT_DIRECTION_PUSH, cbs, &conn)) < 0)
|
|
2927
|
+
if ((error = connect_or_reset_options(remote, GIT_DIRECTION_PUSH, &connect_opts)) < 0)
|
|
2635
2928
|
goto cleanup;
|
|
2636
2929
|
|
|
2637
2930
|
free_refspecs(&remote->active_refspecs);
|
|
@@ -2643,14 +2936,11 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi
|
|
|
2643
2936
|
remote->push = NULL;
|
|
2644
2937
|
}
|
|
2645
2938
|
|
|
2646
|
-
if ((error = git_push_new(&remote->push, remote)) < 0)
|
|
2647
|
-
|
|
2939
|
+
if ((error = git_push_new(&remote->push, remote, opts)) < 0)
|
|
2940
|
+
goto cleanup;
|
|
2648
2941
|
|
|
2649
2942
|
push = remote->push;
|
|
2650
2943
|
|
|
2651
|
-
if (opts && (error = git_push_set_options(push, opts)) < 0)
|
|
2652
|
-
goto cleanup;
|
|
2653
|
-
|
|
2654
2944
|
if (refspecs && refspecs->count > 0) {
|
|
2655
2945
|
for (i = 0; i < refspecs->count; i++) {
|
|
2656
2946
|
if ((error = git_push_add_refspec(push, refspecs->strings[i])) < 0)
|
|
@@ -2665,23 +2955,25 @@ int git_remote_upload(git_remote *remote, const git_strarray *refspecs, const gi
|
|
|
2665
2955
|
}
|
|
2666
2956
|
}
|
|
2667
2957
|
|
|
2668
|
-
if ((error = git_push_finish(push
|
|
2958
|
+
if ((error = git_push_finish(push)) < 0)
|
|
2669
2959
|
goto cleanup;
|
|
2670
2960
|
|
|
2671
|
-
if (
|
|
2672
|
-
(error = git_push_status_foreach(push,
|
|
2961
|
+
if (connect_opts.callbacks.push_update_reference &&
|
|
2962
|
+
(error = git_push_status_foreach(push, connect_opts.callbacks.push_update_reference, connect_opts.callbacks.payload)) < 0)
|
|
2673
2963
|
goto cleanup;
|
|
2674
2964
|
|
|
2675
2965
|
cleanup:
|
|
2966
|
+
git_remote_connect_options_dispose(&connect_opts);
|
|
2676
2967
|
return error;
|
|
2677
2968
|
}
|
|
2678
2969
|
|
|
2679
|
-
int git_remote_push(
|
|
2970
|
+
int git_remote_push(
|
|
2971
|
+
git_remote *remote,
|
|
2972
|
+
const git_strarray *refspecs,
|
|
2973
|
+
const git_push_options *opts)
|
|
2680
2974
|
{
|
|
2975
|
+
git_remote_connect_options connect_opts = GIT_REMOTE_CONNECT_OPTIONS_INIT;
|
|
2681
2976
|
int error;
|
|
2682
|
-
const git_remote_callbacks *cbs = NULL;
|
|
2683
|
-
const git_strarray *custom_headers = NULL;
|
|
2684
|
-
const git_proxy_options *proxy = NULL;
|
|
2685
2977
|
|
|
2686
2978
|
GIT_ASSERT_ARG(remote);
|
|
2687
2979
|
|
|
@@ -2690,23 +2982,17 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_
|
|
|
2690
2982
|
return -1;
|
|
2691
2983
|
}
|
|
2692
2984
|
|
|
2693
|
-
if (opts)
|
|
2694
|
-
|
|
2695
|
-
cbs = &opts->callbacks;
|
|
2696
|
-
custom_headers = &opts->custom_headers;
|
|
2697
|
-
GIT_ERROR_CHECK_VERSION(&opts->proxy_opts, GIT_PROXY_OPTIONS_VERSION, "git_proxy_options");
|
|
2698
|
-
proxy = &opts->proxy_opts;
|
|
2699
|
-
}
|
|
2700
|
-
|
|
2701
|
-
if ((error = git_remote_connect(remote, GIT_DIRECTION_PUSH, cbs, proxy, custom_headers)) < 0)
|
|
2702
|
-
return error;
|
|
2985
|
+
if (connect_opts_from_push_opts(&connect_opts, remote, opts) < 0)
|
|
2986
|
+
return -1;
|
|
2703
2987
|
|
|
2704
2988
|
if ((error = git_remote_upload(remote, refspecs, opts)) < 0)
|
|
2705
|
-
|
|
2989
|
+
goto done;
|
|
2706
2990
|
|
|
2707
|
-
error = git_remote_update_tips(remote,
|
|
2991
|
+
error = git_remote_update_tips(remote, &connect_opts.callbacks, 0, 0, NULL);
|
|
2708
2992
|
|
|
2993
|
+
done:
|
|
2709
2994
|
git_remote_disconnect(remote);
|
|
2995
|
+
git_remote_connect_options_dispose(&connect_opts);
|
|
2710
2996
|
return error;
|
|
2711
2997
|
}
|
|
2712
2998
|
|
|
@@ -2714,19 +3000,20 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_
|
|
|
2714
3000
|
#define SUFFIX_FETCH "insteadof"
|
|
2715
3001
|
#define SUFFIX_PUSH "pushinsteadof"
|
|
2716
3002
|
|
|
2717
|
-
|
|
3003
|
+
static int apply_insteadof(char **out, git_config *config, const char *url, int direction, bool use_default_if_empty)
|
|
2718
3004
|
{
|
|
2719
3005
|
size_t match_length, prefix_length, suffix_length;
|
|
2720
3006
|
char *replacement = NULL;
|
|
2721
3007
|
const char *regexp;
|
|
2722
3008
|
|
|
2723
|
-
|
|
3009
|
+
git_str result = GIT_STR_INIT;
|
|
2724
3010
|
git_config_entry *entry;
|
|
2725
3011
|
git_config_iterator *iter;
|
|
2726
3012
|
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
3013
|
+
GIT_ASSERT_ARG(out);
|
|
3014
|
+
GIT_ASSERT_ARG(config);
|
|
3015
|
+
GIT_ASSERT_ARG(url);
|
|
3016
|
+
GIT_ASSERT_ARG(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH);
|
|
2730
3017
|
|
|
2731
3018
|
/* Add 1 to prefix/suffix length due to the additional escaped dot */
|
|
2732
3019
|
prefix_length = strlen(PREFIX) + 1;
|
|
@@ -2739,7 +3026,7 @@ char *apply_insteadof(git_config *config, const char *url, int direction)
|
|
|
2739
3026
|
}
|
|
2740
3027
|
|
|
2741
3028
|
if (git_config_iterator_glob_new(&iter, config, regexp) < 0)
|
|
2742
|
-
return
|
|
3029
|
+
return -1;
|
|
2743
3030
|
|
|
2744
3031
|
match_length = 0;
|
|
2745
3032
|
while (git_config_next(&entry, iter) == 0) {
|
|
@@ -2748,6 +3035,7 @@ char *apply_insteadof(git_config *config, const char *url, int direction)
|
|
|
2748
3035
|
/* Check if entry value is a prefix of URL */
|
|
2749
3036
|
if (git__prefixcmp(url, entry->value))
|
|
2750
3037
|
continue;
|
|
3038
|
+
|
|
2751
3039
|
/* Check if entry value is longer than previous
|
|
2752
3040
|
* prefixes */
|
|
2753
3041
|
if ((n = strlen(entry->value)) <= match_length)
|
|
@@ -2765,14 +3053,20 @@ char *apply_insteadof(git_config *config, const char *url, int direction)
|
|
|
2765
3053
|
|
|
2766
3054
|
git_config_iterator_free(iter);
|
|
2767
3055
|
|
|
2768
|
-
if (match_length == 0)
|
|
2769
|
-
|
|
3056
|
+
if (match_length == 0 && use_default_if_empty) {
|
|
3057
|
+
*out = git__strdup(url);
|
|
3058
|
+
return *out ? 0 : -1;
|
|
3059
|
+
} else if (match_length == 0) {
|
|
3060
|
+
*out = NULL;
|
|
3061
|
+
return 0;
|
|
3062
|
+
}
|
|
2770
3063
|
|
|
2771
|
-
|
|
3064
|
+
git_str_printf(&result, "%s%s", replacement, url + match_length);
|
|
2772
3065
|
|
|
2773
3066
|
git__free(replacement);
|
|
2774
3067
|
|
|
2775
|
-
|
|
3068
|
+
*out = git_str_detach(&result);
|
|
3069
|
+
return 0;
|
|
2776
3070
|
}
|
|
2777
3071
|
|
|
2778
3072
|
/* Deprecated functions */
|