Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'jc/capabilities' into maint

* jc/capabilities:
  fetch-pack: mention server version with verbose output
  parse_feature_request: make it easier to see feature values
  fetch-pack: do not ask for unadvertised capabilities
  do not send client agent unless server does first
  send-pack: fix capability-sending logic
  include agent identifier in capability string
  • Loading branch information...
commit 59d7cbd343d098783f8a91fb67d90ac3d066ea77 2 parents 2af6d98 + 36c60f7
Junio C Hamano gitster authored
20 builtin/fetch-pack.c
@@ -10,6 +10,7 @@
10 10 #include "remote.h"
11 11 #include "run-command.h"
12 12 #include "transport.h"
  13 +#include "version.h"
13 14
14 15 static int transfer_unpack_limit = -1;
15 16 static int fetch_unpack_limit = -1;
@@ -18,6 +19,7 @@ static int prefer_ofs_delta = 1;
18 19 static int no_done;
19 20 static int fetch_fsck_objects = -1;
20 21 static int transfer_fsck_objects = -1;
  22 +static int agent_supported;
21 23 static struct fetch_pack_args args = {
22 24 /* .uploadpack = */ "git-upload-pack",
23 25 };
@@ -327,6 +329,8 @@ static int find_common(int fd[2], unsigned char *result_sha1,
327 329 if (args.no_progress) strbuf_addstr(&c, " no-progress");
328 330 if (args.include_tag) strbuf_addstr(&c, " include-tag");
329 331 if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta");
  332 + if (agent_supported) strbuf_addf(&c, " agent=%s",
  333 + git_user_agent_sanitized());
330 334 packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
331 335 strbuf_release(&c);
332 336 } else
@@ -783,6 +787,8 @@ static struct ref *do_fetch_pack(int fd[2],
783 787 {
784 788 struct ref *ref = copy_ref_list(orig_ref);
785 789 unsigned char sha1[20];
  790 + const char *agent_feature;
  791 + int agent_len;
786 792
787 793 sort_ref_list(&ref, ref_compare_name);
788 794
@@ -814,11 +820,25 @@ static struct ref *do_fetch_pack(int fd[2],
814 820 fprintf(stderr, "Server supports side-band\n");
815 821 use_sideband = 1;
816 822 }
  823 + if (!server_supports("thin-pack"))
  824 + args.use_thin_pack = 0;
  825 + if (!server_supports("no-progress"))
  826 + args.no_progress = 0;
  827 + if (!server_supports("include-tag"))
  828 + args.include_tag = 0;
817 829 if (server_supports("ofs-delta")) {
818 830 if (args.verbose)
819 831 fprintf(stderr, "Server supports ofs-delta\n");
820 832 } else
821 833 prefer_ofs_delta = 0;
  834 +
  835 + if ((agent_feature = server_feature_value("agent", &agent_len))) {
  836 + agent_supported = 1;
  837 + if (args.verbose && agent_len)
  838 + fprintf(stderr, "Server version is %.*s\n",
  839 + agent_len, agent_feature);
  840 + }
  841 +
822 842 if (everything_local(&ref, nr_match, match)) {
823 843 packet_flush(fd[1]);
824 844 goto all_done;
6 builtin/receive-pack.c
@@ -12,6 +12,7 @@
12 12 #include "string-list.h"
13 13 #include "sha1-array.h"
14 14 #include "connected.h"
  15 +#include "version.h"
15 16
16 17 static const char receive_pack_usage[] = "git receive-pack <git-dir>";
17 18
@@ -121,10 +122,11 @@ static void show_ref(const char *path, const unsigned char *sha1)
121 122 if (sent_capabilities)
122 123 packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
123 124 else
124   - packet_write(1, "%s %s%c%s%s\n",
  125 + packet_write(1, "%s %s%c%s%s agent=%s\n",
125 126 sha1_to_hex(sha1), path, 0,
126 127 " report-status delete-refs side-band-64k quiet",
127   - prefer_ofs_delta ? " ofs-delta" : "");
  128 + prefer_ofs_delta ? " ofs-delta" : "",
  129 + git_user_agent_sanitized());
128 130 sent_capabilities = 1;
129 131 }
130 132
15 builtin/send-pack.c
@@ -8,6 +8,7 @@
8 8 #include "send-pack.h"
9 9 #include "quote.h"
10 10 #include "transport.h"
  11 +#include "version.h"
11 12
12 13 static const char send_pack_usage[] =
13 14 "git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
@@ -251,6 +252,7 @@ int send_pack(struct send_pack_args *args,
251 252 int status_report = 0;
252 253 int use_sideband = 0;
253 254 int quiet_supported = 0;
  255 + int agent_supported = 0;
254 256 unsigned cmds_sent = 0;
255 257 int ret;
256 258 struct async demux;
@@ -266,6 +268,8 @@ int send_pack(struct send_pack_args *args,
266 268 use_sideband = 1;
267 269 if (server_supports("quiet"))
268 270 quiet_supported = 1;
  271 + if (server_supports("agent"))
  272 + agent_supported = 1;
269 273
270 274 if (!remote_refs) {
271 275 fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
@@ -305,12 +309,17 @@ int send_pack(struct send_pack_args *args,
305 309 char *new_hex = sha1_to_hex(ref->new_sha1);
306 310 int quiet = quiet_supported && (args->quiet || !args->progress);
307 311
308   - if (!cmds_sent && (status_report || use_sideband || args->quiet)) {
309   - packet_buf_write(&req_buf, "%s %s %s%c%s%s%s",
  312 + if (!cmds_sent && (status_report || use_sideband ||
  313 + quiet || agent_supported)) {
  314 + packet_buf_write(&req_buf,
  315 + "%s %s %s%c%s%s%s%s%s",
310 316 old_hex, new_hex, ref->name, 0,
311 317 status_report ? " report-status" : "",
312 318 use_sideband ? " side-band-64k" : "",
313   - quiet ? " quiet" : "");
  319 + quiet ? " quiet" : "",
  320 + agent_supported ? " agent=" : "",
  321 + agent_supported ? git_user_agent_sanitized() : ""
  322 + );
314 323 }
315 324 else
316 325 packet_buf_write(&req_buf, "%s %s %s",
4 cache.h
@@ -1038,7 +1038,9 @@ struct extra_have_objects {
1038 1038 };
1039 1039 extern struct ref **get_remote_heads(int in, struct ref **list, unsigned int flags, struct extra_have_objects *);
1040 1040 extern int server_supports(const char *feature);
1041   -extern const char *parse_feature_request(const char *features, const char *feature);
  1041 +extern int parse_feature_request(const char *features, const char *feature);
  1042 +extern const char *server_feature_value(const char *feature, int *len_ret);
  1043 +extern const char *parse_feature_value(const char *feature_list, const char *feature, int *len_ret);
1042 1044
1043 1045 extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
1044 1046
45 connect.c
@@ -115,12 +115,7 @@ struct ref **get_remote_heads(int in, struct ref **list,
115 115 return list;
116 116 }
117 117
118   -int server_supports(const char *feature)
119   -{
120   - return !!parse_feature_request(server_capabilities, feature);
121   -}
122   -
123   -const char *parse_feature_request(const char *feature_list, const char *feature)
  118 +const char *parse_feature_value(const char *feature_list, const char *feature, int *lenp)
124 119 {
125 120 int len;
126 121
@@ -132,14 +127,46 @@ const char *parse_feature_request(const char *feature_list, const char *feature)
132 127 const char *found = strstr(feature_list, feature);
133 128 if (!found)
134 129 return NULL;
135   - if ((feature_list == found || isspace(found[-1])) &&
136   - (!found[len] || isspace(found[len]) || found[len] == '='))
137   - return found;
  130 + if (feature_list == found || isspace(found[-1])) {
  131 + const char *value = found + len;
  132 + /* feature with no value (e.g., "thin-pack") */
  133 + if (!*value || isspace(*value)) {
  134 + if (lenp)
  135 + *lenp = 0;
  136 + return value;
  137 + }
  138 + /* feature with a value (e.g., "agent=git/1.2.3") */
  139 + else if (*value == '=') {
  140 + value++;
  141 + if (lenp)
  142 + *lenp = strcspn(value, " \t\n");
  143 + return value;
  144 + }
  145 + /*
  146 + * otherwise we matched a substring of another feature;
  147 + * keep looking
  148 + */
  149 + }
138 150 feature_list = found + 1;
139 151 }
140 152 return NULL;
141 153 }
142 154
  155 +int parse_feature_request(const char *feature_list, const char *feature)
  156 +{
  157 + return !!parse_feature_value(feature_list, feature, NULL);
  158 +}
  159 +
  160 +const char *server_feature_value(const char *feature, int *len)
  161 +{
  162 + return parse_feature_value(server_capabilities, feature, len);
  163 +}
  164 +
  165 +int server_supports(const char *feature)
  166 +{
  167 + return !!server_feature_value(feature, NULL);
  168 +}
  169 +
143 170 enum protocol {
144 171 PROTO_LOCAL = 1,
145 172 PROTO_SSH,
7 upload-pack.c
@@ -11,6 +11,7 @@
11 11 #include "list-objects.h"
12 12 #include "run-command.h"
13 13 #include "sigchain.h"
  14 +#include "version.h"
14 15
15 16 static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<n>] <dir>";
16 17
@@ -734,9 +735,11 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
734 735 }
735 736
736 737 if (capabilities)
737   - packet_write(1, "%s %s%c%s%s\n", sha1_to_hex(sha1), refname_nons,
  738 + packet_write(1, "%s %s%c%s%s agent=%s\n",
  739 + sha1_to_hex(sha1), refname_nons,
738 740 0, capabilities,
739   - stateless_rpc ? " no-done" : "");
  741 + stateless_rpc ? " no-done" : "",
  742 + git_user_agent_sanitized());
740 743 else
741 744 packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname_nons);
742 745 capabilities = NULL;
21 version.c
... ... @@ -1,5 +1,6 @@
1 1 #include "git-compat-util.h"
2 2 #include "version.h"
  3 +#include "strbuf.h"
3 4
4 5 const char git_version_string[] = GIT_VERSION;
5 6
@@ -15,3 +16,23 @@ const char *git_user_agent(void)
15 16
16 17 return agent;
17 18 }
  19 +
  20 +const char *git_user_agent_sanitized(void)
  21 +{
  22 + static const char *agent = NULL;
  23 +
  24 + if (!agent) {
  25 + struct strbuf buf = STRBUF_INIT;
  26 + int i;
  27 +
  28 + strbuf_addstr(&buf, git_user_agent());
  29 + strbuf_trim(&buf);
  30 + for (i = 0; i < buf.len; i++) {
  31 + if (buf.buf[i] <= 32 || buf.buf[i] >= 127)
  32 + buf.buf[i] = '.';
  33 + }
  34 + agent = buf.buf;
  35 + }
  36 +
  37 + return agent;
  38 +}
1  version.h
@@ -4,5 +4,6 @@
4 4 extern const char git_version_string[];
5 5
6 6 const char *git_user_agent(void);
  7 +const char *git_user_agent_sanitized(void);
7 8
8 9 #endif /* VERSION_H */

0 comments on commit 59d7cbd

Please sign in to comment.
Something went wrong with that request. Please try again.