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
This commit is contained in:
Junio C Hamano 2012-09-11 11:06:45 -07:00
commit 59d7cbd343
8 changed files with 102 additions and 17 deletions

View File

@ -10,6 +10,7 @@
#include "remote.h"
#include "run-command.h"
#include "transport.h"
#include "version.h"
static int transfer_unpack_limit = -1;
static int fetch_unpack_limit = -1;
@ -18,6 +19,7 @@ static int prefer_ofs_delta = 1;
static int no_done;
static int fetch_fsck_objects = -1;
static int transfer_fsck_objects = -1;
static int agent_supported;
static struct fetch_pack_args args = {
/* .uploadpack = */ "git-upload-pack",
};
@ -327,6 +329,8 @@ static int find_common(int fd[2], unsigned char *result_sha1,
if (args.no_progress) strbuf_addstr(&c, " no-progress");
if (args.include_tag) strbuf_addstr(&c, " include-tag");
if (prefer_ofs_delta) strbuf_addstr(&c, " ofs-delta");
if (agent_supported) strbuf_addf(&c, " agent=%s",
git_user_agent_sanitized());
packet_buf_write(&req_buf, "want %s%s\n", remote_hex, c.buf);
strbuf_release(&c);
} else
@ -783,6 +787,8 @@ static struct ref *do_fetch_pack(int fd[2],
{
struct ref *ref = copy_ref_list(orig_ref);
unsigned char sha1[20];
const char *agent_feature;
int agent_len;
sort_ref_list(&ref, ref_compare_name);
@ -814,11 +820,25 @@ static struct ref *do_fetch_pack(int fd[2],
fprintf(stderr, "Server supports side-band\n");
use_sideband = 1;
}
if (!server_supports("thin-pack"))
args.use_thin_pack = 0;
if (!server_supports("no-progress"))
args.no_progress = 0;
if (!server_supports("include-tag"))
args.include_tag = 0;
if (server_supports("ofs-delta")) {
if (args.verbose)
fprintf(stderr, "Server supports ofs-delta\n");
} else
prefer_ofs_delta = 0;
if ((agent_feature = server_feature_value("agent", &agent_len))) {
agent_supported = 1;
if (args.verbose && agent_len)
fprintf(stderr, "Server version is %.*s\n",
agent_len, agent_feature);
}
if (everything_local(&ref, nr_match, match)) {
packet_flush(fd[1]);
goto all_done;

View File

@ -12,6 +12,7 @@
#include "string-list.h"
#include "sha1-array.h"
#include "connected.h"
#include "version.h"
static const char receive_pack_usage[] = "git receive-pack <git-dir>";
@ -121,10 +122,11 @@ static void show_ref(const char *path, const unsigned char *sha1)
if (sent_capabilities)
packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
else
packet_write(1, "%s %s%c%s%s\n",
packet_write(1, "%s %s%c%s%s agent=%s\n",
sha1_to_hex(sha1), path, 0,
" report-status delete-refs side-band-64k quiet",
prefer_ofs_delta ? " ofs-delta" : "");
prefer_ofs_delta ? " ofs-delta" : "",
git_user_agent_sanitized());
sent_capabilities = 1;
}

View File

@ -8,6 +8,7 @@
#include "send-pack.h"
#include "quote.h"
#include "transport.h"
#include "version.h"
static const char send_pack_usage[] =
"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,
int status_report = 0;
int use_sideband = 0;
int quiet_supported = 0;
int agent_supported = 0;
unsigned cmds_sent = 0;
int ret;
struct async demux;
@ -266,6 +268,8 @@ int send_pack(struct send_pack_args *args,
use_sideband = 1;
if (server_supports("quiet"))
quiet_supported = 1;
if (server_supports("agent"))
agent_supported = 1;
if (!remote_refs) {
fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
@ -305,12 +309,17 @@ int send_pack(struct send_pack_args *args,
char *new_hex = sha1_to_hex(ref->new_sha1);
int quiet = quiet_supported && (args->quiet || !args->progress);
if (!cmds_sent && (status_report || use_sideband || args->quiet)) {
packet_buf_write(&req_buf, "%s %s %s%c%s%s%s",
if (!cmds_sent && (status_report || use_sideband ||
quiet || agent_supported)) {
packet_buf_write(&req_buf,
"%s %s %s%c%s%s%s%s%s",
old_hex, new_hex, ref->name, 0,
status_report ? " report-status" : "",
use_sideband ? " side-band-64k" : "",
quiet ? " quiet" : "");
quiet ? " quiet" : "",
agent_supported ? " agent=" : "",
agent_supported ? git_user_agent_sanitized() : ""
);
}
else
packet_buf_write(&req_buf, "%s %s %s",

View File

@ -1038,7 +1038,9 @@ struct extra_have_objects {
};
extern struct ref **get_remote_heads(int in, struct ref **list, unsigned int flags, struct extra_have_objects *);
extern int server_supports(const char *feature);
extern const char *parse_feature_request(const char *features, const char *feature);
extern int parse_feature_request(const char *features, const char *feature);
extern const char *server_feature_value(const char *feature, int *len_ret);
extern const char *parse_feature_value(const char *feature_list, const char *feature, int *len_ret);
extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);

View File

@ -115,12 +115,7 @@ struct ref **get_remote_heads(int in, struct ref **list,
return list;
}
int server_supports(const char *feature)
{
return !!parse_feature_request(server_capabilities, feature);
}
const char *parse_feature_request(const char *feature_list, const char *feature)
const char *parse_feature_value(const char *feature_list, const char *feature, int *lenp)
{
int len;
@ -132,14 +127,46 @@ const char *parse_feature_request(const char *feature_list, const char *feature)
const char *found = strstr(feature_list, feature);
if (!found)
return NULL;
if ((feature_list == found || isspace(found[-1])) &&
(!found[len] || isspace(found[len]) || found[len] == '='))
return found;
if (feature_list == found || isspace(found[-1])) {
const char *value = found + len;
/* feature with no value (e.g., "thin-pack") */
if (!*value || isspace(*value)) {
if (lenp)
*lenp = 0;
return value;
}
/* feature with a value (e.g., "agent=git/1.2.3") */
else if (*value == '=') {
value++;
if (lenp)
*lenp = strcspn(value, " \t\n");
return value;
}
/*
* otherwise we matched a substring of another feature;
* keep looking
*/
}
feature_list = found + 1;
}
return NULL;
}
int parse_feature_request(const char *feature_list, const char *feature)
{
return !!parse_feature_value(feature_list, feature, NULL);
}
const char *server_feature_value(const char *feature, int *len)
{
return parse_feature_value(server_capabilities, feature, len);
}
int server_supports(const char *feature)
{
return !!server_feature_value(feature, NULL);
}
enum protocol {
PROTO_LOCAL = 1,
PROTO_SSH,

View File

@ -11,6 +11,7 @@
#include "list-objects.h"
#include "run-command.h"
#include "sigchain.h"
#include "version.h"
static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<n>] <dir>";
@ -734,9 +735,11 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
}
if (capabilities)
packet_write(1, "%s %s%c%s%s\n", sha1_to_hex(sha1), refname_nons,
packet_write(1, "%s %s%c%s%s agent=%s\n",
sha1_to_hex(sha1), refname_nons,
0, capabilities,
stateless_rpc ? " no-done" : "");
stateless_rpc ? " no-done" : "",
git_user_agent_sanitized());
else
packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname_nons);
capabilities = NULL;

View File

@ -1,5 +1,6 @@
#include "git-compat-util.h"
#include "version.h"
#include "strbuf.h"
const char git_version_string[] = GIT_VERSION;
@ -15,3 +16,23 @@ const char *git_user_agent(void)
return agent;
}
const char *git_user_agent_sanitized(void)
{
static const char *agent = NULL;
if (!agent) {
struct strbuf buf = STRBUF_INIT;
int i;
strbuf_addstr(&buf, git_user_agent());
strbuf_trim(&buf);
for (i = 0; i < buf.len; i++) {
if (buf.buf[i] <= 32 || buf.buf[i] >= 127)
buf.buf[i] = '.';
}
agent = buf.buf;
}
return agent;
}

View File

@ -4,5 +4,6 @@
extern const char git_version_string[];
const char *git_user_agent(void);
const char *git_user_agent_sanitized(void);
#endif /* VERSION_H */