Skip to content

Commit 97349a2

Browse files
committed
Merge branch 'jc/capabilities'
Some capabilities were asked by fetch-pack even when upload-pack did not advertise that they are available. Fix fetch-pack not to do so. * 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
2 parents 4514de7 + 36c60f7 commit 97349a2

File tree

8 files changed

+102
-17
lines changed

8 files changed

+102
-17
lines changed

builtin/fetch-pack.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "remote.h"
1111
#include "run-command.h"
1212
#include "transport.h"
13+
#include "version.h"
1314

1415
static int transfer_unpack_limit = -1;
1516
static int fetch_unpack_limit = -1;
@@ -18,6 +19,7 @@ static int prefer_ofs_delta = 1;
1819
static int no_done;
1920
static int fetch_fsck_objects = -1;
2021
static int transfer_fsck_objects = -1;
22+
static int agent_supported;
2123
static struct fetch_pack_args args = {
2224
/* .uploadpack = */ "git-upload-pack",
2325
};
@@ -327,6 +329,8 @@ static int find_common(int fd[2], unsigned char *result_sha1,
327329
if (args.no_progress) strbuf_addstr(&c, " no-progress");
328330
if (args.include_tag) strbuf_addstr(&c, " include-tag");
329331
if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta");
332+
if (agent_supported) strbuf_addf(&c, " agent=%s",
333+
git_user_agent_sanitized());
330334
packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
331335
strbuf_release(&c);
332336
} else
@@ -783,6 +787,8 @@ static struct ref *do_fetch_pack(int fd[2],
783787
{
784788
struct ref *ref = copy_ref_list(orig_ref);
785789
unsigned char sha1[20];
790+
const char *agent_feature;
791+
int agent_len;
786792

787793
sort_ref_list(&ref, ref_compare_name);
788794

@@ -814,11 +820,25 @@ static struct ref *do_fetch_pack(int fd[2],
814820
fprintf(stderr, "Server supports side-band\n");
815821
use_sideband = 1;
816822
}
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;
817829
if (server_supports("ofs-delta")) {
818830
if (args.verbose)
819831
fprintf(stderr, "Server supports ofs-delta\n");
820832
} else
821833
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+
822842
if (everything_local(&ref, nr_match, match)) {
823843
packet_flush(fd[1]);
824844
goto all_done;

builtin/receive-pack.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "string-list.h"
1313
#include "sha1-array.h"
1414
#include "connected.h"
15+
#include "version.h"
1516

1617
static const char receive_pack_usage[] = "git receive-pack <git-dir>";
1718

@@ -121,10 +122,11 @@ static void show_ref(const char *path, const unsigned char *sha1)
121122
if (sent_capabilities)
122123
packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
123124
else
124-
packet_write(1, "%s %s%c%s%s\n",
125+
packet_write(1, "%s %s%c%s%s agent=%s\n",
125126
sha1_to_hex(sha1), path, 0,
126127
" 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());
128130
sent_capabilities = 1;
129131
}
130132

builtin/send-pack.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "send-pack.h"
99
#include "quote.h"
1010
#include "transport.h"
11+
#include "version.h"
1112

1213
static const char send_pack_usage[] =
1314
"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,
251252
int status_report = 0;
252253
int use_sideband = 0;
253254
int quiet_supported = 0;
255+
int agent_supported = 0;
254256
unsigned cmds_sent = 0;
255257
int ret;
256258
struct async demux;
@@ -266,6 +268,8 @@ int send_pack(struct send_pack_args *args,
266268
use_sideband = 1;
267269
if (server_supports("quiet"))
268270
quiet_supported = 1;
271+
if (server_supports("agent"))
272+
agent_supported = 1;
269273

270274
if (!remote_refs) {
271275
fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
@@ -305,12 +309,17 @@ int send_pack(struct send_pack_args *args,
305309
char *new_hex = sha1_to_hex(ref->new_sha1);
306310
int quiet = quiet_supported && (args->quiet || !args->progress);
307311

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",
310316
old_hex, new_hex, ref->name, 0,
311317
status_report ? " report-status" : "",
312318
use_sideband ? " side-band-64k" : "",
313-
quiet ? " quiet" : "");
319+
quiet ? " quiet" : "",
320+
agent_supported ? " agent=" : "",
321+
agent_supported ? git_user_agent_sanitized() : ""
322+
);
314323
}
315324
else
316325
packet_buf_write(&req_buf, "%s %s %s",

cache.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1038,7 +1038,9 @@ struct extra_have_objects {
10381038
};
10391039
extern struct ref **get_remote_heads(int in, struct ref **list, unsigned int flags, struct extra_have_objects *);
10401040
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);
10421044

10431045
extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
10441046

connect.c

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,7 @@ struct ref **get_remote_heads(int in, struct ref **list,
115115
return list;
116116
}
117117

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)
124119
{
125120
int len;
126121

@@ -132,14 +127,46 @@ const char *parse_feature_request(const char *feature_list, const char *feature)
132127
const char *found = strstr(feature_list, feature);
133128
if (!found)
134129
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+
}
138150
feature_list = found + 1;
139151
}
140152
return NULL;
141153
}
142154

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+
143170
enum protocol {
144171
PROTO_LOCAL = 1,
145172
PROTO_SSH,

upload-pack.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "list-objects.h"
1212
#include "run-command.h"
1313
#include "sigchain.h"
14+
#include "version.h"
1415

1516
static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<n>] <dir>";
1617

@@ -734,9 +735,11 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
734735
}
735736

736737
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,
738740
0, capabilities,
739-
stateless_rpc ? " no-done" : "");
741+
stateless_rpc ? " no-done" : "",
742+
git_user_agent_sanitized());
740743
else
741744
packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname_nons);
742745
capabilities = NULL;

version.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "git-compat-util.h"
22
#include "version.h"
3+
#include "strbuf.h"
34

45
const char git_version_string[] = GIT_VERSION;
56

@@ -15,3 +16,23 @@ const char *git_user_agent(void)
1516

1617
return agent;
1718
}
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+
}

version.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
extern const char git_version_string[];
55

66
const char *git_user_agent(void);
7+
const char *git_user_agent_sanitized(void);
78

89
#endif /* VERSION_H */

0 commit comments

Comments
 (0)