rugged 0.17.0.b6 → 0.17.0.b7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +3 -3
- data/Rakefile +3 -1
- data/ext/rugged/rugged.c +30 -0
- data/ext/rugged/rugged.h +9 -0
- data/ext/rugged/rugged_branch.c +306 -0
- data/ext/rugged/rugged_config.c +16 -13
- data/ext/rugged/rugged_index.c +25 -0
- data/ext/rugged/rugged_object.c +6 -2
- data/ext/rugged/rugged_reference.c +11 -18
- data/ext/rugged/rugged_revwalk.c +1 -1
- data/lib/rugged.rb +1 -0
- data/lib/rugged/branch.rb +28 -0
- data/lib/rugged/commit.rb +5 -5
- data/lib/rugged/repository.rb +32 -7
- data/lib/rugged/tag.rb +5 -1
- data/lib/rugged/version.rb +1 -1
- data/test/branch_test.rb +227 -0
- data/test/config_test.rb +1 -1
- data/test/fixtures/testrepo.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
- data/test/fixtures/testrepo.git/objects/a3/e05719b428a2d0ed7a55c4ce53dcc5768c6d5e +0 -0
- data/test/index_test.rb +31 -0
- data/test/index_test.rb~ +218 -0
- data/test/lib_test.rb +22 -0
- data/test/reference_test.rb +5 -3
- data/vendor/libgit2/Makefile.embed +1 -1
- data/vendor/libgit2/include/git2.h +1 -0
- data/vendor/libgit2/include/git2/branch.h +17 -13
- data/vendor/libgit2/include/git2/checkout.h +83 -22
- data/vendor/libgit2/include/git2/clone.h +6 -3
- data/vendor/libgit2/include/git2/common.h +1 -8
- data/vendor/libgit2/include/git2/config.h +185 -26
- data/vendor/libgit2/include/git2/diff.h +229 -17
- data/vendor/libgit2/include/git2/errors.h +39 -1
- data/vendor/libgit2/include/git2/ignore.h +6 -3
- data/vendor/libgit2/include/git2/indexer.h +1 -0
- data/vendor/libgit2/include/git2/merge.h +1 -1
- data/vendor/libgit2/include/git2/object.h +7 -4
- data/vendor/libgit2/include/git2/odb.h +4 -2
- data/vendor/libgit2/include/git2/odb_backend.h +6 -0
- data/vendor/libgit2/include/git2/oid.h +2 -0
- data/vendor/libgit2/include/git2/pack.h +89 -0
- data/vendor/libgit2/include/git2/refs.h +88 -0
- data/vendor/libgit2/include/git2/refspec.h +0 -8
- data/vendor/libgit2/include/git2/remote.h +34 -1
- data/vendor/libgit2/include/git2/repository.h +238 -6
- data/vendor/libgit2/include/git2/reset.h +4 -1
- data/vendor/libgit2/include/git2/revwalk.h +1 -1
- data/vendor/libgit2/include/git2/status.h +19 -14
- data/vendor/libgit2/include/git2/strarray.h +54 -0
- data/vendor/libgit2/include/git2/submodule.h +451 -45
- data/vendor/libgit2/include/git2/tag.h +16 -0
- data/vendor/libgit2/include/git2/tree.h +2 -2
- data/vendor/libgit2/include/git2/types.h +4 -0
- data/vendor/libgit2/src/amiga/map.c +4 -7
- data/vendor/libgit2/src/attr.c +21 -13
- data/vendor/libgit2/src/attr.h +3 -1
- data/vendor/libgit2/src/attr_file.c +14 -14
- data/vendor/libgit2/src/attr_file.h +6 -5
- data/vendor/libgit2/src/blob.c +22 -12
- data/vendor/libgit2/src/branch.c +62 -66
- data/vendor/libgit2/src/buffer.c +63 -14
- data/vendor/libgit2/src/buffer.h +4 -0
- data/vendor/libgit2/src/cache.c +5 -4
- data/vendor/libgit2/src/checkout.c +381 -159
- data/vendor/libgit2/src/clone.c +221 -94
- data/vendor/libgit2/src/common.h +13 -3
- data/vendor/libgit2/src/compress.c +53 -0
- data/vendor/libgit2/src/compress.h +16 -0
- data/vendor/libgit2/src/config.c +380 -175
- data/vendor/libgit2/src/config.h +2 -5
- data/vendor/libgit2/src/config_file.c +63 -46
- data/vendor/libgit2/src/config_file.h +16 -4
- data/vendor/libgit2/src/crlf.c +4 -3
- data/vendor/libgit2/src/delta.c +491 -0
- data/vendor/libgit2/src/delta.h +112 -0
- data/vendor/libgit2/src/diff.c +310 -67
- data/vendor/libgit2/src/diff.h +10 -1
- data/vendor/libgit2/src/diff_output.c +1030 -337
- data/vendor/libgit2/src/diff_output.h +86 -0
- data/vendor/libgit2/src/errors.c +10 -1
- data/vendor/libgit2/src/fetch.c +108 -24
- data/vendor/libgit2/src/filebuf.c +8 -2
- data/vendor/libgit2/src/fileops.c +342 -177
- data/vendor/libgit2/src/fileops.h +84 -7
- data/vendor/libgit2/src/filter.c +0 -35
- data/vendor/libgit2/src/filter.h +0 -12
- data/vendor/libgit2/src/{compat/fnmatch.c → fnmatch.c} +16 -4
- data/vendor/libgit2/src/{compat/fnmatch.h → fnmatch.h} +4 -3
- data/vendor/libgit2/src/global.c +4 -0
- data/vendor/libgit2/src/ignore.c +122 -23
- data/vendor/libgit2/src/ignore.h +1 -0
- data/vendor/libgit2/src/index.c +56 -10
- data/vendor/libgit2/src/index.h +2 -0
- data/vendor/libgit2/src/indexer.c +8 -9
- data/vendor/libgit2/src/iterator.c +244 -31
- data/vendor/libgit2/src/iterator.h +30 -1
- data/vendor/libgit2/src/message.c +1 -1
- data/vendor/libgit2/src/netops.c +44 -4
- data/vendor/libgit2/src/object.c +80 -69
- data/vendor/libgit2/src/object.h +39 -0
- data/vendor/libgit2/src/odb.c +79 -15
- data/vendor/libgit2/src/odb.h +20 -5
- data/vendor/libgit2/src/odb_pack.c +65 -33
- data/vendor/libgit2/src/oid.c +0 -3
- data/vendor/libgit2/src/pack-objects.c +1315 -0
- data/vendor/libgit2/src/pack-objects.h +87 -0
- data/vendor/libgit2/src/pack.c +36 -12
- data/vendor/libgit2/src/pack.h +1 -0
- data/vendor/libgit2/src/path.c +42 -9
- data/vendor/libgit2/src/path.h +14 -0
- data/vendor/libgit2/src/pkt.c +52 -2
- data/vendor/libgit2/src/pkt.h +10 -0
- data/vendor/libgit2/src/pool.h +11 -0
- data/vendor/libgit2/src/posix.h +8 -0
- data/vendor/libgit2/src/protocol.c +24 -2
- data/vendor/libgit2/src/protocol.h +4 -0
- data/vendor/libgit2/src/reflog.c +1 -1
- data/vendor/libgit2/src/refs.c +292 -124
- data/vendor/libgit2/src/refs.h +4 -2
- data/vendor/libgit2/src/refspec.c +117 -19
- data/vendor/libgit2/src/refspec.h +19 -0
- data/vendor/libgit2/src/remote.c +152 -48
- data/vendor/libgit2/src/remote.h +4 -1
- data/vendor/libgit2/src/repo_template.h +58 -0
- data/vendor/libgit2/src/repository.c +594 -179
- data/vendor/libgit2/src/repository.h +23 -22
- data/vendor/libgit2/src/reset.c +71 -29
- data/vendor/libgit2/src/revparse.c +26 -17
- data/vendor/libgit2/src/revwalk.c +36 -19
- data/vendor/libgit2/src/sha1.h +7 -0
- data/vendor/libgit2/src/{sha1.c → sha1/sha1.c} +0 -0
- data/vendor/libgit2/src/signature.c +12 -10
- data/vendor/libgit2/src/status.c +52 -6
- data/vendor/libgit2/src/submodule.c +1363 -255
- data/vendor/libgit2/src/submodule.h +102 -0
- data/vendor/libgit2/src/tag.c +42 -26
- data/vendor/libgit2/src/thread-utils.h +7 -7
- data/vendor/libgit2/src/transport.h +15 -1
- data/vendor/libgit2/src/transports/git.c +1 -1
- data/vendor/libgit2/src/transports/http.c +197 -36
- data/vendor/libgit2/src/tree.c +3 -3
- data/vendor/libgit2/src/unix/map.c +2 -0
- data/vendor/libgit2/src/unix/posix.h +1 -8
- data/vendor/libgit2/src/util.c +6 -1
- data/vendor/libgit2/src/util.h +7 -0
- data/vendor/libgit2/src/vector.c +16 -0
- data/vendor/libgit2/src/vector.h +1 -0
- data/vendor/libgit2/src/win32/dir.c +8 -21
- data/vendor/libgit2/src/win32/findfile.c +149 -0
- data/vendor/libgit2/src/win32/findfile.h +23 -0
- data/vendor/libgit2/src/win32/posix.h +3 -7
- data/vendor/libgit2/src/win32/posix_w32.c +44 -102
- data/vendor/libgit2/src/win32/pthread.c +68 -0
- data/vendor/libgit2/src/win32/pthread.h +7 -0
- data/vendor/libgit2/src/win32/utf-conv.c +60 -71
- data/vendor/libgit2/src/win32/utf-conv.h +4 -3
- metadata +70 -71
- data/vendor/libgit2/include/git2/windows.h +0 -59
data/vendor/libgit2/src/refs.h
CHANGED
@@ -11,6 +11,7 @@
|
|
11
11
|
#include "git2/oid.h"
|
12
12
|
#include "git2/refs.h"
|
13
13
|
#include "strmap.h"
|
14
|
+
#include "buffer.h"
|
14
15
|
|
15
16
|
#define GIT_REFS_DIR "refs/"
|
16
17
|
#define GIT_REFS_HEADS_DIR GIT_REFS_DIR "heads/"
|
@@ -52,8 +53,9 @@ typedef struct {
|
|
52
53
|
|
53
54
|
void git_repository__refcache_free(git_refcache *refs);
|
54
55
|
|
55
|
-
int
|
56
|
-
int
|
56
|
+
int git_reference__normalize_name_lax(char *buffer_out, size_t out_size, const char *name);
|
57
|
+
int git_reference__normalize_name(git_buf *buf, const char *name, unsigned int flags);
|
58
|
+
int git_reference__is_valid_name(const char *refname, unsigned int flags);
|
57
59
|
int git_reference__update(git_repository *repo, const git_oid *oid, const char *ref_name);
|
58
60
|
|
59
61
|
/**
|
@@ -11,36 +11,124 @@
|
|
11
11
|
#include "refspec.h"
|
12
12
|
#include "util.h"
|
13
13
|
#include "posix.h"
|
14
|
+
#include "refs.h"
|
14
15
|
|
15
|
-
int
|
16
|
+
int git_refspec__parse(git_refspec *refspec, const char *input, bool is_fetch)
|
16
17
|
{
|
17
|
-
|
18
|
+
// Ported from https://github.com/git/git/blob/f06d47e7e0d9db709ee204ed13a8a7486149f494/remote.c#L518-636
|
19
|
+
|
20
|
+
size_t llen;
|
21
|
+
int is_glob = 0;
|
22
|
+
const char *lhs, *rhs;
|
23
|
+
int flags;
|
24
|
+
|
25
|
+
assert(refspec && input);
|
18
26
|
|
19
27
|
memset(refspec, 0x0, sizeof(git_refspec));
|
20
28
|
|
21
|
-
|
29
|
+
lhs = input;
|
30
|
+
if (*lhs == '+') {
|
22
31
|
refspec->force = 1;
|
23
|
-
|
32
|
+
lhs++;
|
24
33
|
}
|
25
34
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
35
|
+
rhs = strrchr(lhs, ':');
|
36
|
+
|
37
|
+
/*
|
38
|
+
* Before going on, special case ":" (or "+:") as a refspec
|
39
|
+
* for matching refs.
|
40
|
+
*/
|
41
|
+
if (!is_fetch && rhs == lhs && rhs[1] == '\0') {
|
42
|
+
refspec->matching = 1;
|
30
43
|
return 0;
|
31
44
|
}
|
32
45
|
|
33
|
-
|
34
|
-
|
46
|
+
if (rhs) {
|
47
|
+
size_t rlen = strlen(++rhs);
|
48
|
+
is_glob = (1 <= rlen && strchr(rhs, '*'));
|
49
|
+
refspec->dst = git__strndup(rhs, rlen);
|
50
|
+
}
|
35
51
|
|
36
|
-
|
37
|
-
if (
|
38
|
-
|
39
|
-
|
40
|
-
|
52
|
+
llen = (rhs ? (size_t)(rhs - lhs - 1) : strlen(lhs));
|
53
|
+
if (1 <= llen && memchr(lhs, '*', llen)) {
|
54
|
+
if ((rhs && !is_glob) || (!rhs && is_fetch))
|
55
|
+
goto invalid;
|
56
|
+
is_glob = 1;
|
57
|
+
} else if (rhs && is_glob)
|
58
|
+
goto invalid;
|
59
|
+
|
60
|
+
refspec->pattern = is_glob;
|
61
|
+
refspec->src = git__strndup(lhs, llen);
|
62
|
+
flags = GIT_REF_FORMAT_ALLOW_ONELEVEL
|
63
|
+
| (is_glob ? GIT_REF_FORMAT_REFSPEC_PATTERN : 0);
|
64
|
+
|
65
|
+
if (is_fetch) {
|
66
|
+
/*
|
67
|
+
* LHS
|
68
|
+
* - empty is allowed; it means HEAD.
|
69
|
+
* - otherwise it must be a valid looking ref.
|
70
|
+
*/
|
71
|
+
if (!*refspec->src)
|
72
|
+
; /* empty is ok */
|
73
|
+
else if (!git_reference__is_valid_name(refspec->src, flags))
|
74
|
+
goto invalid;
|
75
|
+
/*
|
76
|
+
* RHS
|
77
|
+
* - missing is ok, and is same as empty.
|
78
|
+
* - empty is ok; it means not to store.
|
79
|
+
* - otherwise it must be a valid looking ref.
|
80
|
+
*/
|
81
|
+
if (!refspec->dst)
|
82
|
+
; /* ok */
|
83
|
+
else if (!*refspec->dst)
|
84
|
+
; /* ok */
|
85
|
+
else if (!git_reference__is_valid_name(refspec->dst, flags))
|
86
|
+
goto invalid;
|
87
|
+
} else {
|
88
|
+
/*
|
89
|
+
* LHS
|
90
|
+
* - empty is allowed; it means delete.
|
91
|
+
* - when wildcarded, it must be a valid looking ref.
|
92
|
+
* - otherwise, it must be an extended SHA-1, but
|
93
|
+
* there is no existing way to validate this.
|
94
|
+
*/
|
95
|
+
if (!*refspec->src)
|
96
|
+
; /* empty is ok */
|
97
|
+
else if (is_glob) {
|
98
|
+
if (!git_reference__is_valid_name(refspec->src, flags))
|
99
|
+
goto invalid;
|
100
|
+
}
|
101
|
+
else {
|
102
|
+
; /* anything goes, for now */
|
103
|
+
}
|
104
|
+
/*
|
105
|
+
* RHS
|
106
|
+
* - missing is allowed, but LHS then must be a
|
107
|
+
* valid looking ref.
|
108
|
+
* - empty is not allowed.
|
109
|
+
* - otherwise it must be a valid looking ref.
|
110
|
+
*/
|
111
|
+
if (!refspec->dst) {
|
112
|
+
if (!git_reference__is_valid_name(refspec->src, flags))
|
113
|
+
goto invalid;
|
114
|
+
} else if (!*refspec->dst) {
|
115
|
+
goto invalid;
|
116
|
+
} else {
|
117
|
+
if (!git_reference__is_valid_name(refspec->dst, flags))
|
118
|
+
goto invalid;
|
119
|
+
}
|
41
120
|
}
|
42
121
|
|
43
122
|
return 0;
|
123
|
+
|
124
|
+
invalid:
|
125
|
+
return -1;
|
126
|
+
}
|
127
|
+
|
128
|
+
void git_refspec__free(git_refspec *refspec)
|
129
|
+
{
|
130
|
+
git__free(refspec->src);
|
131
|
+
git__free(refspec->dst);
|
44
132
|
}
|
45
133
|
|
46
134
|
const char *git_refspec_src(const git_refspec *refspec)
|
@@ -106,20 +194,20 @@ int git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, con
|
|
106
194
|
return 0;
|
107
195
|
}
|
108
196
|
|
109
|
-
int
|
197
|
+
static int refspec_transform(git_buf *out, const char *from, const char *to, const char *name)
|
110
198
|
{
|
111
|
-
if (git_buf_sets(out,
|
199
|
+
if (git_buf_sets(out, to) < 0)
|
112
200
|
return -1;
|
113
201
|
|
114
202
|
/*
|
115
|
-
* No '*' at the end means that it's mapped to one specific
|
203
|
+
* No '*' at the end means that it's mapped to one specific
|
116
204
|
* branch, so no actual transformation is needed.
|
117
205
|
*/
|
118
206
|
if (git_buf_len(out) > 0 && out->ptr[git_buf_len(out) - 1] != '*')
|
119
207
|
return 0;
|
120
208
|
|
121
209
|
git_buf_truncate(out, git_buf_len(out) - 1); /* remove trailing '*' */
|
122
|
-
git_buf_puts(out, name + strlen(
|
210
|
+
git_buf_puts(out, name + strlen(from) - 1);
|
123
211
|
|
124
212
|
if (git_buf_oom(out))
|
125
213
|
return -1;
|
@@ -127,3 +215,13 @@ int git_refspec_transform_r(git_buf *out, const git_refspec *spec, const char *n
|
|
127
215
|
return 0;
|
128
216
|
}
|
129
217
|
|
218
|
+
int git_refspec_transform_r(git_buf *out, const git_refspec *spec, const char *name)
|
219
|
+
{
|
220
|
+
return refspec_transform(out, spec->src, spec->dst, name);
|
221
|
+
}
|
222
|
+
|
223
|
+
int git_refspec_transform_l(git_buf *out, const git_refspec *spec, const char *name)
|
224
|
+
{
|
225
|
+
return refspec_transform(out, spec->dst, spec->src, name);
|
226
|
+
}
|
227
|
+
|
@@ -19,7 +19,15 @@ struct git_refspec {
|
|
19
19
|
matching :1;
|
20
20
|
};
|
21
21
|
|
22
|
+
#define GIT_REFSPEC_TAGS "refs/tags/*:refs/tags/*"
|
23
|
+
|
22
24
|
int git_refspec_parse(struct git_refspec *refspec, const char *str);
|
25
|
+
int git_refspec__parse(
|
26
|
+
struct git_refspec *refspec,
|
27
|
+
const char *str,
|
28
|
+
bool is_fetch);
|
29
|
+
|
30
|
+
void git_refspec__free(git_refspec *refspec);
|
23
31
|
|
24
32
|
/**
|
25
33
|
* Transform a reference to its target following the refspec's rules,
|
@@ -32,4 +40,15 @@ int git_refspec_parse(struct git_refspec *refspec, const char *str);
|
|
32
40
|
*/
|
33
41
|
int git_refspec_transform_r(git_buf *out, const git_refspec *spec, const char *name);
|
34
42
|
|
43
|
+
/**
|
44
|
+
* Transform a reference from its target following the refspec's rules,
|
45
|
+
* and writes the results into a git_buf.
|
46
|
+
*
|
47
|
+
* @param out where to store the source name
|
48
|
+
* @param spec the refspec
|
49
|
+
* @param name the name of the reference to transform
|
50
|
+
* @return 0 or error if buffer allocation fails
|
51
|
+
*/
|
52
|
+
int git_refspec_transform_l(git_buf *out, const git_refspec *spec, const char *name);
|
53
|
+
|
35
54
|
#endif
|
data/vendor/libgit2/src/remote.c
CHANGED
@@ -18,41 +18,42 @@
|
|
18
18
|
|
19
19
|
#include <regex.h>
|
20
20
|
|
21
|
-
static int
|
21
|
+
static int parse_remote_refspec(git_config *cfg, git_refspec *refspec, const char *var, bool is_fetch)
|
22
22
|
{
|
23
|
-
|
24
|
-
|
25
|
-
memset(refspec, 0x0, sizeof(git_refspec));
|
26
|
-
|
27
|
-
if (*str == '+') {
|
28
|
-
refspec->force = 1;
|
29
|
-
str++;
|
30
|
-
}
|
31
|
-
|
32
|
-
delim = strchr(str, ':');
|
33
|
-
if (delim == NULL) {
|
34
|
-
giterr_set(GITERR_NET, "Invalid refspec, missing ':'");
|
35
|
-
return -1;
|
36
|
-
}
|
37
|
-
|
38
|
-
refspec->src = git__strndup(str, delim - str);
|
39
|
-
GITERR_CHECK_ALLOC(refspec->src);
|
23
|
+
int error;
|
24
|
+
const char *val;
|
40
25
|
|
41
|
-
|
42
|
-
|
26
|
+
if ((error = git_config_get_string(&val, cfg, var)) < 0)
|
27
|
+
return error;
|
43
28
|
|
44
|
-
return
|
29
|
+
return git_refspec__parse(refspec, val, is_fetch);
|
45
30
|
}
|
46
31
|
|
47
|
-
static int
|
32
|
+
static int download_tags_value(git_remote *remote, git_config *cfg)
|
48
33
|
{
|
49
|
-
int error;
|
50
34
|
const char *val;
|
35
|
+
git_buf buf = GIT_BUF_INIT;
|
36
|
+
int error;
|
51
37
|
|
52
|
-
if (
|
53
|
-
return
|
38
|
+
if (remote->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_UNSET)
|
39
|
+
return 0;
|
54
40
|
|
55
|
-
|
41
|
+
/* This is the default, let's see if we need to change it */
|
42
|
+
remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
|
43
|
+
if (git_buf_printf(&buf, "remote.%s.tagopt", remote->name) < 0)
|
44
|
+
return -1;
|
45
|
+
|
46
|
+
error = git_config_get_string(&val, cfg, git_buf_cstr(&buf));
|
47
|
+
git_buf_free(&buf);
|
48
|
+
if (!error && !strcmp(val, "--no-tags"))
|
49
|
+
remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_NONE;
|
50
|
+
else if (!error && !strcmp(val, "--tags"))
|
51
|
+
remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
|
52
|
+
|
53
|
+
if (error == GIT_ENOTFOUND)
|
54
|
+
error = 0;
|
55
|
+
|
56
|
+
return error;
|
56
57
|
}
|
57
58
|
|
58
59
|
int git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch)
|
@@ -81,10 +82,15 @@ int git_remote_new(git_remote **out, git_repository *repo, const char *name, con
|
|
81
82
|
}
|
82
83
|
|
83
84
|
if (fetch != NULL) {
|
84
|
-
if (
|
85
|
+
if (git_refspec__parse(&remote->fetch, fetch, true) < 0)
|
85
86
|
goto on_error;
|
86
87
|
}
|
87
88
|
|
89
|
+
/* A remote without a name doesn't download tags */
|
90
|
+
if (!name) {
|
91
|
+
remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_NONE;
|
92
|
+
}
|
93
|
+
|
88
94
|
*out = remote;
|
89
95
|
return 0;
|
90
96
|
|
@@ -157,7 +163,7 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
|
|
157
163
|
goto cleanup;
|
158
164
|
}
|
159
165
|
|
160
|
-
error = parse_remote_refspec(config, &remote->fetch, git_buf_cstr(&buf));
|
166
|
+
error = parse_remote_refspec(config, &remote->fetch, git_buf_cstr(&buf), true);
|
161
167
|
if (error == GIT_ENOTFOUND)
|
162
168
|
error = 0;
|
163
169
|
|
@@ -172,7 +178,7 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
|
|
172
178
|
goto cleanup;
|
173
179
|
}
|
174
180
|
|
175
|
-
error = parse_remote_refspec(config, &remote->push, git_buf_cstr(&buf));
|
181
|
+
error = parse_remote_refspec(config, &remote->push, git_buf_cstr(&buf), false);
|
176
182
|
if (error == GIT_ENOTFOUND)
|
177
183
|
error = 0;
|
178
184
|
|
@@ -181,6 +187,9 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
|
|
181
187
|
goto cleanup;
|
182
188
|
}
|
183
189
|
|
190
|
+
if (download_tags_value(remote, config) < 0)
|
191
|
+
goto cleanup;
|
192
|
+
|
184
193
|
*out = remote;
|
185
194
|
|
186
195
|
cleanup:
|
@@ -194,7 +203,9 @@ cleanup:
|
|
194
203
|
|
195
204
|
int git_remote_save(const git_remote *remote)
|
196
205
|
{
|
206
|
+
int error;
|
197
207
|
git_config *config;
|
208
|
+
const char *tagopt = NULL;
|
198
209
|
git_buf buf = GIT_BUF_INIT, value = GIT_BUF_INIT;
|
199
210
|
|
200
211
|
if (git_repository_config__weakptr(&config, remote->repo) < 0)
|
@@ -256,6 +267,38 @@ int git_remote_save(const git_remote *remote)
|
|
256
267
|
goto on_error;
|
257
268
|
}
|
258
269
|
|
270
|
+
/*
|
271
|
+
* What action to take depends on the old and new values. This
|
272
|
+
* is describes by the table below. tagopt means whether the
|
273
|
+
* is already a value set in the config
|
274
|
+
*
|
275
|
+
* AUTO ALL or NONE
|
276
|
+
* +-----------------------+
|
277
|
+
* tagopt | remove | set |
|
278
|
+
* +---------+-------------|
|
279
|
+
* !tagopt | nothing | set |
|
280
|
+
* +---------+-------------+
|
281
|
+
*/
|
282
|
+
|
283
|
+
git_buf_clear(&buf);
|
284
|
+
if (git_buf_printf(&buf, "remote.%s.tagopt", remote->name) < 0)
|
285
|
+
goto on_error;
|
286
|
+
|
287
|
+
error = git_config_get_string(&tagopt, config, git_buf_cstr(&buf));
|
288
|
+
if (error < 0 && error != GIT_ENOTFOUND)
|
289
|
+
goto on_error;
|
290
|
+
|
291
|
+
if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_ALL) {
|
292
|
+
if (git_config_set_string(config, git_buf_cstr(&buf), "--tags") < 0)
|
293
|
+
goto on_error;
|
294
|
+
} else if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_NONE) {
|
295
|
+
if (git_config_set_string(config, git_buf_cstr(&buf), "--no-tags") < 0)
|
296
|
+
goto on_error;
|
297
|
+
} else if (tagopt) {
|
298
|
+
if (git_config_delete(config, git_buf_cstr(&buf)) < 0)
|
299
|
+
goto on_error;
|
300
|
+
}
|
301
|
+
|
259
302
|
git_buf_free(&buf);
|
260
303
|
git_buf_free(&value);
|
261
304
|
|
@@ -317,11 +360,10 @@ int git_remote_set_fetchspec(git_remote *remote, const char *spec)
|
|
317
360
|
|
318
361
|
assert(remote && spec);
|
319
362
|
|
320
|
-
if (
|
363
|
+
if (git_refspec__parse(&refspec, spec, true) < 0)
|
321
364
|
return -1;
|
322
365
|
|
323
|
-
|
324
|
-
git__free(remote->fetch.dst);
|
366
|
+
git_refspec__free(&remote->fetch);
|
325
367
|
remote->fetch.src = refspec.src;
|
326
368
|
remote->fetch.dst = refspec.dst;
|
327
369
|
|
@@ -340,11 +382,10 @@ int git_remote_set_pushspec(git_remote *remote, const char *spec)
|
|
340
382
|
|
341
383
|
assert(remote && spec);
|
342
384
|
|
343
|
-
if (
|
385
|
+
if (git_refspec__parse(&refspec, spec, false) < 0)
|
344
386
|
return -1;
|
345
387
|
|
346
|
-
|
347
|
-
git__free(remote->push.dst);
|
388
|
+
git_refspec__free(&remote->push);
|
348
389
|
remote->push.src = refspec.src;
|
349
390
|
remote->push.dst = refspec.dst;
|
350
391
|
|
@@ -386,6 +427,9 @@ int git_remote_connect(git_remote *remote, int direction)
|
|
386
427
|
if (git_transport_new(&t, url) < 0)
|
387
428
|
return -1;
|
388
429
|
|
430
|
+
t->progress_cb = remote->callbacks.progress;
|
431
|
+
t->cb_data = remote->callbacks.data;
|
432
|
+
|
389
433
|
t->check_cert = remote->check_cert;
|
390
434
|
if (t->connect(t, direction) < 0) {
|
391
435
|
goto on_error;
|
@@ -442,25 +486,35 @@ int git_remote_download(git_remote *remote, git_off_t *bytes, git_indexer_stats
|
|
442
486
|
|
443
487
|
int git_remote_update_tips(git_remote *remote)
|
444
488
|
{
|
445
|
-
int error = 0;
|
489
|
+
int error = 0, autotag;
|
446
490
|
unsigned int i = 0;
|
447
491
|
git_buf refname = GIT_BUF_INIT;
|
448
492
|
git_oid old;
|
493
|
+
git_pkt *pkt;
|
494
|
+
git_odb *odb;
|
449
495
|
git_vector *refs;
|
450
496
|
git_remote_head *head;
|
451
497
|
git_reference *ref;
|
452
498
|
struct git_refspec *spec;
|
499
|
+
git_refspec tagspec;
|
453
500
|
|
454
501
|
assert(remote);
|
455
502
|
|
456
|
-
refs = &remote->refs;
|
503
|
+
refs = &remote->transport->refs;
|
457
504
|
spec = &remote->fetch;
|
458
505
|
|
459
506
|
if (refs->length == 0)
|
460
507
|
return 0;
|
461
508
|
|
509
|
+
if (git_repository_odb__weakptr(&odb, remote->repo) < 0)
|
510
|
+
return -1;
|
511
|
+
|
512
|
+
if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0)
|
513
|
+
return -1;
|
514
|
+
|
462
515
|
/* HEAD is only allowed to be the first in the list */
|
463
|
-
|
516
|
+
pkt = refs->contents[0];
|
517
|
+
head = &((git_pkt_ref *)pkt)->head;
|
464
518
|
if (!strcmp(head->name, GIT_HEAD_FILE)) {
|
465
519
|
if (git_reference_create_oid(&ref, remote->repo, GIT_FETCH_HEAD_FILE, &head->oid, 1) < 0)
|
466
520
|
return -1;
|
@@ -470,10 +524,38 @@ int git_remote_update_tips(git_remote *remote)
|
|
470
524
|
}
|
471
525
|
|
472
526
|
for (; i < refs->length; ++i) {
|
473
|
-
|
527
|
+
git_pkt *pkt = refs->contents[i];
|
528
|
+
autotag = 0;
|
474
529
|
|
475
|
-
if (
|
476
|
-
|
530
|
+
if (pkt->type == GIT_PKT_REF)
|
531
|
+
head = &((git_pkt_ref *)pkt)->head;
|
532
|
+
else
|
533
|
+
continue;
|
534
|
+
|
535
|
+
/* Ignore malformed ref names (which also saves us from tag^{} */
|
536
|
+
if (!git_reference_is_valid_name(head->name))
|
537
|
+
continue;
|
538
|
+
|
539
|
+
if (git_refspec_src_matches(spec, head->name)) {
|
540
|
+
if (git_refspec_transform_r(&refname, spec, head->name) < 0)
|
541
|
+
goto on_error;
|
542
|
+
} else if (remote->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_NONE) {
|
543
|
+
|
544
|
+
if (remote->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_ALL)
|
545
|
+
autotag = 1;
|
546
|
+
|
547
|
+
if (!git_refspec_src_matches(&tagspec, head->name))
|
548
|
+
continue;
|
549
|
+
|
550
|
+
git_buf_clear(&refname);
|
551
|
+
if (git_buf_puts(&refname, head->name) < 0)
|
552
|
+
goto on_error;
|
553
|
+
} else {
|
554
|
+
continue;
|
555
|
+
}
|
556
|
+
|
557
|
+
if (autotag && !git_odb_exists(odb, &head->oid))
|
558
|
+
continue;
|
477
559
|
|
478
560
|
error = git_reference_name_to_oid(&old, remote->repo, refname.ptr);
|
479
561
|
if (error < 0 && error != GIT_ENOTFOUND)
|
@@ -485,7 +567,9 @@ int git_remote_update_tips(git_remote *remote)
|
|
485
567
|
if (!git_oid_cmp(&old, &head->oid))
|
486
568
|
continue;
|
487
569
|
|
488
|
-
|
570
|
+
/* In autotag mode, don't overwrite any locally-existing tags */
|
571
|
+
error = git_reference_create_oid(&ref, remote->repo, refname.ptr, &head->oid, !autotag);
|
572
|
+
if (error < 0 && error != GIT_EEXISTS)
|
489
573
|
goto on_error;
|
490
574
|
|
491
575
|
git_reference_free(ref);
|
@@ -496,10 +580,12 @@ int git_remote_update_tips(git_remote *remote)
|
|
496
580
|
}
|
497
581
|
}
|
498
582
|
|
583
|
+
git_refspec__free(&tagspec);
|
499
584
|
git_buf_free(&refname);
|
500
585
|
return 0;
|
501
586
|
|
502
587
|
on_error:
|
588
|
+
git_refspec__free(&tagspec);
|
503
589
|
git_buf_free(&refname);
|
504
590
|
return -1;
|
505
591
|
|
@@ -511,6 +597,11 @@ int git_remote_connected(git_remote *remote)
|
|
511
597
|
return remote->transport == NULL ? 0 : remote->transport->connected;
|
512
598
|
}
|
513
599
|
|
600
|
+
void git_remote_stop(git_remote *remote)
|
601
|
+
{
|
602
|
+
git_atomic_set(&remote->transport->cancel, 1);
|
603
|
+
}
|
604
|
+
|
514
605
|
void git_remote_disconnect(git_remote *remote)
|
515
606
|
{
|
516
607
|
assert(remote);
|
@@ -533,10 +624,8 @@ void git_remote_free(git_remote *remote)
|
|
533
624
|
|
534
625
|
git_vector_free(&remote->refs);
|
535
626
|
|
536
|
-
|
537
|
-
|
538
|
-
git__free(remote->push.src);
|
539
|
-
git__free(remote->push.dst);
|
627
|
+
git_refspec__free(&remote->fetch);
|
628
|
+
git_refspec__free(&remote->push);
|
540
629
|
git__free(remote->url);
|
541
630
|
git__free(remote->pushurl);
|
542
631
|
git__free(remote->name);
|
@@ -548,12 +637,12 @@ struct cb_data {
|
|
548
637
|
regex_t *preg;
|
549
638
|
};
|
550
639
|
|
551
|
-
static int remote_list_cb(const
|
640
|
+
static int remote_list_cb(const git_config_entry *entry, void *data_)
|
552
641
|
{
|
553
642
|
struct cb_data *data = (struct cb_data *)data_;
|
554
643
|
size_t nmatch = 2;
|
555
644
|
regmatch_t pmatch[2];
|
556
|
-
|
645
|
+
const char *name = entry->name;
|
557
646
|
|
558
647
|
if (!regexec(data->preg, name, nmatch, pmatch, 0)) {
|
559
648
|
char *remote_name = git__strndup(&name[pmatch[1].rm_so], pmatch[1].rm_eo - pmatch[1].rm_so);
|
@@ -646,4 +735,19 @@ void git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callback
|
|
646
735
|
assert(remote && callbacks);
|
647
736
|
|
648
737
|
memcpy(&remote->callbacks, callbacks, sizeof(git_remote_callbacks));
|
738
|
+
|
739
|
+
if (remote->transport) {
|
740
|
+
remote->transport->progress_cb = remote->callbacks.progress;
|
741
|
+
remote->transport->cb_data = remote->callbacks.data;
|
742
|
+
}
|
743
|
+
}
|
744
|
+
|
745
|
+
int git_remote_autotag(git_remote *remote)
|
746
|
+
{
|
747
|
+
return remote->download_tags;
|
748
|
+
}
|
749
|
+
|
750
|
+
void git_remote_set_autotag(git_remote *remote, int value)
|
751
|
+
{
|
752
|
+
remote->download_tags = value;
|
649
753
|
}
|