summaryrefslogtreecommitdiff
path: root/send-pack.c
diff options
context:
space:
mode:
Diffstat (limited to 'send-pack.c')
-rw-r--r--send-pack.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/send-pack.c b/send-pack.c
index 7d172ef37f..6129b0fd8e 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -5,10 +5,12 @@
#include "sideband.h"
#include "run-command.h"
#include "remote.h"
+#include "connect.h"
#include "send-pack.h"
#include "quote.h"
#include "transport.h"
#include "version.h"
+#include "sha1-array.h"
static int feed_object(const unsigned char *sha1, int fd, int negative)
{
@@ -27,7 +29,7 @@ static int feed_object(const unsigned char *sha1, int fd, int negative)
/*
* Make a pack stream and spit it out into file descriptor fd
*/
-static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra, struct send_pack_args *args)
+static int pack_objects(int fd, struct ref *refs, struct sha1_array *extra, struct send_pack_args *args)
{
/*
* The child becomes pack-objects --revs; we feed
@@ -70,7 +72,7 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
* parameters by writing to the pipe.
*/
for (i = 0; i < extra->nr; i++)
- if (!feed_object(extra->array[i], po.in, 1))
+ if (!feed_object(extra->sha1[i], po.in, 1))
break;
while (refs) {
@@ -108,7 +110,7 @@ static int receive_status(int in, struct ref *refs)
struct ref *hint;
int ret = 0;
char *line = packet_read_line(in, NULL);
- if (prefixcmp(line, "unpack "))
+ if (!starts_with(line, "unpack "))
return error("did not receive remote status");
if (strcmp(line, "unpack ok")) {
error("unpack failed: %s", line + 7);
@@ -121,7 +123,7 @@ static int receive_status(int in, struct ref *refs)
line = packet_read_line(in, NULL);
if (!line)
break;
- if (prefixcmp(line, "ok ") && prefixcmp(line, "ng ")) {
+ if (!starts_with(line, "ok ") && !starts_with(line, "ng ")) {
error("invalid ref status from remote: %s", line);
ret = -1;
break;
@@ -173,10 +175,25 @@ static int sideband_demux(int in, int out, void *data)
return ret;
}
+static int advertise_shallow_grafts_cb(const struct commit_graft *graft, void *cb)
+{
+ struct strbuf *sb = cb;
+ if (graft->nr_parent == -1)
+ packet_buf_write(sb, "shallow %s\n", sha1_to_hex(graft->sha1));
+ return 0;
+}
+
+static void advertise_shallow_grafts_buf(struct strbuf *sb)
+{
+ if (!is_repository_shallow())
+ return;
+ for_each_commit_graft(advertise_shallow_grafts_cb, sb);
+}
+
int send_pack(struct send_pack_args *args,
int fd[], struct child_process *conn,
struct ref *remote_refs,
- struct extra_have_objects *extra_have)
+ struct sha1_array *extra_have)
{
int in = fd[0];
int out = fd[1];
@@ -205,6 +222,8 @@ int send_pack(struct send_pack_args *args,
quiet_supported = 1;
if (server_supports("agent"))
agent_supported = 1;
+ if (server_supports("no-thin"))
+ args->use_thin_pack = 0;
if (!remote_refs) {
fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
@@ -212,6 +231,9 @@ int send_pack(struct send_pack_args *args,
return 0;
}
+ if (!args->dry_run)
+ advertise_shallow_grafts_buf(&req_buf);
+
/*
* Finally, tell the other end!
*/
@@ -226,6 +248,7 @@ int send_pack(struct send_pack_args *args,
case REF_STATUS_REJECT_ALREADY_EXISTS:
case REF_STATUS_REJECT_FETCH_FIRST:
case REF_STATUS_REJECT_NEEDS_FORCE:
+ case REF_STATUS_REJECT_STALE:
case REF_STATUS_UPTODATE:
continue;
default:
@@ -270,7 +293,7 @@ int send_pack(struct send_pack_args *args,
}
if (args->stateless_rpc) {
- if (!args->dry_run && cmds_sent) {
+ if (!args->dry_run && (cmds_sent || is_repository_shallow())) {
packet_buf_flush(&req_buf);
send_sideband(out, -1, req_buf.buf, req_buf.len, LARGE_PACKET_MAX);
}
@@ -300,8 +323,12 @@ int send_pack(struct send_pack_args *args,
shutdown(fd[0], SHUT_WR);
if (use_sideband)
finish_async(&demux);
+ fd[1] = -1;
return -1;
}
+ if (!args->stateless_rpc)
+ /* Closed by pack_objects() via start_command() */
+ fd[1] = -1;
}
if (args->stateless_rpc && cmds_sent)
packet_flush(out);