summaryrefslogtreecommitdiff
path: root/transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'transport.c')
-rw-r--r--transport.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/transport.c b/transport.c
index ffe2115845..ef66e73090 100644
--- a/transport.c
+++ b/transport.c
@@ -127,7 +127,7 @@ struct bundle_transport_data {
static struct ref *get_refs_from_bundle(struct transport *transport,
int for_push,
- const struct strvec *ref_prefixes)
+ struct transport_ls_refs_options *transport_options)
{
struct bundle_transport_data *data = transport->data;
struct ref *result = NULL;
@@ -236,6 +236,9 @@ static int set_git_option(struct git_transport_options *opts,
list_objects_filter_die_if_populated(&opts->filter_options);
parse_list_objects_filter(&opts->filter_options, value);
return 0;
+ } else if (!strcmp(name, TRANS_OPT_REJECT_SHALLOW)) {
+ opts->reject_shallow = !!value;
+ return 0;
}
return 1;
}
@@ -280,12 +283,14 @@ static void die_if_server_options(struct transport *transport)
* remote refs.
*/
static struct ref *handshake(struct transport *transport, int for_push,
- const struct strvec *ref_prefixes,
+ struct transport_ls_refs_options *options,
int must_list_refs)
{
struct git_transport_data *data = transport->data;
struct ref *refs = NULL;
struct packet_reader reader;
+ int sid_len;
+ const char *server_sid;
connect_setup(transport, for_push);
@@ -297,9 +302,11 @@ static struct ref *handshake(struct transport *transport, int for_push,
data->version = discover_version(&reader);
switch (data->version) {
case protocol_v2:
+ if (server_feature_v2("session-id", &server_sid))
+ trace2_data_string("transfer", NULL, "server-sid", server_sid);
if (must_list_refs)
get_remote_refs(data->fd[1], &reader, &refs, for_push,
- ref_prefixes,
+ options,
transport->server_options,
transport->stateless_rpc);
break;
@@ -310,6 +317,12 @@ static struct ref *handshake(struct transport *transport, int for_push,
for_push ? REF_NORMAL : 0,
&data->extra_have,
&data->shallow);
+ server_sid = server_feature_value("session-id", &sid_len);
+ if (server_sid) {
+ char *sid = xstrndup(server_sid, sid_len);
+ trace2_data_string("transfer", NULL, "server-sid", sid);
+ free(sid);
+ }
break;
case protocol_unknown_version:
BUG("unknown protocol version");
@@ -324,9 +337,9 @@ static struct ref *handshake(struct transport *transport, int for_push,
}
static struct ref *get_refs_via_connect(struct transport *transport, int for_push,
- const struct strvec *ref_prefixes)
+ struct transport_ls_refs_options *options)
{
- return handshake(transport, for_push, ref_prefixes, 1);
+ return handshake(transport, for_push, options, 1);
}
static int fetch_refs_via_pack(struct transport *transport,
@@ -360,6 +373,7 @@ static int fetch_refs_via_pack(struct transport *transport,
args.stateless_rpc = transport->stateless_rpc;
args.server_options = transport->server_options;
args.negotiation_tips = data->options.negotiation_tips;
+ args.reject_shallow_remote = transport->smart_options->reject_shallow;
if (!data->got_remote_heads) {
int i;
@@ -633,6 +647,11 @@ static int print_one_push_report(struct ref *ref, const char *dest, int count,
"stale info",
report, porcelain, summary_width);
break;
+ case REF_STATUS_REJECT_REMOTE_UPDATED:
+ print_ref_status('!', "[rejected]", ref, ref->peer_ref,
+ "remote ref updated since checkout",
+ report, porcelain, summary_width);
+ break;
case REF_STATUS_REJECT_SHALLOW:
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
"new shallow roots not allowed",
@@ -743,6 +762,8 @@ void transport_print_push_status(const char *dest, struct ref *refs,
*reject_reasons |= REJECT_FETCH_FIRST;
} else if (ref->status == REF_STATUS_REJECT_NEEDS_FORCE) {
*reject_reasons |= REJECT_NEEDS_FORCE;
+ } else if (ref->status == REF_STATUS_REJECT_REMOTE_UPDATED) {
+ *reject_reasons |= REJECT_REF_NEEDS_UPDATE;
}
}
free(head);
@@ -854,7 +875,7 @@ void transport_take_over(struct transport *transport,
BUG("taking over transport requires non-NULL "
"smart_options field.");
- data = xcalloc(1, sizeof(*data));
+ CALLOC_ARRAY(data, 1);
data->options = *transport->smart_options;
data->conn = child;
data->fd[0] = data->conn->out;
@@ -1185,6 +1206,7 @@ static int run_pre_push_hook(struct transport *transport,
if (!r->peer_ref) continue;
if (r->status == REF_STATUS_REJECT_NONFASTFORWARD) continue;
if (r->status == REF_STATUS_REJECT_STALE) continue;
+ if (r->status == REF_STATUS_REJECT_REMOTE_UPDATED) continue;
if (r->status == REF_STATUS_UPTODATE) continue;
strbuf_reset(&buf);
@@ -1234,19 +1256,20 @@ int transport_push(struct repository *r,
int porcelain = flags & TRANSPORT_PUSH_PORCELAIN;
int pretend = flags & TRANSPORT_PUSH_DRY_RUN;
int push_ret, ret, err;
- struct strvec ref_prefixes = STRVEC_INIT;
+ struct transport_ls_refs_options transport_options =
+ TRANSPORT_LS_REFS_OPTIONS_INIT;
if (check_push_refs(local_refs, rs) < 0)
return -1;
- refspec_ref_prefixes(rs, &ref_prefixes);
+ refspec_ref_prefixes(rs, &transport_options.ref_prefixes);
trace2_region_enter("transport_push", "get_refs_list", r);
remote_refs = transport->vtable->get_refs_list(transport, 1,
- &ref_prefixes);
+ &transport_options);
trace2_region_leave("transport_push", "get_refs_list", r);
- strvec_clear(&ref_prefixes);
+ strvec_clear(&transport_options.ref_prefixes);
if (flags & TRANSPORT_PUSH_ALL)
match_flags |= MATCH_REFS_ALL;
@@ -1362,12 +1385,12 @@ int transport_push(struct repository *r,
}
const struct ref *transport_get_remote_refs(struct transport *transport,
- const struct strvec *ref_prefixes)
+ struct transport_ls_refs_options *transport_options)
{
if (!transport->got_remote_refs) {
transport->remote_refs =
transport->vtable->get_refs_list(transport, 0,
- ref_prefixes);
+ transport_options);
transport->got_remote_refs = 1;
}
@@ -1433,6 +1456,8 @@ int transport_disconnect(struct transport *transport)
int ret = 0;
if (transport->vtable->disconnect)
ret = transport->vtable->disconnect(transport);
+ if (transport->got_remote_refs)
+ free_refs((void *)transport->remote_refs);
free(transport);
return ret;
}