diff options
Diffstat (limited to 'upload-pack.c')
| -rw-r--r-- | upload-pack.c | 71 | 
1 files changed, 54 insertions, 17 deletions
| diff --git a/upload-pack.c b/upload-pack.c index 0ea8516ebf..df151813f9 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -39,6 +39,8 @@ static unsigned int timeout;   */  static int use_sideband;  static int debug_fd; +static int advertise_refs; +static int stateless_rpc;  static void reset_timeout(void)  { @@ -430,7 +432,7 @@ static int get_common_commits(void)  {  	static char line[1000];  	unsigned char sha1[20]; -	char hex[41], last_hex[41]; +	char last_hex[41];  	save_commit_buffer = 0; @@ -441,25 +443,30 @@ static int get_common_commits(void)  		if (!len) {  			if (have_obj.nr == 0 || multi_ack)  				packet_write(1, "NAK\n"); +			if (stateless_rpc) +				exit(0);  			continue;  		}  		strip(line, len);  		if (!prefixcmp(line, "have ")) {  			switch (got_sha1(line+5, sha1)) {  			case -1: /* they have what we do not */ -				if (multi_ack && ok_to_give_up()) -					packet_write(1, "ACK %s continue\n", -						     sha1_to_hex(sha1)); +				if (multi_ack && ok_to_give_up()) { +					const char *hex = sha1_to_hex(sha1); +					if (multi_ack == 2) +						packet_write(1, "ACK %s ready\n", hex); +					else +						packet_write(1, "ACK %s continue\n", hex); +				}  				break;  			default: -				memcpy(hex, sha1_to_hex(sha1), 41); -				if (multi_ack) { -					const char *msg = "ACK %s continue\n"; -					packet_write(1, msg, hex); -					memcpy(last_hex, hex, 41); -				} +				memcpy(last_hex, sha1_to_hex(sha1), 41); +				if (multi_ack == 2) +					packet_write(1, "ACK %s common\n", last_hex); +				else if (multi_ack) +					packet_write(1, "ACK %s continue\n", last_hex);  				else if (have_obj.nr == 1) -					packet_write(1, "ACK %s\n", hex); +					packet_write(1, "ACK %s\n", last_hex);  				break;  			}  			continue; @@ -519,7 +526,9 @@ static void receive_needs(void)  		    get_sha1_hex(line+5, sha1_buf))  			die("git upload-pack: protocol error, "  			    "expected to get sha, not '%s'", line); -		if (strstr(line+45, "multi_ack")) +		if (strstr(line+45, "multi_ack_detailed")) +			multi_ack = 2; +		else if (strstr(line+45, "multi_ack"))  			multi_ack = 1;  		if (strstr(line+45, "thin-pack"))  			use_thin_pack = 1; @@ -613,7 +622,7 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo  {  	static const char *capabilities = "multi_ack thin-pack side-band"  		" side-band-64k ofs-delta shallow no-progress" -		" include-tag"; +		" include-tag multi_ack_detailed";  	struct object *o = parse_object(sha1);  	if (!o) @@ -637,12 +646,32 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo  	return 0;  } +static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data) +{ +	struct object *o = parse_object(sha1); +	if (!o) +		die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1)); +	if (!(o->flags & OUR_REF)) { +		o->flags |= OUR_REF; +		nr_our_refs++; +	} +	return 0; +} +  static void upload_pack(void)  { -	reset_timeout(); -	head_ref(send_ref, NULL); -	for_each_ref(send_ref, NULL); -	packet_flush(1); +	if (advertise_refs || !stateless_rpc) { +		reset_timeout(); +		head_ref(send_ref, NULL); +		for_each_ref(send_ref, NULL); +		packet_flush(1); +	} else { +		head_ref(mark_our_ref, NULL); +		for_each_ref(mark_our_ref, NULL); +	} +	if (advertise_refs) +		return; +  	receive_needs();  	if (want_obj.nr) {  		get_common_commits(); @@ -664,6 +693,14 @@ int main(int argc, char **argv)  		if (arg[0] != '-')  			break; +		if (!strcmp(arg, "--advertise-refs")) { +			advertise_refs = 1; +			continue; +		} +		if (!strcmp(arg, "--stateless-rpc")) { +			stateless_rpc = 1; +			continue; +		}  		if (!strcmp(arg, "--strict")) {  			strict = 1;  			continue; | 
