Commit 24f2f94e7defd20ab302c30d0d394248a6e43814

Carlos Martín Nieto 2012-09-15T08:07:24

fetch: use the include-tag capability This tells the remote to send us any tags that point to objects that we are downloading.

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