smart-http: support shallow fetch/clone
[gitweb.git] / send-pack.c
index 8c230bf6c925ba6bd3617af62f44cfea8dc09a7b..cd536b4ed5436b9bd63e0649618508f5fdf7ec4e 100644 (file)
@@ -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) {
@@ -106,9 +108,8 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
 static int receive_status(int in, struct ref *refs)
 {
        struct ref *hint;
-       char line[1000];
        int ret = 0;
-       int len = packet_read_line(in, line, sizeof(line));
+       char *line = packet_read_line(in, NULL);
        if (prefixcmp(line, "unpack "))
                return error("did not receive remote status");
        if (strcmp(line, "unpack ok")) {
@@ -119,8 +120,8 @@ static int receive_status(int in, struct ref *refs)
        while (1) {
                char *refname;
                char *msg;
-               len = packet_read_line(in, line, sizeof(line));
-               if (!len)
+               line = packet_read_line(in, NULL);
+               if (!line)
                        break;
                if (prefixcmp(line, "ok ") && prefixcmp(line, "ng ")) {
                        error("invalid ref status from remote: %s", line);
@@ -177,7 +178,7 @@ static int sideband_demux(int in, int out, void *data)
 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];
@@ -213,6 +214,9 @@ int send_pack(struct send_pack_args *args,
                return 0;
        }
 
+       if (!args->dry_run)
+               advertise_shallow_grafts(out);
+
        /*
         * Finally, tell the other end!
         */
@@ -227,6 +231,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:
@@ -301,8 +306,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);