fetch: use the include-tag capability This tells the remote to send us any tags that point to objects that we are downloading.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
diff --git a/include/git2/remote.h b/include/git2/remote.h
index a3913af..032bb30 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -304,6 +304,12 @@ struct git_remote_callbacks {
*/
GIT_EXTERN(void) git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks);
+enum {
+ GIT_REMOTE_DOWNLOAD_TAGS_UNSET,
+ GIT_REMOTE_DOWNLOAD_TAGS_NONE,
+ GIT_REMOTE_DOWNLOAD_TAGS_AUTO
+};
+
/** @} */
GIT_END_DECL
#endif
diff --git a/src/pkt.c b/src/pkt.c
index ad0149d..91f9b65 100644
--- a/src/pkt.c
+++ b/src/pkt.c
@@ -354,6 +354,9 @@ static int buffer_want_with_caps(git_remote_head *head, git_transport_caps *caps
if (caps->multi_ack)
git_buf_puts(&str, GIT_CAP_MULTI_ACK " ");
+ if (caps->include_tag)
+ git_buf_puts(&str, GIT_CAP_INCLUDE_TAG " ");
+
if (git_buf_oom(&str))
return -1;
diff --git a/src/protocol.c b/src/protocol.c
index 4526c85..8f673cd 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -80,6 +80,12 @@ int git_protocol_detect_caps(git_pkt_ref *pkt, git_transport_caps *caps)
continue;
}
+ if(!git__prefixcmp(ptr, GIT_CAP_INCLUDE_TAG)) {
+ caps->common = caps->include_tag = 1;
+ ptr += strlen(GIT_CAP_INCLUDE_TAG);
+ continue;
+ }
+
/* Keep side-band check after side-band-64k */
if(!git__prefixcmp(ptr, GIT_CAP_SIDE_BAND_64K)) {
caps->common = caps->side_band_64k = 1;
diff --git a/src/remote.c b/src/remote.c
index 0ae47c3..2eb2fd1 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -55,6 +55,31 @@ static int parse_remote_refspec(git_config *cfg, git_refspec *refspec, const cha
return refspec_parse(refspec, val);
}
+static int download_tags_value(git_remote *remote, git_config *cfg)
+{
+ const char *val;
+ git_buf buf = GIT_BUF_INIT;
+ int error;
+
+ if (remote->download_tags != GIT_REMOTE_DOWNLOAD_TAGS_UNSET)
+ return 0;
+
+ /* This is the default, let's see if we need to change it */
+ remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
+ if (git_buf_printf(&buf, "remote.%s.tagopt", remote->name) < 0)
+ return -1;
+
+ error = git_config_get_string(&val, cfg, git_buf_cstr(&buf));
+ git_buf_free(&buf);
+ if (!error && !strcmp(val, "--no-tags"))
+ remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_NONE;
+
+ if (error == GIT_ENOTFOUND)
+ error = 0;
+
+ return error;
+}
+
int git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch)
{
git_remote *remote;
@@ -181,6 +206,9 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
goto cleanup;
}
+ if (download_tags_value(remote, config) < 0)
+ goto cleanup;
+
*out = remote;
cleanup:
diff --git a/src/remote.h b/src/remote.h
index 67933a3..51587be 100644
--- a/src/remote.h
+++ b/src/remote.h
@@ -24,7 +24,8 @@ struct git_remote {
git_repository *repo;
git_remote_callbacks callbacks;
unsigned int need_pack:1,
- check_cert;
+ download_tags:2, /* There are three possible values */
+ check_cert:1;
};
const char* git_remote__urlfordirection(struct git_remote *remote, int direction);
diff --git a/src/transport.h b/src/transport.h
index ff3a58d..9c91afd 100644
--- a/src/transport.h
+++ b/src/transport.h
@@ -23,13 +23,15 @@
#define GIT_CAP_MULTI_ACK "multi_ack"
#define GIT_CAP_SIDE_BAND "side-band"
#define GIT_CAP_SIDE_BAND_64K "side-band-64k"
+#define GIT_CAP_INCLUDE_TAG "include-tag"
typedef struct git_transport_caps {
int common:1,
ofs_delta:1,
multi_ack: 1,
side_band:1,
- side_band_64k:1;
+ side_band_64k:1,
+ include_tag:1;
} git_transport_caps;
#ifdef GIT_SSL